亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何獲取指向實際錯誤原因的堆棧跟蹤

如何獲取指向實際錯誤原因的堆棧跟蹤

Go
呼啦一陣風 2021-11-15 15:42:44
假設我有一些這樣的代碼:value, err := some3rdpartylib.DoSomething()if err != nil {    panic(err)}萬一err != nil我會得到這樣的東西:panic: some error explanation heregoroutine 1 [running]:main.main()    /tmp/blabla/main.go:6 +0x80此堆棧跟蹤是完全合法的,但有時這些錯誤消息可能無法說明發生了什么,因此我想深入研究 3rd 方庫的源代碼,以調查究竟是什么原因導致返回此錯誤。但是,當我的代碼像這樣發生混亂時,無法獲得返回此錯誤的實際位置。稍微澄清一點:因為我來自拋出異常的 JVM 世界,所以我可以完全跟蹤拋出異常的代碼行到底是哪一行,因此可以輕松找到位置并查看出了什么問題。Go 堆棧跟蹤正好在我的代碼發生混亂的地方結束,因此在我的情況下不太有用。我在這里創建了一個操場,理想情況下我希望能夠將錯誤追溯到它實際返回的地方,而不是恐慌。(例如第 17 行,return "", errors.New("some error explanation here"))這甚至可能嗎?
查看完整描述

3 回答

?
撒科打諢

TA貢獻1934條經驗 獲得超2個贊

我認為有一種更簡單的方法可以實現這一目標。您可以嘗試包裝錯誤使用golang“默認”的第三方庫的錯誤包:


您需要定義要由您實現的接口error:


type stackTracer interface {

    StackTrace() errors.StackTrace

}

然后在包裝/處理錯誤時使用它:


err, ok := errors.(stackTracer) // ok is false if errors doesn't implement stackTracer


stack := err.StackTrace()

fmt.Println(stack) // here you'll have your stack trace


查看完整回答
反對 回復 2021-11-15
?
炎炎設計

TA貢獻1808條經驗 獲得超4個贊

很快:這是不可能的。由于錯誤是值,因此不會以任何特殊方式處理它們。因此,當函數(通常)返回時,堆棧不再可用(即另一個函數調用可能會覆蓋返回錯誤函數的堆棧使用的內存)。

go1.5 中引入了一個名為trace的工具,但目前,沒有可用的綜合教程,我發現的任何一個都沒有說將包含此類功能。


查看完整回答
反對 回復 2021-11-15
?
紅顏莎娜

TA貢獻1842條經驗 獲得超13個贊

正如其他人指出的那樣,跟蹤 go 中的錯誤并非易事。有像juju/errgo這樣的項目,它允許您包裝錯誤,然后追溯這些錯誤。為了讓它工作起來很艱難,您必須在整個項目中始終如一地使用它們,這不會幫助您解決 3rd 方庫中的錯誤或處理后永遠不會返回的錯誤。


因為這是一個很常見的問題,我真的對此很惱火,所以我編寫了一個小型調試實用程序,它將向 go 文件添加調試代碼,該文件記錄每個返回的錯誤(實現的值error)以及將其返回到 STDOUT 的函數(如果您需要更高級的日志記錄,只需在項目中 hack 記錄器,這真的很簡單)。


安裝


go get github.com/gellweiler/errgotrace

用法


要調試當前目錄中的所有文件:


$ find . -name '*.go' -print0 | xargs -0 errgotrace -w

從 go 文件中刪除添加的調試代碼:


$ find . -name '*.go' -print0 | xargs -0 errgotrace -w -r

然后只需簡單地編譯和運行您的代碼或您的測試用例。


樣本輸出


[...]

2017/12/13 00:54:39 [ERRGOTRACE] parser.*Parser.objectKey: EOF token found

2017/12/13 00:54:39 [ERRGOTRACE] parser.*Parser.objectItem: EOF token found

2017/12/13 00:54:39 [ERRGOTRACE] parser.*Parser.objectKey: EOF token found

2017/12/13 00:54:39 [ERRGOTRACE] parser.*Parser.objectItem: EOF token found

2017/12/13 00:54:39 [ERRGOTRACE] parser.*Parser.objectKey: At 3:4: nested object expected: LBRACE got: ASSIGN

2017/12/13 00:54:39 [ERRGOTRACE] parser.*Parser.objectItem: At 3:4: nested object expected: LBRACE got: ASSIGN

2017/12/13 00:54:39 [ERRGOTRACE] parser.*Parser.objectList: At 3:4: nested object expected: LBRACE got: ASSIGN

2017/12/13 00:54:39 [ERRGOTRACE] parser.*Parser.Parse: At 2:31: literal not terminated

2017/12/13 00:54:39 [ERRGOTRACE] parser.Parse: At 2:31: literal not terminated

2017/12/13 00:54:39 [ERRGOTRACE] hcl.parse: At 2:31: literal not terminated

2017/12/13 00:54:39 [ERRGOTRACE] hcl.ParseBytes: At 2:31: literal not terminated

2017/12/13 00:54:39 [ERRGOTRACE] formula.parse: parsing failed

[...]

從這個輸出中可以看出,很容易判斷錯誤最初發生在哪個函數中。一旦你知道了,你就可以使用調試器來獲得更多的上下文。


查看完整回答
反對 回復 2021-11-15
  • 3 回答
  • 0 關注
  • 292 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號