Uncaught translation error: com.android.dx.cf.code.SimException: stack: overflow 异常
接入bytex.method_call_opt之后,打包编译失败,错误信息如下
[2021-05-12T14:27:32.116Z] Uncaught translation error: com.android.dx.cf.code.SimException: stack: overflow
[2021-05-12T14:27:32.116Z] 1 error; aborting
[2021-05-12T14:27:32.116Z] :app:transformClassesWithDexForMarketRelease FAILED
[2021-05-12T14:27:32.116Z]
[2021-05-12T14:27:32.116Z] FAILURE: Build failed with an exception.
[2021-05-12T14:27:32.116Z]
[2021-05-12T14:27:32.116Z] * What went wrong:
[2021-05-12T14:27:32.116Z] Execution failed for task ':app:transformClassesWithDexForMarketRelease'.
[2021-05-12T14:27:32.116Z] > com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: com.android.ide.common.process.ProcessException: Return code 1 for dex process
[2021-05-12T14:27:32.116Z]
[2021-05-12T14:27:32.116Z] * Try:
[2021-05-12T14:27:32.116Z] Run with --info or --debug option to get more log output. Run with --scan to get full insights.
[2021-05-12T14:27:32.116Z]
[2021-05-12T14:27:32.116Z] * Exception is:
[2021-05-12T14:27:32.116Z] org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:transformClassesWithDexForMarketRelease'.
[2021-05-12T14:27:32.116Z] at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:100)
[2021-05-12T14:27:32.116Z] at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:70)
[2021-05-12T14:27:32.116Z] at org.gradle.api.internal.tasks.execution.OutputDirectoryCreatingTaskExecuter.execute(OutputDirectoryCreatingTaskExecuter.java:51)
[2021-05-12T14:27:32.116Z] at org.gradle.api.internal.tasks.execution.SkipCachedTaskExecuter.execute(SkipCachedTaskExecuter.java:108)
[2021-05-12T14:27:32.116Z] at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:62)
[2021-05-12T14:27:32.116Z] at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:54)
[2021-05-12T14:27:32.116Z] at org.gradle.api.internal.tasks.execution.ResolveBuildCacheKeyExecuter.execute(ResolveBuildCacheKeyExecuter.java:61)
[2021-05-12T14:27:32.116Z] at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:60)
[2021-05-12T14:27:32.116Z] at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesT
我们项目里面有用到Robust热修复组件,ThinkR,resGuard,不知道是否是和其它插桩有冲突导致
即使将methodList 配置为空也会编译失败
apply plugin: 'bytex.method_call_opt'
method_call_opt {
enable true //建议开发模式关闭
enableInDebug false
logLevel "DEBUG"
//是否在log中显示删除方法调用指令后的方法指令,一般调试时使用
showAfterOptInsLog false
//需要删除的方法配置
methodList = [
]
onlyCheckList = [
]
whiteList = [
//"com/facebook/stetho*",
]
}
gradle错误提示中显示
Caused by: com.android.builder.dexing.DexArchiveBuilderException: Error while dexing com/alibaba/sdk/android/utils/c.class
这个类位于com.aliyun.ams:alicloud-android-utils:1.1.3包中
会不会和HookProguard有关?
DexArchiveBuilderException这个异常还有其他报错信息吗?怀疑是字节码修改有问题导致的。 bytex如果报错,可以在app/build/ByteX/xxxx/bytex_log.txt看到一些报错堆栈,这个也可以贴出来参考一下。
对比了jar包中的和transform后有问题的com/alibaba/sdk/android/utils/c.class
唯一的区别是正常的MAXSTACK为3,有问题时MAXSTACK为2,为什么MAXSTACK会变,还在排查中,看看大佬有没有什么建议或思路
Matrix也有类似的问题,并且有个fix,https://github.com/Tencent/matrix/pull/201/files
ByteX都是默认ComputeMax的,问一下,你接入了哪些插件?同时关掉bytex的就能好吗?
我接入了bytex.method_call_opt组件,同时关掉bytex的就好了。目前判断可能是ASM的bug,手工提取com.aliyun.ams:alicloud-android-utils:1.1.3包中的com.alibaba.sdk.android.utils.c类,编写如下测试代码,只是简单的读取com.alibaba.sdk.android.utils.c类然后输出,没做任何处理,输出的 c.b函数的MAXSTACK从3变成了2
public class TestAsm {
public static void main(String[] args) throws IOException {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
FileInputStream fileInputStream=new FileInputStream(new File("D:\\temp\\c.class"));
ClassReader classReader = new ClassReader(fileInputStream);
classReader.accept(cw,0);
byte[] bytes = cw.toByteArray();
fileInputStream.close();
FileOutputStream fileOutputStream=new FileOutputStream("D:\\temp\\c_out.class");
fileOutputStream.write(bytes);
fileOutputStream.close();
}
}
如果改成
ClassWriter cw = new ClassWriter(0);
就没问题
下面这个是class文件 c.zip
com.alibaba.sdk.android.utils.c类中的 c.b函数反编译如下
private boolean b() {
boolean var1 = true;
try {
Class var2 = Class.forName("com.ut.mini.UTAnalytics");
} catch (Throwable var3) {
Log.e("Utils:DataTracker", "ut not exist", var3);
var1 = false;
}
return var1;
}
针对白名单中的class,是否可以不经过ASM,直接输出fileData.getBytes()的数据?看目前ClassFileTransformer#handle的逻辑,即使是白名单中的class,也会经过ASM过一遍