如何解释Go stacktrace
在运行go程序时,我会得到此stacktrace:如何解释Go stacktrace,go,Go,在运行go程序时,我会得到此stacktrace: /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/data
/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
事件函数的签名为:
func (c *Client) Event(e *Event) error
也可以在这里看到:
事件的类型定义如下所示:
客户端的类型定义可在此处查看:
我的问题是,我如何解释这一行的内存地址,更一般地说,任何涉及类型化变量作为目标和参数的堆栈跟踪
github.com/DataDog/datadog-go/statsd.(*Client).Event(0x0, 0xc8200c7ec8, 0x0, 0x0)
当我查看(这是我能找到的关于这个主题的唯一信息)时,我没有看到关于如何解释涉及结构的输出的任何信息。您看到的是一个零指针解引用。(除非您使用的是不安全的软件包,,您可能不应该碰它,所以我假设您不应该碰它。)
当从github.com/some/path/server/http.go:86
调用时,func(c*Client)Event(e*Event)error
的e
参数似乎是nil
,多亏了@twoo>的评论,我想我已经解决了这个问题
在这一行
github.com/DataDog/datadog-go/statsd.(*Client).Event(0x0, 0xc8200c7ec8, 0x0, 0x0)
- 第一个
0x0
是*客户机,它实际上是零
0xc8200c7ec8
是*事件
- 以下
0x0,0x0
表示类型error
的返回值<代码>错误
,根据,是一个接口。根据,接口存储为两个指针。第一个指针指向存储在接口中的类型信息,第二个指针指向存储在接口中的数据
我编写了以下程序来向自己演示不同的函数签名如何出现在堆栈跟踪中:
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()
}
调用作用于*Y
但没有参数或返回值的bam
时,输出包含:
main.(*Y).bam(0xc82002df48)
调用foo
时,它作用于*Y
并将*X
作为参数,但没有返回值,输出包含:
main.(*Y).foo(0xc820033f30, 0xc820033f30)
main.(*Y).bar(0xc820033f30, 0xc820033f30, 0x40fb46)
main.(*Y).baz(0xc820033f38, 0xc820033f38, 0x0, 0x0)
调用bar
时,它作用于*Y
,将*X
作为参数,并返回*Y
,输出包含:
main.(*Y).foo(0xc820033f30, 0xc820033f30)
main.(*Y).bar(0xc820033f30, 0xc820033f30, 0x40fb46)
main.(*Y).baz(0xc820033f38, 0xc820033f38, 0x0, 0x0)
调用baz
时,它作用于*Y
,将*X
作为参数,并返回错误
(这是一个接口),输出包含:
main.(*Y).foo(0xc820033f30, 0xc820033f30)
main.(*Y).bar(0xc820033f30, 0xc820033f30, 0x40fb46)
main.(*Y).baz(0xc820033f38, 0xc820033f38, 0x0, 0x0)
基本上:方法接收器(如果有)、显式参数(如果有)、返回值(如果有)
要理解堆栈跟踪,首先需要理解Go的数据结构的内部表示。例如,slice类型的参数有三个组件,因此func的堆栈跟踪中有三个值:data(指针)、len(int)、cap(int)
您可能会发现它很有用。如果您是Datadog的客户,那么就值得窃听Datadog的支持。@TwoTwo很欣赏指针,但是我的程序不起作用这一事实并不困扰我。我真正想知道的是如何解释堆栈跟踪。谢谢你的回答,虽然我对解决这个问题不感兴趣,但我更感兴趣的是学习如何解释github.com/DataDog/DataDog go/statsd.(*Client).Event(0x0,0xc8200c7ec8,0x0,0x0)中的各种地址的含义。我将编辑我的问题以澄清这一点。@des4maisons——接收者(客户机)在参数列表中位于第一位0x0
是一个零指针0xc8200c7ec8
是事件指针的原始值。不确定最后两个;它们可能是返回的两个单词。请注意,您将获得大量原始单词的传递,因此,例如。有一种叫做的方法可以让这些东西更容易消化,你甚至会发现略读它的来源很有用。@twoo谢谢,这就是它的原意。我写了一个关于你的解释的答案。谢谢你一步一步的例子!