代码之家  ›  专栏  ›  技术社区  ›  Matt Joiner

成功终止后是否自动退出GDB?

  •  11
  • Matt Joiner  · 技术社区  · 14 年前

    我使用一个调试脚本,该脚本与调试器一起连续运行几个相关进程。我正在使用 -x 自动执行几个命令(例如 run ) 当调试过程成功终止时,如何使GDB自动退出? 添加一个 quit 对命令文件的命令将导致该命令不仅在成功终止时被处理,而且在错误发生时(我宁愿在此时接管)。

    以下是发生的事情的摘要:

    + gdb -return-child-result -x gdbbatch --args ./mkfs.cpfs /dev/loop0
    GNU gdb (GDB) 7.1-ubuntu
    Reading symbols from /home/matt/cpfs/mkfs.cpfs...done.
    
    Program exited normally.
    Breakpoint 2 at 0x805224f: file log.c, line 32.
    (gdb)

    内容 gdbbatch :

    start
    b cpfs_log if level >= WARNING
    3 回复  |  直到 12 年前
        1
  •  11
  •   Matthew Slattery    14 年前

    GDB集 $_exitcode 当程序成功终止时。您可以利用它-在脚本开始时将其设置为一个不太可能的值,并且只有 quit 最后,如果它改变了:

    set $_exitcode = -999
    # ...
    run
    # ...
    if $_exitcode != -999
      quit
    end
    

    (设置) 美元出口代码 对于一个不太可能的值是有点难看的,但是如果程序不终止,它就不会被定义,而且似乎没有任何明显的方式来询问“这个变量被定义了吗?”在一个条件中。)

        2
  •  9
  •   Community CDub    8 年前

    我想我已经找到了一个完整的解决方案来解决你的问题 How to make gdb send an external notification on receiving a signal? . 这里的其他人似乎都没有提到或发现 gdb hooks .

    基于马修关于$xEXCODE的提示,现在是我的 App/GdBIT 这完全达到了所需的行为;成功终止后正常退出,并转到gdb提示符,发送电子邮件,其他一切:

    set $_exitcode = -999
    set height 0
    handle SIGTERM nostop print pass
    handle SIGPIPE nostop
    define hook-stop
        if $_exitcode != -999
            quit
        else
            shell echo | mail -s "NOTICE: app has stopped on unhandled signal" root
        end
    end
    echo .gdbinit: running app\n
    run
    
        3
  •  4
  •   Sdaz MacSkibbons    14 年前

    gdb有一种不同的“语言”用于与称为gdb/mi的自动化程序交互(详细说明 here 但是,不幸的是,它看起来不像支持条件句,并且期望从解析和分支的其他程序运行。因此,expect看起来是最简单的(或者至少是一个有效的)解决方案:

    $ cat gdbrunner
    #!/usr/bin/expect -f
    
    #spawn gdb -return-child-result --args ./mkfs.cpfs /dev/loop0
    spawn gdb -return-child-result --args [lindex $argv 0]
    
    #send "start\n"
    #send "b cpfs_log if level >= WARNING"
    send "run\n"
    
    expect {
        normally\.         { send "quit\n" }
        "exited with code" { interact -nobuffer }
    }
    

    我用简单的程序测试了这个:

    $ cat prog1.c
    int main(void) { return 0; }
    $ cat prog2.c
    int main(void) { return 1; }
    

    结果如下:

    $ ./gdbrunner ./prog1
    spawn gdb -return-child-result --args ./prog1
    run
    (gdb) run
    Starting program: /home/foo/prog1
    
    Program exited normally.
    (gdb) quit
    $ ./gdbrunner ./prog2
    spawn gdb -return-child-result --args ./prog2
    run
    (gdb) run
    Starting program: /home/foo/prog2
    
    Program exited with code 01.
    (gdb)
    

    本质上,您必须解析输出并使用其他东西进行分支。这当然可以与任何其他能够处理另一个进程的输入/输出的程序一起工作,但是如果你不介意TCL,那么上面的期望脚本应该让你开始。它应该更好一点,并期望第一个(gdb)提示,但由于stdin缓冲而起作用。

    您还可以修改它以将GDB/MI接口与-I命令行参数一起使用到GDB;如果您将扩展到需要更高级的特性,那么它的命令和输出就更容易被解析,正如您在先前链接的文档中可以看到的那样。