GDB被杀死后,如何从处理器中清除断点?

时间:2018-11-09 00:14:11

标签: debugging gdb

当我的SSH连接断开时,我正在在Linux环境中通过SSH运行的GDB中调试Free Pascal应用程序。我从经验中看到,发生这种情况时GDB已关闭,并且可以肯定的是,我运行了pidof gdb并且什么也没有返回。我重新打开了GDB,并附加到了同一个正在运行的应用程序,几分钟后,我得以继续调试并完成调试。我完成调试一个小时后,该应用程序意外死亡。我唯一反映出发生了什么的日志是这样的:

Nov  5 16:29:59 kernel: [846469.866825] traps: Maintain[9065] trap int3 ip:7f5148924cf1 sp:7f51376a4420 error:0

经过一番研究,似乎发送到应用程序的sigtrap会杀死它,除非它被调试器捕获。我的假设是该信号是由于程序达到我设置的断点而导致的,GDB不再可用于捕获该信号。

这是我的问题:

  1. GDB是否有可能在意外关闭后将断点陷阱留在处理器中?
  2. 如果是这种情况,在应用了断点然后意外关闭之后,是否有某种方法可以从处理器清除断点?

1 个答案:

答案 0 :(得分:0)

  

我的假设是该信号是由程序达到我设置的断点引起的

这种假设可能是不正确的:GDB在从流程中自动分离时会删除所有断点。

陷阱地址7f5148924cf1似乎属于某个共享库。

如果您有核心转储,或在进程处于活动状态时记录了共享库的位置,则可以检查在该地址加载的库,并查看其中的指令。可能是:这是int3与任何GDB断点无关。将__asm__("INT3")__asm__(UD2)放入“不可能发生”分支并有效地实现无法编译的assert并不少见。

另一种可能性:您的应用跳过了野生函数指针。

我刚刚为自己的objdump -d看过libpthread.so.0,并且看到了很多INT3

__pthread_initialize_minimal:
...
    9479:       b8 00 40 00 00          mov    $0x4000,%eax
    947e:       e9 8f fe ff ff          jmpq   9312 <__pthread_initialize_minimal+0x1f2>
    9483:       cc                      int3   
    9484:       cc                      int3   
    9485:       cc                      int3   
    9486:       cc                      int3   
    9487:       cc                      int3   
    9488:       cc                      int3   
    9489:       cc                      int3   

sigcancel_handler:
...
    950c:       e8 2f 9e 00 00          callq  13340 <__pthread_unwind>
    9511:       cc                      int3   
    9512:       cc                      int3   
    9513:       cc                      int3   
    9514:       cc                      int3   

等如果应用程序曾经登陆过0x9511或其他INT3中的任何一个,它将与SIGTRAP一起消失,就像您的应用一样。