3

When I first open a terminal, or open a new one after not having used one for a while, any kind of tab completion in my home directory (for example, ls and Tab) takes several seconds. I have seen this behavior before when using autofs to mount network drives, but I don't have any in ~/. I do mount NFS shares with systemd's automount, but those are in ~/badabing/, so everything in ~/ itself is just a local file.

In case it is an automount issue, here are the relevant /etc/fstab lines (yes, the server is called "badabing", I named it during a Sopranos binge a few years ago):

badabing:/nfs_shares/music /mnt/badabing/music    nfs4  noauto,x-systemd.automount,x-systemd.device-timeout=5sec,x-systemd.idle-timeout=1min    0 0
badabing:/nfs_shares/series /mnt/badabing/series  nfs4  noauto,x-systemd.automount,x-systemd.device-timeout=5sec,x-systemd.idle-timeout=1min    0 0
badabing:/nfs_shares/movies /mnt/badabing/movies  nfs4  noauto,x-systemd.automount,x-systemd.device-timeout=5sec,x-systemd.idle-timeout=1min    0 0

Then, in ~/badabing I have:

$ ls -l ~/badabing/
total 0
lrwxrwxrwx 1 terdon terdon 32 Jan 10  2016 movies -> /mnt/badabing/nfs_shares/movies/
lrwxrwxrwx 1 terdon terdon 31 Jan 10  2016 music -> /mnt/badabing/nfs_shares/music/
lrwxrwxrwx 1 terdon terdon 31 Jan 10  2016 series -> /mnt/badabing/nfs_shares/series

I'd like to investigate this more. Can I somehow strace tab completion? Is the only way to add echo commands in the various bash completion scripts to see what's hanging? There are quite a few of those so I'd really rather avoid that.

So, what's causing this or, at least, how can I debug it further?

  • You can run strace against a given process, and see where the bash process is spending time. Adding echo's to scripts won't show you issues in tab completion. – Thomas Dickey Nov 19 '16 at 13:36
  • @ThomasDickey I was thinking of the scripts in /usr/share/bash-completion which are run when bash tries to complete something. How would I run strace here though? I can't do strace bash 2>log since that will hang. Ah, I just saw that I can attach strace to an already running process. I'll try that, thanks. – terdon Nov 19 '16 at 14:20
  • That's the -p option of strace. – Thomas Dickey Nov 19 '16 at 14:22
  • @ThomasDickey yeah, just tried that but it seems to run and exit immediately. How can I keep it running while I test things in the straced bash session? – terdon Nov 19 '16 at 14:22
  • Perhaps you attached to a child process. If you attach to the parent process and use the -f option, that will follow the (new) child processes. – Thomas Dickey Nov 19 '16 at 14:31
4

I would do this:

sudo strace -pXXXX -tfo /tmp/strace.log

where XXXX is the process id of bash. In a quick check of filename completion on one of my NFS-mounted directory trees, it works without problems:

-f

Trace child processes as they are created by currently traced processes as a result of the fork(2) system call.

-t

Prefix each line of the trace with the time of day.

Some people might prefer -r:

-r

Print a relative timestamp upon entry to each system call. This records the time difference between the beginning of successive system calls.

2

Run set -x to get a trace of every shell command, even those executed by the completion framework.

Run strace -f -p 1234 from another shell to see a trace of system calls. If you get the error “Operation not permitted”, it may be due to a security restriction that restricts the ptrace system call to children of the tracing process.¹ To disable this restriction, run sysctl kernel.yama.ptrace_scope=0 as root. See https://askubuntu.com/questions/41629/after-upgrade-gdb-wont-attach-to-process for more information. Alternatively, you can still start a shell with strace -T -f -o strace.bash bash (-T adds the time spent in each system call) and do your experiments from there.

¹ This restriction limits the impact of running a malicious application from your account. It's only effective if coupled with many other restrictions (typically effected with SELinux or AppArmor), in particular to limit the restricted process to a small set of files. Even in restricted ptrace mode, the typical use case for ptrace, which is for a debugger to debug a child process, remains allowed.

1

Maybe this helps:

PS4='Line ${LINENO}: ' bash -x /usr/share/bash-completion/bash_completion ls
  • Its not clear to me as a neophyte what this command does. Could you help by explaining it – Gabriel Fair Jan 2 at 16:58
  • The command PS4='Line ${LINENO}: ' bash -x XYZ goes line by line through the script XYZ and prints each line with line number. The command includes subscripts and you don’t have to modify the script (like set -X). This is useful if you want to debug scripts. – musbach Jan 2 at 19:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.