panic () stacktrace no muestra los parámetros de la función

Sep 07 2020

En el siguiente código:

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

Se utilizan 6 palabras para almacenar datos y pasar a la función example.

  • 3 palabras para el sliceencabezado
  • 2 palabras para strcadena
  • una palabra para ientero

Seguimiento de pila esperado:

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

Seguimiento de pila real:

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

¿Por qué el stacktrace generado a partir de panic()no muestra esas 6 palabras?

Respuestas

5 Marc Sep 08 2020 at 06:11

Go se muestra main.example(...)porque la función está integrada por el compilador y ya no existe como una función, se ha integrado main()(los detalles de la lógica de impresión están en traceback.go ).

Puede decirle al compilador que no inserte la función usando la go:noinline directiva del compilador :

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

Con la inserción deshabilitada, la salida de seguimiento predeterminada muestra main.exampley sus parámetros:

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

Tenga en cuenta que makeno aparece en el seguimiento de la pila, ni puede hacerlo: ha regresado antes de que panicse alcance.

Un consejo : go:noinlinese utiliza aquí para mostrar por qué el seguimiento de la pila no contiene los argumentos de la función. Por lo general, no se deben forzar las decisiones de optimización del compilador a menos que se depure el compilador o se trate de funciones en tiempo de ejecución que lo necesiten.