必须先让程序运行至并发场景:dlv启动默认停在runtime.main,此时goroutine未调度,列表为空;需用break main.main再continue,或Ctrl+C中断已运行程序后执行goroutines才能获取完整快照。

dlv 调试时 goroutine 列表为空或不全怎么办
断点没触发前,goroutines 命令基本没用——dlv 启动后默认停在入口点(runtime.main),此时其他 goroutine 还没调度起来,列表自然为空或只有一两个。必须先让程序跑起来、触发真实并发场景。
- 用
break main.main打断点,再continue运行到主函数开始;或直接break <业务函数名>(如break handleRequest) - 程序已运行但没断住?按
Ctrl+C中断,dlv 会进入调试态,这时再执行goroutines就能列出当前全部活跃 goroutine -
goroutines -t 5可限制栈深度,避免输出刷屏;状态列里waiting表示阻塞,running表示正在执行,syscall多见于系统调用未返回
切换 goroutine 后查变量总不对,为什么
dlv 的上下文是“全局绑定”的:一旦执行 goroutine 17,后续所有 print、locals、stack 都作用于 ID 17 —— 但很多人切完不确认,回头查的还是上一个 goroutine 的变量。
- 切换前先执行
goroutine(不带参数),看当前 ID;切换后立刻再执行一次goroutine,确认 ID 已变 - 局部变量可能被编译器优化掉,
print v报could not find symbol时,试试print &v或加编译参数go build -gcflags="-N -l"禁用优化 - 闭包变量不在
locals里,得先frame 0切到栈顶帧,再用print *(**int)(0x...)解引用查看(地址从info registers或反汇编中找)
debug.PrintStack() 和 pprof.Lookup("goroutine").WriteTo() 有什么区别
debug.PrintStack() 只打当前 goroutine,轻量但视野窄;pprof.Lookup("goroutine").WriteTo(os.Stdout, 1) 输出全部 goroutine 的完整堆栈快照,适合定位死锁、泄漏或 goroutine 泄洪。
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
-
debug.PrintStack()必须导入"runtime/debug",输出无格式、无颜色,混在日志里容易被忽略;它不终止程序,适合临时埋点 -
pprof.Lookup("goroutine").WriteTo(..., 1)的第二个参数为 1 时显示全部 goroutine(包括系统 goroutine),为 2 时只显示用户创建的;注意它不包含变量值,只展示调用路径 - 想查阻塞原因?对
waiting状态的 goroutine,用print (*runtime.g)(17).waitreason(ID 替换为实际数字)可看到具体等什么(比如semacquire表示等信号量)
GDB 调试 Go 时变量显示为 <optimized out>> 怎么办
Go 编译器默认开启内联和逃逸分析,导致局部变量被优化掉或移入堆,GDB 就找不到符号。这不是 GDB 的问题,而是编译选项没配对。
立即学习“go语言免费学习笔记(深入)”;
- 编译时必须加
go build -gcflags="-N -l":-N禁用优化,-l禁用内联,否则 GDB 查不到变量、断点也可能偏移 - 不要用
go run调试,它临时编译不保留调试信息;始终用go build生成二进制再调试 - GDB 中
info locals显示空?试试info registers看寄存器值,或x/10i $pc查当前指令,结合源码定位真实变量位置

















