Linux之GDB調(diào)試詳解
Linux GDB 調(diào)試
一、初識(shí) GDB
GDB 是一個(gè)開源的、功能強(qiáng)大的調(diào)試工具,主要用于調(diào)試 C、C++ 等語言編寫的程序。
它支持多種操作系統(tǒng)和架構(gòu),能夠幫助開發(fā)者在程序運(yùn)行過程中暫停執(zhí)行、查看變量值、修改程序狀態(tài)等,從而快速定位和修復(fù)問題。
二、啟動(dòng) GDB
1. 加載程序
如果你已經(jīng)編譯好了一個(gè)程序,可以直接通過以下命令啟動(dòng) GDB 并加載程序:
gdb <program>
例如,如果你的程序名為 example,則可以輸入:
gdb example
GDB 會(huì)加載該程序,并進(jìn)入調(diào)試模式。
2. 加載程序與參數(shù)
如果程序需要接收命令行參數(shù),可以使用以下命令啟動(dòng) GDB:
gdb <program> --args <args>
例如,程序需要接收一個(gè)文件路徑作為參數(shù),可以這樣啟動(dòng):
gdb example --args input.txt
在 GDB 中,可以通過 run 命令啟動(dòng)程序,并傳遞參數(shù)。
3. 加載程序與核心轉(zhuǎn)儲(chǔ)文件
當(dāng)程序崩潰并生成了核心轉(zhuǎn)儲(chǔ)文件時(shí),可以通過以下命令啟動(dòng) GDB,加載程序和核心轉(zhuǎn)儲(chǔ)文件進(jìn)行調(diào)試:
gdb <program> <core>
這可以幫助你分析程序崩潰的原因。
三、設(shè)置斷點(diǎn)
斷點(diǎn)是調(diào)試過程中非常重要的工具,它可以讓程序在指定的位置暫停執(zhí)行,方便我們查看程序狀態(tài)。
1. 在函數(shù)處設(shè)置斷點(diǎn)
如果你知道程序在某個(gè)函數(shù)中可能出現(xiàn)問題,可以使用以下命令在該函數(shù)處設(shè)置斷點(diǎn):
break <function>
例如,設(shè)置在 main 函數(shù)處的斷點(diǎn):
break main
程序運(yùn)行到 main 函數(shù)時(shí)會(huì)暫停。
2. 在文件的指定行設(shè)置斷點(diǎn)
如果你已經(jīng)大致知道問題可能出現(xiàn)在代碼的哪一行,可以使用以下命令在指定文件的指定行設(shè)置斷點(diǎn):
break <filename>:<line>
例如,設(shè)置在 example.c 文件的第 10 行的斷點(diǎn):
break example.c:10
程序運(yùn)行到該行時(shí)會(huì)暫停。
3. 在指定內(nèi)存地址處設(shè)置斷點(diǎn)
在某些情況下,你可能需要在指定的內(nèi)存地址處設(shè)置斷點(diǎn),可以使用以下命令:
break *<address>
例如,設(shè)置在內(nèi)存地址 0x1000 處的斷點(diǎn):
break *0x1000
程序運(yùn)行到該地址時(shí)會(huì)暫停。
4. 設(shè)置條件斷點(diǎn)
如果你希望斷點(diǎn)只有在滿足特定條件時(shí)才觸發(fā),可以使用以下命令設(shè)置條件斷點(diǎn):
break <location> if <condition>
例如,設(shè)置在 main 函數(shù)處的斷點(diǎn),只有當(dāng)變量 x 的值大于 10 時(shí)才觸發(fā):
break main if x > 10
這樣可以更精準(zhǔn)地定位問題。
四、運(yùn)行和停止程序
1. 開始運(yùn)行程序
在 GDB 中,可以通過以下命令開始運(yùn)行程序:
run <args>
如果你在啟動(dòng) GDB 時(shí)已經(jīng)指定了程序參數(shù),可以直接輸入 run;如果沒有指定參數(shù),可以在 run 命令后添加參數(shù)。
例如:
run
或者:
run input.txt
程序會(huì)從頭開始運(yùn)行,直到遇到斷點(diǎn)。
2. 從斷點(diǎn)繼續(xù)運(yùn)行
當(dāng)程序在斷點(diǎn)處暫停后,可以通過以下命令從當(dāng)前斷點(diǎn)繼續(xù)運(yùn)行:
continue
程序會(huì)繼續(xù)執(zhí)行,直到遇到下一個(gè)斷點(diǎn)。
3. 單步執(zhí)行
在調(diào)試過程中,有時(shí)需要逐條語句查看程序的執(zhí)行情況,可以使用以下命令:
next:執(zhí)行下一條語句,但不會(huì)進(jìn)入函數(shù)內(nèi)部。如果當(dāng)前語句是一個(gè)函數(shù)調(diào)用,它會(huì)直接跳過該函數(shù),執(zhí)行下一條語句。
next
step:執(zhí)行下一條語句,并進(jìn)入函數(shù)內(nèi)部。如果當(dāng)前語句是一個(gè)函數(shù)調(diào)用,它會(huì)進(jìn)入該函數(shù),繼續(xù)逐條語句執(zhí)行。
step
通過這兩種方式,可以靈活地查看程序的執(zhí)行流程。
4. 執(zhí)行完當(dāng)前函數(shù)
如果你當(dāng)前處于一個(gè)函數(shù)內(nèi)部,可以通過以下命令執(zhí)行完當(dāng)前函數(shù)并返回:
finish
程序會(huì)繼續(xù)執(zhí)行,直到當(dāng)前函數(shù)執(zhí)行完畢并返回。
5. 終止程序運(yùn)行
在調(diào)試過程中,如果需要終止程序的運(yùn)行,可以使用以下命令:
kill
程序會(huì)被強(qiáng)制終止。
五、查看程序狀態(tài)
1. 查看代碼
在 GDB 中,可以通過以下命令查看當(dāng)前代碼位置附近的代碼:
list
默認(rèn)情況下,它會(huì)顯示當(dāng)前代碼位置附近的 10 行代碼。如果需要查看其他部分的代碼,可以在 list 命令后指定文件名和行號(hào):
list <filename>:<line>
例如:
list example.c:20
這可以幫助你快速定位代碼位置。
2. 查看斷點(diǎn)信息
可以通過以下命令查看所有設(shè)置的斷點(diǎn)信息:
info breakpoints
它會(huì)列出所有斷點(diǎn)的編號(hào)、位置、條件等信息,方便你管理斷點(diǎn)。
3. 查看函數(shù)參數(shù)和局部變量
當(dāng)你處于某個(gè)函數(shù)的斷點(diǎn)處時(shí),可以通過以下命令查看當(dāng)前函數(shù)的參數(shù)和局部變量:
info args:查看當(dāng)前函數(shù)的參數(shù)。
info args
info locals:查看當(dāng)前函數(shù)的局部變量。
info locals
這可以幫助你了解函數(shù)的輸入和內(nèi)部狀態(tài)。
4. 查看寄存器內(nèi)容
在某些情況下,你可能需要查看寄存器的內(nèi)容,可以通過以下命令:
info registers
它會(huì)列出所有寄存器的名稱和當(dāng)前值,這對(duì)于底層調(diào)試非常有幫助。
5. 查看調(diào)用棧
當(dāng)程序出現(xiàn)異常時(shí),查看調(diào)用??梢詭椭懔私獬绦虻膱?zhí)行路徑??梢酝ㄟ^以下命令查看調(diào)用棧:
backtrace
或者簡寫為:
bt
它會(huì)從當(dāng)前棧幀開始,向上列出所有調(diào)用棧幀的信息,包括函數(shù)名、文件名、行號(hào)等。
6. 切換調(diào)用棧幀
如果你需要查看調(diào)用棧中某個(gè)特定棧幀的信息,可以通過以下命令切換到該棧幀:
frame <n>
其中 <n> 是棧幀的編號(hào)。例如,切換到編號(hào)為 2 的棧幀:
frame 2
然后可以使用 info args、info locals 等命令查看該棧幀的參數(shù)和局部變量。
六、變量和內(nèi)存操作
1. 打印變量值
在調(diào)試過程中,可以通過以下命令打印變量的值:
print <variable>
例如,打印變量 x 的值:
print x
GDB 會(huì)顯示變量的當(dāng)前值。
2. 打印內(nèi)存內(nèi)容
如果需要查看內(nèi)存中的內(nèi)容,可以通過以下命令:
x/<n><format><address>
<n>表示要顯示的內(nèi)存單元數(shù)量。<format>表示顯示格式,例如x表示十六進(jìn)制,d表示十進(jìn)制,c表示字符等。<address>表示內(nèi)存地址。
例如,查看從地址 0x1000 開始的 10 個(gè)字節(jié)的十六進(jìn)制內(nèi)容:
x/10x 0x1000
這可以幫助你查看內(nèi)存的布局和數(shù)據(jù)。
3. 修改變量值
在某些情況下,你可能需要修改變量的值,可以通過以下命令:
set <variable>=<value>
例如,將變量 x 的值修改為 20:
set x=20
然后可以繼續(xù)運(yùn)行程序,觀察程序行為的變化。
七、退出 GDB
完成調(diào)試后,可以通過以下命令退出 GDB:
quit
或者:
exit
八、GBD基本命令匯總
啟動(dòng) GDB
- gdb :啟動(dòng) GDB 并加載要調(diào)試的程序。
- gdb :加載程序和核心轉(zhuǎn)儲(chǔ)文件進(jìn)行調(diào)試。
- gdb --args :加載程序并傳遞參數(shù)。
設(shè)置斷點(diǎn)
- break :在指定函數(shù)處設(shè)置斷點(diǎn)。
- break : :在指定文件的指定行設(shè)置斷點(diǎn)。
- break *:在指定內(nèi)存地址處設(shè)置斷點(diǎn)。
- break :設(shè)置條件斷點(diǎn),只有滿足條件時(shí)才會(huì)觸發(fā)。
運(yùn)行和停止
- run :開始運(yùn)行程序,并傳遞參數(shù)。
- continue:從當(dāng)前斷點(diǎn)繼續(xù)運(yùn)行程序。
- next:執(zhí)行下一條語句(跳過函數(shù)調(diào)用)。
- step:進(jìn)入函數(shù)內(nèi)部執(zhí)行。
- finish:執(zhí)行完當(dāng)前函數(shù)并返回。
- kill:終止正在運(yùn)行的程序。
- disable breakpoints:指令用于禁用已設(shè)置的斷點(diǎn)。
- enable breakpoints:指令用于重新啟用之前被禁用的斷點(diǎn)。
- display 變量名:跟蹤查看一個(gè)變量,每次停下來都顯示它的值
- undisplay:取消對(duì)先前設(shè)置的那些變量的跟蹤
- delete breakpoints:刪除所有斷點(diǎn)
- set var:修改變量的值
- delete breakpoints n:刪除序號(hào)為n的斷點(diǎn)
查看程序狀態(tài)
- list:顯示當(dāng)前代碼位置附近的代碼。
- info breakpoints:顯示所有斷點(diǎn)信息。
- info args:顯示當(dāng)前函數(shù)的參數(shù)。
- info locals:顯示當(dāng)前函數(shù)的局部變量。
- info registers:顯示寄存器的內(nèi)容。
- backtrace 或 bt:顯示調(diào)用棧。
- frame :切換到指定的調(diào)用棧幀。
變量和內(nèi)存操作
- print :打印變量的值。
- print *:打印指定地址的內(nèi)容。
- set =:修改變量的值。
- x/:查看內(nèi)存內(nèi)容,例如 x/10gx 0x1000 查看 10 個(gè) 8 字節(jié)的內(nèi)容。
信號(hào)處理
- handle stop:讓 GDB 在接收到指定信號(hào)時(shí)暫停程序。
- handle nostop:讓 GDB 不在接收到指定信號(hào)時(shí)暫停程序。
退出 GDB
- quit 或 exit:退出 GDB。
其他
- help:顯示幫助信息。
- help :顯示指定命令的幫助信息。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Linux網(wǎng)絡(luò)配置之FTP配置詳細(xì)教學(xué)
這篇文章主要為大家詳細(xì)介紹了Linux網(wǎng)絡(luò)配置中FTP配置的相關(guān)知識(shí),文中的示例代碼簡潔易懂,具有一定的借鑒價(jià)值,有需要的小伙伴可以了解下2025-06-06
Linux系統(tǒng)下SSD磁盤識(shí)別方法詳解
在當(dāng)今數(shù)據(jù)驅(qū)動(dòng)的時(shí)代,存儲(chǔ)介質(zhì)的選擇直接影響著系統(tǒng)性能,固態(tài)硬盤(SSD)以其卓越的 I/O 性能逐漸取代傳統(tǒng)機(jī)械硬盤(HDD),成為服務(wù)器和高端工作站的標(biāo)配,本文給大家介紹了Linux系統(tǒng)下SSD磁盤識(shí)別方法,需要的朋友可以參考下2025-05-05
優(yōu)化Apache服務(wù)器性能的方法小結(jié)
盡管Apache是一個(gè)高可定制的功能強(qiáng)大且相當(dāng)復(fù)雜的服務(wù)器軟件,我們很有興趣的注意到即使是Apache的標(biāo)準(zhǔn)安裝也可以得到不錯(cuò)的性能。2010-12-12
在centos7上搭建mysql主從服務(wù)器的方法(圖文教程)
這篇文章主要介紹了在centos7上搭建mysql主從服務(wù)器的方法,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-11-11
ubuntu18.0.4安裝mysql并解決ERROR 1698 (28000): Access denied for
這篇文章主要介紹了ubuntu18.0.4安裝mysql并解決ERROR 1698 (28000): Access denied for user 'root'@'localhost',現(xiàn)在將ubuntu18.0.4上安裝mysql并將碰到的問題記錄下來,感興趣的朋友一起看看吧2019-11-11

