linux gdb除錯
gdb除錯常用的命令:
1.顯示程式中的當前位置和表示如何到達當前位置的棧跟蹤:bt, where, info stack;這三個的功能都是一樣的,在程式崩潰之後使用該命令檢視堆疊的歷史記錄,很管用。
用法:
bt n: 顯示程式棧頂的n幀資訊;
bt -n: 顯示程式棧底的n幀資訊;
frame n: 檢視第n幀的簡要資訊;
2.info: 獲取和被除錯程式的相關資訊;
info frame或info frame n: 檢視幀或第n幀的詳細資訊;
info locals: 檢視當前幀中的區域性變數資訊;
3.list: 檢視執行位置的程式碼;
list n: 檢視當前檔案中第n行周圍的原始碼;
list func: 檢視函式func周圍的原始碼;
4.print:打印表達式或者變數的資訊。
用法:p [/format] exptr;
p temp: 列印變數temp的值;
p /x temp: 按十六進位制的形式列印變數temp的值;
------------------------------------------------------------------
format的取值範圍有如下幾種:
- x 按十六進位制格式顯示變數。
- d 按十進位制格式顯示變數。
- u 按十六進位制格式顯示無符號整型。
- o 按八進位制格式顯示變數。
- t 按二進位制格式顯示變數。
- a 按十六進位制格式顯示變數。
- c 按字元格式顯示變數。
- f 按浮點數格式顯示變數。
------------------------------------------------------------------
5.檢視函式的返回值資訊:
a.執行finish至函式結束,此時會自動打印出函式的返回值;
(gdb)finish
Run till exit from #0 foo () at main.c:9
main () at main.c:15
15 }
Value returned is $2 = 100
b.函式返回值會儲存在暫存器eax中,可以直接檢視該暫存器的值:
(gdb)p $eax
$3 = 100
(gdb) info registers
eax 0x64 100
6.檢視記憶體:
examine命令(簡寫x): x /(n/f/u) <addr>;
- n 表示顯示記憶體的長度,也就是說從當前地址向後顯示幾個地址的內容。-----------顯示的變數的個數
- f 表示顯示的格式,如果是字串,則用s,如果是數字,則可以用i。
- u 表示從當前地址往後請求的位元組數,預設是4個bytes。(b單位元組,h雙位元組,w四位元組,g八位元組)--------指定每個變數所佔用的位元組數
- <addr> 表示一個記憶體地址。
例如:以兩位元組為單位顯示陣列arr的地址後32位元組記憶體資訊如下.
(gdb)x /16uh arr
0xbffff4cc: 2 0 4 0 6 0 8 0
0xbffff4dc: 10 0 34032 2052 0 0 0 0
特殊的檢視方式:連續記憶體的檢視;
可以使用GDB的"@"操作符檢視連續記憶體,"@"的左邊是第一個記憶體的地址的值,"@"的右邊則你你想檢視記憶體的長度。
例如,對於如下程式碼:int arr[] = {2, 4, 6, 8, 10};,可以通過如下命令檢視arr前三個單元的資料。
(gdb)p *[email protected]
$2 = {2, 4, 6}
7.設定斷點:
a.非條件斷點:break test.cpp:10(在test.cpp檔案的第10行設定一個斷點);
b.條件斷點:break test.cpp:38 if count==3(在test.cpp的第38行設定一個斷點,如果程式執行到這裡的時候count為3,則程式將暫停執行);
c.“break main”:在main函式入口設定斷點,可以從程式一開始執行就跟蹤除錯程式碼;
8.檢視變數的型別:whatis;
whatis p: 檢視p的型別;
9.在不同的呼叫上下文中切換棧幀:frame;
frame num:切換到棧幀號為num的棧中;
在分析核心檔案時,通過將遍歷棧的命令和檢查變數值的“print”命令結合起來,就能夠復原程式執行時的全部景象。
10.除錯正在執行的程序:有些程序可能無法直接在偵錯程式上執行,可以通過下面的方式來除錯這些程序。
第一種是在GDB命令列上指定程序的PID:先執行程式dataserverhq,然後通過ps -aux | grep dataserverhq獲取程式的pid,最後在另外一個開啟的shell中執行gdb dataserverhq pid;
第二種是先用file命令載入除錯時所需的符號表,然後再通過“attaché”命令進行連線:
(gdb) file /home/xiaowp/debugme Reading symbols from /home/xiaowp/debugme...done.
(gdb) attach 555 ……
除錯結束結束時,用detach斷開連線,讓被除錯的程序可以繼續正常執行下去。
11.載入需要除錯的程式:
第一種方法:gdb dataserverhq;
第二種方法:gdb; file dataserverhq;
第三種方法: gdb attach process_pid;
12.恢復程式執行,直到程式結束(從斷點處繼續執行):continue, c, fg;
13.顯示呼叫和執行一個函式:call function(arg1, arg2,...);
14.結束當前迴圈:until, u;
15.使用info threads 可以檢視執行的執行緒.
thread num: 切換到執行緒號為num的執行緒;
16.檢視當前棧層的資訊:frame, f;
17.info f(或者info frame):打印出更為詳細的當前棧層的資訊;
18.強制函式返回:
如果你的除錯斷點在某個函式中,並還有語句沒有執行完。你可以使用 return 命令強制函式忽略還沒有執行的語句並返回。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
還有就是裡面某個執行緒停住,也沒死,這種情況一般就是死鎖或者涉及訊息接受的超時問題(聽人說的,沒有遇到過)。遇到這種情況,可以使用:
gcore pid (除錯程序的pid號)
手動生成core檔案,在使用pstack(linux下好像不好使)檢視堆疊的情況。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
gdb的tui(terminal user interface)方法除錯程式碼:
前提:程式碼跟執行的程式需要在同一臺主機上,不然找不到原始碼。
開啟/關閉方式:ctrl+x+a;
啟動方式:gdb -tui ./dataserverhq;