Go 部落格
偵錯 Go 程式碼(狀態報告)
在偵錯時,對變數進行檢查的最佳方式還是使用策略性的列印陳述式,或者使用擺放適當位置的 panic 來取得堆疊追蹤。不過,有些時候,您可能沒有耐心或原始程式碼,如果是這樣,一個好的偵錯器就會非常有幫助。這也是為何過去幾次版本以來,我們一直在改善 Go 的 gc 連結器 (6l、8l) 對 GNU 偵錯器 GDB 的支援。
在最新版本(2010-11-02)中,6l 和 8l 連結器會在撰寫 ELF (Linux、FreeBSD) 或 Mach-O (Mac OS X) 二進位檔案時,傳回 DWARF3 偵錯資訊。這個 DWARF 程式碼有足夠的功能,讓您可以進行下列操作:
- 在 GDB 版本 7.x 中載入 Go 程式,
- 按行數列出所有 Go、C 和組譯原始檔(許多 Go 執行期間環境都是使用 C 和組譯寫成的),
- 按行數設定中斷點,並且逐步執行程式碼,
- 印出堆疊追蹤,並檢查堆疊框架,還有
- 找出位址,並列印大多數變數的內容。
有些缺點
- 發出的 DWARF 程式碼無法由搭載 Mac OS X 的 GDB 版本 6.x 讀取。我們樂意接受將 DWARF 輸出與標準的 OS X GDB 相容的修補程式,但在程式碼修補完成之前,您需要下載、建置和安裝 GDB 7.x,才能在 OS X 上使用。原始碼可於 http://sourceware.org/gdb/download/ 取得。由於 OS X 的特殊性,您需要使用
chgrp procmod
和chmod g+s
在本機檔案系統中安裝二進位檔案。 - 名稱使用套件名稱限定,由於 GDB 不了解 Go 套件,因此您必須使用其完整名稱來參照各個項目。例如,套件
main
中的名為v
的變數,必須以單引號引用的'main.v'
形式參照。這會導致無法自動完成變數和函數名稱。 - 詞彙範圍資訊有點混淆。如果存在多個同名的變數,第 n 個實例的字尾會加上「#n」形式的字尾。我們計畫修正這個問題,但需要變更編譯器和連結器之間交換的資料。
- 區段和字串變數表示為其在執行時期函式庫中的底層結構。它們會看起來像
{data = 0x2aaaaab3e320, len = 1, cap = 1}.
對區段而言,您必須取消參考資料指標才能檢查元素。
有些功能還無法使用
- 無法檢查通道、函數、介面和對應變數。
- 僅有 Go 變數會加上類型資訊註解,不會有執行時期的 C 變數。
- Windows 和 ARM 二進位檔不包含 DWARF 除錯資訊,因此無法使用 GDB 檢查。
我們計畫在未來幾個月解決這些問題,變更編譯器和連結器或使用 GDB 的 Python 擴充功能。在此同時,我們希望 Go 程式設計人員能夠從這個眾所周知的除錯工具中獲得更多協助。
P.S. 除了 GDB 以外,其他工具也可以讀取 DWARF 資訊。例如,在 Linux 上可以使用它與 sysprof 全系統剖析器搭配使用。
下一篇: Go:今天一年前
上一篇: 真正的 Go 專案:SmartTwitter 和 web.go
部落格索引