天人合一之毕设——实践阶段2——代码局部插桩

xiaoxiao2021-02-28  59

这就开始实现前面说的局部对if-else分支、循环块的局部插桩了

其实思想很简单,只不过大家书写代码的方式千差万别,所以要考虑的情况还是蛮多的

一、if-else分支(桩=输出当前行)

1. if/else/else if(...)   ...

2. if/else/else if(...)  {...}

1、2插桩需变成:if/else/else if(...)  { 桩  ...}

3.if/else/else if(...){

    ....    (在此处插桩即可)

}

4.if/else/else if(...)

{

    ...     (在此处插桩即可)

}

5.if/else/else if(...)

      ...

6.if/else/else if(...)

   {....}

5、6插桩需变成:

    if/else/else if(...)

       {  桩  ....}

插桩总共需要考虑这6种情形,但是代码中有一些可以合并的

、循环结构

1.for/while结构

(1)for/while(...)   ...

(2)for/while(...)  {...}

(1)/(2)插桩变成:

int cnt;

for/while(...)  {cnt++;  ... }

printf("%d\n",cnt);   (相当于要插三句桩,比if-else复杂一些)

(3)-(6)和上面相似,不一一列出来

2.do while结构

(1) do{

    ...

   }while(...);

(2) do

{

...

}while(...);

(3)do

{...

}

while();

这种情况注意下:不是在遇到}后插输出语句,而是在while语句后

do-while结构好的一点就是应该不会出现那种单行的无{}语句,遇到do之后只需要在后面找有while()的一行就可

三、多重循环

一开始我只考虑了前两块情况,没有注意到可能出现多重循环的可能,譬如:

int cnt1 = 0;

for(int i=0; i<n; i++){

    cnt1++;

    int cnt2 = 0;

    while(a){

       cnt2++;

    }

    output1(cnt2);

}

    output2(cnt1);

  这种情况要插入两个输出语句的桩,但是在检验循环语句的时候,先查到for循环,则output2会先被赋值为output,然后output1会覆盖output2的值成为output,所以应该输出output2的地方就输出不了,插桩失败。

  后来我的解决方式是在repeat_flag的基础上又设置了一个double_repeat_flag

  当double_repeat_flag为true时,重新设置一个output2,此时不会被覆盖,能正确输出

  不足是只能解决双重循环的问题。其实实现三重循环思路应该也差不多,但是有点麻烦,我不太愿意写了..先这样吧

补充:在实现后续操作过程中,发现双重循环的这种插桩方式对cnt2的总次数很难以利用和统计,故需要对以上操作进行更改

int cnt1 = 0;

int sum = 0;

for(int i=0; i<n; i++){

    cnt1++;

    int cnt2 = 0;

    while(a){

       sum+=1;

    }

}

     output1(sum); //放在外面比较好,不然会输出多次,这个暂时还没实现

    output2(cnt1);

   

  一想到在过一遍代码时还要考虑这么多复杂的情况就头大,事在人为,加油吧!


转载请注明原文地址: https://www.6miu.com/read-2622181.html

最新回复(0)