Daniel Jacobowitz wrote:
On Sat, Jul 11, 2009 at 11:07:51AM +0300, Shachar Shemesh wrote:
The problem is that, as a debugger, I need to be able to
differentiate between a SIGTRAP supposedly delivered to the debuggee
because I asked to trace the system calls, and a SIGTRAP actually
delivered to the debuggee. If I don't, my count is going to be off,
and I will totally mis-interpret the debugee's state.

The best way, as far as I can tell, to do that on Linux is to use the
PTRACE_GETSIGINFO command. This provides me with a field, si_code,
that can distinguish between a signal and a system call. This is
important to make sure that I don't get confused over which is which.

Have you seen PTRACE_SETOPTIONS and PTRACE_O_TRACESYSGOOD?

Hi Daniel,

Yes, I have, and the last sentence in the relevant paragraph from the ptrace(2) manual page scares me no end:
              PTRACE_O_TRACESYSGOOD (since Linux 2.4.6)
When delivering syscall traps, set bit 7 in the signal number (i.e., deliver (SIGTRAP | 0x80) This makes it easy for the tracer to tell the difference between normal traps and those caused by a syscall. (PTRACE_O_TRACESYSGOOD may not work on all architectures.)
Admittedly, I tried to find out where the "5" was coming from for GETSIGINFO (as the user space headers only define 1 and 2, and the kernel headers define 1-4). After some research, it appears that the vanilla kernel's "5" si_code report just happens to be the value of SIGTRAP (the actual code is at includes/tracehook.h in the ptrace_report_syscall function, the call to the ptrace_notify function places the value into si_code). In other words, not the most reliable in the world either.

The bottom line is that it does not matter much. Between the platform's inconsistency (single step reports 1 on i686, 2 on amd64), the randomness that is the si_code for syscall tracing, and the fact that you can ask for single step OR be notified of syscalls, but not both, the only conclusion is that there are two valid values for si_code: 0 means a standard signal (including the one generated after an execve), and anything else is a trace/trap/syscall/singlestep, based on what you asked to do. At least for fakeroot-ng, that is good enough.

Don't get me wrong. This is a horrible mess. Then again, particularly on this list, I'm certain I'm not saying anything new to any of you when I say ptrace is a mess. The thing is, it is usable.

Getting back to the matters at hand, the utrace behavior is simply incorrect. EINVAL is supposed to mean that I passed an invalid value to the system call. For GETSIGINFO, it means that the kernel is passing invalid values to me. This should never happen.

Shachar

--
Shachar Shemesh
Lingnu Open Source Consulting Ltd.
http://www.lingnu.com

Reply via email to