
介紹
Go 1.11 和 Go 1.12 允許開發人員調試他們部署到生産環境中經過優化的二進制檔案,并且在這方面有了重大改進。
由于 Go 編譯器越來越緻力于生成更快的二進制檔案,在檔案的可調試性方面卻産生了短闆。在 Go 1.10 中,使用者需要完全禁用優化,才能從 Delve 等互動式工具中獲得良好的調試體驗。但是使用者不應該為了可調試性而放棄性能,尤其是對于生産環境的服務。如果在生産環境中出現問題,則需要在生産環境中對其進行調試,而不是部署未經優化的二進制檔案。
對于 Go 1.11 和 1.12,我們專注于改進優化二進制檔案的調試體驗(Go 編譯器的預設設定)。改進包括
- 特别是對于功能入口的參數,有更準确的值檢查 ;
- 更精确地識别語句邊界,以減少單步調試的跳躍,使斷點更多地落在開發者期望的地方 ;
- 對于 Delve 調用 Go 函數(goroutines 和垃圾回收機制使得 Go 比 C 和 C++ 更複雜)的初步支援。
使用 Delve 調試優化代碼
Delve 是 x86 架構下的 Go 調試器,支援 Linux 和 MacOS。Delve 關注 Goroutines 和其他 Go 的功能,它提供了最好的 Go 調試體驗。Delve 也是 GoLand, VS Code 和 Vim 使用的調試引擎。
Delve 通常會通過
-gcflags "all=-N -l"
重建它正在調試的代碼,這個參數會禁用内聯和大多數優化。要使用 delve 調試優化代碼,首先需要建構優化二進制檔案,然後使用
dlv exec your_program
進行調試。對于發生崩潰的核心檔案,則可以使用
dlv core your_program your_core
進行檢查。使用 Go 1.12 和最新的 Delve 版本,即使在優化的二進制檔案中,你也可以檢查許多變量。
改進的值檢查
通常,在調試 Go 1.10 生成的優化二進制檔案時,變量值完全不可用。然而,從 Go 1.11 開始,即使在優化過的二進制檔案中也可以檢查變量,除非它們已經被完全優化。在 Go 1.11 中,編譯器開始發送 DWARF 位置清單,是以調試器可以在進出寄存器時跟蹤變量,并重構分散在不同寄存器和堆棧槽中的複雜對象。
改進的單步調試
下圖是一個在 1.10 調試器中單步執行簡單函數的示例,其中缺陷(跳過和重複的行)用紅色箭頭來突出顯示。
這樣的缺陷使得在單步執行程式并插入斷點時很容易混淆目前的位置。
Go 1.11 和 1.12 記錄語句邊界資訊,并通過優化和内聯更好地跟蹤源行号。是以,在 Go 1.12 中,逐漸執行這段代碼會在每一行停止,并按照你期望的順序執行操作。
函數調用
Delve 中對于函數調用的支援仍在開發中,但簡單的場景是可以勝任的。例如:
6)
未來展望
Go 1.12 是為了優化二進制檔案提供更好的調試體驗而踏出的一步,我們計劃進一步改進它。
可調試性和性能之間存在基本的權衡,是以我們把重點放在優先級最高的調試缺陷上,并努力收集自動化的名額以監控我們的進度并發現阻礙。
我們專注于為調試器生成有關變量位置的正确資訊,是以可以被輸出的變量都能被正确輸出。我們還在考慮使更多的變量值可用,特别是在函數調用點等關鍵位置。盡管在許多情況下,改進這一問題會減慢程式執行速度。最後,我們正在努力改進單步調試:我們關注 panics 的單步調試順序、循環的單步調試順序,并且通常盡可能地遵循源碼順序。
關于 MacOS 支援的說明
Go 1.11 開始壓縮調試資訊以減少二進制檔案大小。Delve 原生支援 MacOS 上的壓縮調試資訊,但 LLDB 和 GDB 都不支援。如果您使用的是 LLDB 或 GDB ,有兩種解決方法:使用
-ldflags=-compressdwarf=false
或使用 splitdwarf(
go get Golang.org/x/tools/cmd/splitdwarf
)來解壓縮現有二進制檔案中的調試資訊。
via: https://blog.golang.org/debugging-what-you-deploy
作者:David Chase
譯者:RookieWilson
校對:polaris1119