Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stracing to attach to a multi-threaded process

Tags:

linux

strace

If I want to strace a multi-threaded process (of all of its threads), how should I do it?

I know that one can do strace -f to follow forked process? But how about attaching to a process which is already multi-threaded when I start stracing? Is a way to tell strace to trace all of system calls of all the threads which belong to this process?

like image 858
yangsuli Avatar asked Feb 04 '13 20:02

yangsuli


2 Answers

2021 update

strace -fp PID just does the right thing on my system (Ubuntu 20.04.1 LTS). The strace manual page points this out:

       -f          Trace  child  processes  as  they are created by currently traced processes as a result of the fork(2), vfork(2) and clone(2) system                    calls.  Note that -p PID -f will attach all threads of process PID if it is multi-threaded, not only thread with thread_id = PID. 

Looks like this text was added back in 2013. If -f had this behavior on my system at the time, I didn't realize it. It does now, though!

Original 2013 answer

I just did this in a kludgy way, by listing each tid to be traced.

You can find them through ps:

$ ps auxw -T | fgrep program_to_trace me pid tid1 ... me pid tid2 ... me pid tid3 ... me pid tid4 ... 

and then, according to man strace, you can attach to multiple pids at once:

   -p pid      Attach to the process with the process ID pid and begin tracing.  The trace may be terminated at any time by a  keyboard  interrupt                signal  (CTRL-C).  strace will respond by detaching itself from the traced process(es) leaving it (them) to continue running.  Mul‐                tiple -p options can be used to attach to up to 32 processes in addition to command (which is optional if at least one -p option is                given). 

It says pid, but iirc on Linux the pid and tid share the same namespace, and this appeared to work:

$ strace -f -p tid1 -p tid2 -p tid3 -p tid4 

I think that might be the best you can do for now. But I suppose someone could extend strace with a flag for expanding tids. There would probably still be a race between finding the processes and attaching to them in which a freshly started one would be missed. It'd fit in with the existing caveat about strace -f:

   -f          Trace child processes as they are created by currently traced processes as a result of the fork(2) system call.                 On non-Linux platforms the new process is attached to as soon as its pid is known (through the return value of fork(2) in the  par‐                ent process). This means that such children may run uncontrolled for a while (especially in the case of a vfork(2)), until the par‐                ent is scheduled again to complete its (v)fork(2) call.  On Linux the child is traced from its first instruction with no delay.  If                the  parent  process  decides  to  wait(2)  for  a child that is currently being traced, it is suspended until an appropriate child                process either terminates or incurs a signal that would cause it to terminate (as determined from the child's current signal dispo‐                sition).                 On SunOS 4.x the tracing of vforks is accomplished with some dynamic linking trickery. 
like image 104
Scott Lamb Avatar answered Sep 24 '22 23:09

Scott Lamb


As answered in multiple comments, strace -fp <pid> will show the trace of all threads owned by that process - even ones that process already has spawned before strace begins.

like image 36
Blake H Avatar answered Sep 25 '22 23:09

Blake H