为了账号安全,请及时绑定邮箱和手机立即绑定

如何解释 Go 堆栈跟踪

如何解释 Go 堆栈跟踪

Go
largeQ 2022-01-04 09:50:23
运行 go 程序时,我收到此堆栈跟踪:        /home/travis/.gimme/versions/go1.6.linux.amd64/src/runtime/panic.go:464 +0x3e6github.com/DataDog/datadog-go/statsd.(*Client).Event(0x0, 0xc8200c7ec8, 0x0, 0x0)        /home/travis/gopath/src/github.com/DataDog/datadog-go/statsd/statsd.go:286 +0x11fgithub.com/some/path/server.(*Server).buildAndUpdate(0xc820024068, 0xc820064600, 0x0, 0x0)        /home/travis/gopath/src/github.com/some/path/server/http.go:86 +0xf9fcreated by github.com/some/path/server.(*Server).processPullRequestEvent        /home/travis/gopath/src/github.com/some/path/server/http.go:169 +0x53fEvent函数的签名是:func (c *Client) Event(e *Event) error也可以在这里看到:https : //github.com/DataDog/datadog-go/blob/cc2f4770f4d61871e19bfee967bc767fe730b0d9/statsd/statsd.go#L285的类型定义Event可以在这里看到:https : //github.com/DataDog/datadog-go/blob/cc2f4770f4d61871e19bfee967bc767fe730b0d9/statsd/statsd.go#L333的类型定义Client可以在这里看到:https : //github.com/DataDog/datadog-go/blob/cc2f4770f4d61871e19bfee967bc767fe730b0d9/statsd/statsd.go#L59我的问题是,我如何解释这一行的内存地址,更一般地说,任何涉及类型变量作为目标和参数的堆栈跟踪?github.com/DataDog/datadog-go/statsd.(*Client).Event(0x0, 0xc8200c7ec8, 0x0, 0x0)当我查看http://www.goinggo.net/2015/01/stack-traces-in-go.html(这是我能找到的关于该主题的唯一信息)时,我没有看到任何关于当涉及结构时如何解释输出。
查看完整描述

3 回答

?
Helenr

TA贡献1780条经验 获得超4个赞

我想我明白了。

在这一行

github.com/DataDog/datadog-go/statsd.(*Client).Event(0x0, 0xc8200c7ec8, 0x0, 0x0)

我编写了以下程序来向自己演示不同的函数签名如何出现在堆栈跟踪中:

package main


import "errors"


type X struct {

        i int

}


type Y struct {

}


func (y *Y) foo(x *X) {

        panic("panic in foo")

}


func (y *Y) bar(x *X) (*Y) {

        panic("panic in bar")

        return y

}


func (y *Y) baz(x *X) (error) {

        panic("panic in baz")

        return errors.New("error in baz")

}


func (y *Y) bam() {

        panic("panic in bam")

}


func main() {

        y := new(Y)

        x := new(X)

        // comment out the ones you don't want to check

        y.foo(x)

        y.bar(x)

        y.baz(x)

        y.bam()

}

当bam被调用时,它作用于*Y但没有参数或返回值,输出包含:


main.(*Y).bam(0xc82002df48)

当foo被调用时,它作用于*Ya*X作为参数,但没有返回值,输出包含:


main.(*Y).foo(0xc820033f30, 0xc820033f30)

当bar被调用时,它作用于*Y,将 a*X作为参数,并返回 a *Y,输出包含:


main.(*Y).bar(0xc820033f30, 0xc820033f30, 0x40fb46)

当baz被调用时,它作用于*Y,*X作为参数,并返回一个error(它是一个接口),输出包含:


main.(*Y).baz(0xc820033f38, 0xc820033f38, 0x0, 0x0)


查看完整回答
反对 回复 2022-01-04
?
喵喵时光机

TA贡献1846条经验 获得超7个赞

你所拥有的是一个 nil 指针取消引用。(除非您使用的是 package unsafe,您可能不应该接触它,所以我假设您不是。)

看起来e参数 tofunc (c *Client) Event(e *Event) errornil在调用 from 时github.com/some/path/server/http.go:86


查看完整回答
反对 回复 2022-01-04
?
慕妹3146593

TA贡献1820条经验 获得超9个赞

基本上:方法接收器(如果有)、显式参数(如果有)、返回值(如果有)。

要了解堆栈跟踪,您首先需要了解 Go 的数据结构的内部表示。例如,切片类型的参数具有三个组件,因此在 func 的堆栈跟踪中具有三个值:数据(指针)、len(整数)、cap(整数)。

您可能会发现这篇文章很有用。


查看完整回答
反对 回复 2022-01-04
  • 3 回答
  • 0 关注
  • 137 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号