Golang中Gin框架的dlv调试器与Docker及VSCode配置冲突问题

Golang中Gin框架的dlv调试器与Docker及VSCode配置冲突问题 我尝试使用Docker和VSCode为Gin框架设置开发环境。我无法理解为什么断点在调试控制台中可见,但却没有生效。在Docker中我收到了成功的响应,但断点没有起作用:library-go-backend-1 | [GIN] 2024/07/21 - 10:06:11 | 200 | 440.125µs | 192.168.65.1 | GET "/"

我尝试更改端口或在设置中使用不同的选项,但仍然没有头绪。

以下是我的设置: Dockerfile

FROM golang:1.22.1 AS builder
WORKDIR /app/
COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main .
#dlv
RUN CGO_ENABLED=0 go install -ldflags "-s -w -extldflags '-static'" github.com/go-delve/delve/cmd/dlv@latest

FROM alpine:latest
WORKDIR /app/
COPY --from=builder /app/main main
COPY --from=builder /go/bin/dlv /dlv

CMD ["/dlv", "--listen=:8081",  "--headless=true", "--continue", "--accept-multiclient", "--headless=true", "--api-version=2", "exec", "./main"]

docker-compose.yaml

services:
  library-go-backend:
    build: .
    ports:
      - 8080:8080
      - 8081:8081
    volumes:
      # - ./src:/app
      - ~/.dlv:/root/.dlv 

.vscode/lanuch.json

{
    "version": "0.2.0",
    "configurations": [
        {
			"name": "Launch",
			//"processId": 36840,
			"type": "go",
			"request": "attach",
			"mode": "remote",
			//"remotePath": "${workspaceRoot}/main.go",
			"port": 8081,
			"host": "127.0.0.1",
			"showLog": true,
			"trace": "log",
			"logOutput": "rpc""
        }
    ]
}

程序非常简单:

package main

import (
	"fmt"
	"net/http"
	"pbuf/models"

	"github.com/gin-gonic/gin"
)

func sayOk(c *gin.Context) {
	fmt.Println(2 + 2) //<-breakpoint didn't work
	c.JSON(http.StatusOK, gin.H{
		"status": "ok",
	})
}

func GetDBContentTags(c *gin.Context) {
	contentTags := models.ListContentTags()
	c.JSON(http.StatusOK, contentTags)
}

func main() {
	router := gin.Default() // <- breakpoint didn't work 
	router.StaticFile("/content_tag.proto", "./content_tag.proto")
	//router.GET("/albums", getAlbums)
	router.GET("/", sayOk)
	router.GET("/content_tags", GetDBContentTags)

	router.Run()
}

以下是来自VSCode调试控制台的一些额外日志:

DisconnectRequest
Closing Delve.
Remote Debugging: close dlv connection.
DisconnectRequest to parent to shut down protocol server.
DisconnectResponse
Verbose logs are written to:
/var/folders/pl/md29lpmn1bn5cv11vk1s_wk80000gn/T/vscode-go-debug.txt
InitializeRequest
InitializeResponse
AttachRequest
Start remote debugging: connecting 127.0.0.1:8081
InitializeEvent
ConfigurationDoneRequest
ConfigurationDoneResponse {"seq":12,"type":"response","request_seq":3,"command":"configurationDone","success":true}
SetBreakPointsRequest
Halting before setting breakpoints. SkipStopEventOnce is false.
All cleared
Creating on: /Users/tomasz/pbuf/main.go:19
All set:[{"Breakpoint":{"id":60,"name":"","addr":7225507,"addrs":[7225507],"addrpid":[11],"file":"/app/main.go","line":19,"functionName":"main.GetDBContentTags","ExprString":"","Cond":"","HitCond":"","HitCondPerG":false,"continue":false,"traceReturn":false,"goroutine":false,"stacktrace":0,"LoadArgs":{"FollowPointers":true,"MaxVariableRecurse":1,"MaxStringLen":64,"MaxArrayValues":64,"MaxStructFields":-1},"LoadLocals":{"FollowPointers":true,"MaxVariableRecurse":1,"MaxStringLen":64,"MaxArrayValues":64,"MaxStructFields":-1},"WatchExpr":"","WatchType":0,"hitCount":{},"totalHitCount":0,"disabled":false,"RootFuncName":"","TraceFollowCalls":0}}]
SetBreakPointsResponse

我发送了

  • curl localhost:8080,返回结果为 {"status":"ok"}
  • curl localhost:8081curl: (52) Empty reply from server

更多关于Golang中Gin框架的dlv调试器与Docker及VSCode配置冲突问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang中Gin框架的dlv调试器与Docker及VSCode配置冲突问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


从你的配置来看,主要问题在于Delve调试器配置和程序启动方式。以下是需要修正的关键点:

1. Dockerfile中的CMD命令问题:

# 修正后的CMD
CMD ["/dlv", "--listen=:8081", "--headless=true", "--api-version=2", "exec", "./main", "--", "--continue"]

或者更推荐的方式:

# 使用debug模式启动
CMD ["/dlv", "debug", "--listen=:8081", "--headless=true", "--api-version=2", "--accept-multiclient", "./main"]

2. 程序需要以调试模式编译:

FROM golang:1.22.1 AS builder
WORKDIR /app/
COPY . .
# 添加-gcflags="all=-N -l"以保留调试信息
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -gcflags="all=-N -l" -o main .
RUN CGO_ENABLED=0 go install -ldflags "-s -w -extldflags '-static'" github.com/go-delve/delve/cmd/dlv@latest

FROM alpine:latest
RUN apk add --no-cache libc6-compat
WORKDIR /app/
COPY --from=builder /app/main main
COPY --from=builder /go/bin/dlv /dlv

# 使用debug模式启动
CMD ["/dlv", "debug", "--listen=:8081", "--headless=true", "--api-version=2", "--accept-multiclient", "./main"]

3. 修正docker-compose.yaml:

services:
  library-go-backend:
    build: .
    ports:
      - "8080:8080"
      - "8081:8081"
    # 添加security_opt以允许调试
    security_opt:
      - "seccomp:unconfined"
    cap_add:
      - "SYS_PTRACE"
    # 确保源代码映射正确
    volumes:
      - ./:/app:cached

4. 修正.vscode/launch.json:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Attach to Docker",
            "type": "go",
            "request": "attach",
            "mode": "remote",
            "remotePath": "/app",
            "port": 8081,
            "host": "127.0.0.1",
            "showLog": true,
            "trace": "verbose",
            "logOutput": "rpc",
            "cwd": "/app",
            "substitutePath": [
                {
                    "from": "${workspaceFolder}",
                    "to": "/app"
                }
            ]
        }
    ]
}

5. 完整的工作示例:

Dockerfile:

FROM golang:1.22.1 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -gcflags="all=-N -l" -o main .
RUN go install github.com/go-delve/delve/cmd/dlv@latest

FROM alpine:latest
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY --from=builder /app/main .
COPY --from=builder /go/bin/dlv /usr/local/bin/

EXPOSE 8080 8081
CMD ["dlv", "debug", "--listen=:8081", "--headless=true", "--api-version=2", "--accept-multiclient", "--", "./main"]

启动后,在VSCode中附加调试器,断点应该能正常工作了。调试器会在8081端口监听,而你的Gin应用在8080端口提供服务。

回到顶部