警惕Proguard内联优化导致Crash堆栈信息丢失
背景
最近在处理异常时遇到一个诡异的问题:自己的Demo里面混淆一个类后,打印Crash堆栈时这个类里面的调用点直接失踪了! 下面用测试代码说明。
测试代码
// MainActivity.java public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new Test().fun1(); } } // Test.java public class Test { public void fun1() { fun2(); } public void fun2() { Object o = null; o.getClass(); } }
编译配置如下:
... debug { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } ...
这时候报错信息如下:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference at b.a.a.a.b(Test.java:15) at b.a.a.a.a(Test.java:11) at top.vimerzhao.testinline.MainActivity.onCreate(MainActivity.java:13) at android.app.Activity.performCreate(Activity.java:7458) at android.app.Activity.performCreate(Activity.java:7448)
可见虽然类被混淆了,但是堆栈还是正常的,此时如果关闭 debug
开关:
... debug { debuggable false minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } ...
错误信息如下:
Caused by: java.lang.NullPointerException: throw with null exception at top.vimerzhao.testinline.MainActivity.onCreate(MainActivity.java:3) at android.app.Activity.performCreate(Activity.java:7458) at android.app.Activity.performCreate(Activity.java:7448) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1286)
此时不仅前两次调用的信息丢失了,而且 onCreate
的调用位置也不准。而罪魁祸首就是 proguard-android-optimize.txt
,这个Proguard配置开启了优化,导致一些小的方法调用被 内联,而一开始 debuggable
是默认打开,所以优化没有启动,设置成 false
之后就会出现堆栈信息不准的状况。如文档所述:
By default, ProGuard optimizes all code. It inlines and merges classes and class members, and it optimizes all methods at a bytecode level.
所以,如非明确需要,不要轻易开启Proguard的优化选项,也不要使用自己不了解的混淆配置 (如proguard-android-optimize.txt
,AS默认写在 release
的配置里,有点坑),应该设置 -dontoptimize
。
感悟
一开始只是确认了混淆造成的,懵逼了好久,最后还是通过:
proguard stack trace loss top frame
这句话搜到了类似问题,如何描述遇到的问题也很重要~。