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

350 天前
 lightjiao

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

func main() {
    go TestGoException()
    time.Sleep(1000)
}

func TestGoException() {
    go TestGoException2()
}

func TestGoException2() {
    panic("this is a panic")
}
1616 次点击
所在节点    Go 编程语言
14 条回复
aapeli
350 天前
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
350 天前
通过堆栈信息可以获取到最近一次 panic 产生的位置.
GopherDaily
350 天前
- 记忆中没有
- 间接的方法是用 context 传递
- 这是个伪需求
GopherDaily
350 天前
AnroZ
350 天前
如果在 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
350 天前
@aapeli
@AnroZ
我分别尝试了二位的方法,并不能打印出完整的 stack ,无法知道最开始是 main 调用触发的,还是其他函数触发的
lightjiao
350 天前
@GopherDaily
开发期间追踪异步调用链排查问题是最基础的需求
Context 我没试过,对这块不太熟
aapeli
350 天前
```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
350 天前
@aapeli 我期望的是谁调用了 TestGoException ,需要一条完整的异步调用链
docxs
350 天前
g 的原始结构里有个 gopc 字段,是创建这个 g 的父 g 的 pc 位置,试试依次回溯
aapeli
350 天前
要不试试 jaeger 之类的 opentracing 吧,成熟的链路追踪产品,有 UI 告诉你相关的调用链路

https://github.com/opentracing/opentracing-go
https://www.jaegertracing.io/
https://github.com/jaegertracing/jaeger
lightjiao
350 天前
@aapeli 链路追踪产品是给分布式微服务用的,我这里显然不是这个场景,你可以看一下我的 append
hzzhzzdogee
350 天前
f 应该没有办法
AnroZ
350 天前
@lightjiao runtime.Stack(buff, true)倒是可以打印所有在运行的堆栈。
但在你这个例子中,因为调用 TestGoException 的 goroutine 其实也早已退出了,所以即使调用 runtime.Stack(buff, true)也是打印不出来的。
如果你想实现你想要的追溯,建议自己增加 log 记录或增加上下文信息

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/940100

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX