The Go Programming Language
› http://golang.org/
› Go Playground
Go Projects
› Revel Web Framework
herozzm

go 程序无故退出, panic 也捕获不到,求解决方案

  •  
  •   herozzm · Apr 11, 2022 via Android · 4379 views
    This topic created in 1670 days ago, the information mentioned may be changed or developed.

    程序里面用了若干 go 子线程(盲猜问题在子线程但是无法定位),有些错误会直接 os.exit ,每个函数方法都写了 panic 捕获写日志,程序退出时不会返回 panic 。

    大神们有什么好的办法定位错误处吗?

    生产环境问题出了几个月还是找不到问题,有时运行半天,有时运行几天,退出的时候 cpu 和内存都没有大量占用

    31 replies  •  2022-04-14 22:44:54 +08:00
    nuk
    nuk
    Apr 11, 2022
    1
    b os.exit
    ETiV
    ETiV
    Apr 11, 2022 via iPhone
    2
    试试 sentry ?
    foam
    foam
    Apr 11, 2022 via Android
    3
    找找有没有不安全指针
    kwanzaa
    kwanzaa
    Apr 11, 2022
    4
    attach processes 或者直接远程上去 debug ?
    txx
    txx
    Apr 11, 2022❤️2
    5
    我最近也遇到了类似的 Bug ,服务器崩溃了,但是 Sentry 无法收集到崩溃,但是退出还是有日志的。

    我遇到的情况是这样的:一个第三方库出了些问题,在 map 里面野指针了。而 Map 在 Go Runtime 里面的实现是 ASM 实现的,然后 Link 到 Runtime 里面。如果 ASM 内部发生了野指针相关的问题,直接会被系统走了 unix signal 退出,导致无法被 recover handle 。
    CEBBCAT
    CEBBCAT
    Apr 11, 2022
    6
    我看日志说 os.Exit() 会把程序立即退出,这个真的是你需要的函数吗?
    kinghui
    kinghui
    Apr 11, 2022
    7
    设置环境变量 GOTRACEBACK=crash 运行 Go 程序,core dump 后用 GDB 查,参见: https://pkg.go.dev/runtime
    herozzm
    herozzm
    OP
    Apr 11, 2022 via Android
    8
    @CEBBCAT 不是自己主动写的 os.exit 而是一些莫名的错误导致的
    herozzm
    herozzm
    OP
    Apr 11, 2022 via Android
    9
    @foam 就是找起来很麻烦 代码行一多逻辑一复杂简直不可能
    herozzm
    herozzm
    OP
    Apr 11, 2022 via Android
    10
    @txx 你是如何找到错误地方的?
    dbskcnc
    dbskcnc
    Apr 11, 2022
    11
    1.lint 错误全部要修改过来
    2.race 运行检测
    3.付费请人
    CEBBCAT
    CEBBCAT
    Apr 11, 2022 via iPhone
    12
    @herozzm 错误只会产生 err ,Exit 自己主动调用才会被执行
    xmge
    xmge
    Apr 11, 2022
    13
    map 并发读写导致的程序崩溃。这种崩溃通过 panic 无法捕捉,检查下全局 map 是否有并发读写的情况吧。
    luwill
    luwill
    Apr 11, 2022
    14
    看看日志库,有没有接管退出方法,导致退出前没有 flush 日志。

    如果短时间可以浮现,服务器上 nohup strace 启动服务看退出前的行为。
    joesonw
    joesonw
    Apr 11, 2022 via iPhone
    15
    先跑一遍 golangci-lint 吧。
    freemoon
    freemoon
    Apr 11, 2022
    16
    @xmge 这个会有堆栈信息的
    xsen
    xsen
    Apr 11, 2022
    17
    1. strace
    可以有这个 api 的调用关系

    2. gdb
    有堆栈
    txx
    txx
    Apr 11, 2022
    18
    @herozzm log 文件呀,我 go 的 binary 的启动是套了一层 supervisor 的,在 supervisor 对应的 err 里面是有崩溃 stack trace 的
    MeetTheFuture
    MeetTheFuture
    Apr 11, 2022
    19
    在 Goroutines 里面写 defer func(){}
    kirisamemarisas
    kirisamemarisas
    Apr 11, 2022
    20
    像楼上说的,多打日志。我之前也是有这种类似的情况,多打日志就好了,极限一点每个模块都用不同的日志文件记录,方便定位
    herozzm
    herozzm
    OP
    Apr 11, 2022
    21
    @MeetTheFuture 我只是在每个子线程里面的 defer 捕获 panic ,但是出错的地方根本没有返回 panic ,感觉是直接 os
    .exit 了

    @kirisamemarisas 打了日志啊,根本没有信息
    herozzm
    herozzm
    OP
    Apr 11, 2022
    22
    @txx supervisor 是啥 属于 go 的范围吗?还是 linux 层面的?
    herozzm
    herozzm
    OP
    Apr 11, 2022
    23
    @joesonw 跑了没问题
    herozzm
    herozzm
    OP
    Apr 11, 2022
    24
    @xmge 貌似直接崩溃有好些可能性,比如指针错误,并发写入公共变量,还有第三方库可能是 os.exit
    txx
    txx
    Apr 11, 2022
    25
    @herozzm 本质上就是 stderr 啊...
    CEBBCAT
    CEBBCAT
    Apr 11, 2022
    26
    什么神仙第三方库会 os.Exit() ?
    keenkiller
    keenkiller
    Apr 12, 2022
    27
    提示一点……panic 日志是不会打在你指定的文件里的,总是输出到 stderr

    所以如果你没对 stderr 进行重定向的话,应该是看不到日志的。
    yeqown
    yeqown
    Apr 12, 2022
    28
    目前看起来是猜测已经够多了只差验证了,我提供一个验证的思路:利用 BPF 技术追踪下 os.Exit 和 panic 调用,能够定位到底是因为哪一种方式导致程序退出的。
    herozzm
    herozzm
    OP
    Apr 12, 2022
    29
    @tairan2006 panic 可以捕获啊,捕获后想怎么样都可以
    keenkiller
    keenkiller
    Apr 12, 2022 via Android
    30
    @herozzm 你调用第三方库,它自己开了个协程的话,你是没法捕获的…
    smartshallot
    smartshallot
    Apr 14, 2022
    31
    @herozzm panic 在外面捕获不到的,一般都是在 go func 协程里崩的,得在协程里 recover 才行
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   4782 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 68ms · UTC 08:14 · PVG 16:14 · LAX 00:14 · JFK 03:14
    ♥ Do have faith in what you're doing.