接收信号时,在循环时停止gdb

时间:2017-09-12 08:14:41

标签: c debugging gdb

我正试图在我的程序中找到一个不会一直发生的分段错误。我正在尝试在gdb的循环中运行我的程序,直到发生分段错误。

我的问题是gdb在收到seg错误后继续while循环,并没有提示我使用gdb shell。

当我运行我的gdb时,我使用:

set $i=0
while($i<100)
  set $i = $i+1
  r
end

任何人都知道如何让gdb在第一次segfault停止而不是100次运行?

谢谢!

2 个答案:

答案 0 :(得分:0)

您可以使用expect编写GDB交互脚本。

但是this answer的解决方案应该就是你需要的所有内容。

  

退出时没有为我工作

您的程序可能会调用_exit而不是exit,因此您可能需要在那里设置断点。

您的程序也可能执行直接SYS_exit系统调用而无需通过exit_exit

在Linux上,您可以通过以下方式识别:

catch syscall exit
catch syscall exit_group

应该触发四个变体中的至少一个(只需手动运行程序)。一旦知道哪个变量实际触发,将命令附加到相应的断点,并使用上面的解决方案。

答案 1 :(得分:0)

gdb文档非常庞大,很难找到您想要的内容,但我可以通过略微调整您的脚本来实现这一目标。

完成后,gdb会将$_exitcode设置为退出代码值。

如果发生segv,则值不会更改。所以我的想法是将它设置为一些愚蠢的值(我选择244)并运行。但是如果在运行命令之后返回代码仍然是244,那么退出循环(可能还有另一种方法)

警告:黑客攻击(但有效)

set $i=0
while($i<100)
  set $i = $i+1
  set $_exitcode = 244
  r
  if $_exitcode==244
    set $i = 200
  end
end

我用交互式程序测试了它。键入n表示正常执行,y表示触发段错误(好吧触发它,但有很好的机会发生这种情况)

#include <stdio.h>
#include <stdlib.h>

int main()
{
   printf("want segfault?\n");
   char c = getchar();
   if (c=='y')
   {
    printf("%s", 'a');  // this is broken on purpose, to trigger segfault
   }
   return 0;
}

在gdb会话中进行测试:

(gdb) source gdbloop.txt
[New Thread 6216.0x1d2c]
want segfault?
n
[Inferior 1 (process 6216) exited normally]
[New Thread 7008.0x1264]
want segfault?
n
[Inferior 1 (process 7008) exited normally]
[New Thread 8000.0x2754]
want segfault?
y

Breakpoint 1, 0x76b2d193 in wtoi () from C:\windows\syswow64\msvcrt.dll
(gdb) 

所以当触发段错误时我会收到提示。