如何为C ++代码生成调用图 [英] How to Generate a calling graph for C++ code

查看:204
本文介绍了如何为C ++代码生成调用图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试生成调用图,通过该图可以找到击中特定函数的所有可能执行路径(因此,我不必手动找出所有路径,因为有许多路径可以导致此功能)。例如:

I'm trying to generate calling graph with which to find out all the possible execution paths that are hitting a particular function (so that I don't have to figure out all the paths manually, as there are many paths that lead to this function). For instance:

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。

I have tried Codeviz and Doxygen, somehow both results show nothing but callees of target function, D. In my case, D is a member function of a class whose object will be wrapped within a smart pointer. Clients will always obtain the smart pointer object through a factory in order to invoke 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

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

Yields some shiny picture (there is an "external node", because main has external linkage and might be called from outside that translation unit too):

您可能希望使用 c ++ filt 对其进行后处理,以便获得所涉及的函数和类的完整名称。像下面这样

You may want to postprocess this with c++filt, so that you can get the unmangled names of the functions and classes involved. Like in the following

#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    

产生这种美感(哦,天哪,启用的优化太大!)

Yields this beauty (oh my, the size without optimizations turned on was too big!)

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

That mystical unnamed function, Node0x884c4e0, is a placeholder assumed to be called by any function whose definition is not known.

这篇关于如何为C ++代码生成调用图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆