Golang 里 goroutine a 调用 goroutine b, b 里面发生了 panic,能知道是谁调用了 a 导致这次请求的吗? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
lightjiao

Golang 里 goroutine a 调用 goroutine b, b 里面发生了 panic,能知道是谁调用了 a 导致这次请求的吗?

  •  
  •   lightjiao
    lightjiao 2023 年 5 月 15 日 via iPhone 2365 次点击
    这是一个创建于 1075 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如如下代码,开发时如何知道这个 panic 是由于 main 函数调用触发的

    func main() { go TestGoException() time.Sleep(1000) } func TestGoException() { go TestGoException2() } func TestGoException2() { panic("this is a panic") } 
    第 1 条附言    2023 年 5 月 15 日
    ```
    func main() {
    randomizer := rand.New(rand.NewSource(1000))
    go DelayPanic(randomizer.Int())
    go DelayPanic(randomizer.Int())
    time.Sleep(time.Second * 2)
    }
    func DelayPanic(n int) {
    time.Sleep(time.Millisecond * time.Duration(n))
    go TestGoException()
    }

    func TestGoException() {
    goTestGoException2()
    }

    func TestGoException2() {
    // 原始的需求是希望这个函数里的 log 或者 panic ,能知道是 main 函数里的哪一行导致的调用
    panic("this is a panic")
    }
    ```
    14 条回复    2023-05-15 18:28:39 +08:00
    aapeli
        1
    aapeli  
       2023 年 5 月 15 日
    time.Sleep(1000) 这个值太小了(1000 纳秒), 改成 time.Sleep(time.Second * 1) 试试, panic 后堆栈会打印出来


    ```xxx
    panic: this is a panic

    goroutine 6 [running]:
    main.TestGoException2()
    /Users/aapeli/main.go:15 +0x45
    created by main.TestGoException
    /Users/aapeli/main.go:10 +0x25
    exit status 2
    ```
    aapeli
        2
    aapeli  
       2023 年 5 月 15 日
    通过堆栈信息可以获取到最近一次 panic 产生的位置.
    GopherDaily
        3
    GopherDaily  
       2023 年 5 月 15 日
    - 记忆中没有
    - 间接的方法是用 context 传递
    - 这是个伪需求
    AnroZ
        5
    AnroZ  
       2023 年 5 月 15 日
    如果在 TestGoException2 函数内可以 recover 的话,是可以通过获取 runtime.Stack 获取调用堆栈信息。比如:
    ```
    func TestGoException2() {
    defer func() {
    if info := recover(); info != nil {
    fmt.Println(info)

    buff := make([]byte, 1024)
    runtime.Stack(buff, false)

    fmt.Println(string(buff))
    }
    }()

    panic("this is a panic")
    }
    ```
    lightjiao
        6
    lightjiao  
    OP
       2023 年 5 月 15 日 via iPhone   1
    @aapeli
    @AnroZ
    我分别尝试了二位的方法,并不能打印出完整的 stack ,无法知道最开始是 main 调用触发的,还是其他函数触发的
    lightjiao
        7
    lightjiao  
    OP
       2023 年 5 月 15 日 via iPhone
    @GopherDaily
    开发期间追踪异步调用链排查问题是最基础的需求
    Context 我没试过,对这块不太熟
    aapeli
        8
    aapeli  
       2023 年 5 月 15 日
    ```xxx
    panic: this is a panic

    goroutine 6 [running]:
    main.TestGoException2()
    /Users/aapeli/main.go:15 +0x45 # painic 的位置
    created by main.TestGoException
    /Users/aapeli/main.go:10 +0x25. # 这里有告诉你是谁调用的 TestGoException2
    exit status 2
    ```
    lightjiao
        9
    lightjiao  
    OP
       2023 年 5 月 15 日 via iPhone
    @aapeli 我期望的是谁调用了 TestGoException ,需要一条完整的异步调用链
    docxs
        10
    docxs  
       2023 年 5 月 15 日 via iPhone   1
    g 的原始结构里有个 gopc 字段,是创建这个 g 的父 g 的 pc 位置,试试依次回溯
    aapeli
        11
    aapeli  
       2023 年 5 月 15 日
    要不试试 jaeger 之类的 opentracing 吧,成熟的链路追踪产品,有 UI 告诉你相关的调用链路

    https://github.com/opentracing/opentracing-go
    https://www.jaegertracing.io/
    https://github.com/jaegertracing/jaeger
    lightjiao
        12
    lightjiao  
    OP
       2023 年 5 月 15 日 via iPhone
    @aapeli 链路追踪产品是给分布式微服务用的,我这里显然不是这个场景,你可以看一下我的 append
    hzzhzzdogee
        13
    hzzhzzdogee  
       2023 年 5 月 15 日
    f 应该没有办法
    AnroZ
        14
    AnroZ  
       2023 年 5 月 15 日   1
    @lightjiao runtime.Stack(buff, true)倒是可以打印所有在运行的堆栈。
    但在你这个例子中,因为调用 TestGoException 的 goroutine 其实也早已退出了,所以即使调用 runtime.Stack(buff, true)也是打印不出来的。
    如果你想实现你想要的追溯,建议自己增加 log 记录或增加上下文信息
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2828 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 53ms UTC 05:18 PVG 13:18 LAX 22:18 JFK 01:18
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86