C++ Clang-获取实际函数指针声明回溯

C++ Clang-获取实际函数指针声明回溯,c++,c,clang,abstract-syntax-tree,static-analysis,C++,C,Clang,Abstract Syntax Tree,Static Analysis,我是clang的新手,正在研究C/C++代码的解析。我给出下面的代码作为输入,但无法使用clang找到实际的函数名 #包括 typedef int(*ExampleCallback)(void*某物,int状态); //这将在一个单独的文件中 void moduleAPI_start(例如某物上的回调); int moduleAPI_run(); 静态示例回调存储回调; void moduleAPI_start(例如某项内容的回调) { storedCallback=onSomething; }

我是clang的新手,正在研究C/C++代码的解析。我给出下面的代码作为输入,但无法使用clang找到实际的函数名

#包括
typedef int(*ExampleCallback)(void*某物,int状态);
//这将在一个单独的文件中
void moduleAPI_start(例如某物上的回调);
int moduleAPI_run();
静态示例回调存储回调;
void moduleAPI_start(例如某项内容的回调)
{
storedCallback=onSomething;
}
int moduleAPI_run()
{
返回storedCallback(NULL,'0');
}
//回调实现示例回调签名
int myCallback(void*something,int status)
{
返回状态;
}
内部主(空)
{
模块PI_启动(myCallback);
printf(“%d\n”,moduleAPI_run());
返回0;
}
我的问题是,我怎么知道,每当我调用
moduleAPI\u run
,它实际上是通过
storedCallback
调用
myCallback

简而言之,我如何获得下面的序列,以便使用
myCallback
进行进一步处理。
storedCallback->onSomething->myCallback

注: 我已经通过了这个帖子,但无法得到明确的解决方案

编辑: 在更大的方面,我们试图解决函数指针标识问题。我们使用相同的签名编写了不同的函数,它们有不同的用途(在运行时将适当的函数注册为回调函数)。有了这个铿锵分析工具,我们希望可视化实际调用的函数

我的问题是,我怎么知道,每当我调用moduleAPI_run时,它实际上是通过storedCallback调用myCallback

这不是解析器或抽象语法树能够回答的问题

回调函数不是固定函数。它是一个变量,用于保存指向可分配和重新分配的函数的指针。因此,它可以在程序运行过程中携带许多不同的值。对于能够在不运行程序的情况下回答相关问题的软件工具,称为(问题中添加了标记):

您可能会看到这个简单的单文件示例,并且您自己会看到storedCallback被分配到一个位置……并且这个位置只执行一次,没有任何路径可以避免它。但是,由于停机问题,分析工具实际上不可能告诉您任意输入程序在运行时的行为,如果您还没有意识到这一点:

我不知道您希望涵盖哪类查询,仅从您的一个示例。但我要说的是,静态分析工具往往有相当特殊的用途——主要用于查找bug。许多是商业性的,价格昂贵


更新:它本身就是叮当声(显然是一个非常好的声音)。但乍一看,我没有看到它的任何“API”,只有如何使用该工具。因此,如果您想要访问它用来生成报告的信息,您可能必须破解代码并进行修改。但是其他人可能比我更清楚。

谢谢你的清晰描述。我编辑这个问题是为了更好地理解我试图解决的问题。是的,我正在尝试进行全面的静态分析,但我认为这应该是可能的,在最坏的情况下,通过将所有函数指针存储在表中并跟踪所有函数指针。另一种方法可能是使用
sourcelocation
查找实际函数。是吗?@SaumyaSuhagiya我没有用叮当来做这个(我老了,它是新的)。所以我不知道具体的API。但是,当你研究这类问题时,你可能应该做的是制定一些你期望它能够检测到的场景(无论你检测到什么),然后是一些你认为它很难检测到的场景。然后具体地向自己解释是什么区别了简单的案例和太难的案例。如果你能非常清楚地知道这一点,你就有机会制作出一个也能知道这一点的工具。这就是这些东西的工作原理。