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: ...
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.
Does anyone know how to achieve this?
A call graph (also known as a call multigraph) is a control-flow graph, which represents calling relationships between subroutines in a computer program. Each node represents a procedure and each edge (f, g) indicates that procedure f calls procedure g. Thus, a cycle in the graph indicates recursive procedure calls.
On the bottom right, select the "Call graph" tab. This shows an interactive call graph that correlates to performance metrics in other windows as you click the functions. To export the graph, right click it and select "Export Graph".
The cflow utility analyzes a collection of source files written in C programming language and outputs a graph charting dependencies between various functions.
Function call graphs, or call trees, are a standard tool often found in reverse engineering tools, code browsers, IDEs, and even file editors. They provide fundamental information about the control flow dependencies for the functions you're examining in your tool.
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(); }
Then
$ clang++ -S -emit-llvm main1.cpp -o - | opt -analyze -dot-callgraph $ dot -Tpng -ocallgraph.png callgraph.dot
Yields some shiny picture (there is an "external node", because main
has external linkage and might be called from outside that translation unit too):
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!)
That mystical unnamed function, Node0x884c4e0
, is a placeholder assumed to be called by any function whose definition is not known.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With