Golang Go语言程序无故退出,panic也捕获不到,求解决方案
程序里面用了若干 go 子线程(盲猜问题在子线程但是无法定位),有些错误会直接 os.exit ,每个函数方法都写了 panic 捕获写日志,程序退出时不会返回 panic 。
大神们有什么好的办法定位错误处吗?
生产环境问题出了几个月还是找不到问题,有时运行半天,有时运行几天,退出的时候 cpu 和内存都没有大量占用
Golang Go语言程序无故退出,panic也捕获不到,求解决方案
b os.exit
更多关于Golang Go语言程序无故退出,panic也捕获不到,求解决方案的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
试试 sentry ?
找找有没有不安全指针
attach processes 或者直接远程上去 debug ?
我最近也遇到了类似的 Bug ,服务器崩溃了,但是 Sentry 无法收集到崩溃,但是退出还是有日志的。
我遇到的情况是这样的:一个第三方库出了些问题,在 map 里面野指针了。而 Map 在 Go Runtime 里面的实现是 ASM 实现的,然后 Link 到 Runtime 里面。如果 ASM 内部发生了野指针相关的问题,直接会被系统走了 unix signal 退出,导致无法被 recover handle 。
我看日志说 os.Exit() 会把程序立即退出,这个真的是你需要的函数吗?
设置环境变量 GOTRACEBACK=crash 运行 Go 程序,core dump 后用 GDB 查,参见: https://pkg.go.dev/runtime
不是自己主动写的 os.exit 而是一些莫名的错误导致的
就是找起来很麻烦 代码行一多逻辑一复杂简直不可能
你是如何找到错误地方的?
1.lint 错误全部要修改过来
2.race 运行检测
3.付费请人
map 并发读写导致的程序崩溃。这种崩溃通过 panic 无法捕捉,检查下全局 map 是否有并发读写的情况吧。
看看日志库,有没有接管退出方法,导致退出前没有 flush 日志。
如果短时间可以浮现,服务器上 nohup strace 启动服务看退出前的行为。
先跑一遍 golangci-lint 吧。
这个会有堆栈信息的
- strace
可以有这个 api 的调用关系
2. gdb
有堆栈
log 文件呀,我 go 的 binary 的启动是套了一层 supervisor 的,在 supervisor 对应的 err 里面是有崩溃 stack trace 的
在 Goroutines 里面写 defer func(){}
像楼上说的,多打日志。我之前也是有这种类似的情况,多打日志就好了,极限一点每个模块都用不同的日志文件记录,方便定位
我只是在每个子线程里面的 defer 捕获 panic ,但是出错的地方根本没有返回 panic ,感觉是直接 os
.exit 了
打了日志啊,根本没有信息
supervisor 是啥 属于 go 的范围吗?还是 linux 层面的?
跑了没问题
貌似直接崩溃有好些可能性,比如指针错误,并发写入公共变量,还有第三方库可能是 os.exit
本质上就是 stderr 啊…
什么神仙第三方库会 os.Exit() ?
提示一点……panic 日志是不会打在你指定的文件里的,总是输出到 stderr
所以如果你没对 stderr 进行重定向的话,应该是看不到日志的。
目前看起来是猜测已经够多了只差验证了,我提供一个验证的思路:利用 BPF 技术追踪下 os.Exit 和 panic 调用,能够定位到底是因为哪一种方式导致程序退出的。
panic 可以捕获啊,捕获后想怎么样都可以
panic 在外面捕获不到的,一般都是在 go func 协程里崩的,得在协程里 recover 才行