panic() 堆栈跟踪不显示函数参数

ove*_*nge 0 go

在下面的代码中:

package main
    
func main() {
    example(make([]string, 2, 4), "hello", 10)
}
    
func example(slice []string, str string, i int) {
    panic("Want stack trace")
}
Run Code Online (Sandbox Code Playgroud)

6 个字用于存储数据并传递给函数example

  • slice标题3个字
  • 2 个字表示str字符串
  • 一个字表示i整数

预期的堆栈跟踪:

goroutine 1 [running]:
main.example(0xc000042748, 0x2, 0x4, 0x106abae, 0x5, 0xa)
    stack_trace/example1/example1.go:13 +0x39
main.main()
    stack_trace/example1/example1.go:8 +0x72
    
// Declaration
main.example(slice []string, str string, i int)
    
// Call
make([]string, 2, 4), "hello", 10
    
// Values (0xc000042748, 0x2, 0x4, 0x106abae, 0x5, 0xa)
Slice Value:   0xc000042748, 0x2, 0x4
String Value:  0x106abae, 0x5
Integer Value: 0xa
Run Code Online (Sandbox Code Playgroud)

实际堆栈跟踪:

panic: Want stack trace
    
goroutine 1 [running]:
main.example(...)
        /home/../Main.go:8
main.main()
        /home/../Main.go:4 +0x39
exit status 2
Run Code Online (Sandbox Code Playgroud)
$ go version
go version go1.14.3 linux/amd64
Run Code Online (Sandbox Code Playgroud)

为什么从生成的堆栈跟踪panic()不显示这 6 个单词?

Mar*_*arc 5

Go 之所以显示main.example(...),是因为该函数由编译器内联,并且不再作为函数存在,它已被嵌入main()(打印逻辑的详细信息在traceback.go 中)。

您可以使用编译器指令告诉编译器不要内联函数go:noinline

//go:noinline
func example(slice []string, str string, i int) {
  panic("Want stack trace")
}
Run Code Online (Sandbox Code Playgroud)

禁用内联后,默认回溯输出显示main.example及其参数:

panic: Want stack trace

goroutine 1 [running]:
main.example(0xc000046738, 0x2, 0x4, 0x473f27, 0x5, 0xa)
    /home/me/stuff/src/github.com/me/testing/panic/main.go:9 +0x39
main.main()
    /home/me/stuff/src/github.com/me/testing/panic/main.go:4 +0x72
Run Code Online (Sandbox Code Playgroud)

请注意,make它不会出现在堆栈跟踪中,也不会出现:它在panic到达之前已经返回。

一个忠告go:noinline这里用来说明为什么堆栈跟踪不包含函数参数。除非调试编译器或处理需要它的运行时函数,否则通常不应强制执行编译器优化决策。