Функция runtime.Stack
Функция runtime.Stack используется для получения трассировки стека
выполняющихся горутин. Она заполняет переданный срез байтов
информацией о стеке и возвращает количество записанных байтов.
Первый параметр - срез байтов для записи, второй - булев флаг,
указывающий, нужно ли включать информацию о всех горутинах
(true) или только о текущей (false).
Синтаксис
runtime.Stack(buf []byte, all bool) int
Пример
Давайте получим трассировку стека текущей горутины:
package main
import (
"fmt"
"runtime"
)
func main() {
func() {
buf := make([]byte, 1024)
n := runtime.Stack(buf, false)
fmt.Printf("n: %d\n", n)
fmt.Println(string(buf[:n]))
}()
}
Результат выполнения кода:
"n: 214"
"goroutine 1 [running]:
runtime.Stack(0xc000014240?, 0x0?, 0x0?)
/usr/local/go/src/runtime/mprof.go:... +0x...
main.main.func1()
/path/to/file.go:... +0x...
main.main()
/path/to/file.go:... +0x..."
Пример
Получим трассировку стека всех горутин с помощью флага true:
package main
import (
"fmt"
"runtime"
"time"
)
func worker() {
time.Sleep(time.Hour)
}
func main() {
go worker()
time.Sleep(10 * time.Millisecond)
buf := make([]byte, 4096)
n := runtime.Stack(buf, true)
fmt.Printf("%s", buf[:n])
}
Результат выполнения кода (сокращенный):
"goroutine 1 [running]:
runtime.Stack(0xc00001c0c0?, 0x1?, 0x0?)
/usr/local/go/src/runtime/mprof.go:... +0x...
main.main()
/path/to/file.go:... +0x...
goroutine 6 [sleep]:
runtime.gopark(...)
/usr/local/go/src/runtime/proc.go:... +0x...
time.Sleep(...)
/usr/local/go/src/runtime/time.go:... +0x...
main.worker()
/path/to/file.go:... +0x...
created by main.main
/path/to/file.go:... +0x..."
Пример
Используем runtime.Stack для отладки в обработчике паники:
package main
import (
"fmt"
"log"
"runtime"
)
func causePanic() {
panic("something went wrong")
}
func main() {
defer func() {
if r := recover(); r != nil {
buf := make([]byte, 2048)
n := runtime.Stack(buf, false)
log.Printf("Panic: %v\nStack trace:\n%s", r, buf[:n])
}
}()
causePanic()
}
Результат выполнения кода:
"Panic: something went wrong"
"Stack trace:
goroutine 1 [running]:
log.(*Logger).Output(...)
/usr/local/go/src/log/log.go:... +0x...
log.Printf(...)
/usr/local/go/src/log/log.go:... +0x...
main.main.func1()
/path/to/file.go:... +0x...
panic(...)
/usr/local/go/src/runtime/panic.go:... +0x...
main.causePanic(...)
/path/to/file.go:... +0x...
main.main()
/path/to/file.go:... +0x..."
Смотрите также
-
функцию
runtime.Caller,
которая возвращает информацию о вызывающем файле и строке -
функцию
runtime.Callers,
которая заполняет срез адресами программных счетчиков -
функцию
runtime.FuncForPC,
которая возвращает информацию о функции по адресу счетчика -
функцию
runtime.Goexit,
которая завершает выполнение текущей горутины