Тип runtime.Frames

Тип runtime.Frames предоставляет удобный способ итерации по последовательности стековых фреймов, которые были получены с помощью функции runtime.Callers. Он используется для извлечения информации о каждом фрейме в стеке вызовов, такой как имя функции, имя файла и номер строки. Создается экземпляр runtime.Frames путем передачи среза []uintptr, содержащего адреса возврата, в функцию runtime.CallersFrames. Основной метод Next последовательно возвращает каждый фрейм, пока они не закончатся.

Синтаксис

goframes := runtime.CallersFrames(pcs)
frame, more := frames.Next()

Пример

Давайте получим информацию о текущем стеке вызовов и выведем данные о каждом фрейме:

gopackage main

import (
  "fmt"
  "runtime"
)

func main() {
  // Создаем срез для хранения адресов возврата
  pcs := make([]uintptr, 10)
  // Заполняем срез адресами текущего стека
  n := runtime.Callers(0, pcs)
  pcs = pcs[:n]
  
  // Создаем объект Frames для итерации
  frames := runtime.CallersFrames(pcs)
  
  // Итерируем по всем фреймам
  for {
    frame, more := frames.Next()
    fmt.Println("Функция:", frame.Function)
    fmt.Println("Файл:", frame.File)
    fmt.Println("Строка:", frame.Line)
    fmt.Println("---")
    
    if !more {
      break
    }
  }
}

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

go"Функция: main.main"
"Файл: /path/to/main.go"
"Строка: 12"
"---"
"Функция: runtime.main"
"Файл: /usr/local/go/src/runtime/proc.go"
"Строка: 255"
"---"

Пример

Давайте создадим вложенные функции и получим стек вызовов из глубокой вложенности:

gopackage main

import (
  "fmt"
  "runtime"
)

func level3() {
  pcs := make([]uintptr, 20)
  n := runtime.Callers(0, pcs)
  pcs = pcs[:n]
  
  frames := runtime.CallersFrames(pcs)
  
  for i := 0; i < 3; i++ {
    frame, _ := frames.Next()
    fmt.Printf("Frame %d: %s\n", i+1, frame.Function)
  }
}

func level2() {
  level3()
}

func level1() {
  level2()
}

func main() {
  level1()
}

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

go"Frame 1: main.level3"
"Frame 2: main.level2"
"Frame 3: main.level1"

Смотрите также

  • функцию runtime.Callers,
    которая заполняет срез адресами возврата стека вызовов
  • функцию runtime.Caller,
    которая возвращает информацию о вызывающем фрейме
  • функцию runtime.FuncForPC,
    которая возвращает информацию о функции по адресу
  • функцию runtime.Frame,
    которая представляет структуру одного фрейма стека