Say I'm writing a hypothetical debugger. A debugger wants to set breakpoints and watchpoints (both software and hardware) and what not. When a tracee hits a breakpoint a SIGTRAP is generated.

But using ptrace, it too, can "generate" SIGTRAP signals, which leads me to this question - is there a way to immediately differentiate between a SIGTRAP caused by some ptrace request? It would allow for not having to "scan" all the breakpoints the debugger might have potentially set, to see if the SIGTRAP was caused by a breakpoint it set or by some ptrace request.

Sure, one way would be to store some meta data/state, representing if the tracer has issued a ptrace request - but this is fragile (very, very fragile) as anything might have happened between issuing the request and seeing the signal (from the tracer's perspective). Many of the (if not all) of the PTRACE_O_... (so called PTRACE_EVENT stops) settings can be inspected via some bit shifting, but these are events reported "automatically"; they don't come after some issued ptrace request.

1

There are 1 best solutions below

6
jpalecek On BEST ANSWER

Yes, as is written in the documentation, for example:

PTRACE_O_TRACEFORK (since Linux 2.5.46)
      Stop the tracee at the next fork(2) and automatically start tracing the newly forked process, which will start with a SIGSTOP, or PTRACE_EVENT_STOP if PTRACE_SEIZE was used.  A waitpid(2) by the tracer will return a status value such that

         status>>8 == (SIGTRAP | (PTRACE_EVENT_FORK<<8))

You'll get the the distinction in the status returned by waitpid.

If you talk about response to a PTRACE_INTERRUPT request, then IMHO you should rethink whether it really matters that it stopped for this reason or due to a breakpoint hit earlier. And of course "scaning" all the breakpoints the debugger might have potentially set is basically the bread and butter of the debugger's operation.