理解恐慌堆疊追蹤中的「未知欄位」
在破解恐慌堆疊追蹤的過程中,可能會遇到不熟悉的元素。一個這樣的實例發生在恐慌堆疊追蹤中函數呼叫的第二個參數內。
讓我們考慮以下程式碼來說明這一點:
<code class="go">package main func F(a int) { panic(nil) } func main() { F(1) }</code>
執行時,此程式碼輸出:
panic: nil goroutine 1 [running]: main.F(0x1, 0x10436000) /tmp/sandbox090887108/main.go:4 +0x20 main.main() /tmp/sandbox090887108/main.go:8 +0x20
main.F(0x1, 0x10436000) 中的第二個參數(0x10436000) 需要澄清。
解碼未知欄位
堆疊追蹤中顯示的值是函數的參數,但它們並不會直接對應於傳入的值。相反,它們表示以指標大小的值儲存的原始資料。
在給定的情況下,playground 在具有 32 位元指標的 64 位元架構上運行 (GOARCH=amd64p32)。在這樣的設定中,每個值都儲存在 64 位元字中,而指標則是 32 位元。
函數 F(a int) 採用 int 型別的單一參數。堆疊追蹤參數儲存在 64 位元字中。由於指標大小為 32 位,因此前 32 位包含指向參數的指標 (0x1),其餘 32 位 (0x10436000) 未使用。
更多範例
為了進一步示範這個概念,讓我們考慮另一個例子:
<code class="go">func F(a uint8) { panic(nil) } func main() { F(1) }</code>
這段程式碼輸出:
panic: nil goroutine 1 [running]: main.F(0x97301, 0x10436000)
這裡,參數a 是uint8 類型,佔用8位元。 64 位元字的前 8 位元包含 a (1) 的值,而其餘 56 位元(0x97300 和 0x10436000)未使用。
傳回值
除了參數之外,堆疊幀還顯示回傳值,這些值會在堆疊上分配。例如,函數簽章:
<code class="go">func F(a int64) (int, int)</code>
在amd64 系統上,會將堆疊框架參數顯示為:
main.F(0xa, 0x1054d60, 0xc420078058)
第一個值代表參數,而後面的兩個值代表傳回值(int 和int)。但是,由於返回值未初始化,因此它們沒有提供太多有用的信息。
以上是Go Panic 堆疊追蹤中的「未知字段」是什麼?的詳細內容。更多資訊請關注PHP中文網其他相關文章!