You can set catchpoints to catch the SIGTRAP signal and add commands to decide whether to continue or stop. In this handler, you can check for handy variables like $_siginfo because of the signal.
Of particular interest is $_siginfo.si_code , its value depends on the transmitted signal. sigaction (2) The Linux manual page describes the exact relationship. You can find the numerical values for these codes SI_USER , SI_KERNEL , etc. SI_KERNEL program or looking at the headers (my system uses the /usr/include/bits/siginfo.h header). Some of the values I came across are as follows:
- 0x00 (0):
SI_USER - 0x80 (128):
SI_KERNEL - 0x02 (2):
TRAP_TRACE
With this information in hand, here is an example that catches SIGTRAP and prints the reason, and then continues:
catch signal SIGTRAP commands p $_siginfo.si_code c end # Set another breakpoint for testing break sleep
Now consider this test program, which sleeps 5 seconds, then runs the debug trap on x86 (-64):
#include <unistd.h> int main(void) { for (;;) { sleep(5); asm("int3"); } return 0; }
This program continues to stop gdb on the int3 line because the signal is caught ( si_code is 0x80, SI_KERNEL ), but then the command is repeated again. Therefore, to skip this instruction, the program counter ( $pc ) must be increased. After that, I found out this information about SIGTRAP and si_code :
- Breakpoints start SIGTRAP with code 128 (
SI_KERNEL ). - After continuing the U-turn, SIGTRAP with code 2 (
TRAP_TRACE ) is TRAP_TRACE (due to the catch point for SIGTRAP ). - The
int3 instruction starts SIGTRAP with the code 128. Thus, you need to distinguish something from the instructions.
Here are the final GDB commands that skip int3 traps and still retain interrupt functionality:
catch signal SIGTRAP commands silent
One final note: SIGTRAP is used internally by the debugger, it is possible that the above catches too much. This has been tested with GDB 7.10 on Arch Linux.
source share