V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
Ayanokouji
V2EX  ›  Go 编程语言

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

  •  
  •   Ayanokouji · 2023-02-08 12:52:45 +08:00 · 2055 次点击
    这是一个创建于 655 天前的主题,其中的信息可能已经有所发展或是发生改变。
    10 条回复    2023-07-27 00:02:55 +08:00
    fgwmlhdkkkw
        1
    fgwmlhdkkkw  
       2023-02-08 12:56:01 +08:00
    runtime.Callers
    tairan2006
        2
    tairan2006  
       2023-02-08 13:08:38 +08:00
    用 %w 就行,好像 1.18 开始支持的吧
    warlock
        3
    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()
    }
    DefoliationM
        5
    DefoliationM  
       2023-02-08 19:26:15 +08:00
    没法,你得自己写个 error 的 wrap 方法,在 wrap 的时候加上行号,最后再打印出来就行了
    zap 那个调用栈是反的,没用,很鸡肋
    0o0O0o0O0o
        6
    0o0O0o0O0o  
       2023-02-08 19:39:45 +08:00 via iPhone
    debug.Stack
    lysS
        7
    lysS  
       2023-02-09 14:17:38 +08:00
    可以用第三方的 error ,如 https://github.com/pkg/errors ;当然本质是调用 runtime 里的函数
    wencan
        8
    wencan  
       2023-02-12 10:16:02 +08:00
    自己实现 error 。每次创建时,收集调用堆栈。但建议用专用的方法输出调用堆栈。
    jxia
        9
    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
        10
    lotusgrm  
       2023-07-27 00:02:55 +08:00
    可以使用 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(),
    }
    }
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2845 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 00:38 · PVG 08:38 · LAX 16:38 · JFK 19:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.