繁体   English   中英

针对特定函数递归搜索C ++调用图[关闭]

[英]Search C++ call graph recursively for specific functions [closed]

我有一个大型的C / C ++项目,我想分析函数子集的调用图。

Ex之类的东西:

void A_Func1(){}
void A_Func2(){}

void IntermediateFunc()
{
  A_Func1();
  A_Func2();
}

void StartFunc()
{
  IntermediateFunc();
}

我想从StartFunc直接或间接调用以“A_”开头的函数列表。

我的第一个想法是使用具有CallGraph动作的clang,但文档很稀疏,我慢慢得出结论,我不能按我想要的方式使用它。

所以问题是:如何使用clangs工具库来执行生成这样的列表?

Clang为它的调用图输出 .dot文件。 这是一种非常简单的格式 ,可以使用像PEG.js这样的工具轻松解析。 当您收到DAG调用时,您可以运行一个简单的DFS ,它标记所有带有A_前缀的节点。

另一种解决方案是使用Clang的代码库自己完成 正如您已经发现的那样,这是一个非常复杂的方法。

此外,您应该知道clang会生成一个乐观的调用图,即“可以调用哪些函数”。 例如, void f() { if (g()) h(); } void f() { if (g()) h(); } “调用” gh ,即使bool g() { return false; } bool g() { return false; }

可能,你正在寻找“从那里真正调用的所有功能”。 然后,您需要运行一些分析器来收集调用堆栈。

最好的解决方案是为某些IDE制作调试器脚本 ,但我不知道任何具有此类选项的C ++ IDE。

我发现polkovnikov.ph的答案是更干净的方法。 我不知道.dot是如此简单,我肯定会用这种方式解决类似的问题。

不幸的是,我还必须分析其他组件的接口是C函数的软件组件 - 这些组件通过extern关键字使用。 由于clang :: CallGraph中的内部过滤器( includeInGraph (const Decl *D) Decl includeInGraph (const Decl *D) ),它们不会出现在clang调用图中。

所以我不得不复制clang::CallGraph ,删除限制并在clang::ASTConsumer使用它:

virtual void HandleTranslationUnit(clang::ASTContext &Context) {
    _visitor.TraverseDecl(Context.getTranslationUnitDecl());
    for (auto root : _visitor)
    {
        if (const clang::NamedDecl* namedDecl = llvm::dyn_cast_or_null<clang::NamedDecl>(root.first))
            if(namedDecl->getIdentifier() != nullptr && namedDecl->getIdentifier()->getName().startswith("Start"))
            {
                llvm::outs() << "StartFunc: " << namedDecl->getName() << "\n";
                printAFunctions(root.second);
            }
    }
}
void printAFunctions(const clang::CallGraphNode* node)
{
    if (node != nullptr)
    {
        if (const clang::NamedDecl* namedDecl = llvm::dyn_cast_or_null<clang::NamedDecl>(node->getDecl()))
        {
            if (namedDecl->getName().startswith("A_"))
            {
                llvm::outs() << "A_ call: " << namedDecl->getName() << "\n";
            }
        }
        for (auto subNode : *node)
        {
            printAFunctions(subNode);
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM