panic () stacktrace n'affiche pas les paramètres de fonction

Sep 07 2020

Dans le code ci-dessous:

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

6 mots sont utilisés pour stocker les données et passer à la fonction example.

  • 3 mots pour l'en- slicetête
  • 2 mots pour la strchaîne
  • un mot pour ientier

Trace de pile attendue:

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

Trace réelle de la pile:

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

Pourquoi le stacktrace généré à partir de panic()ne pas afficher ces 6 mots?

Réponses

5 Marc Sep 08 2020 at 06:11

Go s'affiche main.example(...)parce que la fonction est intégrée par le compilateur et n'existe plus en tant que fonction, elle a été intégrée main()(les détails de la logique d'impression sont dans traceback.go ).

Vous pouvez dire au compilateur de ne pas insérer la fonction en utilisant la go:noinline directive du compilateur :

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

Avec l'inlining désactivé, la sortie de traceback par défaut affiche main.exampleet ses paramètres:

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

Notez que cela maken'apparaît pas dans la trace de la pile, ni ne le peut: il est retourné avant d' panicêtre atteint.

Un conseil : go:noinlineest utilisé ici pour montrer pourquoi la trace de pile ne contient pas les arguments de la fonction. Il ne faut généralement pas forcer les décisions d'optimisation du compilateur à moins de déboguer le compilateur ou de traiter les fonctions d'exécution qui en ont besoin.