Tag: #strace

Another strace useful option

This article will be really quick. I found another useful strace option. It allows to track system calls related to specified path -P. It is part of strace utility, so we can assume, it will be much more efficient than grepping the output.

As an example I can show you tracing all data sent by communication program to another device connected via RS-485 (/dev/ttyO4)

# strace -p 313 -x -e trace=write,read -P /dev/ttyO4
Process 313 attached
read(6, "\xff\xff\x01\x03\xd0\x07\x00\x00\xab\x01", 256) = 10
read(6, "\x00\x00\xb6\x01\x00\x00\x9e\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10", 256) = 21
read(6, "\x07\x10\x00\x00\x00\x00\x00\x3b\x99\xff\x02", 256) = 11
write(6, "\xff\x01\x01\x06\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeb\xf0\xff"..., 33) = 33
read(6, "\xff\xff\x01\x01\xd0\x07\x00\x00", 256) = 8
read(6, "\x9d\x01\x00\x00\xa6\x01\x00\x00\x90\x01\x00\x00\x00", 256) = 13
read(6, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00", 256) = 12
read(6, "\x00\x00\x00\x00\x00\x11\x41\xff\x02", 256) = 9
write(6, "\xff\x01\x02\x06\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x33\x06\xff"..., 33) = 33
read(6, "\xff\xff\x01\x02\xd0\x07", 256) = 6

Program works on PID 313 (-p 313), we want to show data in hexadecimal form (-x) and trace only write and read syscalls (-e trace=write,read). Finally the option specifying the right path is -P /dev/ttyO4. As we can see, only file descriptor 6. To proof that it’s the right one, let’s list all file descriptors used by the process:

# ls -la /proc/313/fd
total 0
dr-x------    2 root     root             0 Nov  8 08:03 .
dr-xr-xr-x    8 root     root             0 Nov  8 08:03 ..
lr-x------    1 root     root            64 Nov  8 08:03 0 -> /dev/null
l-wx------    1 root     root            64 Nov  8 08:03 1 -> /dev/null
l-wx------    1 root     root            64 Nov  8 08:03 2 -> /dev/null
lrwx------    1 root     root            64 Nov  8 08:03 3 -> socket:[8861]
lrwx------    1 root     root            64 Nov  8 08:03 4 -> anon_inode:[timerfd]
lrwx------    1 root     root            64 Nov  8 08:03 5 -> anon_inode:[timerfd]
lrwx------    1 root     root            64 Nov  8 08:04 6 -> /dev/ttyO4
lrwx------    1 root     root            64 Nov  8 08:04 7 -> /dev/pts/0

File descriptor number 6 is linked to our resource – /dev/ttyO4. This option is very useful in solving wide range of problems. Hope it will help.

Favourite strace options

I will try to avoid writing next article about Linux developer/admin swiss army knife, which is obviously strace. Instead, I would like to focus on most useful options:

Follow forks -f

If you try to debug your multithreading application, don’t forget about -f option. After that, strace will track all new threads and child processes.

This is really useful for checking what’s going on, after any sort of deamon, like sshd or getty, accept new client.

For example, I want to catch any file operations made by new, logged on user on SSH:

# pgrep sshd # (1) returns sshd PID -> 256
256
# strace -p 256 -e trace=file -f
 ... a lot of spam (checking user authentity in files like /etc/passwd...
[pid  9883] open("/root/.ash_history", O_WRONLY|O_CREAT|O_APPEND|O_LARGEFILE, 0600) = 3
[pid  9883] stat64("/bin/cat", {st_mode=S_IFREG|S_ISUID|0755, st_size=655180, ...}) = 0
Process 9894 attached
[pid  9894] execve("/bin/cat", ["cat", "/etc/network/interfaces"], [/* 20 vars */]) = 0
...ld and dynamic linking stuff...
[pid  9894] open("/etc/network/interfaces", O_RDONLY|O_LARGEFILE) = 3
[pid  9894] +++ exited with 0 +++
[pid  9883] --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=9894, si_uid=0, si_status=0, si_utime=1, si_stime=3} ---
# # (4)
  1. If you don’t have pgrep, just use top or htop. pgrep might return several PIDs, which are main sshd process and it’s children (existing sessions). Probably it will be first one.
  2. -e trace=fileis my next favourite option. It tracks all syscalls related to file manipulation and reading.
  3. This guy executed cat /etc/network/interfaces
Filtering out syscalls

strace have great filtering options. Embedded systems quite often has some limits on it, but it’s still quite useful

  • Track file related syscalls: -e trace=file
  • Filtering precise syscall: -e trace=mmap2.
  • Track network stuff, but not sendto/recvfrom: -e trace=network -e trace=\!sendto -e trace=\!recvfrom – some shells need backslash before exclamation mark
  • Last resort, if those filters not fit, you can use grep. This example show syscalls which fails on errno EAGAIN: strace -p XXX 2>&1 | grep EAGAIN – remember, that strace output is taken into stderr. To pipe it together with stdout you need add 2>&1. grep is much more flexible, however there is big efficiency impact without using strace builtin filters. Each process usually make huge amount of syscalls, and all of them are piped.
Performance analysis

Really nice feature is measuring time spent in each syscall. You can make it with -T option, and check how many seconds it lasts. Remember that if your process is preempted on a syscall, the time of other jobs is accumulated into measurement. That’s beacuse time is measured between entering syscall and returning it’s exit code.

Usually useful is adding -tt option which prefixes all records with microsecond timestamp. It lets you correlate syscalls with other logs.

Worth noting here is possibility to track several processes. You can use -p option multiple times and give several PIDs. I’ve used this option recently to track how threads connected through IPC are preempting each other.

Don’t forget…

…that ever debug tool have impact on system you follow. In this case every syscall generates huge console output, which slows down execution.

Strace implementation are different. Especially on embedded systems not all options are available

Obviously you must have root privileges to use strace.