panic () stacktrace n'affiche pas les paramètres de fonction
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
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.