我该如何找到调用函数的名称?

13 浏览
0 Comments

我该如何找到调用函数的名称?

我一直在使用PRETTY_FUNCTION来输出当前函数名,但是我重新实现了一些函数,并希望找出调用它们的函数。在C++中,我如何获得调用例程的函数名呢?

0
0 Comments

最近的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;
}

0
0 Comments

问题的原因是用户想要找到调用函数的名称。用户尝试了使用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()函数不包括类方法的类名。尽管如此,这些内置函数仍然可以为用户提供一些有用的信息。

0
0 Comments

如何找到调用函数的名称?

问题的出现原因:想要在调用函数的地方打印出函数的名称,但是不想对实际的函数代码进行修改。

解决方法:使用预处理器的技巧,通过宏定义来实现。

具体操作如下:

1. 将原始函数重命名为FunctionNameReal,然后定义一个宏FunctionName,将它替换为一个printf语句和FunctionNameReal函数的调用。

2. 如果需要捕捉返回值或者调用类成员函数,需要对代码做一些调整,但是基本技巧是一样的。

3. 可以使用预处理器的其他宏,如__LINE__和__FILE__,根据不同的编译器选择合适的宏。

4. 可以使用条件编译来控制宏的开关,也可以在头文件中定义这些宏,用#ifdef guards来控制是否重命名实际函数的名称。

在代码示例中,展示了使用C++来处理这个问题的完整示例。通过定义一个类和operator()函数来实现对函数的调用捕捉和打印。

示例输出展示了函数的调用者信息。

另外还给出了处理类成员函数的示例,通过使用装饰类和方法链来实现对函数的调用捕捉和打印。

这种方法虽然有些hacky,但是可以在所有的操作系统上使用,并且不需要对实际函数代码进行修改,非常方便。

0