found bad pointer in Go heap 排查指南
2025-11-23 14:30:06
本文主要记录:fatal error: found bad pointer in Go heap (incorrect use of unsafe or cgo?) 的排查过程,并给出此类问题的排查指南。
首先,我给一个例子:
| |
接着我们编译为二进制文件并运行:
go build -o app && ./app报错信息中,和 main.go 有关的是:
| |
详细报错信息如下:
报错堆栈,点击展开
| |
这里 main.go:17 对应的是 misleadFunc 里第一个 runtime.GC() 而出错的其实是第 26 行,第 27 行调用了 misleadFunc 函数而已,可见出错时并没有立即 panic,而是在 GC 运行时,检测到错误才打印堆栈并 panic,且打印的堆栈是 GC 触发时的堆栈,和真正的命案现场毫不相关,这也是该问题的难查之处:出错在 GC 阶段,堆栈是 Golang 内部的堆栈,而之所以这样是因为 go build 构建出来的二进制是优化过的,对于内存问题,他不是实时检测而是在 gc 运行时检测,想要解决该问题,就必须开启内存问题的实时检测:
go build -gcflags="all=-N -l -d=checkptr=2" -o app && ./app此时,报错信息中,和 main.go 有关的是:
| |
详细的错误信息如下:
报错堆栈,点击展开
| |
根据这个错误信息,我们可以非常清楚的看到,问题出在 main.go 的第 26 行,在生产环境,更推荐的写法是:
go build -v -gcflags="github.com/...=-N -l -d=checkptr=2" -gcflags="$(go list -m)/...=-N -l -d=checkptr=2"github.com/… 表示对以 github.com 开头的包应用该规则,如果没有 /… 则仅对 github.com 这一个包应用该规则,这是一个很容易踩坑的地方。
最后更新于