0

In the following code, get_func_name() can be a system call, a library call, or a function defined my myself. Without taking any parameter, how can I let get_func_name() print out the name of the calling function, without using the information from the stack?

Also, besides the name of the caller, can I print out anything in get_func_name() that can uniquely identify the caller?

void get_func_name(){
        /*What magic goes here?*/
}

void func2(){
       func3();
       get_func_name(); /*Should print out "func2()"*/
}

void func1(){
       func2();
       get_func_name(); /*Should print out "func1()"*/
}

void main(){
       func1();
       get_func_name(); /*Should print out "main()"*/
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Qi Zhang
  • 631
  • 1
  • 7
  • 15
  • Can you pass the calling function name into the `get_func_name()` function? You say "No"…then I don't think there's a way for you to know the calling function without inspecting the stack frames (stack contents) to find out the function that's calling, and even that's modestly tricky — especially if the functions are inlined. – Jonathan Leffler Jun 30 '16 at 23:40
  • Not without inspecting the stack. You'd need to find the return address on the stack. That identifies the calling function by virtue of knowing the address range for each function, which means looking at esoteric, highly platform-specific information (which might not even be present). There are libraries that do this, but they inspect the stack. One (bad) way to do it is to have a preamble and postamble to each function that pushes its name (`__func__`) onto a (user-controlled) stack of pointers; then you can find the calling hierarchy. The pain is making sure no-one ever makes a mistake. – Jonathan Leffler Jun 30 '16 at 23:55
  • @Jonathan Not even inspecting the stack would help; There's no guarantee that a string containing the calling function's name even exists in the binary (eg static functions, which don't form an external interface and whose name thus needn't be recorded as an entry point). These same functions could be inlined into their own callers, so the return address would point to the caller's caller. Lastly, if the caller is part of a tail-call chain, the return pointer will indicate the function that initiated the chain; This could be *very* distant from the immediate calling function. – Iwillnotexist Idonotexist Jul 01 '16 at 03:07

1 Answers1

2

It depends on your scenario.

You could consider the pre-defined identifier __func__. The standard says:

The identifier __func__ shall be implicitly declared by the translator as if, immediately following the opening brace of each function definition, the declaration

static const char __func__[] = "function-name";

appeared, where function-name is the name of the lexically-enclosing function.
....

EXAMPLE Consider the code fragment:

#include <stdio.h>
void myfunc(void)
{
    printf("%s\n", __func__);
    /* ... */
}

Each time the function is called, it will print to the standard output stream:

myfunc

You could somewhat mimic get_func_name with a macro like this:

#define print_func_name() { printf("%s\n", __func__); }

However if your task is different and you want the name of the caller in a general case, then I see no way to get it without checking the stack. (And even if you have access to the stack, you need some debug information to map the caller's address to caller's name.)

AlexD
  • 32,156
  • 3
  • 71
  • 65
  • Thanks @AlexD. Is the \_\_func\_\_ macro get the function name from the stack? – Qi Zhang Jun 30 '16 at 23:39
  • 2
    No, it doesn't -- the `__func__` variable is static and so lives in the data seciton. – Purag Jun 30 '16 at 23:41
  • @QiZhang: The `__func__` predefined identifier holds the name of the current function. If you used `__func__` in `get_func_name()`, it would report `get_func_name` and would not report the name of the calling function. As a result, I don't think this answer helps solve the problem. – Jonathan Leffler Jun 30 '16 at 23:41
  • @JonathanLeffler Yes, you are right. But there is another identifier named \_\_PRETTY\_FUNCTION\__, which is able to return the name of the caller. Is that correct? – Qi Zhang Jun 30 '16 at 23:43
  • 1
    @QiZhang Not really. See http://stackoverflow.com/a/4384825. All those things (`__func__`, `__PRETTY_FUNCTION__`, `__FUNCTION__`) are similar and work in the scope of the current function. – AlexD Jun 30 '16 at 23:45
  • Besides the name of the caller, can I print out anything in get_func_name() that can uniquely identify the caller? – Qi Zhang Jun 30 '16 at 23:51
  • @QiZhang Not sure if it fits, but you could use `__FILE__` and `__LINE__`. (And get_func_name would be perhaps a macro, not a real function.) – AlexD Jun 30 '16 at 23:56
  • 2
    But `__FILE__` and `__LINE__` would be for the current function. Clearly, you could pass them to the called function — `get_func_name()` — but you could also pass the name of the calling function: `#define get_func_name() real_get_func_name(__func__)` which would do the job (except that it passes the name on the stack, which is nominally precluded by the question). – Jonathan Leffler Jun 30 '16 at 23:58
  • Yes, of course. Basically either we "prepare" the functions to be tracked, or we are out of luck. I'm not sure how to discuss "function names" at runtime, especially after optimizers do their job. – AlexD Jul 01 '16 at 00:05