2010年9月16日 星期四

[GNU 程式設計] C 及 C++ 程式除錯器 : gdb 的編譯與啟動


前言 :
這裡要介紹一個 C 及 C++ 程式除錯的一個強而有力的工具 - gdb. 就某些方面來說, gdb 類似 BSD UNIX 之原始程式碼除錯器 dbx. gdb 的功能包括 C++ 原始程式的除錯與執行中程式的除錯. 除此之外, gdb 還可以讓你在程式中設定中斷點並在執行過程中檢視並修改變數, 呼叫函數與追縱程式的執行過程.

gdb 的編譯 :
要使用gdb 進行程式除錯之前, 須先以-g 選項編譯你的程式. 這會使編譯器產生額外的符號表, 例如下面命令 :
%gcc -g file1.c file2.c file3.o

編譯C原始程式 file1.c 與 file2.c , 會產生一擴充之符號表以供 gdb使用, 這些檔案與 file3.o 連結, 這是一個編譯過的物件檔. 則gdb 可以對 file1.c 及 file2.c 之原始碼除錯, 但不能對 file3.c 的原始碼除錯, 除非它也是以 -g 選項編譯的. 最後一提的是編譯器的-g 及 -O 選項並無不相容問題 ; 你可以同時兼顧編譯最佳化與除錯能力 ; 在本質上, 在最佳化過程會對程式本身做出改變, 原始程式中的指令關係在可執行程式中已經改變. 因此你也許會發現某些變數 (甚至數行程式碼) 會因最佳化而消失, 所以最好盡可能先徹底的先進行除錯在進行最佳化.

啟動 gdb :
對編譯過的程式進行除錯, 使用下面指令 :
%gdb program [ core-dump ]

program 是你要除錯的執行檔名稱, core-dump 則是上次執行你的程式所留下來的 core-dump 檔案名稱. 用 gdb 檢視 core-dump , 你可以發現程式在什麼地方, 以及為何會當掉. 例如下面命令執行 gdb, 參數為 john 檔案及 core.9876 core-dump :
%gdb john core.9876
GDB is free software and you are welcome to distribute copies of it
...(中間省略)...
#0 0x2734 in john (1=93643, u=912323, start=1) at john.c:123
123 do j++; while(j<=u &&x[j] < t);
(gdb) quit <離開 gdb>

開場白告訴你 gdb 的版本然後告訴你 core 檔案是如何產生的及程式在第幾行(執行到123) 當掉. 執行擋及 core 檔的參數都是 optional 的, 你可以稍後再用 core 命令叫出 core 檔. 任何一種狀況下, 只要你輸入的檔案名稱不存在, 或檔案的格式不對, gdb 都會顯示如下錯誤訊息 :
[benjamin@localhost ~]$ gdb notexist
GNU gdb 6.1.1 [FreeBSD]
Copyright 2004 Free Software Foundation, Inc.
...(中間省略)...
This GDB was configured as "i386-marcel-freebsd"...notexist: No such file or directory.

你可以在gdb 啟動時附加一些參數, 下列是一些常用參數 :
參數 | 說明
-d dir | 告訴 gdb 去 dir 目錄找原始檔案.
-x file | 在接受任何命令之前, gdb 會讀入並執行 file 中的命令, 讓你可以設定 gdb 執行一些你每次都會用的指令, 如在某一行設斷點, 你可以設多個-x 參數, 不同的檔案會依次執行.
-nx | 不要執行初始環境設定擋 (通常是 .gdbinit) 中的命令.
-q | 不要在啟動時顯示開場白即版權訊息.
-help | 顯示所有命令選項後結束.
-batch | 以批次模式執行 ; 先執行任何初始環境設定擋 (除非你要求它不要作), 然後執行 -x 選項指定的檔案, 結束執行並傳回狀態0.
This message was edited 2 times. Last update was at 20/02/2010 16:33:40

沒有留言:

張貼留言

[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...