c++ - 如何为 C++ 代码生成调用图

标签 c++ static-analysis call-graph

我正在尝试生成调用图,用它找出所有可能的执行路径,这些路径是命中特定函数的(这样我就不必手动找出所有路径,因为有很多路径可以引导到这个功能)。例如:

path 1: A -> B -> C -> D  
path 2: A -> B -> X -> Y -> D  
path 3: A -> G -> M -> N -> O -> P -> S -> D  
...  
path n: ...

我尝试过 Codeviz 和 Doxygen,不知何故,这两个结果都只显示目标函数 D 的被调用者。在我的例子中,D 是一个类的成员函数,其对象将被包装在一个智能指针中。客户端将始终通过工厂获取智能指针对象,以便调用 D。

有谁知道如何做到这一点?

最佳答案

static void D() { }
static void Y() { D(); }
static void X() { Y(); }
static void C() { D(); X(); }
static void B() { C(); }
static void S() { D(); }
static void P() { S(); }
static void O() { P(); }
static void N() { O(); }
static void M() { N(); }
static void G() { M(); }
static void A() { B(); G(); }

int main() {
  A();
}

然后

$ clang++ -S -emit-llvm main1.cpp -o - | opt -analyze -dot-callgraph
$ dot -Tpng -ocallgraph.png callgraph.dot

产生一些 Shiny 的图片(有一个“外部节点”,因为 main 具有外部链接,也可能从该翻译单元外部调用):

Callgraph

您可能希望使用 c++filt 对其进行后处理,以便获得所涉及的函数和类的未损坏名称。如下所示

#include <vector>

struct A { 
  A(int);
  void f(); // not defined, prevents inlining it!
};

int main() {
  std::vector<A> v;
  v.push_back(42);
  v[0].f();
}

$ clang++ -S -emit-llvm main1.cpp -o - |
   opt -analyze -std-link-opts -dot-callgraph
$ cat callgraph.dot | 
   c++filt | 
   sed 's,>,\\>,g; s,-\\>,->,g; s,<,\\<,g' | 
   gawk '/external node/{id=$1} $1 != id' | 
   dot -Tpng -ocallgraph.png    

产生这种美感(天哪,没有开启优化的尺寸太大了!)

Beauty

那个神秘的未命名函数 Node0x884c4e0 是一个占位符,假定由任何定义未知的函数调用。

关于c++ - 如何为 C++ 代码生成调用图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5373714/

相关文章:

c++ - 从 char 到 String* C++ 的无效转换

.net - 如何开始使用ndepend?

java - 简单、普遍、基于代码分析器的 Java 问题

python - django 中的 PyCallGraph 中间件

c# - 代码流可视化软件

c - 调用图如何解析函数指针?

c++ - 在 gdb 中打印流值 - C++

c++ - -> 运算符不允许在 C++ 中静态分配的对象上使用?

c++ - "Expression must be a modifiable LValue"

C++ 在 64 位变量中存储 32 位值时发出警告