panic () stacktrace nie pokazuje parametrów funkcji

Sep 07 2020

W poniższym kodzie:

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

6 słów jest używanych do przechowywania danych i przekazywania ich do funkcji example.

  • 3 słowa na slicenagłówek
  • 2 słowa na strstring
  • jedno słowo dla iliczby całkowitej

Oczekiwany ślad stosu:

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

Rzeczywisty ślad stosu:

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

Dlaczego ślad stosu wygenerowany z panic()nie pokazuje tych 6 słów?

Odpowiedzi

5 Marc Sep 08 2020 at 06:11

Go jest wyświetlane, main.example(...)ponieważ funkcja jest wbudowana przez kompilator i nie istnieje już jako funkcja, została osadzona w main()(szczegóły logiki drukowania znajdują się w traceback.go ).

Możesz powiedzieć kompilatorowi, aby nie wstawiał funkcji , używając go:noinline dyrektywy kompilatora :

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

Gdy wstawianie jest wyłączone, domyślne dane wyjściowe śledzenia zwrotnego main.examplei jego parametry są wyświetlane:

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

Zauważ, że makenie pojawia się w śladzie stosu, ani też nie może: powrócił, zanim paniczostał osiągnięty.

Jedna rada : go:noinlineużyto tutaj, aby pokazać, dlaczego ślad stosu nie zawiera argumentów funkcji. Generalnie nie powinno się wymuszać decyzji dotyczących optymalizacji kompilatora, chyba że debugowanie kompilatora lub zajmowanie się funkcjami uruchomieniowymi, które tego potrzebują.