求教: golang error 如何打印调用栈

2023-02-08 12:52:45 +08:00
 Ayanokouji
1780 次点击
所在节点    Go 编程语言
10 条回复
fgwmlhdkkkw
2023-02-08 12:56:01 +08:00
runtime.Callers
tairan2006
2023-02-08 13:08:38 +08:00
用 %w 就行,好像 1.18 开始支持的吧
warlock
2023-02-08 13:48:15 +08:00
我一般这样写:

func CallStack(skip int) string {
pcs := make([]uintptr, 32)
numFrames := runtime.Callers(skip, pcs)
for numFrames == len(pcs) {
pcs = make([]uintptr, len(pcs)*2)
numFrames = runtime.Callers(skip, pcs)
}
pcs = pcs[:numFrames]
frames := runtime.CallersFrames(pcs)
sb := strings.Builder{}
for frame, more := frames.Next(); more; frame, more = frames.Next() {
sb.WriteString(frame.Function)
sb.WriteByte('\n')
sb.WriteByte('\t')
sb.WriteString(frame.File)
sb.WriteByte(':')
sb.WriteString(strconv.Itoa(frame.Line))
}
return sb.String()
}
xuyang2
2023-02-08 15:42:27 +08:00
DefoliationM
2023-02-08 19:26:15 +08:00
没法,你得自己写个 error 的 wrap 方法,在 wrap 的时候加上行号,最后再打印出来就行了
zap 那个调用栈是反的,没用,很鸡肋
0o0O0o0O0o
2023-02-08 19:39:45 +08:00
debug.Stack
lysS
2023-02-09 14:17:38 +08:00
可以用第三方的 error ,如 https://github.com/pkg/errors ;当然本质是调用 runtime 里的函数
wencan
2023-02-12 10:16:02 +08:00
自己实现 error 。每次创建时,收集调用堆栈。但建议用专用的方法输出调用堆栈。
jxia
2023-02-12 10:47:57 +08:00
欢迎使用 https://github.com/gookit/goutil 的 `errorx`

```go
err := errorx.New("the error message")

fmt.Println(err)
```

输出类似:

```
the error message
STACK:
github.com/gookit/goutil/errorx_test.returnXErr()
/Users/inhere/Workspace/godev/gookit/goutil/errorx/errorx_test.go:21
github.com/gookit/goutil/errorx_test.returnXErrL2()
/Users/inhere/Workspace/godev/gookit/goutil/errorx/errorx_test.go:25
github.com/gookit/goutil/errorx_test.TestNew()
/Users/inhere/Workspace/godev/gookit/goutil/errorx/errorx_test.go:29
testing.tRunner()
/usr/local/Cellar/go/1.18/libexec/src/testing/testing.go:1439
runtime.goexit()
/usr/local/Cellar/go/1.18/libexec/src/runtime/asm_amd64.s:1571
```
lotusgrm
281 天前
可以使用 github.com/pkg/errors 实现打印调用堆栈,在 pkg/errors 中除了可以使用 withMessage 附加错误信息以外还可以 withStack 附加堆栈信息,源码如下:

// Wrap returns an error annotating err with a stack trace
// at the point Wrap is called, and the supplied message.
// If err is nil, Wrap returns nil.
func Wrap(err error, message string) error {
if err == nil {
return nil
}
err = &withMessage{
cause: err,
msg: message,
}
return &withStack{
err,
callers(),
}
}

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

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

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

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

© 2021 V2EX