3

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?

Jarod42
  • 203,559
  • 14
  • 181
  • 302
VINOTH ENERGETIC
  • 1,775
  • 4
  • 23
  • 38
  • 6
    A macro is resolved on compile time and there is no way of knowing what function has called the current function. On runtime, there are environment libraries that can show the call stack as shown here: http://stackoverflow.com/a/691742/104774 – stefaanv Mar 19 '14 at 11:03
  • 1
    Here is a wild idea, though. (1) create a 'call stack' array, (2) add [function entry/exit codes](http://stackoverflow.com/questions/1472769/is-there-a-compiler-feature-to-inject-custom-function-entry-and-exit-code) to update the stack, (3) .. profit. Depends on your compiler, though. – Jongware Mar 19 '14 at 11:07
  • @Jongware the (compiler specific) pre/post functions are a good idea except they would be faced with the same problem (since __FUNCTION__ would be those functions, not the caller). You would need a pre/post macro instead, which probably doesn't exist via simple compiler flags. – mah Mar 19 '14 at 11:20

2 Answers2

4

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.

anderas
  • 5,744
  • 30
  • 49
2

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.

Sigcont
  • 717
  • 2
  • 8
  • 16