比如如下代码,开发时如何知道这个 panic 是由于 main 函数调用触发的
func main() {
go TestGoException()
time.Sleep(1000)
}
func TestGoException() {
go TestGoException2()
}
func TestGoException2() {
panic("this is a panic")
}
1
aapeli 2023-05-15 13:32:08 +08:00
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 ``` |
2
aapeli 2023-05-15 13:33:01 +08:00
通过堆栈信息可以获取到最近一次 panic 产生的位置.
|
3
GopherDaily 2023-05-15 13:33:05 +08:00
- 记忆中没有
- 间接的方法是用 context 传递 - 这是个伪需求 |
4
GopherDaily 2023-05-15 13:35:01 +08:00
|
5
AnroZ 2023-05-15 13:37:37 +08:00
如果在 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") } ``` |
6
lightjiao OP |
7
lightjiao OP |
8
aapeli 2023-05-15 14:11:28 +08:00
```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 ``` |
9
lightjiao OP @aapeli 我期望的是谁调用了 TestGoException ,需要一条完整的异步调用链
|
10
docxs 2023-05-15 14:16:26 +08:00 via iPhone 1
g 的原始结构里有个 gopc 字段,是创建这个 g 的父 g 的 pc 位置,试试依次回溯
|
11
aapeli 2023-05-15 14:19:30 +08:00
要不试试 jaeger 之类的 opentracing 吧,成熟的链路追踪产品,有 UI 告诉你相关的调用链路
https://github.com/opentracing/opentracing-go https://www.jaegertracing.io/ https://github.com/jaegertracing/jaeger |
12
lightjiao OP @aapeli 链路追踪产品是给分布式微服务用的,我这里显然不是这个场景,你可以看一下我的 append
|
13
hzzhzzdogee 2023-05-15 14:41:34 +08:00
f 应该没有办法
|