Функция runtime.Stack

Функция runtime.Stack используется для получения трассировки стека выполняющихся горутин. Она заполняет переданный срез байтов информацией о стеке и возвращает количество записанных байтов. Первый параметр - срез байтов для записи, второй - булев флаг, указывающий, нужно ли включать информацию о всех горутинах (true) или только о текущей (false).

Синтаксис

goruntime.Stack(buf []byte, all bool) int

Пример

Давайте получим трассировку стека текущей горутины:

gopackage 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]))
  }()
}

Результат выполнения кода:

go"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:

gopackage 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])
}

Результат выполнения кода (сокращенный):

go"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 для отладки в обработчике паники:

gopackage 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()
}

Результат выполнения кода:

go"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,
    которая завершает выполнение текущей горутины