在 Go 中轉儲 Goroutine 堆疊跟蹤
Jay Singh
2022年4月22日
處理奇怪情況的慣用方法是在 Go 程式中使用錯誤。錯誤導致軟體中出現的大多數異常情況。
但是,在極少數情況下,軟體將由於異常狀態而無法繼續執行。在這種情況下,panic
可以提前結束程式。
當函式遇到 panic
時,函式的執行將停止,任何延遲的函式都將執行,並且控制權將返回給函式的呼叫者。
這個過程一直持續到所有當前 goroutine 的函式都返回,此時程式在終止之前列印 panic
訊息,然後是堆疊跟蹤。
當我們構建一個示例程式時,這將變得更加清晰。
在 Go 中使用 panic
轉儲 Goroutine 堆疊跟蹤
這個簡單的指令碼將列印一個人的全名。fullName
函式返回一個人的全名。
此方法檢查 firstName
和 lastName
指標中的 nil
值。如果它是 nil
,該函式會傳送一個帶有訊息的 panic
訊號。
當程式完成時,它將列印此訊息。
package main
import (
"fmt"
)
func fullName(firstName *string, lastName *string) {
if firstName == nil {
panic("runtime error: first name cannot be nil")
}
if lastName == nil {
panic("runtime error: last name cannot be nil")
}
fmt.Printf("%s %s\n", *firstName, *lastName)
fmt.Println("returned normally from fullName")
}
func main() {
firstName := "Jay"
fullName(&firstName, nil)
fmt.Println("returned normally from main")
}
輸出:
panic: runtime error: last name cannot be nil
goroutine 1 [running]:
main.fullName(0x405058?, 0xc000070f70?)
/tmp/sandbox885911142/prog.go:12 +0x114
main.main()
/tmp/sandbox885911142/prog.go:20 +0x35
現在,下面的示例犯了一個常見錯誤,即嘗試使用內建 len
提供的長度來訪問切片的最終元素。
為了說明為什麼這可能會導致恐慌
,請執行以下程式碼。
package main
import (
"fmt"
)
func main() {
names := []string{
"Iron Man",
"Thor",
}
fmt.Println("My favorite superhero is:", names[len(names)])
}
輸出:
panic: runtime error: index out of range [2] with length 2
goroutine 1 [running]:
main.main()
/tmp/sandbox2746930010/prog.go:12 +0x1b