1. 程式人生 > >gdb除錯基礎

gdb除錯基礎

##除錯基礎
獲取core dump(核心轉儲)檔案,儲存了問題發生時的狀態。  
大多數Linux發行版預設情況下關閉了核心轉儲的功能。通過使用ulimit命令可以檢視當前的核心轉儲功能是否有效。  
ulimit -c  
0  
-c表示核心轉儲檔案的大小限制,為0表示核心轉儲無效。可以使用ulimit -c ulimited,設為無限制之後,發生問題時程序的記憶體就可以全部轉儲到核心轉儲檔案中。  
通過file core*檔案我們可以檢視core檔案的相關資訊。  
例如:  
core.7561: ELF 64-bit LSB core file x86-64,version 1(SYSV),SVR4-style,from './a.out'  
通過使用gdb ./a.out core.7561啟動core檔案的除錯。  
##在專用目錄中生成核心儲存

在生成core檔案時,我們希望指定core檔案的所在目錄,以及相關的core檔案格式,我們可通過sysctl變數kernel.core_pattern設定。假設在/etc/sysctl.conf中這樣設定。  
cat /etc/sysctl.conf  
kernel.core_pattern = /var/core/%t-%e-%p-%c.core  
kernel.core_uses_pid = 0  
sysctl -p
在這種情況下,就會在/var/core/下生成核心轉儲檔案。  
格式說明  
|-----%% ----|--------------字元本身----------|  
|-----%p ----|--------被轉儲的程序ID----------|  
|-----%u ----|----被轉儲程序的真實使用者ID-------|  
|-----%g ----|----被轉儲程序的真實組ID---------|  
|-----%s ----|----引發轉儲的訊號編號-----------|  
|-----%t ----|----------轉儲時刻--------------|  
|-----%h ----|-------------主機名-------------|  
|-----%e ----|-------------可執行檔名--------|  
|-----%c ----|------轉儲檔案的大小上限----------|
##GDB的基本使用方法

1.準備   
通過gcc的-g選項生成除錯資訊。如果使用makefile構建,一般要在CFLAGS中指定-g選項。  
2.啟動  
gdb  
3.設定斷點  
b,斷點可以通過函式名,當前檔案內的行號來設定,也可以先指定檔名在指定行號,還可以指定與暫停位置的偏移量,或者用地址來設定。  
格式:  
break 函式名  
break 行號  
break 檔名:行號  
break 檔名:函式名  
break +偏移量  
break -偏移量  
break *地址  
例子:  
break main
break main.c:10
break +3  
break *0x12345678  
如果不指定斷點位置,預設會在下一行程式碼上設定斷點。通過info break命令可以檢視設定好的斷點。  
4.執行:  
run 引數  
5.顯示棧幀:  
bt(backtrace)顯示所有的棧幀  
bt -N只顯示開頭N個棧幀   
bt full -N只顯示最後的N個棧幀  
5.顯示變數:  
print 變數  
6.顯示暫存器:  
info reg(register)可以顯示暫存器。通過與p $eax可以檢視暫存器裡面的值。  
顯示暫存器可以使用的格式  
x 顯示為十六進位制  
d 顯示為十進位制數  
u 顯示為無符號十進位制數  
o 顯示為八進位制數  
t(two) 顯示為二進位制數  
a 地址  
c 顯示為字元(ASCII)  
f 浮點小數  
s 顯示為字串  
i 顯示為機器語言  
例子:  
p/c $eax 將eax暫存器中的內容以字元方式顯示  
通過x命令可以顯示記憶體的內容,x/格式 地址  
x $eip  
x/i $eip顯示eip對應地址的彙編指令 。
x/10i $eip 顯示eip所指地址開始的10條指令。
7.單步執行  
執行原始碼中一行的命令為n(next),執行時如果遇到函式,可能會希望執行到函式內部,此時可以使用s(step)。
8.繼續執行  
c(continue),程式在遇到斷點後再次停止執行。如果沒有斷點,就會一直執行到結束。  
9.監視點  
在大型軟體或大量使用指標的程式中,很難弄清變數在什麼地方被改變。要想找到變數在何處被改變,可以使用watch命令。  
watch <表示式> 表示式發生變化是暫停執行。
10.刪除斷點和監視點  
d(delete) <編號>此處的編號我們可以通過使用info b來檢視斷點的編號