gdb除錯基礎
阿新 • • 發佈:2018-11-23
##除錯基礎
獲取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來檢視斷點的編號
獲取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來檢視斷點的編號