13

我使用了一个调试脚本,它使用调试器连续运行多个相关进程。我目前正在使用-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
4

3 回答 3

12

我想我已经找到了一个完整的解决方案来解决您在如何使 gdb 在接收信号时发送外部通知中寻找类似内容的问题?. 这里的其他人似乎都没有提到或发现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
于 2011-03-12T22:45:29.273 回答
11

gdb 设置$_exitcode程序成功终止的时间。您可以利用它 - 在脚本开始时将其设置为不太可能的值,并且仅quit在脚本发生更改时才设置:

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

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

于 2010-09-18T14:35:34.280 回答
4

GDB 有一种与称为 GDB/MI 的自动化程序交互的不同“语言”(详见此处),但不幸的是,它看起来不支持条件,并且预计可以通过解析和分支从其他程序运行。因此,看起来 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)提示,但由于标准输入缓冲而起作用。

您还可以修改它以使用 GDB/MI 接口和 GDB 的 -i 命令行参数;它的命令和输出更容易解析,如果您将扩展以需要更多高级功能,如您在先前链接的文档中所见。

于 2010-09-18T08:34:43.090 回答