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

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

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

ptrace系統(tǒng)調用

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

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

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

ptrace使用示例

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

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

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

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