這篇分為兩個部分,需要的人可以跳著看
- 本地開發
- Docker開發
Debug GO
官方文件推薦使用Delve,而不是GDB 雖然Delve可以用command來debug,但我已經很習慣用VSCode邊寫邊debug了,所以接下來來設定環境吧~
本地開發
側邊欄選擇Run and Debug,點擊create a launch.json file,然後選擇Go: Launch Package,VSCode會自動建立一個.vscode/launch.json檔,長得像這樣:
1{
2 // Use IntelliSense to learn about possible attributes.
3 // Hover to view descriptions of existing attributes.
4 // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 "version": "0.2.0",
6 "configurations": [
7 {
8 "name": "Launch Package",
9 "type": "go",
10 "request": "launch",
11 "mode": "auto",
12 "program": "${fileDirname}"
13 }
14 ]
15}
然後就可以下斷點,F5開始debug,很簡單吧!
但我用的是Docker
現在很多人用Docker作為開發環境,尤其是Docker Compose能一次開很多服務真的很方便
這種情況可以用Remote Debug
一樣在側邊欄選擇Run and Debug,點擊create a launch.json file,然後選擇Connect to a server
VSCode也會建立一個.vscode/launch.json檔,但還沒完,需要修改兩個參數:
- port:這個隨便取,不要跟其他服務撞到就好
- substitutePath:怎麼把code volume 到conatiner裡面,這裡就怎麼設 最後我的launch.json長這樣:
1{
2 // Use IntelliSense to learn about possible attributes.
3 // Hover to view descriptions of existing attributes.
4 // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 "version": "0.2.0",
6 "configurations": [
7 {
8 "name": "Connect to server",
9 "type": "go",
10 "request": "attach",
11 "mode": "remote",
12 "substitutePath": [
13 {
14 "from": "${workspaceFolder}",
15 "to": "/app"
16 },
17 ],
18 "port": 4040,
19 "host": "127.0.0.1"
20 }
21 ]
22}
現在來給net/http的範例code寫一個Dockerfile
1FROM golang:1.21.4-alpine
2
3RUN mkdir /app
4COPY .. /app
5WORKDIR /app
6
7RUN go install github.com/go-delve/delve/cmd/dlv@master
8ENTRYPOINT dlv debug --headless --continue --listen :4040 --accept-multiclient .
--continue
可以在delve 伺服器一啟動後立刻開始debug,而用了--continue
以後就要一並使用--accept-multiclient
注意compose.yaml也要設定port mapping和volume!
1version: "3"
2services:
3 app:
4 build:
5 dockerfile: Dockerfile
6 context: .
7 volumes:
8 - ./:/app
9 ports:
10 - 8080:8080
11 - 4040:4040
12 networks:
13 - go-docker-net
14
15networks:
16 go-docker-net:
跟CompileDaemon一起
開發的時候,每次變更都要手動build非常不方便,所以我都會用CompileDaemon,它可以偵測*.go檔案變更,自動build專案
每次編譯之後,可以用CompileDaemon的command option,寫一個script 發送SIGINT終止Delve的headless server
kill_and_debug.sh
1#! /bin/bash
2kill -SIGINT $(ps aux | grep '[d]lv exec' | awk '{print $1}')
3dlv exec --headless --continue --listen :4040 --accept-multiclient ./app
修改一下Dockerfile
1FROM golang:1.21.4-alpine
2
3# Environment variables which CompileDaemon requires to run
4ENV PROJECT_DIR=/app \
5 GO111MODULE=on \
6 CGO_ENABLED=0
7
8RUN mkdir /app
9COPY .. /app
10WORKDIR /app
11
12RUN go get github.com/githubnemo/CompileDaemon
13RUN go install github.com/githubnemo/CompileDaemon
14RUN go install github.com/go-delve/delve/cmd/dlv@master
15
16ENTRYPOINT CompileDaemon -build="go build -o app" -command="sh kill_and_debug.sh"
每次在儲存新修改之前,先斷開remote debug的連接,儲存後等待build,之後就可以跟平常一樣debug了~