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