16

I'm working on an linux application incorporating ptrace to observe the threads of another process. When the application I observe forks a child process this already works quite well. By calling waitpid in my application I can obtain the following signals in the observing application:

  • SIGSTOP form the child process
  • SIGTRAP from the parent

To keep track of all the children I setup ptrace with PTRACE_O_TRACEFORK, PTRACE_O_TRACEVFORK, PTRACE_O_TRACECLONE and PTRACE_O_TRACEEXIT.

While everything is working quite fine with child processes, I cannot observe the threads of the application. I get the SIGTRAP from the process creating the thread but I don't get any signals from the thread.

Is there anything special with threads and ptrace? How does strace keep track of threads (I could not find any special routines dedicated to threads in the code of strace)?

This is how I use ptrace in my application:

  • First I attach to a process: ptrace(PTRACE_ATTACH, pid, NULL, NULL);
  • Then, I call waitpid(): trace_pid = waitpid(-1, &status, 0);
  • Set ptrace options: ptrace(PTRACE_SETOPTIONS, pid, NULL, PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACECLONE | PTRACE_O_TRACEEXIT);

After attaching to pid I'm calling waitpid() in a loop and call ptrace(PTRACE_SETOPTIONS... for every new task reported by ptrace. Of course, I continue the tasks with SIGCONT after event handling.

perror
  • 7,071
  • 16
  • 58
  • 85
mupro
  • 333
  • 2
  • 11
  • 2
    I think I've come a bit closer to the core of the problem: When a new thread is created I don't even receive the sigstop in the observing process. However,in the ptrace documentatio it sais: "automatically start tracing the newly cloned process, which will start with a SIGSTOP." How can this happen? – mupro Sep 03 '11 at 11:09
  • I've done a bit of further investigation using procfs and a little application using posix threads. All the application does is to start a new thread and sleep for a while. The new thread is also sleeping for a few seconds. As I said, I don'd receive a sigstop with waitpid for the new thread. However the status file in procfs for the new thread is telling me: Name: thread_test State: t (tracing stop) Tgid: 2538 Pid: 2545 PPid: 2395 TracerPid: 2540 So the new thread is stopped but waitpid does not receive the stop signal. What's the correct way of tracing threads? – mupro Sep 03 '11 at 13:03
  • note that `ptrace(1)`'s man page line 604 states: "Flags are inherited by new tracees created and "auto-attached" via active PTRACE_O_TRACEFORK, PTRACE_O_TRACEVFORK, or PTRACE_O_TRACECLONE options." So that means you don't need to call `PTRACE_SETOPTIONS` for every new task. – fvalasiad Jun 20 '22 at 11:58

1 Answers1

16

Finally, I've found the solution myself: I got the signals from all the threads by calling

waitpid(-1, &status, __WALL)

instead of

waitpid(-1, &status, 0)
mupro
  • 333
  • 2
  • 11