一文看懂?|?GDB?底層實現(xiàn)原理
時間:2021-11-09 13:49:08
手機看文章
掃描二維碼
隨時隨地手機看文章
[導讀]在程序出現(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.htmlptrace使用示例
下面通過一個簡單例子來說明?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,?