133

I used strace to attach to a process briefly. The process created 90 threads. When I found the offending thread, I had to tediously search for the parent thread, then the grandparent thread, and so on all the way to the root process.

Is there a trick or tool to quickly figure out which thread created another? Or better yet, print the tree of thread creations like pstree?

phs
  • 10,687
  • 4
  • 58
  • 84
projectshave
  • 3,771
  • 5
  • 23
  • 24

4 Answers4

162

strace -f to trace child process that's fork()ed.

Je Rog
  • 5,675
  • 8
  • 39
  • 47
  • It's worth noting though that if you are attaching strace to an already running process, any _existing_ child processes are not traced even with `-f` – sparrowt May 25 '23 at 08:51
28

I can't see an easy way:

You could use the -ff option with -o filename to produce multiple files (one per pid).

eg:

strace -o process_dump -ff ./executable
grep clone process_dump*

that would help you see which parent created what. Maybe that would help you - at least then you could search backwards.

stackmate
  • 908
  • 9
  • 17
23

There is a perl script called strace-graph. Here is a version from github. It is packaged with crosstool-ng versions of compilers. It works for me even used cross platform.

There is also a more modern python3 script. It can be installed on Debian/Ubuntu (and many other systems) with pip3 install strace-process-tree.

The process below to capture data is the same for both (but use strace-process-tree instead to create the graph). Thanks Jan Tojnar

It seems the perl script may suffer from bit rot. For a cross platform solution with older busybox type ps, it may work.


ARM Linux box.

$ ./strace -f -q -s 100 -o app.trc -p 449
$ tftp -pr app.trc 172.0.0.133

X86_64 Linux box.

$ ./strace-graph /srv/tftp/app.trc 
 (anon)
  +-- touch /tmp/ppp.sleep
  +-- killall -HUP pppd
  +-- amixer set Speaker 70%
  +-- amixer set Speaker 70%
  +-- amixer set Speaker 70%
  +-- amixer set Speaker 70%
  +-- amixer set Speaker 50%
  +-- amixer set Speaker 70%
  `-- amixer set Speaker 50%

The output can be used to help navigate the main trace log.


strace-process-tree example

$ strace -f -q -o app.trc sh -c 'for i in `seq 0 10` ; do /usr/bin/echo "Hello There"; done;'
$ strace-process-tree -A -C app.trc
356 sh -c 'for i in `seq 0 10` ; do /usr/bi...'
  |-357 seq 0 10
  |-358 /usr/bin/echo "Hello There"
  |-359 /usr/bin/echo "Hello There"
  |-360 /usr/bin/echo "Hello There"
  |-361 /usr/bin/echo "Hello There"
  |-362 /usr/bin/echo "Hello There"
  |-363 /usr/bin/echo "Hello There"
  |-364 /usr/bin/echo "Hello There"
  |-365 /usr/bin/echo "Hello There"
  |-366 /usr/bin/echo "Hello There"
  |-367 /usr/bin/echo "Hello There"
  `-368 /usr/bin/echo "Hello There"
artless noise
  • 21,212
  • 6
  • 68
  • 105
  • 1
    very nice, this is almost exactly something i wanted for at least several days. surprisingly, i can even see it in my /usr/share/doc/strace/examples/. – mykhal Dec 03 '13 at 15:59
  • 1
    Actually, looks like the Perl script is considered broken upstream: https://github.com/strace/strace/commit/5685c0d0335246b37c57e65303c82206bdd45e65 – Jan Tojnar May 24 '23 at 00:52
1

To capture traffic for a single process you can use strace, as @stackmate suggested.

strace -f -e trace=network -s 10000 -p <PID>;

or output it to a file.

strace -f -e trace=network -s 10000 -o dumpfile -p <PID>

-f for all forked process, -s for string size to print, and -o to dump the output to a file.

alshaboti
  • 643
  • 8
  • 18