GDB:自动’下一步’?

这一次很快。

是否有可能(除了永远按下输入)gdb不断地通过一个程序一行一行地找到错误发生的位置?

编辑: continue不是我想要的; 我想有效地看到完整的程序执行,一行一行,就像你从next反复获得的那样。

这是一个非常尴尬的东西我发布它有点尴尬。 但是,如果你只需要一次性,它可能会让你获得你想要的信息。 确实应该有更好的方法。

您可以定义一个执行stepnext命令一定次数的愚蠢的小gdb脚本:

 # file: step_mult.gdb define step_mult set $step_mult_max = 1000 if $argc >= 1 set $step_mult_max = $arg0 end set $step_mult_count = 0 while ($step_mult_count < $step_mult_max) set $step_mult_count = $step_mult_count + 1 printf "step #%d\n", $step_mult_count step end end 

(我没有特别好的理由使用步骤而不是next ;只需将其更改为您需要的任何内容。)

然后你可以运行该命令(带有一个可选的计数),它会很好地显示每stepnext

这是一个示例程序,它在尝试取消引用NULL指针时会崩溃:

 #include int x[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8,9, 10 }; int* p[11]; int main() { int i; for (i = 0; i < 11; ++i) { p[i] = &x[i]; } p[5] = 0; for (i = 0; i < 11; ++i) { printf( "*p[%d] == %d\n", i, *p[i]); } return 0; } 

这是一个gdb会话(在Windows上)调试该程序并使用step_mult脚本:

 C:\temp>gdb test.exe GNU gdb (GDB) 7.2 ... Reading symbols from C:\temp/test.exe...done. (gdb) source c:/temp/step_mult.gdb (gdb) start Temporary breakpoint 1 at 0x401385: file C:\temp\test.c, line 23. Starting program: C:\temp/test.exe [New Thread 5396.0x1638] Temporary breakpoint 1, main () at C:\temp\test.c:23 23 for (i = 0; i < 11; ++i) { (gdb) step_mult 70 step #1 24 p[i] = &x[i]; step #2 23 for (i = 0; i < 11; ++i) { step #3 24 p[i] = &x[i]; step #4 23 for (i = 0; i < 11; ++i) { step #5 24 p[i] = &x[i]; step #6 23 for (i = 0; i < 11; ++i) { step #7 24 p[i] = &x[i]; step #8 23 for (i = 0; i < 11; ++i) { step #9 24 p[i] = &x[i]; step #10 23 for (i = 0; i < 11; ++i) { step #11 24 p[i] = &x[i]; step #12 23 for (i = 0; i < 11; ++i) { step #13 24 p[i] = &x[i]; step #14 23 for (i = 0; i < 11; ++i) { step #15 24 p[i] = &x[i]; step #16 23 for (i = 0; i < 11; ++i) { step #17 24 p[i] = &x[i]; step #18 23 for (i = 0; i < 11; ++i) { step #19 24 p[i] = &x[i]; step #20 23 for (i = 0; i < 11; ++i) { step #21 24 p[i] = &x[i]; step #22 23 for (i = 0; i < 11; ++i) { step #23 27 p[5] = 0; step #24 29 for (i = 0; i < 11; ++i) { step #25 30 printf( "*p[%d] == %d\n", i, *p[i]); step #26 *p[0] == 0 29 for (i = 0; i < 11; ++i) { step #27 30 printf( "*p[%d] == %d\n", i, *p[i]); step #28 *p[1] == 1 29 for (i = 0; i < 11; ++i) { step #29 30 printf( "*p[%d] == %d\n", i, *p[i]); step #30 *p[2] == 2 29 for (i = 0; i < 11; ++i) { step #31 30 printf( "*p[%d] == %d\n", i, *p[i]); step #32 *p[3] == 3 29 for (i = 0; i < 11; ++i) { step #33 30 printf( "*p[%d] == %d\n", i, *p[i]); step #34 *p[4] == 4 29 for (i = 0; i < 11; ++i) { step #35 30 printf( "*p[%d] == %d\n", i, *p[i]); step #36 Program received signal SIGSEGV, Segmentation fault. 0x004013d2 in main () at C:\temp\test.c:30 30 printf( "*p[%d] == %d\n", i, *p[i]); step #37 Program received signal SIGSEGV, Segmentation fault. 0x004013d2 in main () at C:\temp\test.c:30 30 printf( "*p[%d] == %d\n", i, *p[i]); step #38 Program exited with code 030000000005. step #39 The program is not being run. (gdb) 

不幸的是,由于在发生段错误时脚本没有停止,gdb决定只是停止调试程序,所以你不能进行任何进一步的有用查询。 但是日志可能仍然有用。

我确信有很多方法可以使脚本更加智能化。 不幸的是,我不知道如何做到这一点,GDB的用户级文档似乎对这些细节没有太大帮助。 最好的方法是,如果脚本可以检测到段错误或信号已经发生,然后停止,而不是依赖于某些任意计数。 我想gdb / MI接口,甚至可能是Python脚本接口可能都有一个很好的机制,但我对这些并不了解。

第一次运行后,您可以使用显示的计数(在我的示例中为37)并重新启动程序,并给出一个只是在它之前崩溃的地方并且手动控制的计数。

就像我说的那样, 它并不是特别漂亮 - 但它可能会让你在那里 。

您可以使用continuec继续执行下一个断点。

另请参阅在GDB中运行应用程序直到发生exception(StackOverflow)有关如何设置“catchpoint”,这将在抛出exception时中断执行。

continue命令将一直运行,直到断点发生,应用程序导致exception(即崩溃)或应用程序终止。

  • GDB参考

另见这篇文章: c – GDB自动步进 – 自动打印输出线,同时自由运行? ,它使用python接口的gdb。