一文看懂 | GDB底層實(shí)現(xiàn)原理
時間:2021-11-11 13:46:21
手機(jī)看文章
掃描二維碼
隨時隨地手機(jī)看文章
[導(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_PEEKUSER
、PTRACE_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.htmlptrace使用示例
下面通過一個簡單例子來說明?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,?