c - GDB:自动 'Next' ing?

标签 c debugging gdb

这次快一点。

gdb 是否有可能(除了一直按 enter 键)逐行通过程序不断 next 以查找错误发生的位置?

编辑:continue 不是我想要的;我希望逐行有效地查看完整的程序执行,就像您一遍又一遍地从 nexting 中获得的那样。

最佳答案

这里有一些东西太骇人听闻了,我有点不好意思发布它。但是,如果您只需要一次性的,它可能足以让您获得所需的信息。确实应该有更好的方法。

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

# 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

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

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

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

#include<stdio.h>

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;
}

这是调试该程序并使用 step_mult 脚本的 gdb session (在 Windows 上):

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 接口(interface),甚至可能是 Python 脚本接口(interface)可能有一个很好的机制,但我对这些一无所知。

第一次运行后,您可以使用显示的计数(在我的示例中为 37)并重新启动程序并给出一个略低于之前崩溃位置的计数并手动控制。

就像我说的,it's not particularly pretty - but it might get you there .

关于c - GDB:自动 'Next' ing?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5812411/

相关文章:

c++ - 使用 %。在 printf 中

java - 不幸的是MyApp已停止。我该如何解决?

multithreading - 如何在 Visual Studio 中所有线程的调用堆栈中转储或搜索

c++ - 可以在 gdb 中调用内联函数和/或使用 GCC 发出它们吗?

C 预处理多遍

c - 我怎样才能将这个C 转换成MIPS?

c - 如果字符串在内存中重叠怎么办?

python - 如何在不修改源代码的情况下检查 Winpdb Python 调试器中的返回值?

c - 什么是\363\353\377\377\377\177?

linux - 为什么gdb需要root权限才能调试用户程序?