當(dāng)前位置:首頁 > 公眾號精選 > 程序喵大人
[導(dǎo)讀]在程序出現(xiàn)bug的時候,最好的解決辦法就是通過?GDB?調(diào)試程序,然后找到程序出現(xiàn)問題的地方。比如程序出現(xiàn)?段錯誤(內(nèi)存地址不合法)時,就可以通過?GDB?找到程序哪里訪問了不合法的內(nèi)存地址而導(dǎo)致的。本文不是介紹GDB的使用方式,而是大概介紹GDB的實(shí)現(xiàn)原理,當(dāng)然GDB是一個龐大...

在程序出現(xiàn)bug的時候,最好的解決辦法就是通過?GDB?調(diào)試程序,然后找到程序出現(xiàn)問題的地方。比如程序出現(xiàn)?段錯誤(內(nèi)存地址不合法)時,就可以通過?GDB?找到程序哪里訪問了不合法的內(nèi)存地址而導(dǎo)致的。

本文不是介紹 GDB 的使用方式,而是大概介紹 GDB 的實(shí)現(xiàn)原理,當(dāng)然 GDB 是一個龐大而復(fù)雜的項(xiàng)目,不可能只通過一篇文章就能解釋清楚,所以本文主要是介紹 GDB 使用的核心的技術(shù) -?ptrace。

ptrace系統(tǒng)調(diào)用

ptrace()?系統(tǒng)調(diào)用是 Linux 提供的一個調(diào)試進(jìn)程的工具,ptrace()?系統(tǒng)調(diào)用非常強(qiáng)大,它提供非常多的調(diào)試方式讓我們?nèi)フ{(diào)試某一個進(jìn)程,下面是?ptrace()?系統(tǒng)調(diào)用的定義:

long?ptrace(enum?__ptrace_request?request,??pid_t?pid,?void?*addr,??void?*data);
下面解釋一下?ptrace()?各個參數(shù)的作用:

  • request:指定調(diào)試的指令,指令的類型很多,如:PTRACE_TRACEME、PTRACE_PEEKUSERPTRACE_CONT、PTRACE_GETREGS等等,下面會介紹不同指令的作用。
  • pid:進(jìn)程的ID(這個不用解釋了)。
  • addr:進(jìn)程的某個地址空間,可以通過這個參數(shù)對進(jìn)程的某個地址進(jìn)行讀或?qū)懖僮鳌?/li>
  • data:根據(jù)不同的指令,有不同的用途,下面會介紹。
ptrace()?系統(tǒng)調(diào)用詳細(xì)的介紹可以參考以下鏈接:https://man7.org/linux/man-pages/man2/ptrace.2.html

ptrace使用示例

下面通過一個簡單例子來說明?ptrace()?系統(tǒng)調(diào)用的使用,這個例子主要介紹怎么使用?ptrace()?系統(tǒng)調(diào)用獲取當(dāng)前被調(diào)試(追蹤)進(jìn)程的各個寄存器的值,代碼如下(ptrace.c):

#include?
#include?
#include?
#include?
#include?
#include?

int?main()
{???pid_t?child;
????struct?user_regs_struct?regs;

????child?=?fork();??//?創(chuàng)建一個子進(jìn)程
????if(child?==?0)?{?//?子進(jìn)程
????????ptrace(PTRACE_TRACEME,?0,?NULL,?NULL);?//?表示當(dāng)前進(jìn)程進(jìn)入被追蹤狀態(tài)
????????execl("/bin/ls",?"ls",?NULL);??????????//?執(zhí)行?`/bin/ls`?程序
????}?
????else?{?//?父進(jìn)程
????????wait(NULL);?//?等待子進(jìn)程發(fā)送一個?SIGCHLD?信號
????????ptrace(PTRACE_GETREGS,?child,?NULL,?
本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
關(guān)閉
關(guān)閉