是否有任何预定义的宏来识别调用函数。
要打印我们使用的当前功能名称
printf("%s", __FUNCTION__);
如果函数a
调用b
并且控件位于b
,那么是否有办法找出a
?
答案 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);
}
这段代码将为您提供概念,我已经从我的一个项目中复制了它。