作为开发人员,您如何使用 gdb 来跟踪代码中的错误?你用什么技巧让你的生活更轻松?
7 回答
一些提示:
- 使用图形前端(kdbg 非常好,ddd 至少比命令行 gdb 好,kdevelop 有一个不错的 gdb 前端但有一些 bgs,nemiver 看起来也不错,但仍在工作中)
- 确保所有重要部分都有调试符号和源代码(您自己的代码和一些系统库)
- 在 RedHat 上,您可以安装 -debuginfo 包以使符号和源代码神奇地出现在调试器中 - 非常酷,因为您可以查看 libc 函数调用等。
- 在 Debian/Ubuntu 上,您可以安装 -dbg 包来获取符号;不过,为系统包安装适当的源文件似乎很困难
- 我倾向于在不应该到达的地方或我想研究的地方(某种重量级断点)添加 assert() 和 abort() 调用
- 理想情况下,assert() 或 abort() 调用应该包含在某些方法或宏中,仅在 Debug 版本中启用它们,或者更好的是仅在设置了某个 env var 时才启用它们
- 为 SIGSEGV 和 SIGABRT 安装信号处理程序;我个人在安装处理程序之前检查是否设置了某个环境变量;在处理程序中,我执行一个硬编码的外部命令,该命令通常位于 ~/.local/bin/; 然后该命令可能会启动 kdbg 并将其附加到崩溃的应用程序。瞧,当您的应用程序出现问题时,调试器就会弹出。
- 如果您使用单元测试,您可以类似地在测试用例失败时附加一个调试器,然后检查应用程序。
gdb 的一个特别有用的特性是它能够检查崩溃程序的最终状态。
要检查故障转储(或更常用的核心文件),请按如下方式启动 gdb:
gdb <program-name> <core-file>
例如:
gdb a.out core
在核心文件上运行此命令后,gdb 将告诉您程序如何终止并显示程序中发生错误的位置:
Program terminated with signal 11, Segmentation fault.
#0 0x08048364 in foo () at foo.c:4
4 *x = 100;
在上面的示例中,您可以看到程序在尝试为指针分配值时因分段错误而终止。通过在 gdb 的提示符下键入backtrace(或bt或where),您可以查看程序的完整回溯:
(gdb) backtrace
#0 0x08048364 in foo () at foo.c:4
#1 0x0804837f in main () at foo.c:9
此时,您知道在尝试main()
为. 很多时候,这提供了足够的信息来让您修复错误。foo()
foo()
*x
In general you find something that isn't how it should be, and work backwards until you understand why.
The most obvious is the most useful: Setting a breakpoint on a function or line number and walking through the code line by line.
Another handy tip is to have show functions for all your structures/objects even if they are never used in your program, because you can run these functions from within gdb:
gdb> p show_my_struct(struct)
My custom display of Foo:
...
Watchpoints can be really handy too, but may slow down your program a lot. These break the flow when the value of a variable or address changes.:
gdb> watch foo
Watchpoint4: foo
gdb>
您也可以使用Geany。
我做了很多并行程序开发,所以我发现在 python/ruby 中使用一个简单的包装器,它允许我将 gdb 附加到所有节点上的所有进程并与我通信非常有帮助(我没有如果有人知道,找到一种更好的方法,而不是劫持线程,虽然......)
我不确定OP的经验如何,所以:
GDB 文档非常好,而且包罗万象。第一章很好地介绍了所有基础知识。
http://www.gnu.org/software/gdb/documentation/
虽然不是 gdb,但它们是相关的:我个人发现分解复杂的行以帮助确定哪些语句出错会有所帮助。
此外,Valgrind(http://valgrind.org/)对于解决缓冲区溢出等问题非常好/有用(我没有运气使用 gdb 来做这件事。
基本但非常有用 - 使用带有选项 -tui的文本 gui 。
使用 ddd,一个 gdb 的可视化前端。它使您只需单击几下鼠标即可轻松完成操作,并可视化代码的工作方式,此外,在调试器控制台中,您还有一个交互式 gdb。