#go
#Вперед
Вопрос:
В приведенном ниже коде:
package main
func main() {
example(make([]string, 2, 4), "hello", 10)
}
func example(slice []string, str string, i int) {
panic("Want stack trace")
}
для хранения данных и передачи в функцию используются 6 слов example
.
- 3 слова для
slice
заголовка - 2 слова для
str
строки - одно слово для
i
целого числа
Ожидаемая трассировка стека:
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
Фактическая трассировка стека:
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
Почему в stacktrace, сгенерированном на основе panic()
, не отображаются эти 6 слов?
Комментарии:
1. Обычно ли трассировки стека включают значения переменных? Я этого раньше не видел. Если вы хотите реализовать это самостоятельно, вы можете захватить стек с помощью golang.org/pkg/runtime/debug/#Stack а затем также выведите значения.
2. Я думаю, вы ищете время выполнения. SetTraceback()
Ответ №1:
Отображается Go, main.example(...)
поскольку функция встроена компилятором и больше не существует как функция, она была встроена в main()
(подробности логики печати находятся в traceback.go).
Вы можете указать компилятору не вставлять функцию, используя go:noinline
директиву компилятора:
//go:noinline
func example(slice []string, str string, i int) {
panic("Want stack trace")
}
При отключенном встраивании отображается вывод обратной трассировки по умолчанию main.example
и его параметры:
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
Обратите внимание, что make
это не отображается в трассировке стека и не может быть: оно вернулось до того, как panic
было достигнуто.
Небольшой совет: go:noinline
здесь используется, чтобы показать, почему трассировка стека не содержит аргументов функции. Как правило, не следует форсировать решения по оптимизации компилятора, если не выполняется отладка компилятора или работа с функциями среды выполнения, которые в этом нуждаются.
Комментарии:
1. Что означает «функция встроена компилятором»?
2. Ожидаемая трассировка стека также имеет
make()
вызов. Это также считается встроенным? Фактическая трассировка стека этого не показывает.3. Почему
make
это должно быть там? Это не вызовpanic
, это вызвано и вернулось раньшеpanic
.