Как получить текущее имя функции
Для целей трассировки я хотел бы напечатать текущее имя функции, например макрос __FUNCTION__
в gcc.
Итак, когда у меня есть функция
func foo () {
trace()
}
он автоматически распечатает Entering foo()...
или что-то в этом роде.
Ответы
Ответ 1
[Примечание: перейдите на 1. 7+ рекомендует использовать runtime.CallersFrames
вместо runtime.FuncForPC
; другой ответ содержит обновленный пример].
Пакет runtime - это ваш друг здесь:
func trace() {
pc := make([]uintptr, 10) // at least 1 entry needed
runtime.Callers(2, pc)
f := runtime.FuncForPC(pc[0])
file, line := f.FileLine(pc[0])
fmt.Printf("%s:%d %s\n", file, line, f.Name())
}
Ответ 2
В Go 1.7 добавлены некоторые функции времени выполнения для улучшения доступа к информации стекового фрейма.
Из Go 1.7 Примечания к выпуску:
Новая функция CallersFrames преобразует фрагмент ПК, полученный от Callers, в последовательность кадров, соответствующую стеку вызовов. Этот новый API следует предпочитать вместо прямого использования FuncForPC, поскольку последовательность кадров может более точно описывать стеки вызовов с помощью встроенных вызовов функций.
Улучшенный пример:
func trace2() {
pc := make([]uintptr, 15)
n := runtime.Callers(2, pc)
frames := runtime.CallersFrames(pc[:n])
frame, _ := frames.Next()
fmt.Printf("%s:%d %s\n", frame.File, frame.Line, frame.Function)
}
площадка: https://play.golang.org/p/YkEN5mmbRld
Ответ 3
Здесь более простая версия, которой не нужно выделять массив.
func trace() (string, int, string) {
pc, file, line, ok := runtime.Caller(1)
if !ok { return "?", 0, "?" }
fn := runtime.FuncForPC(pc)
return file, line, fn.Name()
}