2014-09-19 62 views
19

为了追踪目的,我想打印出当前函数名称,如gcc中的__FUNCTION__宏。golang:获取当前函数名称范围

所以,当我有一个函数

​​

它会自动打印出Entering foo()...或类似的东西。

回答

39

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

天哪,这是自吹。没有想法的运行时间使它变得如此简单。 – twotwotwo 2014-09-19 07:21:50

+1

哇..我也是。我将不得不改变我的堆栈跟踪正则表达式到这..它更好! +1 – 2014-09-19 09:34:50

+0

仅供参考 - 文档确实说明了这一点,但这看起来不准确。我深入调用了这3种方法,它在第22行报告了源文件中的第24行。然后,我尝试了一个深度方法调用,它是一行关闭 - 对我的需求来说不够好:(文档没有声明'结果如果pc不是f中的程序计数器,它将不准确......但我不确定我应该如何解释它。似乎不像从堆栈跟踪中提取文件和行号那样准确。 – 2014-09-21 12:35:50

6

对于那些在2017年看这个问题,一些golang运行时功能被加入,似乎处理正在打印的不正确的行号。

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/z2kHQJoeUo