GDB 調試 C++ 程序 core dump

前天晚上(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 test
2. 經常使用命令
使用 gdb test 便可以進入調試程序, 如下列出幾個經常使用命 令.
  • 顯示圖形化代碼 Ctrl+x+a
  • 啓動程序 r (run)
  • 斷點 b (breakpoint)
  • 清除/禁用/啓用斷點 delete/disable/enable
  • 單步 s (step 碰到函數會進入)
  • 單行 n (next 碰到函數不會進行, 而是整條執行)
  • 執行到下一個斷點 c (continue)
  • 查看變量 p (print)
  • 顯示變量 display
  • 查看當前調用堆棧 bt (backtrace)
  • 查看某一層調用代碼 f (frame)

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 文件 
編譯運行程序, 生成 core 文件, 使用  gdb 來調試 core, 能夠看到此時直接定位到的地方是庫函數中的某一行; 

庫函數都是通過千錘百煉, 基本不可能出錯, 因此咱們先從本身的程序找起. 這時咱們須要知道的是代碼是從哪條語句執行到這裏的, 使用 backtrace(或者 where)  命令列出當前調用堆棧, 再使用 frame n 命令列出第 n 層堆棧的信息, 就能夠直接看到出錯的代碼語句了, 接下來就是進一步分析了.

4. 環境: Ubuntu 12.04(64-bit) + gcc 4.8.1 + gdb 7.6.1 進程

待添加: 設置 core file size 在全部 shell 都生效, 不要每次打開一個 shell 就要設置一下. ip

相關文章
相關標籤/搜索