【问题标题】:Make gdb quit automatically on successful termination?使gdb在成功终止时自动退出?
【发布时间】:2011-04-14 00:50:53
【问题描述】:

我使用了一个调试脚本,它使用调试器连续运行多个相关进程。我目前正在使用-x 自动执行几个命令(例如run)。 当被调试的进程成功终止时,如何使 gdb 自动退出?quit 命令添加到命令文件将导致该命令不仅在成功终止时被处理,而且在发生错误时也被处理(什么时候我宁愿接手)。

这里是正在发生的事情的摘录:

+ gdb -return-child-result -x gdbbatch --args ./mkfs.cpfs /dev/loop0
GNU gdb (GDB) 7.1-ubuntu
从 /home/matt/cpfs/mkfs.cpfs 读取符号...完成。

程序正常退出。
0x805224f 处的断点 2:文件 log.c,第 32 行。
(gdb)

gdbbatch的内容:

开始
b cpfs_log if level >= WARNING

【问题讨论】:

标签: c linux gdb ubuntu-10.04


【解决方案1】:

我想我已经为您在How to make gdb send an external notification on receiving a signal? 中寻找类似内容的问题找到了完整的解决方案。这里的其他人似乎都没有提到或发现gdb hooks

根据 Matthew 关于 $_exitcode 的提示,现在这是我的 app/.gdbinit ,它完全实现了想要的行为;成功终止后正常退出并进入 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

【讨论】:

    【解决方案2】:

    gdb 在程序成功终止时设置$_exitcode。您可以利用它 - 在脚本开始时将其设置为不太可能的值,如果它已更改,则仅在末尾设置 quit

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

    (将$_exitcode 设置为一个不太可能的值有点难看,但如果程序没有终止,则根本不会定义它,并且似乎没有任何明显的方式询问“这是变量定义了吗?”在条件中。)

    【讨论】:

    • This document 展示了如何将_isvoid_exitcode 一起使用,以避免将其设置为“不太可能的值”。
    • 丹尼尔你的链接坏了:(
    【解决方案3】:

    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 接口和 GDB 的 -i 命令行参数;它的命令和输出更容易解析,如果您将扩展以需要更多高级功能,如您在之前链接的文档中所见。

    【讨论】:

      猜你喜欢
      • 2020-04-06
      • 1970-01-01
      • 2017-04-30
      • 2019-10-05
      • 2019-03-16
      • 1970-01-01
      • 2020-05-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多