预定义的宏来识别调用函数?

时间:2014-03-19 10:56:17

标签: c++ c macros

是否有任何预定义的宏来识别调用函数。

要打印我们使用的当前功能名称

printf("%s", __FUNCTION__);

如果函数a调用b并且控件位于b,那么是否有办法找出a

2 个答案:

答案 0 :(得分:4)

没有。为此,预处理器必须知道哪些函数调用了您的函数。但是,此信息当时不可用。对于(动态或静态)库,此信息在编译时实际上永远不可用。

编辑:正如@stefaanv在评论中所说,你必须使用运行时手段,例如他在运行时链接的StackWalker lib。这是你知道什么函数调用你的函数的唯一点。

答案 1 :(得分:2)

您可以使用堆栈跟踪,了解所有方法的流程。

void StackTrace::printStackTrace( ){
std::cout<<"stack Trace\n";
std::cerr<<"stachTrace\n";
// storage array for stack trace address data
void* addrlist[maxFrame+1];

// retrieve current stack addresses
int addrlen = backtrace(addrlist, sizeof(addrlist) / sizeof(void*));
if (addrlen == 0) {
    std::cerr<<"  <empty, possibly corrupt>\n";
    std::cout<<" <empty, possibly corrupt\n";


}
// resolve addresses into strings containing "filename(function+address)",
// this array must be free()-ed
char** symbollist = backtrace_symbols(addrlist, addrlen);
// allocate string which will be filled with the demangled function name
size_t funcnamesize = 256;
char* funcname = (char*)malloc(funcnamesize);
// iterate over the returned symbol lines. skip the first, it is the
// address of this function.
for (int i = 1; i < addrlen; i++){
    char *begin_name = 0, *begin_offset = 0, *end_offset = 0;
    // find parentheses and +address offset surrounding the mangled name:
    // ./module(function+0x15c) [0x8048a6d]
    for (char *p = symbollist[i]; *p; ++p){
        if (*p == '(')
            begin_name = p;
        else if (*p == '+')
            begin_offset = p;
        else if (*p == ')' && begin_offset) {
            end_offset = p;
            break;

        }
    }
    if (begin_name && begin_offset && end_offset
            && begin_name < begin_offset){
        *begin_name++ = '\0';
        *begin_offset++ = '\0';
        *end_offset = '\0';
        // mangled name is now in [begin_name, begin_offset) and caller
        // offset in [begin_offset, end_offset). now apply
        // __cxa_demangle():
        int status;
                    char* ret =abi::__cxa_demangle(begin_name, funcname, &funcnamesize, &status);
        if (status == 0) {
            funcname = ret; // use possibly realloc()-ed string
            //fprintf(out, "  %s : %s+%s\n",
                //  symbollist[i], funcname, begin_offset);
            std::cerr<<symbollist[ i ]<<funcname<<begin_offset<<std::endl;
    std::cout<<symbollist[ i ] << funcname << begin_offset<<std::endl;
        }else{

        //fprintf(out, "  %s\n", symbollist[i]);
            std::cerr<<symbollist[ i ]<<std::endl;
    std::cout<<symbollist [ i ]<<std::endl;
        }
    }
}
free(funcname);
free(symbollist);

}

这段代码将为您提供概念,我已经从我的一个项目中复制了它。