connglli / ELEGANT

ELEGANT - a tool to Effectively LocatE fraGmentAtion-iNduced compaTibility issues.
MIT License
3 stars 0 forks source link

weekly report: 2018.01.17-2018.01.23 #13

Closed connglli closed 6 years ago

connglli commented 6 years ago

周报

2018.01.17 ~ 2018.01.23

停了近一个月的 FicFinder,这周又开始工作了!先回顾一下上次 FicFinder 周报的内容:

回顾

上次对 AnkiDroid 几个有问题(buggy)以及问题被解决后(fixed)提交版本对进行了编译,并根据编译和目前 FicFinder 的测试结果给出了几种问题解决方式(bug fixing manner):

  1. direct-checking
  2. method-checking
  3. static-checking
  4. reflection-fixing
  5. polymorphism-fixing
  6. workaround-fixing

上次提到,针对以上 1-4 目前的 FicFinder 已经可以解决(针对目前的测试,还需要更多的测试来巩固和加强),但针对 4、5 仍无法完成,并且给出了针对 4、5 的简单的解决方案描述,本周针对上次的描述进行了实现,同时对遇到的新问题进行阐述。

relfection-fixing

上周提到,针对这种形式的解决开发者(可能会以如下的方式解决):

// 开发者知道 getActionBar 可能会出现问题,但不知道是哪个版本会出现问题,直接利用运行时环境信息查看是否可用是一种简便(但略微牺牲性能)的方式。
Method getActionBar = Activity.class.getMethod("getActionBar");
if (null != getActionBar) { // 可用!
  ActionBar actionBar = (ActionBar) getActionBar.invoke(this);
  actionBar.setTitle("This is title");
}

因此针对这种形式我们的解决方案如下:

function ReflectionFixing(acpair) do
  collect all call sites of "<java.lang.Class: java.lang.reflect.Method getMethod(java.lang.String,java.lang.Class[])>" save them to S
  for each call site s in S do
    if (s gets the handler of acpair.api) {
      r = s.return value
      for each invoking point p on r do
        if (does not check non-nullness of r before p) then
          report p
        fi
      done
    }
  done
done

解释一下:

对代码中所有对 <java.lang.Class: java.lang.reflect.Method getMethod(java.lang.String,java.lang.Class[])> 的 call site 进行查找,并存在集合 S 中(第 2 行)。对于 S 中的每一处调用 s (第 3 行),如果 s 是对 acpair.api 的调用(第 4 行),对 s 的返回值 r 进行保存,并检测对 r 之后的所有调用点 p(第 6 行),如果 p 之前没有对 r 非空的判断(第 7 行),认为 s 没解决掉这个 FIC bug,并对这处进行报告。否则,继续进行遍历 S

针对这部分的代码位于 src/com/example/ficfinder/reflectionfinder/RFinder.java 中。

polymorphis-fixing

上周提到,针对这种形式的解决开发者(可能会以如下的方式解决):

// 多态引入
public interface Compact {
    public void invalidateOptionsMenu(Activity activity);
}

public class CompactV3 implements Compact {
    @Override
  public void invalidateOptionsMenu(Activity activity) {
    // 构造一个空方法
  }
}

public class CompactV11 implements Compact {
    @Override
    public void invalidateOptionsMenu(Activity activity) {
        activity.invalidateOptionsMenu();
    }
}

// 使用的时候假设其一直存在
Compact compact;

if (getApiLevel() > 11) {
  compact = new CompactV11();
} else {
  compact = new CompactV3();
}

compact.invalidateOptionsMenu(this);

针对这样的解决,我们仍然沿用以前的方式,并对以前的代码进行了部分修正,从而完成这部分的检测。

问题

利用目前的 FicFinder 来对上周提到的编译版本进行测试,除了 invalidateOptionsMenu 这个例子外其他都三个都已通过(buggy 版本能够检测到,fixed 版本检测不到),现在来阐述下一些目前能想到的但仍待解决的问题:

其他

另外,本周还对代码进行了部分重构,现在结构如下:

  1. com.example.ficfinder.finder.reflectionfinder 中的 RFinder 主要完成对 reflection-fixing 的工作,plainfinder 中的 PFinder 完成其他工作

  2. RFinderPFinder 都是 AbstractFinder 的实现。一个 AbstractFinder 包括:

    detection/validation/generation 三个部分,(顾名思义,)分别完成对一个 api-context pair 的检测与构建、剪枝、生成 issue 三方面的工作。

代码仍然在 call-site-tree 分支。