我该如何找到调用函数的名称?
最近的glibc版本中提供了GNU backtrace函数,可以获取完整的堆栈跟踪信息,包括调用函数的名称、模块和偏移量。使用这个函数可以很容易地解决问题。如果这不是你想要的,那么可以尝试使用libunwind,但这需要更多的工作量。
需要注意的是,你不能静态地知道调用函数的名称(与PRETTY_FUNCTION不同),你实际上需要遍历堆栈来确定是哪个函数调用了你。因此,在普通的调试printf中,这不是一件值得做的事情。但是,如果你想进行更严格的调试或分析,那么这可能对你有用。
下面是代码示例:
#include#include #include void print_calling_function_name() { void* callstack[128]; int frames = backtrace(callstack, 128); char** symbols = backtrace_symbols(callstack, frames); printf("Calling function: %s\n", symbols[1]); free(symbols); } void foo() { print_calling_function_name(); } int main() { foo(); return 0; }
问题的原因是用户想要找到调用函数的名称。用户尝试了使用GCC的内置函数__builtin_FUNCTION()来获取调用函数的名称,但是该函数在GCC版本大于等于4.8才可用。用户提供了一个示例代码来说明如何使用__builtin_FUNCTION()函数,并输出了调用函数的名称。然而,__builtin_FUNCTION()函数不包括类方法的类名,并且没有类似__builtin_PRETTY_FUNCTION()的函数。但是,用户指出可以使用__builtin_LINE()和__builtin_FILE()来获取更有用的信息。
解决方法是使用GCC的内置函数__builtin_FUNCTION()来获取调用函数的名称。用户提供了一个示例代码来说明如何使用该函数。然而,需要注意的是,该函数只在GCC版本大于等于4.8时可用。此外,用户还提到了其他一些有用的内置函数,如__builtin_LINE()和__builtin_FILE(),它们可以用来获取行号和文件名。虽然__builtin_FUNCTION()函数不包括类方法的类名,但是这些额外的内置函数可以提供更多的帮助。
总结起来,用户想要找到调用函数的名称。他们尝试使用GCC的__builtin_FUNCTION()函数,但是该函数在GCC版本大于等于4.8才可用。用户还提供了其他一些有用的内置函数,如__builtin_LINE()和__builtin_FILE(),它们可以用来获取行号和文件名。然而,__builtin_FUNCTION()函数不包括类方法的类名。尽管如此,这些内置函数仍然可以为用户提供一些有用的信息。
如何找到调用函数的名称?
问题的出现原因:想要在调用函数的地方打印出函数的名称,但是不想对实际的函数代码进行修改。
解决方法:使用预处理器的技巧,通过宏定义来实现。
具体操作如下:
1. 将原始函数重命名为FunctionNameReal,然后定义一个宏FunctionName,将它替换为一个printf语句和FunctionNameReal函数的调用。
2. 如果需要捕捉返回值或者调用类成员函数,需要对代码做一些调整,但是基本技巧是一样的。
3. 可以使用预处理器的其他宏,如__LINE__和__FILE__,根据不同的编译器选择合适的宏。
4. 可以使用条件编译来控制宏的开关,也可以在头文件中定义这些宏,用#ifdef guards来控制是否重命名实际函数的名称。
在代码示例中,展示了使用C++来处理这个问题的完整示例。通过定义一个类和operator()函数来实现对函数的调用捕捉和打印。
示例输出展示了函数的调用者信息。
另外还给出了处理类成员函数的示例,通过使用装饰类和方法链来实现对函数的调用捕捉和打印。
这种方法虽然有些hacky,但是可以在所有的操作系统上使用,并且不需要对实际函数代码进行修改,非常方便。