2016-04-06 153 views
3

運行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 

事件函數的簽名是:

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

@twotwotwo欣賞指針,但是我並沒有因爲我的程序不工作而感到困擾。我真正想知道的是如何解釋堆棧跟蹤。 – des4maisons

回答

7

感謝來自@twotwotwo的評論,我想我明白了這一點。

在這一行

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當被調用時,它作用於*Y,並採取了*X作爲參數,b UT沒有返回值,輸出包含:

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) errornilgithub.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'是事件指針的原始值。不知道最後兩個;它們可能是_returned_ [interface value](http://research.swtch.com/interfaces)中的兩個單詞。請注意,您會收到傳遞的原始文字的轉儲,因此,例如[一個切片顯示爲三個字](http://research.swtch.com/godata)。有一種叫做[panicparse](https://github.com/maruel/panicparse)的東西,可以讓這些東西更易消化,你甚至可以發現它的源代碼很有用。 – twotwotwo

+0

@twotwotwo謝謝,這正是它是。我寫了一個答案,擴展你的解釋。 – des4maisons