overexchange
overexchange

Reputation: 1

panic() stacktrace does not show function parameters

In the below code:

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

6 words are being used to store data and pass to function example.


Expected stack trace:

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

Actual stack trace:

panic: Want stack trace
    
goroutine 1 [running]:
main.example(...)
        /home/../Main.go:8
main.main()
        /home/../Main.go:4 +0x39
exit status 2

$ go version
go version go1.14.3 linux/amd64

Why does the stacktrace generated from panic() not show those 6 words?

Upvotes: 0

Views: 1110

Answers (1)

Marc
Marc

Reputation: 21035

Go is showing main.example(...) because the function is inlined by the compiler and doesn't exist as a function anymore, it's been embedded in main() (details of the printing logic are in traceback.go).

You can tell the compiler not to inline the function by using the go:noinline compiler directive:

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

With inlining disabled, the default traceback output shows main.example and its parameters:

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

Note that make does not appear in the stack trace, nor can it: it has returned before panic is ever reached.

A word of advice: go:noinline is used here to show why the stack trace does not contain the function arguments. One should generally not force compiler optimization decisions unless debugging the compiler or dealing with runtime functions that need it.

Upvotes: 6

Related Questions