天天看點

使用Delve調試Golang 代碼安裝調試代碼進階調試

追蹤代碼中的錯誤可能是一件非常頭疼的事情。這在高度依賴goroutine的Golang代碼調試中更加的突出。有一個趁手的 debug 工具就顯得非常的重要。我們先來看看 Go 官方的debug tool文檔寫的啥。

GDB does not understand Go programs well. The stack management, threading, and runtime contain aspects that differ enough from the execution model GDB expects that they can confuse the debugger, even when the program is compiled with gccgo. In short, the instructions below should be taken only as a guide to how to use GDB when it works, not as a guarantee of success. In time, a more Go-centric debugging architecture may be required.

總結一下上面說的話。

Go 的debug工具有GDB這個玩意,但是目前貌似工作的不咋滴

目前官方隻是給你介紹介紹這個玩意怎麼用,但是不保證能成功

實話說,我們需要一個更懂 Go 的調試器

Delve目的就是為了解決開發者在使用 GDB 調試中遇到的各種各樣的問題。我們開始詳細的介紹一些使用Delve 調試代碼的例子。

首先預設你已經安裝了 Go 環境,安裝指令很簡單,一句話。

注意:如果你使用Go1.5,你必須在運作這個指令前設定<code>GO15VENDOREXPERIMENT=1</code>

首先得說明一下,實誠點說,當你想用debug 工具的時候,你的代碼估計已經不按照你想象的方式運作了。隻是你不知道為什麼會這樣,是以你可能需要換一種方式啟動你的程式,下面我們來示範一下如果使用<code>dlv</code>來啟動你的程式。我們的示例代碼如下:

在這個示例代碼中,我們建立了10個<code>goroutine</code>,這種代碼對于 GDB 來說是幾乎不可讀的,因為它對于<code>goroutine</code>的支援很差。但是<code>Delve</code>作為一個專業的 Go 調試器,對于<code>goroutine</code>這種殺手級功能還是非常了解的。下面我們來啟動程式。

運作這個指令,dlv會去編譯你的代碼,然後傳一些參數給編譯器,好讓編譯器編譯出來更加友善調試的可執行檔案,然後啟動了你的程式,并且<code>attach</code>上去,這樣你的console就會停留在了<code>debug session</code>,下面就可以調試程式了。

首先我們在main函數上設定一個斷點。

輸出資訊裡面告訴了我們斷點的 ID和斷點的位置,函數名和檔案名以及所在行數。我們使用<code>continue</code>指令讓程式運作到我們打斷點的地方。

現在程式就停在了第一個斷點,現在我們可以使用<code>next</code>指令讓程式運作到下一句話,如果你想繼續向下,可以直接按回車(Delve會重複上一條指令如果你按下Enter鍵)。

現在我們可以嘗試使用<code>print</code>指令去看一下變量的值。

同時你也可以輸出一個表達式

下面我們在另外一個函數<code>dostuff</code>上設定一個斷點

我們使用<code>continue</code>到我們設定斷點的地方,然後<code>next</code>

可以看到Delve會告訴你目前的goroutine id,我們試試輸出一下i和wg.

我們建立了10個goroutine,如果你繼續使用next,你會發現你還是在同一個goroutine下。這樣就避免了被調試器跳轉到了另外的goroutine下導緻不必要的調試錯誤。可見還是為 Go 而生的調試器才是真愛啊。

其實很多時候,我們調試的代碼可能是<code>daemon</code>程式或者需要實作編譯好在不同機器運作的程式。這就需要我們<code>attach</code>到一個已經在運作中的程式上,下面我們就使用上面的代碼來示範一下如何<code>attach</code>到一個程式上進行調試。首先将剛才的程式運作起來,我這裡直接使用了

然後使用ps檢視正在運作的程式pid

然後我們<code>attach</code>上去

可以看到,熟悉的<code>debug seesion</code>又回來了。下面我們可以繼續使用上面的指令去設定斷點了

我使用<code>continue</code>使程式運作到我設定斷點的地方

可以看到,Delve已經列印出來了目前正在運作的goroutine,下面我們<code>print</code>一下我們目前的i

和上面一樣,而且<code>attach</code>到這個程序後,也可以把對應的源碼顯示出來,是不是很強大呢。更多的功能就自己參考文檔摸索吧。