使用 gdb 查看 main() 中每条指令的回溯 ('bt') 堆栈
Viewing the backtrace ('bt') stack for each instruction in main() using gdb
这是参考 gdb 调试器。通过在头文件或其他源代码而不是正在执行的文件中放置断点,可以跟踪从 main() 函数(正在执行的文件)中的指令开始到通过在 gdb 中输入 bt 来放置断点(在头文件或其他源代码中)(本质上显示堆栈)。
是否可以显示main()中每条指令的堆栈,而不必在其他文件中放置断点,然后按bt?目前,我在各种文件中放置断点,然后将它们的路径追溯到我感兴趣的文件。相反,我希望为我感兴趣的 main() 函数中的每条指令显示整个路径(bt 'stack')。
您可以像这样定义一个组合 stepi
和 bt
的用户命令:
(gdb) define sbt
Type commands for definition of "sbt".
End with a line saying just "end".
>stepi
>bt
>end
这是用法示例:
$ cat t.c
int bar() { return 42; }
int foo() { return bar(); }
int main() { return foo(); }
$ gcc -g t.c
$ gdb -q ./a.out
定义sbt
命令如上。现在使用它:
(gdb) start
Temporary breakpoint 1 at 0x40050c: file t.c, line 3.
Starting program: /tmp/a.out
Temporary breakpoint 1, main () at t.c:3
3 int main() { return foo(); }
(gdb) sbt
0x0000000000400511 3 int main() { return foo(); }
#0 0x0000000000400511 in main () at t.c:3
(gdb)
此处只需按 Enter 即可重复之前的 (sbt
) 命令。
foo () at t.c:2
2 int foo() { return bar(); }
#0 foo () at t.c:2
#1 0x0000000000400516 in main () at t.c:3
(gdb)
0x00000000004004f9 2 int foo() { return bar(); }
#0 0x00000000004004f9 in foo () at t.c:2
#1 0x0000000000400516 in main () at t.c:3
(gdb)
2 int foo() { return bar(); }
#0 foo () at t.c:2
#1 0x0000000000400516 in main () at t.c:3
(gdb)
0x0000000000400501 2 int foo() { return bar(); }
#0 0x0000000000400501 in foo () at t.c:2
#1 0x0000000000400516 in main () at t.c:3
(gdb)
bar () at t.c:1
1 int bar() { return 42; }
#0 bar () at t.c:1
#1 0x0000000000400506 in foo () at t.c:2
#2 0x0000000000400516 in main () at t.c:3
...等等
P.S。由于您想检查每条指令的堆栈,因此将 x/i $pc
添加到 sbt
命令也可能有意义,这样您就知道要跳过的指令。
这是参考 gdb 调试器。通过在头文件或其他源代码而不是正在执行的文件中放置断点,可以跟踪从 main() 函数(正在执行的文件)中的指令开始到通过在 gdb 中输入 bt 来放置断点(在头文件或其他源代码中)(本质上显示堆栈)。
是否可以显示main()中每条指令的堆栈,而不必在其他文件中放置断点,然后按bt?目前,我在各种文件中放置断点,然后将它们的路径追溯到我感兴趣的文件。相反,我希望为我感兴趣的 main() 函数中的每条指令显示整个路径(bt 'stack')。
您可以像这样定义一个组合 stepi
和 bt
的用户命令:
(gdb) define sbt
Type commands for definition of "sbt".
End with a line saying just "end".
>stepi
>bt
>end
这是用法示例:
$ cat t.c
int bar() { return 42; }
int foo() { return bar(); }
int main() { return foo(); }
$ gcc -g t.c
$ gdb -q ./a.out
定义sbt
命令如上。现在使用它:
(gdb) start
Temporary breakpoint 1 at 0x40050c: file t.c, line 3.
Starting program: /tmp/a.out
Temporary breakpoint 1, main () at t.c:3
3 int main() { return foo(); }
(gdb) sbt
0x0000000000400511 3 int main() { return foo(); }
#0 0x0000000000400511 in main () at t.c:3
(gdb)
此处只需按 Enter 即可重复之前的 (sbt
) 命令。
foo () at t.c:2
2 int foo() { return bar(); }
#0 foo () at t.c:2
#1 0x0000000000400516 in main () at t.c:3
(gdb)
0x00000000004004f9 2 int foo() { return bar(); }
#0 0x00000000004004f9 in foo () at t.c:2
#1 0x0000000000400516 in main () at t.c:3
(gdb)
2 int foo() { return bar(); }
#0 foo () at t.c:2
#1 0x0000000000400516 in main () at t.c:3
(gdb)
0x0000000000400501 2 int foo() { return bar(); }
#0 0x0000000000400501 in foo () at t.c:2
#1 0x0000000000400516 in main () at t.c:3
(gdb)
bar () at t.c:1
1 int bar() { return 42; }
#0 bar () at t.c:1
#1 0x0000000000400506 in foo () at t.c:2
#2 0x0000000000400516 in main () at t.c:3
...等等
P.S。由于您想检查每条指令的堆栈,因此将 x/i $pc
添加到 sbt
命令也可能有意义,这样您就知道要跳过的指令。