在下面的代码中:
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个字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 个单词?
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这里用来说明为什么堆栈跟踪不包含函数参数。除非调试编译器或处理需要它的运行时函数,否则通常不应强制执行编译器优化决策。