GDB:自动“下一个"? [英] GDB: Automatic 'Next'ing?

查看:20
本文介绍了GDB:自动“下一个"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这次快点.

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 不是我想要的;我想有效地看到完整的程序执行,一行一行,就像你一遍又一遍地从 nexting 得到的那样.

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 nexting 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脚本来执行stepnext命令一定次数:

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.)

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

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆