程序里面用了若干 go 子线程(盲猜问题在子线程但是无法定位),有些错误会直接 os.exit ,每个函数方法都写了 panic 捕获写日志,程序退出时不会返回 panic 。
大神们有什么好的办法定位错误处吗?
生产环境问题出了几个月还是找不到问题,有时运行半天,有时运行几天,退出的时候 cpu 和内存都没有大量占用
1
nuk 2022-04-11 00:25:38 +08:00
b os.exit
|
2
ETiV 2022-04-11 00:40:38 +08:00 via iPhone
试试 sentry ?
|
3
foam 2022-04-11 00:41:15 +08:00 via Android
找找有没有不安全指针
|
4
kwanzaa 2022-04-11 00:44:20 +08:00
attach processes 或者直接远程上去 debug ?
|
5
txx 2022-04-11 01:13:05 +08:00 2
我最近也遇到了类似的 Bug ,服务器崩溃了,但是 Sentry 无法收集到崩溃,但是退出还是有日志的。
我遇到的情况是这样的:一个第三方库出了些问题,在 map 里面野指针了。而 Map 在 Go Runtime 里面的实现是 ASM 实现的,然后 Link 到 Runtime 里面。如果 ASM 内部发生了野指针相关的问题,直接会被系统走了 unix signal 退出,导致无法被 recover handle 。 |
6
CEBBCAT 2022-04-11 01:36:11 +08:00
我看日志说 os.Exit() 会把程序立即退出,这个真的是你需要的函数吗?
|
7
kinghui 2022-04-11 07:14:07 +08:00
设置环境变量 GOTRACEBACK=crash 运行 Go 程序,core dump 后用 GDB 查,参见: https://pkg.go.dev/runtime
|
11
dbskcnc 2022-04-11 09:21:49 +08:00
1.lint 错误全部要修改过来
2.race 运行检测 3.付费请人 |
13
xmge 2022-04-11 10:00:23 +08:00
map 并发读写导致的程序崩溃。这种崩溃通过 panic 无法捕捉,检查下全局 map 是否有并发读写的情况吧。
|
14
luwill 2022-04-11 10:56:39 +08:00
看看日志库,有没有接管退出方法,导致退出前没有 flush 日志。
如果短时间可以浮现,服务器上 nohup strace 启动服务看退出前的行为。 |
15
joesonw 2022-04-11 11:09:55 +08:00 via iPhone
先跑一遍 golangci-lint 吧。
|
17
xsen 2022-04-11 12:39:50 +08:00
1. strace
可以有这个 api 的调用关系 2. gdb 有堆栈 |
18
txx 2022-04-11 15:09:26 +08:00
@herozzm log 文件呀,我 go 的 binary 的启动是套了一层 supervisor 的,在 supervisor 对应的 err 里面是有崩溃 stack trace 的
|
19
MeetTheFuture 2022-04-11 15:52:10 +08:00
在 Goroutines 里面写 defer func(){}
|
20
kirisamemarisas 2022-04-11 16:17:33 +08:00
像楼上说的,多打日志。我之前也是有这种类似的情况,多打日志就好了,极限一点每个模块都用不同的日志文件记录,方便定位
|
21
herozzm OP @MeetTheFuture 我只是在每个子线程里面的 defer 捕获 panic ,但是出错的地方根本没有返回 panic ,感觉是直接 os
.exit 了 @kirisamemarisas 打了日志啊,根本没有信息 |
26
CEBBCAT 2022-04-11 20:46:22 +08:00
什么神仙第三方库会 os.Exit() ?
|
27
tairan2006 2022-04-12 10:24:25 +08:00
提示一点……panic 日志是不会打在你指定的文件里的,总是输出到 stderr
所以如果你没对 stderr 进行重定向的话,应该是看不到日志的。 |
28
yeqown 2022-04-12 11:22:10 +08:00
目前看起来是猜测已经够多了只差验证了,我提供一个验证的思路:利用 BPF 技术追踪下 os.Exit 和 panic 调用,能够定位到底是因为哪一种方式导致程序退出的。
|
29
herozzm OP @tairan2006 panic 可以捕获啊,捕获后想怎么样都可以
|
30
tairan2006 2022-04-12 13:16:46 +08:00 via Android
@herozzm 你调用第三方库,它自己开了个协程的话,你是没法捕获的…
|
31
smartshallot 2022-04-14 22:44:54 +08:00
@herozzm panic 在外面捕获不到的,一般都是在 go func 协程里崩的,得在协程里 recover 才行
|