我不能手动"continue"所有这些无关的SIGTRAP . 但是如果我使用命令 handle SIGTRAP nostop noprint
,则GDB不会在我的断点处停止 .
似乎必须有一种方法来教育GDB,以便它了解哪个SIGTRAP有利于停止,哪个不利于停止 . 很明显,GDB知道它是否处于断点,因为输出非常可靠地不同:在断点处,它提到“断点”并显示断点号 - 但在任何其他SIGTRAP中,它只是说“SIGTRAP” . 所以不是打印关于SIGTRAP的消息,我真的很喜欢GDB对自己说,“哇,这是一个SIGTRAP,这里没有断点 - 看着我,我要停下来打印一个完全破坏调试会话的无用的SIGTRAP消息!我只是静静地继续?“如果有人有办法,请告诉我 .
1 回答
您可以设置catchpoints以捕获SIGTRAP信号并添加命令以决定是继续还是停止 . 在此处理程序中,您可以检查convenience variables,例如$_siginfo,以了解信号的原因 .
特别感兴趣的是
$_siginfo.si_code
,其值取决于所传递的信号 . sigaction(2) Linux手册页描述了确切的关系 . 您可以通过编译程序或查找 Headers 来找到这些SI_USER
,SI_KERNEL
等代码的数值(在我的系统上它使用 Headers/usr/include/bits/siginfo.h
) . 我遇到的一些值是:0x00(0):
SI_USER
0x80(128):
SI_KERNEL
0x02(2):
TRAP_TRACE
有了这些信息,这里有一个捕获SIGTRAP并打印原因的例子,然后继续:
现在考虑这个睡眠时间为5秒的测试程序,然后在x86(-64)上触发调试陷阱:
该程序在
int3
行停止gdb
,因为信号被捕获(si_code
恰好是0x80,SI_KERNEL
),但随后指令再次重复 . 因此,要跳过此指令,必须递增程序计数器($pc
) . 完成后,我学习了有关SIGTRAP
和si_code
的信息:断点使用代码128(
SI_KERNEL
)触发SIGTRAP .继续破坏之后,接收到代码为2(
TRAP_TRACE
)的SIGTRAP(因为SIGTRAP
的捕获点) .int3
指令使用代码128触发SIGTRAP . 因此,您需要一些东西来区分指令 .以下是跳过
int3
陷阱并仍保持断点功能的最终GDB命令:最后一点:SIGTRAP由调试器在内部使用,上述内容可能过多 . 这是在Arch Linux上使用GDB 7.10测试的 .