前天晚上(2013.10.15)参加 Topcoder 竞赛时, 碰到一个比较没有头绪的问题, 想解法就想了半天, 写代码时又出了问题,之前在 Visual Studio 下图形化调试的习惯根深蒂固, GDB 又不熟悉, 因此只能用最笨的 printf 来进行调试, 大大下降了效率, 到了急需砍柴时才后悔没有磨好刀啊. shell
如今趁着有时间, 就把 GDB 再好好练习一下, 就不罗列一大堆命令了, 只是把碰到的/用过的整理一下, 之后再使用到新的命令, 再补充. 有几篇总结的比较好的文章能够参考: 《LINUX C/C++ GDB调试(概述)上》、《LINUX C/C++ GDB调试(概述)下》、《手把手教你玩转GDB(二)——Breakpoint, Watchpoint和Catchpoint》 函数
1. 添加调试信息
为了能使用 gdb 进行调试, 须要添加 -g 选项添加调试信息. spa
g++ -g test.cpp -o test2. 经常使用命令
3. 调试 core dump
程序执行时, 常常会由于段错误(Segment Fault)而退出, 操做系统会把此程序当前内存信息 dump 到磁盘上(详见 wiki), 即生成 core 文件. 对 core 进行分析能够很快分析出致使程序 crash 的地方. 操作系统
(1). 设置 core 文件大小
系统默认不会生成 core 文件, 须要进一步设置. core 文件的生成依赖于 shell 的设置, 在 shell 中运行命令: ulimit -a, 从第一行的设置项能够看到系统设置的 core file size 为 0, 即不生成 core file.
使用命令: ulimit -c unlimited 能够设置 core file size 为无限.
指针
(2). 生成简单 core 文件
在 C++ 中制造一个 segment falt 太容易了, 直接给一个空指针赋值就能够了.
调试
int main(int argc, char const *argv[]) { char* p = nullptr; *p = 'a'; return 0; }保存文件为 coreDumpTest.cpp, 编译并运行, 便可以现磁盘上多了一个 core 文件, 就是这个程序发生段错误 dump 下来的进程信息.
(3). 调试简单 core 文件
使用 gdb ./coreDumpTest core 来调试 core, 发现 gdb 直接就定位到了出错的语句(第4行赋值语句), 还能够经过 print 来查看当前上下文变量, 如指针 p 的值为 nullptr. code
(4). 生成稍复杂 core 文件
上面的例子太简单了, 下面经过一个稍微复杂的例子来介绍一下 gdb 中命令 backtrace 和 frame 的使用. 下面代码很简单, 就是越界访问, 用 vector 是为了体现调用层次...
blog
#include <vector> using namespace std; int main(int argc, char const *argv[]) { vector<int> a; vector<int> b; b.push_back(a[0]); return 0; }(5). 调试稍复杂 core 文件
4. 环境: Ubuntu 12.04(64-bit) + gcc 4.8.1 + gdb 7.6.1 进程
待添加: 设置 core file size 在全部 shell 都生效, 不要每次打开一个 shell 就要设置一下. ip