如何使用Android开发者控制台崩溃报告查找崩溃源?

4
自从我在Google Play商店发布了新版本的应用程序后,我在Android开发者控制台中收到了崩溃报告。
我在发布新版本后立即上传了ProGuard的“mappings.txt”。因此,所有日志都未被混淆(所有类名和方法都以明文形式出现)。但是我仍然不确定如何阅读它们。 存在三个主要问题:
  1. 报告仅显示崩溃方法,但没有行号。因此,我不知道方法的哪一部分导致了崩溃。
  2. 一些崩溃报告显示使用OR的不同方法。这是什么意思?
  3. 并非所有报告都被解密。有些仍然显示匿名类和方法名称。
示例:
// Crash Log with is NOT obfuscated
Caused by: java.lang.NullPointerException: 
1:  at com.example.MyApp.Path.To.Package.MyClass.myMethod1 (MyClass.java)  // <-- No Line Numbers...
    or                     .myMethod2 (MyClass.java)    // <-- WHAT does this OR mean???
    or                     .myMethod3 (MyClass.java)
2:  at com.example.MyApp.Path.To.Package.MyClass.onCreateView (MyClass.java)
3:  at android.support.v4.app.Fragment.performCreateView (Fragment.java)
4:  at android.support.v4.app.FragmentManagerImpl.access$500 (FragmentManagerImpl.java)
    or                     .access$600 (FragmentManagerImpl.java)
    or                     .addFragment (FragmentManagerImpl.java)
    or                     .allocBackStackIndex (FragmentManagerImpl.java)
    or                     .animateRemoveFragment (FragmentManagerImpl.java)
    ...

5:  at android.support.v4.app.FragmentManagerImpl.access$500 (FragmentManagerImpl.java)
...


// Other crash seems to show the same problem but is still obfuscated
Caused by: java.lang.NullPointerException: 
1:  at com.example.MyApp.Path.To.Package.MyClass.a (MyClass.java:89)  // <-- Line numbers available here...
2:  at com.example.MyApp.Path.To.Package.MyClass.b (MyClass.java:40)
3:  at android.support.v4.app.Fragment.performCreateView (Fragment.java)
... // Same call stack as above  

问题:

  • 为什么有些日志已被解密,而其他一些日志(似乎显示相同的错误)则没有?两个日志都是在上传映射文件后创建的。旧版本的日志没有映射文件,会显示明确的“日志已被混淆”消息。
  • 调用堆栈中的OR语句的意义是什么?这是否意味着异常发生在这些方法中的每一个(这应该如何实现)?
  • 为什么解密后的日志中没有行号?给定的方法非常长,并且没有任何进一步的信息,我不知道到底是什么导致了问题。混淆后的行号似乎指向与实际代码无关的随机行。

所以主要问题是:

如何使用日志信息找到崩溃的源头?

2个回答

4
你需要在Proguard配置中添加以下选项:

你需要在你的Proguard配置中添加以下选项:

# This option forces Proguard to use different obfuscated names
# for different members. It avoids the 'or' stack traces.
-useuniqueclassmembernames

# These options produce useful stacktraces preserving line numbers
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable

没有使用-useuniqueclassmembernames选项,Proguard可以为同一类中的不同方法分配相同的混淆名称(您可以在mapping.txt文件中看到)。这就是为什么堆栈跟踪知道错误发生在A方法B方法中,但并不知道确切的方法。
使用-useuniqueclassmembernames选项,所有混淆名称都将不同,就不会再有堆栈跟踪了。更多信息请参见此处
除此之外,Proguard不保留关于行号的信息,除非我们使用-renamesourcefileattribute-keepattributes选项,如上所示。更多信息请参见此处
这些选项会稍微增加您的apk大小,但完全值得。这使我节省了许多分析我的堆栈跟踪的头痛。

0
最好使用 Fabric。它将提供崩溃报告以及行号。

1
虽然我可能会在未来的版本中尝试,但这并不是当前问题的真正解决方案,对吧? - Andrei Herford

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接