Emacs 除錯祕籍之 GUD 偵錯程式
本文簡短地對 Emacs 的除錯工具 GUD 的特性進行了探索。
如果你是一個 C 或 C++ 開發者,你很可能已經使用過 GDB(GNU 偵錯程式),毫無疑問,它是現今最強大、最無可匹敵的偵錯程式之一。它唯一的缺點就是它基於命令列,雖然仍能提供許多強大的功能,但有時也會具有一些侷限性。這也就是為什麼聰明的人們開始追求整合了編輯器和偵錯程式的圖形化整合開發環境。仍有些開發者堅信使用滑鼠會降低工作效率,在 GUI 上用滑鼠點~點~點~是來自惡魔的誘惑。
因為 Emacs 是現今最酷的文字編輯器之一,我將為你展示如何在不碰滑鼠且不離開 Emacs 的情況下,實現寫程式碼、編譯程式碼、除錯程式碼的過程。
GUD(LCTT 譯註:全稱大統一偵錯程式,鑑於其縮寫形式更為人熟知,以下全文將使用縮寫替代此全稱)是 Emacs 下的一個模式,用於在 Emacs 中執行 GDB。它向 GDB 提供了 Emacs 的所有特性,使使用者無需離開編輯器就可以對程式碼進行除錯。
使用 GUD 的前期準備
如果你正在使用一個 Linux 機器,很可能你已經安裝了 GDB 和 gcc,接下來就是要確保已經安裝了 Emacs。以下的內容我將假設讀者熟悉 GDB 並且至少用它做過基本的除錯。如果你未曾接觸過 GDB,你可以做個快速入門,這些資料在網上隨處可得。
對於那些 Emacs 新手,我將向你介紹一些基本術語。縱覽整篇文章,你將看到諸如 C-c M-x
等快捷鍵。此處 C
代表 Ctrl
鍵,M
代表 Alt
鍵。C-c
代表 Ctrl
鍵和 c
鍵被同時按下。如果你看到 C-c c
,它代表同時按下 Ctrl
鍵和 c
鍵,釋放後緊接著按下 c
鍵。在 Emacs 中,編輯文字的主要區域被稱為主緩衝區,而在 Emacs 視窗下方用於輸入命令的區域被稱為迷你緩衝區。
啟動 Emacs,並按下 C-x C-f
來建立一個新檔案。Emacs 將提示你輸入一個檔名,此處讓我們將檔案命名為 buggyFactorial.cpp
。一旦檔案開啟,輸入如下程式碼:
#include<iostream>
#include <assert.h>
int factorial(int num) {
int product = 1;
while(num--) {
product *= num;
}
return product;
}
int main() {
int result = factorial(5);
assert(result == 120);
}
使用 C-x C-s
快捷鍵儲存檔案。檔案儲存完畢,是時候進行編譯了。按下 M-x
,在彈出的提示符後輸入 compile
並點選回車。然後在提示符後,將內容替換為 g++ -g buggyFactorial.cpp
並再次點選回車。
這將在 Emacs 中開啟另一個緩衝區,顯示編譯的狀態。如果你的程式碼輸入沒有錯誤,你將預期得到如圖 2 所示的緩衝區。
要想隱藏編譯緩衝區,首先確保你的游標在編譯緩衝區中(你可以不使用滑鼠,而是通過 C-x o
快捷鍵將游標從一個緩衝區移動到另一個),然後按下 C-x 0
。下一步就是執行程式碼,並觀察是否執行良好。按下 M-!
快捷鍵並在迷你緩衝區的提示符後面輸入 ./a.out
。
你可以看到迷你緩衝區中顯示斷言失敗。很明顯程式碼中有錯誤,因為 5 的階乘是 120。那麼讓我們現在開始除錯吧。
使用 GUD 調式程式碼
現在,我們的程式碼已經編譯完成,是時候看看到底哪裡出錯了。按下 M-x
快捷鍵並在提示符後輸入 gdb
。在接下來的提示符後,輸入 gdb -i=mi a.out
。如果一切順利,GDB 會在 Emacs 緩衝區中啟動,你會看到如圖 4 所示的視窗。
在 gdb
提示符後,輸入 break main
來設定斷點,並輸入 r
來執行程式。程式會開始執行並停在 main()
函式處。
一旦 GDB 到達了 main
處設定的斷點,就會彈出一個新的緩衝區顯示你正在除錯的程式碼。注意左側的紅點,正是你設定斷點的位置,同時會有一個小的標誌提示你當前程式碼執行到了哪一行。當前,該標誌就在斷點處(如圖 5)。
為了除錯 factorial
函式,我們需要單步執行。想要達到此目的,你可以在 GBD 提示符使用 GDB 命令 step
,或者使用 Emacs 快捷鍵 C-c C-s
。還有其它一些快捷鍵,但我更喜歡 GDB 命令。因此我將在本文的後續部分使用它們。
單步執行時讓我們注意一下區域性變數中的階乘值。參考圖 6 來設定在 Emacs 幀中顯示區域性變數值。
在 GDB 提示符中進行單步執行並觀察區域性變數值的變化。在迴圈的第一次迭代中,我們發現了一個問題。此處乘法的結果應該是 5 而不是 4。
本文到這裡也差不多結束了,讀者可以自行探索發現 GUD 模式這片新大陸。GDB 中的所有命令都可以在 GUD 模式中執行。我將此程式碼的修復留給讀者作為一個練習。看看你在除錯的過程中,可以做哪一些定製化,來使你的工作流更加簡單和高效。
via: https://opensourceforu.com/2019/09/debugging-in-emacs-the-grand-unified-debugger/
作者:Vineeth Kartha 選題:lujun9972 譯者:cycoe 校對:wxy
相關文章
- 偵錯程式工作原理(三):除錯資訊除錯
- 偵錯程式工作原理(3):除錯資訊除錯
- 反除錯 -- 利用ptrace阻止偵錯程式附加除錯
- 反除錯&反反除錯 -- 利用sysctl檢測偵錯程式是否存在除錯
- Richard Stallman 反對 Emacs 加入 LLVM 偵錯程式支援MacLVM
- 使用GDB命令列偵錯程式除錯C/C++程式命令列除錯C++
- 微信偵錯程式
- [Win32]一個偵錯程式的實現(五)除錯符號Win32除錯符號
- Xcode偵錯程式LLDBXCodeLLDB
- go語言偵錯程式Go
- 揭秘Linux核心偵錯程式之內幕(轉)Linux
- Python 偵錯程式入門Python
- 偵錯程式到底怎樣工作
- PsySH作為偵錯程式
- 偵錯程式--jdb.exe(轉)
- CodeBlocks偵錯程式設定錯誤問題BloC
- VS除錯技巧之附加程式除錯
- 另一個Swoole偵錯程式 - Yasd
- 偵錯程式是個大騙子!
- GDB偵錯程式(學習筆記)筆記
- Python之PySnooper程式碼除錯PythonOOP除錯
- 在Docker內部使用gdb偵錯程式報錯-Operation not permittedDockerMIT
- 《Node.js 除錯指南》開源書籍Node.js除錯
- Python 程式碼除錯—使用 pdb 除錯Python除錯
- Linux gdb偵錯程式用法全面解析Linux
- iOS Debuger(便捷輔助偵錯程式)iOS
- 輕量級偵錯程式mimikatz
- 偵錯程式工作原理(1):基礎篇
- Linux 核心偵錯程式內幕(轉)Linux
- 為什麼在Docker裡使用gdb偵錯程式會報錯Docker
- AS之Debug除錯除錯
- 除錯篇——除錯物件與除錯事件除錯物件事件
- UE4藍圖AI角色製作(四)之Gameplay偵錯程式AIGAM
- 除錯應用程式記憶體中的神祕問題除錯記憶體
- Rails開發中使用byebug偵錯程式AI
- 如何在Docker內部使用gdb偵錯程式Docker
- 與偵錯程式共舞 – LLDB 的華爾茲LLDB
- 偵錯程式工作原理(2):實現斷點斷點