I am getting this stacktrace when running a go program:
/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
The signature of the Event function is:
func (c *Client) Event(e *Event) error
which can also be seen here: https://github.com/DataDog/datadog-go/blob/cc2f4770f4d61871e19bfee967bc767fe730b0d9/statsd/statsd.go#L285
The type definition for Event
can be seen here: https://github.com/DataDog/datadog-go/blob/cc2f4770f4d61871e19bfee967bc767fe730b0d9/statsd/statsd.go#L333
The type definition for Client
can be seen here: https://github.com/DataDog/datadog-go/blob/cc2f4770f4d61871e19bfee967bc767fe730b0d9/statsd/statsd.go#L59
My question is, how do I interpret the memory addresses on this line, and more generally, any stack traces which involve typed variables as targets and as arguments?
github.com/DataDog/datadog-go/statsd.(*Client).Event(0x0, 0xc8200c7ec8, 0x0, 0x0)
When I looked at http://www.goinggo.net/2015/01/stack-traces-in-go.html (which is the only information I was able to find on the subject), I didn't see anything about how to interpret the output when structs were involved.
Thanks to a comment from @twotwotwo, I think I figured this out.
In this line
github.com/DataDog/datadog-go/statsd.(*Client).Event(0x0, 0xc8200c7ec8, 0x0, 0x0)
0x0
is the *Client
, which is indeed nil.0xc8200c7ec8
is *Event
0x0, 0x0
represent the return value of type error
. error
, according to http://blog.golang.org/error-handling-and-go, is an interface. According to http://research.swtch.com/interfaces, interfaces are stored as two pointers. The first pointer points to the type information stored in the interface, and the second pointer points to the data stored in the interface.I wrote the following program to demonstrate to myself how different function signatures appear in a stack trace:
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()
}
When bam
is called, which acts on *Y
but has no arguments or return value, the output contains:
main.(*Y).bam(0xc82002df48)
When foo
is called, which acts on *Y
and takes a *X
as argument, but has no return value, the output contains:
main.(*Y).foo(0xc820033f30, 0xc820033f30)
When bar
is called, which acts on *Y
, takes a *X
as argument, and returns a *Y
, the output contains:
main.(*Y).bar(0xc820033f30, 0xc820033f30, 0x40fb46)
When baz
is called, which acts on *Y
, takes *X
as argument, and returns an error
(which is an interface), the output contains:
main.(*Y).baz(0xc820033f38, 0xc820033f38, 0x0, 0x0)
What you have is a nil pointer dereference. (Unless you are using package unsafe
, which you probably shouldn't touch, so I'm assuming you're not.)
It looks like the e
argument to func (c *Client) Event(e *Event) error
is nil
when called from github.com/some/path/server/http.go:86
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With