GDB:自动“下一个"? [英] GDB: Automatic 'Next'ing?
问题描述
这次快点.
gdb 是否有可能(除了永远按 Enter 键)通过程序逐行不断地next
来查找错误发生的位置?
Is it possible (other than pressing enter forever) for gdb to continually next
through a program line by line to find where a bug is happening?
continue
不是我想要的;我想有效地看到完整的程序执行,一行一行,就像你一遍又一遍地从 next
ing 得到的那样.
continue
isn't what I would like; I would like to see effectively the complete program execution, line by line, as you would get from next
ing over and over.
推荐答案
这里有这样一个 hack,我有点不好意思发布它.但是,如果您只需要一次性的,它可能足以让您获得所需的信息.确实应该有更好的方法.
Here's something's that's such a hack I'm a bit embarrassed to post it. But if you need just a one-off, it might do well enough to let you get the information you want. There really should be a better way.
你可以定义一个愚蠢的小gdb脚本来执行step
或next
命令一定次数:
You can define a stupid little gdb script that executes the step
or next
command a certain number of times:
# 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
", $step_mult_count
step
end
end
(我没有特别好的理由使用 step 而不是 next
;只需将其更改为您需要的任何内容.)
(I used step instead of next
for no particularly good reason; just change it to whatever you need.)
然后您可以运行该命令(使用可选计数),它会很好地显示每个 step
或 next
.
Then you can run that command (with an optional count), and it'll display each step
or next
nicely.
这是一个示例程序,当它尝试取消引用 NULL 指针时会崩溃:
Here's a sample program that'll crash when it tries to dereference a NULL pointer:
#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
", i, *p[i]);
}
return 0;
}
这是一个 gdb 会话(在 Windows 上)调试该程序并使用 step_mult
脚本:
Here's a gdb session (on Windows) debugging that program and using the step_mult
script:
C: emp>gdb test.exe
GNU gdb (GDB) 7.2
...
Reading symbols from C: emp/test.exe...done.
(gdb) source c:/temp/step_mult.gdb
(gdb) start
Temporary breakpoint 1 at 0x401385: file C: emp est.c, line 23.
Starting program: C: emp/test.exe
[New Thread 5396.0x1638]
Temporary breakpoint 1, main () at C: emp est.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
", i, *p[i]);
step #26
*p[0] == 0
29 for (i = 0; i < 11; ++i) {
step #27
30 printf( "*p[%d] == %d
", i, *p[i]);
step #28
*p[1] == 1
29 for (i = 0; i < 11; ++i) {
step #29
30 printf( "*p[%d] == %d
", i, *p[i]);
step #30
*p[2] == 2
29 for (i = 0; i < 11; ++i) {
step #31
30 printf( "*p[%d] == %d
", i, *p[i]);
step #32
*p[3] == 3
29 for (i = 0; i < 11; ++i) {
step #33
30 printf( "*p[%d] == %d
", i, *p[i]);
step #34
*p[4] == 4
29 for (i = 0; i < 11; ++i) {
step #35
30 printf( "*p[%d] == %d
", i, *p[i]);
step #36
Program received signal SIGSEGV, Segmentation fault.
0x004013d2 in main () at C: emp est.c:30
30 printf( "*p[%d] == %d
", i, *p[i]);
step #37
Program received signal SIGSEGV, Segmentation fault.
0x004013d2 in main () at C: emp est.c:30
30 printf( "*p[%d] == %d
", i, *p[i]);
step #38
Program exited with code 030000000005.
step #39
The program is not being run.
(gdb)
不幸的是,由于发生段错误时脚本并没有停止,gdb 决定简单地停止调试程序,因此您无法进行任何进一步的有用查询.但是日志可能仍然有用.
Unfortunately, since the script doesn't stop when the segfault happens, gdb decides to simply stop debugging the program, so you can't make any further useful inquiries. But the log might still be useful.
我确信有很多方法可以使脚本更智能.不幸的是,我不知道该怎么做,而且 GDB 的用户级文档似乎对这些细节没有太大帮助.最好的方法是,如果脚本可以检测到段错误或信号已经发生,然后停止,而不是依赖于任意计数.我想 gdb/MI 接口,甚至可能是 Python 脚本接口可能有一个很好的机制,但我对这些一无所知.
I'm sure there are numerous ways one might make the script more intelligent. Unfortunately, I have no idea how to do that, and the user level docs for GDB don't seem too helpful for those details. The best way would be if the script could detect the segfault or signal had happened and just stop then instead of relying on some arbitrary count. I imagine the gdb/MI interface, or probably even the Python scripting interface might have a good mechanism, but I don't know anything about those.
在您第一次运行后,您可以使用显示的计数(在我的示例中为 37)并重新启动程序并给出一个略低于之前崩溃位置的计数并手动控制.
After your first run you could use the count displayed (37 in my example) and restart the program and give a count that's just shy of where it crashed before and take control manually.
就像我说的,它不是特别漂亮 - 但它可能会让你到达那里一个>.
这篇关于GDB:自动“下一个"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!