Тип runtime.Frame
Тип runtime.Frame представляет собой структуру, содержащую информацию об одном фрейме в стеке вызовов программы. Он используется в низкоуровневых операциях для анализа стека, отладки и профилирования. Основные поля структуры включают: PC (программный счетчик), Func (указатель на функцию), Function (имя функции), File (путь к файлу с исходным кодом) и Line (номер строки в файле).
Синтаксис
type Frame struct {
PC uintptr
Func *Func
Function string
File string
Line int
Entry uintptr
}
Пример
Давайте получим информацию о текущем фрейме стека с помощью функции runtime.Caller:
package main
import (
"fmt"
"runtime"
)
func main() {
pc, file, line, ok := runtime.Caller(0)
if ok {
fn := runtime.FuncForPC(pc)
if fn != nil {
frame := runtime.Frame{
PC: pc,
Func: fn,
Function: fn.Name(),
File: file,
Line: line,
Entry: fn.Entry(),
}
fmt.Printf("Function: %s\n", frame.Function)
fmt.Printf("File: %s\n", frame.File)
fmt.Printf("Line: %d\n", frame.Line)
}
}
}
Результат выполнения кода:
"Function: main.main"
"File: /path/to/main.go"
"Line: 10"
Пример
Давайте получим все фреймы стека с помощью функции runtime.Callers и итератора runtime.Frames:
package main
import (
"fmt"
"runtime"
)
func main() {
callers := make([]uintptr, 10)
n := runtime.Callers(0, callers)
frames := runtime.CallersFrames(callers[:n])
for {
frame, more := frames.Next()
if !more {
break
}
fmt.Printf("Function: %s\n", frame.Function)
fmt.Printf("File: %s\n", frame.File)
fmt.Printf("Line: %d\n", frame.Line)
fmt.Println("---")
}
}
Результат выполнения кода:
"Function: runtime.Callers"
"File: /usr/local/go/src/runtime/..."
"Line: 123"
"---"
"Function: main.main"
"File: /path/to/main.go"
"Line: 10"
"---"
Пример
Давайте создадим функцию для получения фрейма на определенной глубине стека:
package main
import (
"fmt"
"runtime"
)
func getFrame(skip int) runtime.Frame {
pc, file, line, ok := runtime.Caller(skip)
if !ok {
return runtime.Frame{}
}
fn := runtime.FuncForPC(pc)
if fn == nil {
return runtime.Frame{}
}
return runtime.Frame{
PC: pc,
Func: fn,
Function: fn.Name(),
File: file,
Line: line,
Entry: fn.Entry(),
}
}
func main() {
frame := getFrame(1)
fmt.Printf("Caller function: %s\n", frame.Function)
fmt.Printf("Caller file: %s\n", frame.File)
fmt.Printf("Caller line: %d\n", frame.Line)
}
Результат выполнения кода:
"Caller function: main.main"
"Caller file: /path/to/main.go"
"Caller line: 25"
Смотрите также
-
функцию
runtime.Caller,
которая возвращает информацию о вызывающем фрейме -
функцию
runtime.Callers,
которая заполняет срез адресами программных счетчиков -
тип
runtime.Frames,
который предоставляет итератор по фреймам стека -
тип
runtime.Func,
который представляет функцию в исполняемом файле