WeMobileDev / article

articles by WeChat Mobile Development Team
4.33k stars 654 forks source link

请教《ART下的方法内联策略及其对Android热修复方案的影响分析》中的关于判断新旧DexCache的问题 #17

Open VERFLY opened 7 years ago

VERFLY commented 7 years ago

最近我的Android N手机上京东App偶现crash,通过log发现京东App使用了tinker热修复方案,这个crash和 ART下的方法内联策略及其对Android热修复方案的影响分析中描述的第二种crash相似:

oldDex里的typeid >= newDex的DexCache的长度 被SIGABORT干掉,Abort Message为数组下标越界

但是我对判断新旧DexCache时存在一些疑惑,已知条件:

f.sC内联了h.getExternalStorageDirectory (12288+1292)/4 = 3395,对应compatible.util.h的typeid (12288+1120) / 4 = 3352,对应compatible.d.p的typeid

按照我对文章的理解,因为3395对应的类为null或者没有初始化,然后跳转到0x036e40ea这个地方去执行,按照类的加载流程加载了新的类,并且形成了新的DexCache,继而3352作为索引的DexCache是新的DexCache。但是由于内联的原因,3352这个索引对应的是旧的DexCache,因此会出现问题。

我的疑惑就在于这一系列动作的触发条件,那就是只有3395对应的类为null或者没有初始化才会跳转去执行后面的流程。3395对应的是旧的DexCache,按照我的理解,它应该既不为NULL也应该初始化了才对,非常的不理解这点,盼望解答一下。

1480595723104

shwenzhang commented 7 years ago

这里关键就是某个类内联了一个在patch里面的类,用了旧的typeid去新的dex那边查找了

VERFLY commented 7 years ago

感谢回复。你讲的这点我理解,我不理解的是jmp 0x036e40ea这个跳转,这个跳转需要targetClass == null 或者是targetClass没有初始化,但是它既然在OldDexCache中存在,我的理解这个跳转应该不成立才对。不知道哪里理解错了?