Stack Traces In Go这篇文章主要讲了当Golang程序发生panic时,如何读懂stack trace中的函数参数。归纳为下面两个例子:

(1)

package main

import "fmt"

type trace struct{}

func main() {
    slice := make([]string, 2, 4)

    var t trace
    t.Example(slice, "hello", 10)
}

func (t *trace) Example(slice []string, str string, i int) {
    fmt.Printf("Receiver Address: %p\n", t)
    panic("Want stack trace")
} 

执行结果如下:

Receiver Address: 0x570560
panic: Want stack trace

goroutine 1 [running]:
main.(*trace).Example(0x570560, 0xc08201ff50, 0x2, 0x4, 0x4ecc10, 0x5, 0xa)
        C:/Work/gocode/src/Hello.go:16 +0x11d
main.main()
        C:/Work/gocode/src/Hello.go:11 +0xb5
......

可以看到,main.(*trace).Example包含6个参数:第一个(0x570560)是t的地址;接下来三个(0xc08201ff500x20x4)是slice的内容:指向底层数组的指针,lengthcapcity;接下来两个是字符串的内容:同slice相比,缺少了capcity;最后是10这个参数。

(2)

package main
func main() {
    Example(true, false, true, 25)
}

func Example(b1, b2, b3 bool, i uint8) {
    panic("Want stack trace")
}

执行结果如下:

panic: Want stack trace

goroutine 1 [running]:
main.Example(0x19010001)
        C:/Work/gocode/src/Hello.go:7 +0x6b
main.main()
        C:/Work/gocode/src/Hello.go:3 +0x39

上面4个参数每个都占据一个byte,编译器把它们打包在一个word中。