首頁 系統教程 Linux 深入探討Linux調試器的高階話題

深入探討Linux調試器的高階話題

Jan 08, 2024 pm 10:42 PM
linux linux教程 紅帽 linux系統 linux指令 linux認證 紅帽linux linux視頻

導讀 我們終於來到這個系列的最後一篇文章!這次,我將對調試中的一些更高級的概念進行高層的概述:遠端調試、共享庫支援、表達式計算和多線程支援。這些想法實現起來比較複雜,所以我不會詳細說明如何做,但是如果你有問題的話,我很樂意回答有關這些概念的問題。
系列索引
  1. 準備環境
  2. 斷點
  3. 暫存器和記憶體
  4. Elves 和 dwarves
  5. 原始碼和訊號
  6. 原始碼層逐步執行
  7. 原始碼層斷點
  8. 呼叫堆疊
  9. 處理變數
  10. 進階主題
遠端偵錯

遠端偵錯對於嵌入式系統或對不同環境進行偵錯非常有用。它還在高級偵錯器操作和與作業系統和硬體的互動之間設置了一個很好的分界線。事實上,像 GDB 和 LLDB 這樣的偵錯器即使在偵錯本機程式時也可以作為遠端偵錯器運行。一般架構是這樣的:
Linux 调试器之高级主题!

debugarch

#調試器是我們透過命令列互動的元件。也許如果你使用的是 IDE,那麼在其上有另一個層可以透過機器介面與調試器進行通訊。在目標機器上(可能與本機一樣)有一個調試存根,理論上它是一個非常小的操作系統調試庫的包裝程序,它執行所有的低級調試任務,如在地址上設置斷點。我說“在理論上”,因為如今調試存根變得越來越大。例如,我機器上的 LLDB 偵錯存根大小是 7.6MB。調試存根透過使用一些特定於作業系統的功能(在我們的例子中是 ptrace)和被調試進程以及透過遠端協定的調試器通訊。
最常見的遠端調試協定是 GDB 遠端協定。這是一種基於文字的資料包格式,用於在偵錯器和調試存根之間傳遞命令和資訊。我不會詳細介紹它,但你可以在這裡進一步閱讀。如果你啟動 LLDB 並執行命令 log enable gdb-remote packets,那麼你將獲得透過遠端協定發送的所有資料包的追蹤資訊。在 GDB 上,你可以用 set remotelogfile 做同樣的事情。

作為一個簡單的例子,這是設定斷點的資料包:

$Z0,400570,1#43
登入後複製

$ 標記資料包的開始。 Z0 是插入記憶體斷點的命令。 400570 和 1 是參數,其中前者是設定斷點的位址,後者是特定目標的斷點類型說明符。最後,#43 是校驗值,以確保資料沒有損壞。

GDB 遠端協定非常易於擴展自訂資料包,這對於實現平台或語言特定的功能非常有用。

共享庫和動態載入支援

偵錯器需要知道被偵錯程式載入了哪些共用程式庫,以便它可以設定斷點、取得原始程式碼層級的資訊和符號等。除查找被動態連結的庫之外,偵錯器還必須追蹤在運行時透過 dlopen 載入的庫。為了達到這個目的,動態連結器維護一個 交會結構體。此結構體維護共享庫描述符的鍊錶,以及一個指向每當更新鍊錶時調用的函數的指標。這個結構儲存在 ELF 檔案的 .dynamic 段中,在程式執行之前被初始化。

一個簡單的追蹤演算法:

  • 追蹤程式在 ELF 頭中尋找程式的入口(或可以使用儲存在 /proc//aux 中的輔助向量)。
  • 追蹤程式在程式的入口處設定一個斷點,並開始執行。
  • 當到達斷點時,透過在 ELF 檔案中尋找 .dynamic 的載入位址找到交會結構體的位址。
  • 檢查交會結構體以取得目前載入的庫的清單。
  • 連結器更新函數上設定斷點。
  • 每當到達斷點時,清單都會更新。
  • 追蹤程式無限循環,繼續執行程式並等待訊號,直到追蹤程式訊號退出。

我給這些概念寫了一個小例子,你可以在這裡找到。如果有人有興趣,我可以將來寫得更詳細一點。

表達式計算

表達式計算是程式的一項功能,允許使用者在偵錯程式時對原始來源語言中的表達式進行計算。例如,在 LLDB 或 GDB 中,可以執行 print foo() 來呼叫 foo 函數並列印結果。

根據表達式的複雜程度,有幾種不同的計算方法。如果表達式只是一個簡單的標識符,那麼偵錯器可以查看偵錯訊息,找到該變數並列印該值,就像我們在本系列最後一部分中所做的那樣。如果表達式有點複雜,則可能將程式碼編譯成中間表達式 (IR) 並解釋以獲得結果。例如,對於某些表達式,LLDB 將使用 Clang 將表達式編譯為 LLVM IR 並將其解釋。如果表達式更複雜,或者需要呼叫某些函數,那麼程式碼可能需要 JIT 到目標並在被偵錯者的位址空間中執行。這涉及到調用 mmap 來分配一些可執行內存,然後將編譯的程式碼複製到該區塊並執行。 LLDB 透過使用 LLVM 的 JIT 功能來實現。

如果你想更了解 JIT 編譯,我強烈推薦 Eli Bendersky 關於這個主題的文章。

多线程调试支持

本系列展示的调试器仅支持单线程应用程序,但是为了调试大多数真实程序,多线程支持是非常需要的。支持这一点的最简单的方法是跟踪线程的创建,并解析 procfs 以获取所需的信息。

Linux 线程库称为 pthreads。当调用 pthread_create 时,库会使用 clone 系统调用来创建一个新的线程,我们可以用 ptrace 跟踪这个系统调用(假设你的内核早于 2.5.46)。为此,你需要在连接到调试器之后设置一些 ptrace 选项:

ptrace(PTRACE_SETOPTIONS, m_pid, nullptr, PTRACE_O_TRACECLONE);
登入後複製

现在当 clone 被调用时,该进程将收到我们的老朋友 SIGTRAP 信号。对于本系列中的调试器,你可以将一个例子添加到 handle_sigtrap 来处理新线程的创建:

case (SIGTRAP | (PTRACE_EVENT_CLONE << 8)):
//get the new thread ID
unsigned long event_message = 0;
ptrace(PTRACE_GETEVENTMSG, pid, nullptr, message);
//handle creation
//...
登入後複製

一旦收到了,你可以看看 /proc//task/ 并查看内存映射之类来获得所需的所有信息。

GDB 使用 libthread_db,它提供了一堆帮助函数,这样你就不需要自己解析和处理。设置这个库很奇怪,我不会在这展示它如何工作,但如果你想使用它,你可以去阅读这个教程。

多线程支持中最复杂的部分是调试器中线程状态的建模,特别是如果你希望支持不间断模式或当你计算中涉及不止一个 CPU 的某种异构调试。

最后!

呼!这个系列花了很长时间才写完,但是我在这个过程中学到了很多东西,我希望它是有帮助的。如果你有关于调试或本系列中的任何问题,请在 Twitter @TartanLlama或评论区联系我。如果你有想看到的其他任何调试主题,让我知道我或许会再发其他的文章。

以上是深入探討Linux調試器的高階話題的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

vscode需要什麼電腦配置 vscode需要什麼電腦配置 Apr 15, 2025 pm 09:48 PM

VS Code 系統要求:操作系統:Windows 10 及以上、macOS 10.12 及以上、Linux 發行版處理器:最低 1.6 GHz,推薦 2.0 GHz 及以上內存:最低 512 MB,推薦 4 GB 及以上存儲空間:最低 250 MB,推薦 1 GB 及以上其他要求:穩定網絡連接,Xorg/Wayland(Linux)

Linux體系結構:揭示5個基本組件 Linux體系結構:揭示5個基本組件 Apr 20, 2025 am 12:04 AM

Linux系統的五個基本組件是:1.內核,2.系統庫,3.系統實用程序,4.圖形用戶界面,5.應用程序。內核管理硬件資源,系統庫提供預編譯函數,系統實用程序用於系統管理,GUI提供可視化交互,應用程序利用這些組件實現功能。

notepad怎麼運行java代碼 notepad怎麼運行java代碼 Apr 16, 2025 pm 07:39 PM

雖然 Notepad 無法直接運行 Java 代碼,但可以通過借助其他工具實現:使用命令行編譯器 (javac) 編譯代碼,生成字節碼文件 (filename.class)。使用 Java 解釋器 (java) 解釋字節碼,執行代碼並輸出結果。

vscode終端使用教程 vscode終端使用教程 Apr 15, 2025 pm 10:09 PM

vscode 內置終端是一個開發工具,允許在編輯器內運行命令和腳本,以簡化開發流程。如何使用 vscode 終端:通過快捷鍵 (Ctrl/Cmd ) 打開終端。輸入命令或運行腳本。使用熱鍵 (如 Ctrl L 清除終端)。更改工作目錄 (如 cd 命令)。高級功能包括調試模式、代碼片段自動補全和交互式命令歷史。

git怎麼查看倉庫地址 git怎麼查看倉庫地址 Apr 17, 2025 pm 01:54 PM

要查看 Git 倉庫地址,請執行以下步驟:1. 打開命令行並導航到倉庫目錄;2. 運行 "git remote -v" 命令;3. 查看輸出中的倉庫名稱及其相應的地址。

vscode 無法安裝擴展 vscode 無法安裝擴展 Apr 15, 2025 pm 07:18 PM

VS Code擴展安裝失敗的原因可能包括:網絡不穩定、權限不足、系統兼容性問題、VS Code版本過舊、殺毒軟件或防火牆干擾。通過檢查網絡連接、權限、日誌文件、更新VS Code、禁用安全軟件以及重啟VS Code或計算機,可以逐步排查和解決問題。

vscode在哪寫代碼 vscode在哪寫代碼 Apr 15, 2025 pm 09:54 PM

在 Visual Studio Code(VSCode)中編寫代碼簡單易行,只需安裝 VSCode、創建項目、選擇語言、創建文件、編寫代碼、保存並運行即可。 VSCode 的優點包括跨平台、免費開源、強大功能、擴展豐富,以及輕量快速。

vscode 可以用於 mac 嗎 vscode 可以用於 mac 嗎 Apr 15, 2025 pm 07:36 PM

VS Code 可以在 Mac 上使用。它具有強大的擴展功能、Git 集成、終端和調試器,同時還提供了豐富的設置選項。但是,對於特別大型項目或專業性較強的開發,VS Code 可能會有性能或功能限制。

See all articles