static analysis - How do you include subroutine calls in a control flow graph? -
i idea of control flow graph; involves nodes basic blocks (sequences of operations occur), connected edges represent jumps.
but how represent subroutine call?
if have 2 functions this:
int tweedledee(void) { int x = 16; return x + do_something(); } int tweedledum(int n) { if (n < 0) return n; else return n + do_something(); }
with both functions calling do_something()
, need way allow jump block in tweedledee
do_something
, jump tweedledee
, , jump block in tweedledum
do_something
, tweedledum
, there's never jump tweedledee
do_something
, tweedledum
. (or tweedledum
→ do_something
→ tweedledee
) seems plain directed graph wouldn't suffice define these relationships... maybe i'm missing something.
procedures make cfgs , static analysis in general quite complicated. there different approaches representing routine calls in control flow graphs.
one first , common solution create cfg each routine, , split "call nodes" (the basic block corresponding "call do_something()" in tweedledee example) 2 nodes, actual call block c , block r writing return value.
an edge (normally of special type) inserted between c , initial block of routine being called, , 1 between end block of routine being called , r. simple example:
void foo() { int x = bar(); } int bar() { return 1; }
might transformed to:
[init::foo] ==> [call bar()] [x = retval(bar())] ==> [end::foo] || /\ \/ || [init::bar] ==> [ret = 1 (end::bar)]
if there call bar(), e.g. routine
void foo2() { int y = bar(); }
then following graph might result:
[init::foo] ==> [call bar()] [x = retval(bar())] ==> [end::foo] || /\ \/ || [init::bar] ==> [ret = 1 (end::bar)] /\ || || \/ [init::foo2]==> [call bar()] [x = retval(bar())] ==> [end::foo2]
the problem here: there paths in graph (e.g. init::foo ==> call bar() ==> init::bar ==> ret = 1 ==> x = retval(bar()) ==> end::foo2) make no sense in program. might mean wondering whether "plain directed graph" suffices. there different approaches problem, e.g.: make copies of routine (here bar) each invocation of it. helps if there no real recursion, , expensive in general. static analysis useful "overapproximate" number of paths using fixed number of such copies.
the slides interprocedural analysis lecture notes (stephen chong) seem introduction. there quite books constructing such graphs, e.g. principles of program analysis nielson et al.
Comments
Post a Comment