35

如果我想 strace 一个多线程进程(它的所有线程),我应该怎么做?

我知道可以执行 strace -f 来跟踪分叉进程?但是当我开始跟踪时附加到一个已经是多线程的进程怎么样?有一种方法可以告诉 strace 跟踪属于该进程的所有线程的所有系统调用吗?

4

2 回答 2

37

2021 年更新

strace -fp PID只是在我的系统上做正确的事(Ubuntu 20.04.1 LTS)。strace手册页指出了这一点:

       -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.

看起来这个文本是在 2013 年添加的。如果-f当时我的系统上有这种行为,我没有意识到。不过现在可以了!

2013年原始答案

我只是通过列出要跟踪的每个 tid 以一种笨拙的方式做到这一点。

您可以通过以下方式找到它们ps

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

然后,根据man strace,您可以一次附加到多个 pid:

   -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).

它说pid,但 iirc 在 Linux 上 pid 和 tid 共享相同的命名空间,这似乎工作:

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

我认为这可能是你目前能做的最好的事情。但我想有人可以strace用一个标志来扩展 tids。在寻找流程和附加流程之间可能仍然存在一场竞赛,其中一个新开始的流程将被错过。它符合现有的警告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.
于 2013-11-17T19:05:55.690 回答
24

正如多条评论中所回答的那样,strace -fp <pid>将显示该进程拥有的所有线程的跟踪——即使是那些进程在strace开始之前已经产生的线程。

于 2018-03-05T12:03:54.173 回答