For example, there is no native BreakpointEvent notification. Rather, the debugger implementer needs to keep track of all breakpoints; if a SIGTRAP occurs at the address where an active breakpoint exists, then it is most likely because the said breakpoint was hit.
Another solution is to use PTRACE_GETSIGINFO (available since kernel 2.3.99) and inspect the
siginfo_t
structure:
struct siginfo_t {
int si_signo; /* Signal number */
int si_errno; /* An errno value */
int si_code; /* Signal code */
pid_t si_pid; /* Sending process ID */
uid_t si_uid; /* Real user ID of sending process */
int si_status; /* Exit value or signal */
clock_t si_utime; /* User time consumed */
clock_t si_stime; /* System time consumed */
sigval_t si_value; /* Signal value */
int si_int; /* POSIX.1b signal */
void *si_ptr; /* POSIX.1b signal */
void *si_addr; /* Memory location which caused fault */
int si_band; /* Band event */
int si_fd; /* File descriptor */
}
For a SIGTRAP signal, the si_code field may be TRAP_BRKPT, in which case we know that the program hit a breakpoint.
At any rate, it is up to the debugger application to create higher-level abstractions, based on signals and ptrace notifications.
Linux is not the easiest nor most pleasant system to program on, but the implementation is so simple a child could understand it. Ahem.
No comments:
Post a Comment