使用dlv调试protoc的Go语言插件断点问题
调试由protoc调度的Go语言protoc插件(protoc-gen-myplugin)
方法1:直接用dlv运行插件,模拟protoc请求
protoc调用插件时通过标准输入输出传递Protobuf请求/响应,我们可以先捕获请求数据,再用dlv直接运行插件并传入请求:
- 捕获protoc发给插件的请求数据:
用cat替代你的插件,让protoc把请求输出到文件:protoc --proto_path=protos --go_out=protos --go_opt=paths=source_relative --myplugin_out=./migrations --myplugin_opt=paths=source_relative --plugin=protoc-gen-myplugin=cat service.proto options.proto > plugin_request.bin - 用dlv启动插件并传入捕获的请求:
此时dlv会进入调试会话,你可以设置断点、单步执行,插件会从dlv exec ./protoc-gen-myplugin -- < plugin_request.binplugin_request.bin读取请求并处理。
方法2:让protoc通过dlv启动插件
通过自定义脚本让protoc调用dlv来启动你的插件,直接调试被调度的进程:
- 创建一个可执行脚本(比如
run_dlv.sh):
给脚本添加执行权限:#!/bin/bash # 启动dlv调试插件,允许IDE远程连接(可选),保留终端交互 dlv exec --listen=:2345 --headless=false --api-version=2 ./protoc-gen-myplugin -- "$@"chmod +x run_dlv.sh - 调用protoc时指定用这个脚本作为插件执行程序:
运行后dlv会启动调试会话,你可以直接在终端操作,或者用GoLand、VS Code等IDE连接到protoc --proto_path=protos --go_out=protos --go_opt=paths=source_relative --myplugin_out=./migrations --myplugin_opt=paths=source_relative --plugin=protoc-gen-myplugin=./run_dlv.sh service.proto options.protolocalhost:2345进行远程调试。
方法3:用runtime.Breakpoint配合dlv attach
如果之前用runtime.Breakpoint()没生效,大概率是编译时开启了内联优化,按以下步骤操作:
- 在插件代码的断点位置添加:
import "runtime" func main() { // 调试断点 runtime.Breakpoint() // ... 后续逻辑 } - 编译插件时关闭内联优化,保留完整调试信息:
go build -gcflags="all=-l" -o protoc-gen-myplugin main.go - 运行protoc调用插件,此时进程会在
runtime.Breakpoint()处暂停:protoc --proto_path=protos --go_out=protos --go_opt=paths=source_relative --myplugin_out=./migrations --myplugin_opt=paths=source_relative service.proto options.proto - 打开新终端,找到插件进程ID:
pgrep protoc-gen-myplugin - 用dlv附加到进程开始调试:
dlv attach <进程ID>
内容的提问来源于stack exchange,提问作者jsnb
相关产品推荐
相关产品推荐

