Функция runtime.FuncForPC
Функция runtime.FuncForPC возвращает объект типа *runtime.Func,
который содержит информацию о функции, ассоциированной с переданным
значением программного счетчика (PC). В качестве аргумента она принимает
значение типа uintptr, представляющее адрес инструкции.
Если переданный PC не соответствует ни одной известной функции,
функция возвращает nil.
Синтаксис
runtime.FuncForPC(pc uintptr) *runtime.Func
Полученный объект *runtime.Func предоставляет методы для получения
имени функции, ее исходного файла и строки, а также для преобразования
значений PC внутри функции.
Пример 1
Давайте получим информацию о текущей функции с помощью
runtime.Caller и runtime.FuncForPC:
package main
import (
"fmt"
"runtime"
)
func main() {
pc, file, line, ok := runtime.Caller(0)
if !ok {
fmt.Println("Failed to get caller information")
return
}
fn := runtime.FuncForPC(pc)
if fn != nil {
fmt.Printf("Function: %s\n", fn.Name())
fmt.Printf("File: %s\n", file)
fmt.Printf("Line: %d\n", line)
}
}
Результат выполнения кода:
"Function: main.main"
"File: /path/to/your/file.go"
"Line: 10"
Пример 2
Получим информацию о функции, вызванной из другой функции.
Для этого используем runtime.Callers для получения стека вызовов:
package main
import (
"fmt"
"runtime"
)
func outer() {
inner()
}
func inner() {
pc := make([]uintptr, 10)
n := runtime.Callers(1, pc)
if n == 0 {
fmt.Println("No callers found")
return
}
for i := 0; i < n; i++ {
fn := runtime.FuncForPC(pc[i])
if fn != nil {
fmt.Printf("Caller %d: %s\n", i, fn.Name())
}
}
}
func main() {
outer()
}
Результат выполнения кода:
"Caller 0: main.inner"
"Caller 1: main.outer"
"Caller 2: main.main"
Пример 3
Используем метод runtime.Func.Entry для получения начального
адреса функции и метод runtime.Func.FileLine для получения
файла и строки по конкретному значению PC:
package main
import (
"fmt"
"runtime"
)
func testFunc() {
fmt.Println("Inside testFunc")
}
func main() {
pc, _, _, _ := runtime.Caller(0)
fn := runtime.FuncForPC(pc)
if fn != nil {
fmt.Printf("Entry point: %x\n", fn.Entry())
}
testFn := runtime.FuncForPC(runtime.FuncForPC(pc).Entry())
if testFn != nil {
file, line := testFn.FileLine(pc)
fmt.Printf("FileLine: %s:%d\n", file, line)
}
}
Результат выполнения кода:
"Entry point: 106b6c0"
"FileLine: /path/to/your/file.go:15"
Смотрите также
-
функцию
runtime.Caller,
которая возвращает информацию о вызывающей функции -
функцию
runtime.Callers,
которая заполняет срез адресами программных счетчиков из стека вызовов -
тип
runtime.Func,
который представляет информацию о функции в рантайме -
функцию
runtime.Stack,
которая возвращает текущий стек вызовов в виде среза байт