我正试图在我的程序中找到一个不会一直发生的分段错误。我正在尝试在gdb的循环中运行我的程序,直到发生分段错误。
我的问题是gdb在收到seg错误后继续while循环,并没有提示我使用gdb shell。
当我运行我的gdb时,我使用:
set $i=0
while($i<100)
set $i = $i+1
r
end
任何人都知道如何让gdb在第一次segfault停止而不是100次运行?
谢谢!
答案 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)
所以当触发段错误时我会收到提示。