Search code examples
functioncallstackpycparsercall-hierarchy

pycparser retrieving function call hierarchy


is there a way to get the function call stack with pycparser ?

for example if i have code like this:

static int Func_1(int *val)
{
    unsigned int data_1 = 0;
    int result;

    result = Func_2(val,
                    data_1
                   );

    result = Func_3(val,
                    result
                   );                 

    return result;
}

so with FuncDefVisitor i can retrieve Func_1 and with FuncCallVisitor i could retrieve Func_2 and Func_3

but how can i retrieve the information that e.g. Func_2 is called from within Func_1 ?


Solution

  • You can write a visitor that finds FuncDef nodes and runs another visitor on them that finds all FuncCall nodes. For example:

    class FuncDefVisitor(c_ast.NodeVisitor):
        def visit_FuncDef(self, node):
            # Here node is a FuncDef node for the function definition.
            v = FuncCallVisitor()
            v.visit(node)
    
    class FuncCallVisitor(c_ast.NodeVisitor):
        def visit_FuncCall(self, node):
            # do something
    

    In visit_FuncDef, we create a new call visitor and run it on node, which means it only runs within the AST node for the function definition. It will find Func_2 and Func_3 in your code, but not func calls in other functions.


    That said, note that you will only get the static call graph from this. In C functions can call others via function pointers and that's not something you can know statically in the general case.