小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

gdb到底是怎樣實(shí)現(xiàn)的?

 漢無為 2019-07-06

gdb這個(gè)debug工具,應(yīng)該無人不知吧。服務(wù)器開發(fā)和客戶端開發(fā)人員應(yīng)該都或多或少的通過這個(gè)工具排查問題。但有沒有想過它的實(shí)現(xiàn)原理,為什么打斷點(diǎn)能夠在斷點(diǎn)處停止運(yùn)行?為什么能查看cpu寄存器?等等。我們就帶著這些疑問接著往下看。

知識鋪墊

我們都聽說過系統(tǒng)調(diào)用,這里簡單的解釋下系統(tǒng)調(diào)用的含義。操作系統(tǒng)提供了一種標(biāo)準(zhǔn)的服務(wù)來讓程序員實(shí)現(xiàn)對底層的硬件和服務(wù)的控制,比如申請、釋放內(nèi)存,打開、關(guān)閉文件等等,這就叫做系統(tǒng)調(diào)用(system calls)。

系統(tǒng)調(diào)用的過程比較復(fù)雜,大致流程是這樣的:將相關(guān)參數(shù)放進(jìn)系統(tǒng)調(diào)用的相關(guān)寄存器中,然后調(diào)用軟中斷(0x80),這個(gè)中斷作用就是讓一個(gè)程序從用戶態(tài)陷入到內(nèi)核態(tài)執(zhí)行,程序?qū)?shù)和系統(tǒng)調(diào)用號交給內(nèi)核,內(nèi)核來執(zhí)行。

看完這個(gè)知識鋪墊,估計(jì)心里猜測跟系統(tǒng)調(diào)用有關(guān)系了。確實(shí)不是特別高大上的技術(shù),只是利用了Linux提供的非常優(yōu)雅的方式:ptrace系統(tǒng)調(diào)用,用man查看以下這個(gè)系統(tǒng)調(diào)用。ptrace可以讓父進(jìn)程觀察和控制其子進(jìn)程的檢查、執(zhí)行,改變其寄存器和內(nèi)存的內(nèi)容。主要的作用就是大家常用的打斷點(diǎn)的功能了,還有一個(gè)功能是打印系統(tǒng)調(diào)用的軌跡信息。

我們先來看下這個(gè)ptrace函數(shù)的原型:


#include <sys/ptrace.h>long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);

第一個(gè)參數(shù)決定了ptrace的行為與其他參數(shù)的使用方法??扇〉闹涤校?/p>


PTRACE_MEPTRACE_PEEKTEXTPTRACE_PEEKDATAPTRACE_PEEKUSERPTRACE_POKETEXTPTRACE_POKEDATAPTRACE_POKEUSERPTRACE_GETREGSPTRACE_GETFPREGS,PTRACE_SETREGSPTRACE_SETFPREGSPTRACE_CONTPTRACE_SYSCALL,PTRACE_SINGLESTEPPTRACE_DETACH

下面對常用的幾種模式進(jìn)行說明。

  1. PTRACE_ME(跟蹤我):這是相對父進(jìn)程而言的。功能是指示父進(jìn)程,對其進(jìn)行跟蹤。trace工具的實(shí)現(xiàn)就是用這個(gè)模式。
  2. PTRACE_GETREGS:讀取寄存器的值。如果你想在系統(tǒng)調(diào)用或者進(jìn)程停止前讀取它的寄存器。這就回答了文章開頭的第二個(gè)問題。
  3. PTRACE_SINGLESTEP:單步。會使內(nèi)核在子進(jìn)程的每一條指令執(zhí)行前先將其阻塞,然后控制權(quán)交給父進(jìn)程。
  4. PTRACE_PEEKDATA:設(shè)置斷點(diǎn)。調(diào)試器怎么設(shè)置斷點(diǎn)的呢?通常情況下,將當(dāng)前需要執(zhí)行的指令替換成trap指令,于是就會停在當(dāng)前位置。被調(diào)試程序恢復(fù)運(yùn)行以后調(diào)試器將原指令放回來就可以了。具體實(shí)現(xiàn)過程請接著往下看!

詳細(xì)可參考《http:///linux/man-pages/man2/ptrace.2.html》

gdb三種調(diào)試方式

看完ptrace使用方法,再來看看gdb的三種調(diào)試方式。

  1. attach并調(diào)試一個(gè)已經(jīng)運(yùn)行的進(jìn)程: 確定需要進(jìn)行調(diào)試的進(jìn)程id ;運(yùn)行g(shù)db,輸入attch pid,如:gdb 12345。gdb將對指定進(jìn)行執(zhí)行如下操作:ptrace(PTRACE_ATTACH,pid,0,0)
  2. 運(yùn)行并調(diào)試一個(gè)新的進(jìn)程 :運(yùn)行g(shù)db,通過命令行參數(shù)或file指定目標(biāo)調(diào)試程序,如gdb ./test ;輸入run命令,gdb執(zhí)行下述操作: 通過fork()系統(tǒng)調(diào)用創(chuàng)建一個(gè)新進(jìn)程 。在新創(chuàng)建的子進(jìn)程中調(diào)用ptrace(PTRACE_TRACEME,0,0,0) 。在子進(jìn)程中通過execv()系統(tǒng)調(diào)用加載用戶指定的可執(zhí)行文件
  3. 遠(yuǎn)程調(diào)試目標(biāo)主機(jī)上新創(chuàng)建的進(jìn)程 :gdb運(yùn)行在調(diào)試機(jī),gdbserver運(yùn)行在目標(biāo)機(jī),通過二者之間定義的數(shù)據(jù)格式進(jìn)行通信。

斷點(diǎn)的實(shí)現(xiàn)過程

再回到剛文章開頭的問題,斷點(diǎn)是怎樣實(shí)現(xiàn)的呢?我從上面文字中知道gdb調(diào)試的實(shí)現(xiàn)都是建立在信號的基礎(chǔ)上的。在使用參數(shù)為PTRACE_TRACEME或PTRACE_ATTACH的ptrace系統(tǒng)調(diào)用建立調(diào)試關(guān)系后,交付給目標(biāo)程序的任何信號首先都會被gdb截獲。

因此gdb可以先行對信號進(jìn)行相應(yīng)處理,并根據(jù)信號的屬性決定是否要將信號交付給目標(biāo)程序。

當(dāng)用breakpoint 設(shè)置一個(gè)斷點(diǎn)后,gdb會在=找到該位置對應(yīng)的具體地址,然后向該地址寫入斷點(diǎn)指令I(lǐng)NT3,即0xCC。

目標(biāo)程序運(yùn)行到這條指令時(shí),就會觸發(fā)SIGTRAP信號,gdb會首先捕獲到這個(gè)信號。然后根據(jù)目標(biāo)程序當(dāng)前停止的位置在gdb維護(hù)的斷點(diǎn)鏈表中查詢,若存在,則可判定為命中斷點(diǎn)。

喜歡這篇文章,請不要忘記點(diǎn)擊右下方“在看”,謝謝!

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多