panic () stacktrace non mostra i parametri della funzione

Sep 07 2020

Nel codice sottostante:

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

6 parole vengono utilizzate per memorizzare i dati e passare alla funzione example.

  • 3 parole per l' sliceintestazione
  • 2 parole per strstringa
  • una parola per iintero

Traccia dello stack prevista:

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

Traccia dello stack effettivo:

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

Perché lo stacktrace generato da panic()non mostra quelle 6 parole?

Risposte

5 Marc Sep 08 2020 at 06:11

Go viene mostrato main.example(...)perché la funzione è inline dal compilatore e non esiste più come funzione, è stata incorporata main()(i dettagli della logica di stampa sono in traceback.go ).

Puoi dire al compilatore di non inline la funzione usando la go:noinline direttiva del compilatore :

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

Con l'inlining disabilitato, l'output del traceback predefinito mostra i main.examplesuoi parametri:

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

Nota che makenon appare nella traccia dello stack, né può: è tornato prima che panicsia mai raggiunto.

Un consiglio : go:noinlineè usato qui per mostrare perché la traccia dello stack non contiene gli argomenti della funzione. In genere non si dovrebbero forzare le decisioni di ottimizzazione del compilatore a meno che non esegua il debug del compilatore o si occupi delle funzioni di runtime che ne hanno bisogno.