【问题标题】:How do you include subroutine calls in a control flow graph?如何在控制流图中包含子例程调用?
【发布时间】:2015-07-08 23:11:23
【问题描述】:

我想到了control flow graph;它涉及的节点是基本块(总是发生的操作序列),由代表跳跃的边连接。

但是你如何表示一个子程序调用呢?

如果我有两个这样的功能:

int tweedledee(void)
{
    int x = 16;
    return x + do_something();
}

int tweedledum(int n)
{
    if (n < 0)
       return n;
    else
       return n + do_something();
}

两个函数都调用do_something(),那么我需要一种方法来允许从tweedledee 中的块跳转到do_something,然后再跳转回tweedledee,并从@987654327 中的块跳转@ 到 do_something 然后返回到 tweedledum,但从来没有从 tweedledeedo_something 再到 tweedledum 的跳转。 (或tweedledumdo_somethingtweedledee)所以看起来一个普通的有向图不足以定义这些关系......也许我错过了一些东西。

【问题讨论】:

    标签: static-analysis control-flow-graph


    【解决方案1】:

    程序使 CFG 和静态分析通常相当复杂。 在控制流图中表示例程调用有不同的方法。

    第一个也是常见的解决方案是为每个例程创建一个CFG,并将“调用节点”(例如tweedledee中与“CALL do_something()”对应的基本块)拆分为两个节点,实际调用块C 和一个用于写入返回值的块 R。

    在 C 和被调用例程的初始块之间插入一条边(通常是特殊类型的),在被调用例程的结束块和 R 之间插入另一条。一个简单的例子:

    void foo() { int x = bar(); }
    int bar() { return 1; }
    

    可能会转化为:

    [init::foo] ==> [CALL bar()]  [x = RETVAL(bar())] ==> [end::foo]
                         ||            /\
                         \/            ||
                    [init::bar] ==> [ret = 1 (end::bar)]
    

    如果有另一个对 bar() 的调用,例如例行公事

    void foo2() { int y = bar(); }
    

    那么结果可能如下图:

     [init::foo] ==> [CALL bar()]  [x = RETVAL(bar())] ==> [end::foo]
                         ||            /\
                         \/            ||
                    [init::bar] ==> [ret = 1 (end::bar)]
                         /\            ||
                         ||            \/
     [init::foo2]==> [CALL bar()]  [x = RETVAL(bar())] ==> [end::foo2]
    

    这里的问题:这个图中现在有路径(例如 init::foo ==> CALL bar() ==> init::bar ==> ret = 1 ==> x = RETVAL(bar() ) ==> end::foo2) 这在程序中没有意义。这就是您想知道“普通有向图”是否足够的意思。这个问题有不同的方法,例如:为每次调用复制一个例程(这里是条形图)。这仅在没有真正递归的情况下才有帮助,并且通常很昂贵。对于静态分析,仅使用固定数量的此类副本来“过度近似”路径数量通常很有用。

    幻灯片Interprocedural Analysis Lecture Notes (Stephen Chong) 似乎是一个很好的介绍。 还有一些关于构建此类图表的好书,例如Principles of Program Analysis Nielson 等人。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-09
      • 1970-01-01
      • 2021-01-16
      相关资源
      最近更新 更多