一、GDB調(diào)試工具的原理
1.1 未執(zhí)行進(jìn)程調(diào)試
啟用gdb調(diào)試運行g(shù)db ./test的時候,在操作系統(tǒng)里發(fā)生了很多復(fù)雜的事情,系統(tǒng)首先會啟動gdb進(jìn)程,這個進(jìn)程會調(diào)用系統(tǒng)函數(shù)fork()來創(chuàng)建一個子進(jìn)程,這個子進(jìn)程做兩件事情:
?調(diào)用系統(tǒng)函數(shù)ptrace(PTRACE_TRACEME,[其他參數(shù)]);
?通過exec來加載、執(zhí)行可執(zhí)行程序test,那么test程序就在這個子進(jìn)程中開始執(zhí)行了。
1.2 執(zhí)行中進(jìn)程調(diào)試
如果想對一個已經(jīng)執(zhí)行的進(jìn)程進(jìn)行調(diào)試,那么就要在gdb這個父進(jìn)程中調(diào)用ptrace(PTRACE_ATTACH,[其他參數(shù)]),此時,gdb進(jìn)程會attach(綁定)到已經(jīng)執(zhí)行的進(jìn)程B,gdb把進(jìn)程B收養(yǎng)成為自己的子進(jìn)程,而子進(jìn)程B的行為等同于它進(jìn)行了一次 PTRACE_TRACEME操作。
此時gdb進(jìn)程會發(fā)送SIGSTO信號給子進(jìn)程B,子進(jìn)程B接收到SIGSTOP信號后,就會暫停執(zhí)行進(jìn)入TASK_STOPED狀態(tài),表示自己準(zhǔn)備好被調(diào)試了。
1.3 gdb系統(tǒng)調(diào)用原型介紹
#include < sys/ptrace.h >
long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);
ptrace系統(tǒng)函數(shù)是Linux內(nèi)核提供的一個用于進(jìn)程跟蹤的系統(tǒng)調(diào)用,通過它,一個進(jìn)程(gdb)可以讀寫另外一個進(jìn)程(test)的指令空間、數(shù)據(jù)空間、堆棧和寄存器的值。
而且gdb進(jìn)程接管了test進(jìn)程的所有信號,也就是說系統(tǒng)向test進(jìn)程發(fā)送的所有信號,都被gdb進(jìn)程接收到,這樣一來,test進(jìn)程的執(zhí)行就被gdb控制了,從而達(dá)到調(diào)試的目的。
下面對各個參數(shù)進(jìn)行解釋:
- ** enum __ptrace_request request:** 是一個枚舉類型,用于指定要執(zhí)行的操作類型。這個參數(shù)告訴** ptrace** 函數(shù)將要對進(jìn)程進(jìn)行何種跟蹤操作,例如讀取寄存器、寫型,其定義了一系列跟蹤請求類型的常量。例如,**PTRACE_ATTACH **表示附加到一個新進(jìn)程,PTRACE_GETREGS 表示獲取寄存器值。request的主要類型如下:
PTRACE_TRACEME:用于將當(dāng)前進(jìn)程標(biāo)記為被跟蹤的目標(biāo)。調(diào)用進(jìn)程使用這個類型請求后,它的父進(jìn)程可以使用 PTRACE_ATTACH 來附加到它,對其進(jìn)行調(diào)試和跟蹤。
PTRACE_ATTACH:用于將一個進(jìn)程附加到另一個進(jìn)程上進(jìn)行調(diào)試和跟蹤。調(diào)試器進(jìn)程可以使用這個類型請求,通過指定目標(biāo)進(jìn)程ID來附加到目標(biāo)進(jìn)程。
PTRACE_DETACH:用于從一個已經(jīng)被附加和調(diào)試的進(jìn)程上分離調(diào)試器。這個請求會停止對目標(biāo)進(jìn)程的跟蹤,并將其恢復(fù)為正常運行狀態(tài)。
PTRACE_PEEKDATA:用于從目標(biāo)進(jìn)程的內(nèi)存中讀取數(shù)據(jù)??梢允褂迷撜埱髞碜x取目標(biāo)進(jìn)程的內(nèi)存值,例如寄存器、棧幀等。
PTRACE_POKEDATA:用于向目標(biāo)進(jìn)程的內(nèi)存中寫入數(shù)據(jù)??梢允褂迷撜埱髞硇薷哪繕?biāo)進(jìn)程的內(nèi)存值,例如修改寄存器、改變變量值等。
PTRACE_GETREGS:用于獲取目標(biāo)進(jìn)程的寄存器值。通過這個請求,可以獲得目標(biāo)進(jìn)程的 CPU 寄存器的當(dāng)前值,用于調(diào)試和跟蹤。
PTRACE_SETREGS:用于設(shè)置目標(biāo)進(jìn)程的寄存器值。通過這個請求,可以將特定的寄存器值設(shè)置為目標(biāo)進(jìn)程中的特定值。
PTRACE_CONT:用于繼續(xù)執(zhí)行已附加的目標(biāo)進(jìn)程。調(diào)試器進(jìn)程可以使用這個請求來繼續(xù)目標(biāo)進(jìn)程的執(zhí)行,直到下一個斷點或者其他事件觸發(fā)。
2. pid_t pid: 是一個整數(shù)類型,表示要操作的目標(biāo)進(jìn)程的進(jìn)程ID(PID)。pid指定了要對哪個進(jìn)程進(jìn)行跟蹤操作,可以是當(dāng)前進(jìn)程、正在運行的其他進(jìn)程或子進(jìn)程等。
3. void addr: 是一個指針類型,用于指定內(nèi)存地址,具體用途根據(jù)不同的request *參數(shù)而定。例如,對于一些讀寫內(nèi)存的請求,addr指定了要讀取或?qū)懭氲膬?nèi)存地址。
4. void data: 是一個指針類型,用于傳遞數(shù)據(jù),具體用途也根據(jù)不同的request *參數(shù)而定。對于一些讀寫內(nèi)存或寄存器的請求,data指定了要讀取或?qū)懭氲臄?shù)據(jù)存儲位置。
ptrace函數(shù)返回一個long類型值,表示操作的結(jié)果或錯誤碼。通常情況下,返回值大于等于0表示成功,小于0表示發(fā)生錯誤。
如果沒有g(shù)db調(diào)試,操作系統(tǒng)與目標(biāo)進(jìn)程之間是直接交互的;如果使用gdb來調(diào)試程序,那么操作系統(tǒng)發(fā)送給目標(biāo)進(jìn)程的信號就會被gdb截獲,gdb根據(jù)信號的屬性來決定:在繼續(xù)運行目標(biāo)程序時是否把當(dāng)前截獲的信號轉(zhuǎn)交給目標(biāo)程序,如此一來,目標(biāo)程序就在gdb發(fā)來的信號指揮下進(jìn)行相應(yīng)的動作。
-
寄存器
+關(guān)注
關(guān)注
31文章
5425瀏覽量
123639 -
調(diào)試工具
+關(guān)注
關(guān)注
1文章
52瀏覽量
12791 -
gdb
+關(guān)注
關(guān)注
0文章
60瀏覽量
13556
發(fā)布評論請先 登錄
請問如何建立開發(fā)環(huán)境
VIM編輯器怎么實現(xiàn)對嵌入式軟件的調(diào)試功能?
VIM中怎么實現(xiàn)嵌入式軟件調(diào)試?
如何搭建嵌入式Linux的GDB調(diào)試環(huán)境
基于Windows的ARM GCC開發(fā)環(huán) 境
N32G031系列GCC開發(fā)環(huán)境應(yīng)用筆記分享
嵌入式Linux和嵌入式Linux開發(fā)環(huán)境

如何在VIM中對嵌入式軟件進(jìn)行調(diào)試

初學(xué)GDB調(diào)試工具需要注意的事項

STM32CubeIDE乃ST官方提供的免費且功能強(qiáng)大的集成開發(fā)工具

Linux嵌入式 gdb VSCode圖形化調(diào)試教程

如何使用GDB調(diào)試工具

評論