39

In the C language, __FUNCTION__ can be used to get the current function's name. But if I define a function named a() and it is called in b(), like below:

b()
{
    a();
}

Now, in the source code, there are lots of functions like b() that call a(), e.g. c(), d(), e()...

Is it possible, within a(), to add some code to detect the name of the function that called a()?

Further:

  1. Sorry for the misleading typo. I have corrected it.
  2. I am trying to find out which function calls a() for debugging purposes. I don't know how you do when in the same situation?
  3. And my code is under vxWorks, but I am not sure whether it is related to C99 or something else.
rohit89
  • 5,745
  • 2
  • 25
  • 42
Tom Xue
  • 3,169
  • 7
  • 40
  • 77
  • Not sure. But [this](http://stackoverflow.com/questions/2154852/get-a-pointer-to-the-current-function-in-c-gcc) maybe helpful to you – Suvarna Pattayil Apr 19 '13 at 08:10
  • Why do you want to do this? Is it for debugging purpose? – fstamour Apr 19 '13 at 08:13
  • If this is only for debugging you can define a as a macro, that way using `__func__` will return b, as you want. – Joe Apr 19 '13 at 08:15
  • Which compiler has **FUNCTION** to return the name of the current function? The identifier that is foreseen in the C standard for that is `__func__` IIRC. – Jens Gustedt Apr 19 '13 at 08:18
  • what you write is wrong. `__FUNC__` returns the current method name AFAIK. To get the caller, you'd have to look at the stacktrace – Daij-Djan Apr 19 '13 at 08:19
  • @Daij-Djanm, how can a question be wrong? In any case I checked and the C standard defines `__func__` for that purpose (section 6.4.2.2). So again my question, what compiler has this with the identifier `FUNCTION`? That would be completely wrong, since that is any identifier that is clearly reserved for use in applications (by a C programmer). – Jens Gustedt Apr 19 '13 at 08:24
  • "In C language, we can use FUNCTION to get the caller function's name." - first statement of the question. and that is wrong ^^ – Daij-Djan Apr 19 '13 at 08:25
  • 1. Do you need platform-specific solution or cross-platform solution? 2. Do you need compile-time or run-time information? It will be good if you brifely describe, what you are doing. – Dmitry Sazonov Apr 19 '13 at 08:36
  • @JensGustedt: GCC has `__FUNCTION__`, so it propably a typo by the OP. – alk Apr 19 '13 at 08:53
  • Underscores are significant to markdown, hence the bold formatting. I've edited to fix that, which hopefully will reduce the confusion a bit, but I haven't fixed the issue of whether the questioner should have mentioned the C99 standard version or the older GCC version. – Steve Jessop Apr 19 '13 at 08:58
  • @JensGustedt "how can a question be wrong?" -- More silly games, eh? Daij-Dan wrote "what you write is wrong", which is clearly true. "That would be completely wrong" -- which is what Daij-Dan said, but stronger. – Jim Balter Apr 19 '13 at 09:04
  • If it is for debugging puposes have you tried to set a breakpoint in `a`? The other option would be to use a profiler and generate call graph. – Jens Mar 17 '18 at 22:11
  • Does this answer your question? [How to find \_\_FUNCTION\_\_, \_\_LINE\_\_ and \_\_FILE\_\_ of parent function?](https://stackoverflow.com/questions/42135276/how-to-find-function-line-and-file-of-parent-function) – Dominique Aug 09 '21 at 12:53

11 Answers11

57

There's nothing you can do only in a.

However, with a simple standard macro trick, you can achieve what you want, IIUC showing the name of the caller.

void a()
{
    /* Your code */
}

void a_special( char const * caller_name )
{
    printf( "a was called from %s", caller_name );
    a();
}

#define a() a_special(__func__)

void b()
{
    a();
}
Haseeb Mir
  • 928
  • 1
  • 13
  • 22
Didier Trosset
  • 36,376
  • 13
  • 83
  • 122
  • I had to declare the caller_name variable as `const char* caller_name`, but it worked! – redcurry Feb 11 '14 at 18:33
  • Precision: `__func__` is part of the C99 standard, [...] `__FUNCTION__` is another name for `__func__`, provided for backward compatibility with old versions of GCC. (source: https://gcc.gnu.org/onlinedocs/gcc/Function-Names.html) – Camille G. Jun 02 '17 at 09:18
  • 1
    Could you tell me how can I use your example with ellipsis in function declaration, please? `void a(int a, char *fmt, ...)` How can I include it in the macro definition? – Alejandro Galera Jan 09 '19 at 12:56
  • @mulg0r Have a look at `va_list` , `va_arg` and companions. however I doubt you can apply this trick to a function using ellipsis: it should be written with `va_list` instead, just like the `vprintf` function series :-( – Didier Trosset Jan 10 '19 at 12:57
  • @mulg0r Using [variadic macros](https://en.wikipedia.org/wiki/Variadic_macro) you can achieve what you want (eg.`#define a(...) a_special (__func__, __VA_ARGS__)`, for a function `void a_special(char const * caller_name, ...){}`) They are around in C since C99 and in C++ since C++11. – Toto Nov 19 '19 at 14:17
13

You can do it with a gcc builtin.

void * __builtin_return_address(int level)

The following way should print the immediate caller of a function a().

Example:

a() {
    printf ("Caller name: %pS\n", __builtin_return_address(0));
}
Leon
  • 2,926
  • 1
  • 25
  • 34
Vicky
  • 431
  • 1
  • 6
  • 12
11

If you are using Linux system, you can use the backtrace() function.

See the man page for more details and a code example.

Bechir
  • 987
  • 10
  • 26
10

Try this:

void a(<all param declarations to a()>);

#ifdef DEBUG
#  define a(<all params to a()>) a_debug(<all params a()>, __FUNCTION__)
void a_debug(<all params to a()>, const char * calledby);
#endif

void b(void)
{
  a(<all values to a()>);
}

#ifdef DEBUG
#  undef a
#endif

void a(<all param declarations to a()>)
{
  printf("'%s' called\n", __FUNCTION__);
}

#ifdef DEBUG
void a_debug(<all param declarations to a()>, const char * calledby)
{
  printf("'%s' calledby '%s'", __FUNCTION__, calledby);
  a(<all params to a()>);
}
#endif

If for example <all param declarations to a()> is int i, double d, void * p then <all params to a()> is i, d, p.


Or (less evil ;->> - but more code modding, as each call to a() needs to be touched):

void a((<all params of normal a()>    
#ifdef DEBUG
  , const char * calledby
#endif
  );

void a((<all params of normal a()>    
#ifdef DEBUG
  , const char * calledby
#endif
  )
{
#ifdef DEBUG
  printf("'%s' calledby '%s', __FUNCTION__, calledby);
#endif
  ...
}

...

void b(void)
{
    a(<all params of normal a()>
#ifdef DEBUG
      , __FUNC__
#endif
    );
}

__FUNCTION__ is available on GCC (at least?), if using a different C99 compiler replace it with __func__.

alk
  • 69,737
  • 10
  • 105
  • 255
5

Refer: https://www.gnu.org/software/libc/manual/html_node/Backtraces.html

A backtrace is a list of the function calls that are currently active in a thread. The usual way to inspect a backtrace of a program is to use an external debugger such as gdb. However, sometimes it is useful to obtain a backtrace programmatically from within a program, e.g., for the purposes of logging or diagnostics.

The header file execinfo.h declares three functions that obtain and manipulate backtraces of the current thread.

Raunak
  • 3,314
  • 1
  • 22
  • 28
2

If you're only after knowing where you were for logging/debug purposes you can use a macro to avoid __func__ giving the name of your logging/debug function but of the function calling it.

Being in a macro will not result in a change to __func__ but will "feel" like using a function.

e.g.

#define LOG(s, data...) log("%s: "s, __function__, ## data)
Joe
  • 7,378
  • 4
  • 37
  • 54
2

If your platform is Windows, you may use this: walking the callstack

Dmitry Sazonov
  • 8,801
  • 1
  • 35
  • 61
0

You can tag each function that calls a() with an integer identifier which is passed to a() as a parameter and then use a switch-case construct in a() to tell which function has invoked a().A printf() would tell which function invoked a() depending on the integer identifier value if you use that as an argument to a switch-case construct in a()

#include<stdio.h>

void a(int);
void b();
void c();
void d();

int main(void)
{

b();
c();
d();

}

void b()
{

int x=1;
a(x);

}

void c()
{

int x=2;
a(x);

}

void d()
{

int x=3;
a(x);

}

void a(int x)
{

switch(x)
{
case 1:
printf("b called me\n");
break;
 case 2:
printf("c called me\n");
break;
case 3:
printf("d called me\n");
}

}
Rüppell's Vulture
  • 3,583
  • 7
  • 35
  • 49
  • It is a "workaround", not a solution. If you need to provide external API - your direct way will be useless. – Dmitry Sazonov Apr 19 '13 at 08:40
  • @DmitrySazonov I answered what the poster asked for.Not more,not less.It IS a solution. – Rüppell's Vulture Apr 19 '13 at 08:43
  • 2
    It is not a solution, because you had changed function signature. Nevermind, it just my opinion ;) – Dmitry Sazonov Apr 19 '13 at 09:18
  • 1
    Or, you can just pass `__FUNCTION__` into a(). No switch required, and it handles new functions, changed function names, etc. Of course, as Dmitry Sazonov says, adding that parameter _does_ change the function's signature. – RobH Apr 19 '13 at 16:05
0

If the function in question is in a different c file, you can do

#define name_of_function(...) \
    printf("Function %s is parent\n", __FUNCTION__); \
    name_of_function(__VA_ARGS__);

And at the top of the c file it lives in

#ifdef name_of_function
#undef name_of_function
#endif

If they're in the same file, you can wrap the function definition in the second macro, then redefine the first macro at the end. It's not terribly extensible because you can't generate new defines from other defines, but if you're trying to track down parents for a particular function it works without any nonsense.

https://godbolt.org/z/f2jKOm

Koala Bear
  • 163
  • 3
  • 15
0

Use another C-function as a wrapper for the original function which is to debug, means suppress the return data of the original function. Or you need to synchronize return types of the wrapper and the original function.

To avoid type-sync a C-macro should be used as suggested here:

/* You need to debug the function foo().
 * So rename foo() to foo_debug() in source and header files.
 * Then define a macro named foo().
 *
 * Benefits:
 *   - you don't have to care about the return type
 *     of the original function;
 *   - C-macro is inline solution -- there are not
 *     extra calls in the backtrace.
 */

/* Function which is to debug after renaming. */
type_t foo_debug();

#define foo() \
    ({                                                       \
        fprintf(stderr, "[DEBUG] %s:%d %s() called by %s\n", \
                __FILE__, __LINE__, "foo", __FUNCTION__);    \
        foo_debug();                                         \
    })

Or one line C-macro:

#define foo() (fprintf(stderr, "[DEBUG] %s:%d %s() called by %s\n", __FILE__, __LINE__, "foo", __FUNCTION__), foo_debug())
-1
#include <stdio.h>
#include <stdlib.h>

#define FUNCTION_NAME(FUNCTION) printf("FUNCTION=%s \r\n", #FUNCTION);

int a() {
  printf("A function call");
}

int b() {
  printf("B function call");
}

int main(){
FUNCTION_NAME(a);
FUNCTION_NAME(b);
return 0;

}