VINOTH ENERGETIC
VINOTH ENERGETIC

Reputation: 1843

predefined macro to identify the calling function?

Is there any predefined macro to identify the calling function.

To print the current function name we use

printf("%s", __FUNCTION__);

Like that if function a calls b and control is in b, then is there is way to find out a?

Upvotes: 3

Views: 640

Answers (2)

Sigcont
Sigcont

Reputation: 715

you can use stack trace, to know the flow of all methods.

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);

}

this code will provide you the concept, I have copied it from one of my project.

Upvotes: 2

anderas
anderas

Reputation: 5854

No. For this purpose, the preprocessor would have to know which functions call your function. This information is not available at that time, however. In the case of (dynamic or static) libraries, this information is actually never fully available at compile-time.

Edit: as said in the comment by @stefaanv, you would have to use runtime means such as the StackWalker lib linked by him at runtime. That is the only point where you know what function called your function.

Upvotes: 4

Related Questions