我们怎么知道调用者函数的名字?

Tom*_*Xue 26 c

在C语言中,__FUNCTION__可以用来获取当前函数的名称.但是,如果我定义一个名为a()的函数,并在b()中调用它,如下所示:

b()
{
    a();
}
Run Code Online (Sandbox Code Playgroud)

现在,在源代码中,有很多函数,比如b()调用a(),例如c(),d(),e()......

是否有可能在()中添加一些代码来检测调用a()的函数的名称?

进一步:

  1. 对不起误导性的拼写错误.我纠正了它.
  2. 我试图找出哪个函数调用a()进行调试.在同样的情况下,我不知道你怎么做?
  3. 我的代码在vxWorks下,但我不确定它是否与C99或其他相关.

Did*_*set 43

你只能做一件事.

但是,使用简单的标准宏技巧,您可以实现您想要的,IIUC显示调用者的名称.

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();
}
Run Code Online (Sandbox Code Playgroud)


alk*_*alk 9

试试这个:

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
Run Code Online (Sandbox Code Playgroud)

如果<all param declarations to a()>是,int i, double d, void * p那么<all params to a()>i, d, p.


或者(更少邪恶; - >> - 但更多代码修改,因为每次调用a()都需要触及):

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
    );
}
Run Code Online (Sandbox Code Playgroud)

__FUNCTION__如果使用不同的C99编译器替换它,可以在GCC(至少?)上使用__func__.

  • :D它对我来说看起来很邪恶,但它是一种很酷的方式来做IMO (2认同)

Bec*_*hir 7

如果您使用的是Linux系统,则可以使用该backtrace()功能.

有关更多详细信息和代码示例,请参见手册页.


Rau*_*nak 5

请参阅:https://www.gnu.org/software/libc/manual/html_node/Backtraces.html

回溯是线程中当前活动的函数调用的列表。检查程序回溯的常用方法是使用外部调试器,例如 gdb。然而,有时从程序内以编程方式获取回溯是有用的,例如,出于日志记录或诊断的目的。

头文件 execinfo.h 声明了三个函数,用于获取和操作当前线程的回溯。


Vic*_*cky 5

您可以使用内置的gcc来实现。

void * __builtin_return_address(int level)

以下方法应打印函数a()的直接调用方。

例:

a() {
    printf ("Caller name: %pS\n", __builtin_return_address(0));
}
Run Code Online (Sandbox Code Playgroud)

  • 这确实打印返回地址(仍然有用),但不打印函数名称。 (3认同)