2016-04-06 2 views
3

Я получаю эту трассировку стека при запуске программы 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/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 (это единственная информация, я был в состоянии найти на эту тему), я не вижу ничего о том, как интерпретировать выходные, когда были вовлечены Структуры.

+0

Возможно, вам стоит подслушать поддержку Datadog, если вы являетесь клиентом. – twotwotwo

+1

@twotwotwot оценить указатель, однако меня не беспокоит то, что моя программа не работает. Я действительно хочу знать, как интерпретировать трассировку стека. – des4maisons

ответ

7

Благодаря комментарию от @twotwotwo, я думаю, что понял это.

В этой строке

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 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 называется, который действует на *Y и принимает *X в качестве аргумента, б ут не имеет возвращаемого значения, выход содержит:

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

Когда bar называется, который действует на *Y, принимает *X в качестве аргумента, и возвращает *Y, выход содержит:

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

При baz, который действует на *Y, принимает *X как аргумент и возвращает error (который является интерфейсом), выход содержит:

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

Спасибо за пошаговые примеры! – gmcnaughton

2

То, что у вас есть, является разыменованием нулевого указателя. (Если вы не используете пакет unsafe, который вы, вероятно, не следует трогать, поэтому я предполагаю, что это не так.)

Похоже e аргумент func (c *Client) Event(e *Event) error является nil при вызове из github.com/some/path/server/http.go:86.

+0

Спасибо за ответ, хотя я не заинтересован в решении этой конкретной проблемы настолько, насколько мне интересно узнать, как интерпретировать различные адреса в github.com/DataDog/datadog-go/statsd.(*Client). Событие (0x0, 0xc8200c7ec8, 0x0, 0x0) означает. Я отредактирую свой вопрос, чтобы это было ясно. – des4maisons

+2

@ des4maisons - приемник ('* Client') появляется первым в списке аргументов. '0x0' - это указатель на нуль. '0xc8200c7ec8' - это необработанное значение указателя Event. Не уверен в последних двух; они могут быть двумя словами в _returned_ [значение интерфейса] (http://research.swtch.com/interfaces). Обратите внимание, что вы получаете дамп сырых слов, переданных, например, [фрагмент будет отображаться как три слова] (http://research.swtch.com/godata). Есть что-то, называемое [panicparse] (https://github.com/maruel/panicparse), которое делает их более удобоваримыми, и вы даже можете найти облегчение его источника. – twotwotwo

+0

@twotwotwo спасибо, это именно то, что было. Я написал ответ, расширяющий ваше объяснение. – des4maisons

Смежные вопросы