如何解释 Go 堆栈跟踪

运行 go 程序时,我收到此堆栈跟踪:


        /home/travis/.gimme/versions/go1.6.linux.amd64/src/runtime/panic.go:464 +0x3e6

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

        /home/travis/gopath/src/github.com/DataDog/datadog-go/statsd/statsd.go:286 +0x11f

github.com/some/path/server.(*Server).buildAndUpdate(0xc820024068, 0xc820064600, 0x0, 0x0)

        /home/travis/gopath/src/github.com/some/path/server/http.go:86 +0xf9f

created by github.com/some/path/server.(*Server).processPullRequestEvent

        /home/travis/gopath/src/github.com/some/path/server/http.go:169 +0x53f

Event函数的签名是:


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(这是我能找到的关于该主题的唯一信息)时,我没有看到任何关于当涉及结构时如何解释输出。


largeQ
浏览 138回答 3
3回答

Helenr

我想我明白了。在这一行github.com/DataDog/datadog-go/statsd.(*Client).Event(0x0, 0xc8200c7ec8, 0x0, 0x0)第一个0x0是*Client,它确实为零。0xc8200c7ec8 是 *Event以下0x0, 0x0代表类型的返回值error。error,根据http://blog.golang.org/error-handling-and-go,是一个接口。根据http://research.swtch.com/interfaces,接口存储为两个指针。第一个指针指向接口中存储的类型信息,第二个指针指向接口中存储的数据。我编写了以下程序来向自己演示不同的函数签名如何出现在堆栈跟踪中:package mainimport "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)

喵喵时光机

你所拥有的是一个 nil 指针取消引用。(除非您使用的是 package unsafe,您可能不应该接触它,所以我假设您不是。)看起来e参数 tofunc (c *Client) Event(e *Event) error是nil在调用 from 时github.com/some/path/server/http.go:86。

慕妹3146593

基本上:方法接收器(如果有)、显式参数(如果有)、返回值(如果有)。要了解堆栈跟踪,您首先需要了解 Go 的数据结构的内部表示。例如,切片类型的参数具有三个组件,因此在 func 的堆栈跟踪中具有三个值:数据(指针)、len(整数)、cap(整数)。您可能会发现这篇文章很有用。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go