Get list of processes that were forked off the currently running process

processprocess-managementps

I am writing a wrapper application to bash scripts and want the application to keep a track of which tools/processes have been launched from user scripts. I would like to know what is the best way to determine the list of child processes that were spawned of this parent process.

I tried

  1. Periodically invoking ps command and building a process tree (like ps -ejH) but this misses out on processes that ran to completion very quickly.
  2. Using a tool like forkstat that uses the proc connector interface, but that would only run with elevated privileges. While this gives the correct data, running as sudo would not work in my case?

Any suggestions how this can be achieved?

Best Answer

If you're using Linux, you can use strace to trace system calls used by a process. For example:

~ strace -e fork,vfork,clone,execve -fb execve -o log ./foo.sh
foo bar
~ cat log
4817  execve("./foo.sh", ["./foo.sh"], [/* 42 vars */]) = 0
4817  clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f1bb563b9d0) = 4818
4818  execve("/bin/true", ["/bin/true"], [/* 42 vars */] <detached ...>
4817  --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=4818, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
4817  clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f1bb563b9d0) = 4819
4817  clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f1bb563b9d0) = 4820
4820  execve("/bin/echo", ["/bin/echo", "foo", "bar"], [/* 42 vars */] <detached ...>
4817  --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=4820, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
4817  +++ exited with 0 +++
4819  execve("/bin/sleep", ["sleep", "1"], [/* 42 vars */] <detached ...>

You can see that the script forked off three processes (PIDs 4818, 4819, 4820) using the clone(2) system call, and the execve(2) system calls in those forked off processes show the commands executed.

  • -e fork,vfork,clone,execve limits strace output to these system calls
  • -f follows child processes
  • -b execve detaches from a process when the execve is reached, so we don't see further tracing of child processes.
Related Question