自动化 GDB 调试会话的最佳方法是啥?

Posted

技术标签:

【中文标题】自动化 GDB 调试会话的最佳方法是啥?【英文标题】:What are the best ways to automate a GDB debugging session?自动化 GDB 调试会话的最佳方法是什么? 【发布时间】:2012-05-31 16:29:23 【问题描述】:

GDB 是否有内置脚本机制,我应该编写一个期望脚本,还是有更好的解决方案?

我将每次发送相同的命令序列,并将每个命令的输出保存到文件中(很可能使用 GDB 的内置日志记录机制,除非有人有更好的想法)。

【问题讨论】:

子集:***.com/questions/13935443/… 【参考方案1】:

基本上,在这个例子中,我想在代码的特定位置获取一些变量值;并让它们输出直到程序崩溃。所以这里首先是一个小程序 guaranteed to crash 在几个步骤中,test.c:

#include <stdio.h>
#include <stdlib.h>

int icount = 1; // default value

main(int argc, char *argv[])

  int i;

  if (argc == 2) 
    icount = atoi(argv[1]);
  

  i = icount;
  while (i > -1) 
    int b = 5 / i;
    printf(" 5 / %d = %d \n", i, b );
    i = i - 1;
  

  printf("Finished\n");
  return 0;

程序接受命令行参数的唯一原因是能够选择崩溃前的步数 - 并表明gdb 在批处理模式下会忽略--args。这是我编译的:

gcc -g test.c -o test.exe

然后,我准备以下脚本 - 这里的主要技巧是为每个 breakpoint 分配一个 command,最终将是 continue(另见 Automate gdb: show backtrace at every call to function puts)。这个脚本我叫test.gdb

# http://sourceware.org/gdb/wiki/FAQ: to disable the
# "---Type <return> to continue, or q <return> to quit---"
# in batch mode:
set width 0
set height 0
set verbose off

# at entry point - cmd1
b main
commands 1
  print argc
  continue
end

# printf line - cmd2
b test.c:17
commands 2
  p i
  p b
  continue
end

# int b = line - cmd3
b test.c:16
commands 3
  p i
  p b
  continue
end

# show arguments for program
show args
printf "Note, however: in batch mode, arguments will be ignored!\n"

# note: even if arguments are shown;
# must specify cmdline arg for "run"
# when running in batch mode! (then they are ignored)
# below, we specify command line argument "2":
run 2     # run

#start # alternative to run: runs to main, and stops
#continue

请注意,如果您打算在批处理模式下使用它,则必须在最后“启动”脚本,使用 runstart 或类似的东西。

有了这个脚本,我可以在批处理模式下调用gdb - 这将在终端中生成以下输出:

$ gdb --batch --command=test.gdb --args ./test.exe 5
Breakpoint 1 at 0x804844d: file test.c, line 10.
Breakpoint 2 at 0x8048485: file test.c, line 17.
Breakpoint 3 at 0x8048473: file test.c, line 16.
Argument list to give program being debugged when it is started is "5".
Note, however: in batch mode, arguments will be ignored!

Breakpoint 1, main (argc=2, argv=0xbffff424) at test.c:10
10    if (argc == 2) 
$1 = 2

Breakpoint 3, main (argc=2, argv=0xbffff424) at test.c:16
16      int b = 5 / i;
$2 = 2
$3 = 134513899

Breakpoint 2, main (argc=2, argv=0xbffff424) at test.c:17
17      printf(" 5 / %d = %d \n", i, b );
$4 = 2
$5 = 2
 5 / 2 = 2 

Breakpoint 3, main (argc=2, argv=0xbffff424) at test.c:16
16      int b = 5 / i;
$6 = 1
$7 = 2

Breakpoint 2, main (argc=2, argv=0xbffff424) at test.c:17
17      printf(" 5 / %d = %d \n", i, b );
$8 = 1
$9 = 5
 5 / 1 = 5 

Breakpoint 3, main (argc=2, argv=0xbffff424) at test.c:16
16      int b = 5 / i;
$10 = 0
$11 = 5

Program received signal SIGFPE, Arithmetic exception.
0x0804847d in main (argc=2, argv=0xbffff424) at test.c:16
16      int b = 5 / i;

请注意,当我们指定命令行参数 5 时,循环仍然只旋转了两次(正如 gdb 脚本中的 run 规范一样);如果run 没有任何参数,它只旋转一次(程序的默认值),确认--args ./test.exe 5 被忽略。

但是,由于现在这是在单个调用中输出,并且无需任何用户交互,因此可以使用 bash 重定向将命令行输出轻松捕获到文本文件中,例如:

gdb --batch --command=test.gdb --args ./test.exe 5 > out.txt

c - GDB auto stepping - automatic printout of lines, while free running?中还有一个使用python自动化gdb的例子

希望这会有所帮助, 干杯!

【讨论】:

感谢分享,很有用 对我来说太麻烦了。 detachcommand 使 gdb 崩溃,continuecoammand 导致奇怪的 Selected thread is running. 警报。【参考方案2】:

gdb 运行后执行文件.gdbinit。 所以你可以将你的命令添加到这个文件中,看看它是否适合你。 这是.gdbinit 的示例,用于打印所有f() 调用的回溯:

set pagination off
set logging file gdb.txt
set logging on
file a.out
b f
commands
bt
continue
end
info breakpoints
r
set logging off
quit

【讨论】:

我可以设置一个环境变量来让 GDB 在启动时运行不同的文件吗? @Anonymous 没有,但是有一个命令行选项:--command=FILE, -x Execute GDB commands from FILE.【参考方案3】:

如果带有文件的-x 对您来说太多,只需使用多个-ex

这是一个跟踪正在运行的程序的示例,显示(并保存)崩溃时的回溯

sudo gdb -p "$(pidof my-app)" -batch \
  -ex "set logging on" \
  -ex continue \
  -ex "bt full" \
  -ex quit

【讨论】:

以上是关于自动化 GDB 调试会话的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

LinuxLinux调试器--gdb详解

使用 Typescript 自动验证请求的最佳方法是啥?

Linux环境开发工具gdb调试工具+Makefile自动化构建工具

自动布局动态大小 uitableview 单元格的最佳方法是啥

在 C/C++ 项目中自动检测库依赖关系的最佳方法是啥?

颤抖每24小时自动更新一次Firebase的最佳方法是啥?