如何知道哪个函数调用了另一个函数。

11

我想知道如何获取当前执行的函数被调用的位置,也就是在哪个文件和哪一行。 我使用C语言,正在寻找类似于__FUNCTION__、__LINE__或__FILE__宏的东西。


1
你可以通过使用宏来实现这一点。看看我的解决方案。 - bits
如果您实际上想将此作为代码中可用的数据,那是一个不寻常的请求。您为什么想要这个?也许我们可以帮助您解决引发这个问题的任何问题? - WillfulWizard
7个回答

15

重命名你的函数。

void Function(param1)
{
}

void Function_debug(param1, char * file, char * func, unsigned long line)
{
}

然后定义一个宏,像这样:

#define Function(param1) Function_debug(param1, __FILE__, __FUNCTION__, __LINE__)

1
哦,这真是一种美丽而简单的方法。非常感谢。Sérgio - Sérgio
1
如果你真的想感谢bits,你应该点击答案左侧的复选框来表示它是解决了你的问题的答案。 - WillfulWizard
1
这就是我所做的,当时我只是没有点击,因为我需要10分钟来接受答案 =) - Sérgio

3

C语言本身没有提供这些信息。你可以自己跟踪这些信息(在进入/退出时),或者依赖于特定于平台的API来遍历调用堆栈并确定调用函数,但是不会得到更多信息。


2

__FILE____LINE__等是预处理器宏,可以在编译时轻松展开为正确的值。一个函数可能会从许多可能的位置调用,所以无法通过预处理器来完成。找到调用者的名称将非常困难;这涉及遍历堆栈并将地址与符号匹配。

如果你可以接受小的hack,这个方法可能有用(未经测试):

/* Add a called argument to your function */
void _myFunction(char *caller, int more_args)

/* And define a macro that adds it automagically */
#define myFunction(a) _myFunction(__FUNCTION__, a)

1

没有任何在所有实现中都支持做你想要的事情。我偶尔发现自己处于同样的情况,需要跟踪调用者几个方法,并执行以下操作:

#ifdef TRACKBACK
int foo(int arg1, int arg2, const char * file, int line)
{
    SEND_TO_LOG("foo", file, line);
#else
int foo(int arg1, int arg2)
{
#endif
    ...
    ...

当然,在调用端会有点麻烦,所以你可能需要做一些像这样的事情:

#ifdef TRACKBACK
    #define TRACKING, __FILE__, __LINE__
#else
    #define TRACKING
#endif

然后是调用:

foo(arg1, arg2 TRACKING);  //note the lack of the comma

当一切失效时,它能发挥作用。


0

你可以使用日志。

#define BEGIN_FUNC(X,Y,Z) printf("Function %s Entered at line %d from file %s",X,Z,Y)
#define END_FUNC(X)  printf("Function %s Exited at line %d from file %s",X,Z,Y)

foo()
{
BEGIN_FUNC(__func__,__FILE__,__LINE__);

//Your code here


END_FUNC(__func___FILE__,__LINE__);

}

使用GDB中的“bt”命令,它被称为回溯。


0

如果你需要在运行时知道它,我认为这是不可能的。

如果你需要在调试时知道它,你可以在想要的函数上设置断点,然后使用 GDB(使用 bt 命令)或 Visual Studio 的调试器,检查当前的堆栈跟踪。


0

实际上,这个做起来有点复杂。最好的方法是在调试器上获得一个回溯,或者找到类似于您所用平台的pstack的程序。手动的方法将涉及遍历调用堆栈,并使用调试符号将其转换为文件和行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接