最近碰到一個問題,如何在Windows的IDE或者文本編輯器上,遠程調試Linux服務器上的golang程序。
雖然想說gdb走你,但既然go有dlv這樣的類似Java的jdwp的原生方案,而且我用的Visual Code的官方Go插件支持這種方案,那就試一下這個方案吧。
2019-03-15追加:dlv支持debug、attach和exec三種方式。其中,debug是需要重新編譯源代碼的,后面兩種不需要。也因此debug更適合開發階段那種“寫幾個函數,F5一下看看能不能動”的場景,也是Visual Code官方文檔記述的遠程調試go的唯一方式。這篇文章講述的是dlv debug這個方式,后續兩個方式將在后續發出。
環境
- 近端
- Win7 64bit
- Visual Code 1.32.1 x64
- Go 1.10
- 遠端
- OpenSuSE 42.1
- Go 1.10
- git 2.12.3
- 示例項目
- hello/main.go,內容如下
package main import "fmt" var globalVar int func main() { globalVar = 2 localVar := 1 globalVar++ localVar++ fmt.Printf("%v + %v = %v\n", globalVar, localVar, globalVar+localVar) }
准備01. 部署遠端dlv
首先遠端需要先裝好go、git和make的編譯全家桶。然后設置好GOPATH,在這里我把/root/go作為這次的GOPATH。
export GOPATH=/root/go
然后從github.com上下載dlv下來,將dlv編譯(make)出來后,將編譯好的dlv加入可執行文件搜索路徑(PATH)中。
git clone https://github.com/go-delve/delve.git $GOPATH/src/github.com/go-delve/delve
cd $GOPATH/src/github.com/go-delve/delve
make install
export PATH=$PATH:$GOPATH/bin
這時候,執行dlv version
應該能看到下面的類似信息(版本和Build隨版本不同而不一樣)。
Delve Debugger
Version: 1.2.0 Build: ac3b1c7a786d681a5aefcdded9888090d69b3832
准備02. 部署近端dlv
近端可以直接用go來安裝dlv,也可以使用Visual Code的Go插件來安裝,Visual Code都能識別。這里使用的是Go插件的方法。
在Visual Code的菜單欄上,通過View->Command Palette打開Visual Code的命令界面,輸入>Go:install/update Tools
后回車,就能看到選擇安裝哪個go工具的菜單。選中dlv后,點擊OK按鈕,就會自動安裝了。安裝過程以及提示信息可以在OUTPUT窗口查看。

准備03. 添加debug方案
另外,需要給Visual Code添加對應的debug方案(debug configuration)。在Visual Code的菜單欄上,通過Debug->Open Configurations打開launch.json的編輯界面。在configurations數組中,加入以下內容后,保存文件。
{ "name": "Launch remote", "type": "go", "request": "launch", "mode": "remote", "remotePath": "/root/go/src/hello", "port": 2345, "host": "192.168.33.123", "program": "${fileDirname}", "env": {} }
現在,我們就完成了遠程調試的所有必須准備了。
執行方法
dlv的debug遠程調試需要遠端和近端都持有全部的源代碼文件。為了方便,這里就不改變GOPATH,在遠端直接將整個項目,扔到$GOPATH/src里面,源代碼文件路徑為$GOPATH/src/hello/main.go;在近端,直接創建hello目錄,就把源代碼文件直接放在里面。
首先,我們需要先到項目里,啟動dlv的服務端。
cd $GOPATH/src/hello
dlv debug --headless --listen ":2345" --log --api-version 2
畫面顯示以下內容則說明dlv服務端已經就緒。
API server listening at: [::]:2345 INFO[0004] launching process with args: [/root/go/src/hello/debug] layer=debugger
然后,回到Visual Code進入debug界面,選擇“Launch remote”方案后,點擊啟動來進行go debugger,就能啟動遠程調試。大部分的操作和本地調試無異,堆棧、變量、watch都能正常使用。

總結
通過Visual Code+dlv來進行go程序的遠程調試,對“開發用Windows,生產用Linux”之類的場合下,調試與系統相關的問題非常有幫助。而且,Visual Code的圖形界面和代碼提示實在是相當方便。
但是debug這個做法有兩點不完善的地方。第一個是它原理上需要遠端對源代碼進行編譯,局限了它在除了開發測試環境外的使用場景,也使得每次調試都得等它編譯;另一個是因為遠端和近端都得有相同的源代碼,無論是dlv還是Visual Code的Go插件,目前都沒法自動將本地改動過的代碼上傳到遠端去,因此無法實現“F5走你”的一鍵操作,手工工序太多,使得“debug驅動開發”(笑,雖然不鼓勵,但無法消滅啊)的模式難以開展。
所以,最好還是乖乖裝個Linux桌面本地調試吧。