panic () stacktrace não mostra parâmetros de função
No código abaixo:
package main
func main() {
example(make([]string, 2, 4), "hello", 10)
}
func example(slice []string, str string, i int) {
panic("Want stack trace")
}
6 palavras estão sendo usadas para armazenar dados e passar para a função example.
- 3 palavras para
slicecabeçalho - 2 palavras para
strstring - uma palavra para
iinteiro
Rastreamento de pilha 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
Rastreamento de pilha 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 que o rastreamento de pilha gerado panic()não mostra essas 6 palavras?
Respostas
Go está sendo exibido main.example(...)porque a função é embutida pelo compilador e não existe mais como uma função, ela foi incorporada main()(os detalhes da lógica de impressão estão em traceback.go ).
Você pode dizer ao compilador para não embutir a função usando a go:noinline diretiva do compilador :
//go:noinline
func example(slice []string, str string, i int) {
panic("Want stack trace")
}
Com o inlining desativado, a saída de traceback padrão mostra main.examplee seus 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
Observe que makenão aparece no rastreamento da pilha, nem pode: ele retornou antes de panicser alcançado.
Um conselho : go:noinlineé usado aqui para mostrar porque o rastreamento de pilha não contém os argumentos da função. Geralmente, não se deve forçar as decisões de otimização do compilador, a menos que depure o compilador ou lide com funções de tempo de execução que precisam dele.