经常我们使用的vscode、pycharm等等ide,都带有断点设置,参数检查等,但是GDB就没有这些,那我们能不能通过设置,把gdb用起来更简单喃? 比如,如果你知道这些的话,可以跳过了.
- gdb 脚本配合–batch
- gdb .gdbinit 文件
使用 GDB 进行调试
在过去的几年里,我大部分时间都在用 Python 工作,而且我非常喜欢用 Python 进行调试。您只需将断点()函数调用放入代码中的某个位置,然后将其重新放入程序。我想看看在 c 语言中,我能接近到什么程度。由于 c 语言不是直译语言,我的期望不是很高,但是结果证明用 c 语言调试是相当舒服的。作为奖励,您可以使用 GDB 不仅调试 c 和 c + + ,还可以调试 Rust、 Nim,可能还有任何 C-ABI 的语言。
GDB 基础
首先,我们需要一个程序来调试:
// program.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void print_product(int a, int b) {
int product = a * b;
printf("Product: %d\n", product);
}
void print_arguments(int argc, char **argv) {
for (int i = 1; i < argc; i++) {
printf("%s ", argv[i]);
}
printf("\n");
}
int main(int argc, char **argv) {
print_arguments(argc, argv);
srand(time(NULL));
for (int i = 0; i < 10; i++) {
print_product(rand(), rand());
}
return 0;
}
要调试程序,包含调试符号非常重要。使用 gcc 编译时添加调试符号,请添加 -g
标志。所以让我们编译这个程序:
gcc -g -o program program.c
现在我们可以通过运行以下命令来调试这个程序:
使用 gdb 脚本
了解GDB脚本功能
https://www.adacore.com/gems/gem-119-gdb-scripting-part-1
https://www.adacore.com/gems/gem-120-gdb-scripting-part-2
但这仍然不是很好,现在我们必须在重新启动调试会话时反复输入所有断点。但是有一种方法可以解决这个问题: gdb 脚本。如果使用-x 选项调用 gdb,则可以传递一个包含 gdb 命令的文件给它,它应该执行这个文件。
现在我们可以将断点写入脚本,例如。
现在,我们的断点被存储了。但是还有更多的原因。通常我想检查一些变量。目前希望看到所有循环的乘积变量的值,而不关心其余的:
# gdbscript
b 6
commands
p product
c
end
run
然后用这样的--batch
运行 gdb:
gdb -x gdbscript program --batch
现在,gdb 将快速打印出所有迭代的产品值,然后再次退出。断点后的命令语句将在命中断点后执行所有包含的命令。最后一个命令 c 表示 continue 并将继续程序流,直到命中下一个断点,一旦上次命中了断点,gdb 将通过 – batch 参数结束执行。
另一个很酷的例子: 让我们假设,不管出于什么原因,我们只对 print_ product()
的第三次调用中的product的值感兴趣。(这当然很傻,因为程序无论如何都会打印它,但在现实调试中,可能会出现这种情况)
set $n = 0
b 6
commands
set $n = $n + 1
if $n == 3
printf "Product is: %d\n", product
else
c
end
end
run
正如您所看到的,我们定义了一个变量 $n,并使用它来计数,然后在第三轮中打印所需的信息。第三轮之后,gdb 会自动退出,退出的原因是 – batch。
.gdbinit 文件
有一个脚本,如果它存在,gdb 将始终隐式加载它: ~/.gdbinit ,你可以把你经常使用的函数放在那里,或者配置。我的是这样的:
set width 0
set height 0
set print pretty on
set confirm off
设置 width 和 height 为0,将防止 gdb 分页长输出,第三行使 gdb 美化输出,最后一行防止它询问我们是否真的想退出。
总结
经常我们使用的vscode、pycharm等等ide,都带有断点设置,参数检查等,但是对于gdb来说就没有GUI来设置这些东西了,难免有点不习惯,但是对于经常使用linux开发者的用户来说,掌握gdb是一个必须的技能。下面这个命令,可以简单地将它们附加到调试器调用中:
gdb -x gdbscript --batch --args program --flags and some args
此外,如果您需要更复杂的调试设置,例如,因为您还必须启动其他程序,那么可以将所有这些组合在一个 shell 脚本中。
当然,还有很多关于 gdb 的内容需要了解,而这仅仅是一个介绍。
Read more
https://www.adacore.com/gems/gem-119-gdb-scripting-part-1
https://felix-knorr.net/posts/2022-02-27-direct-gdb.html
github博客 微信公众号:chasays, 欢迎关注一起吹牛逼,也可以加微信号「xiaorik」互吹。