启用 Dexguard 时,Crashlytics 的堆栈跟踪将文件名显示为未知来源

Posted

技术标签:

【中文标题】启用 Dexguard 时,Crashlytics 的堆栈跟踪将文件名显示为未知来源【英文标题】:Crashlytics' stacktraces show file name as Unknown Source while Dexguard is enabled 【发布时间】:2018-08-20 06:54:37 【问题描述】:

当我在项目中启用 Dexguard 时,我的 Fabric Crashlytics 崩溃报告出现问题。

我在我的项目中启用了 Dexguard,它运行良好。 然后我按照this page 中的说明进行操作,并添加了上述配置以启用结构对我的堆栈跟踪进行去混淆处理并显示正确的崩溃报告。以下是我在主模块的build.gradle 中应用fabric 和dexguard 插件的方法:

apply plugin: 'com.android.application'
apply plugin: 'dexguard'
apply plugin: 'io.fabric'

这是我的proguard-project.txt 文件中的配置:

# Fabric
#############################################################################
-keepattributes *Annotation*,SourceFile,LineNumberTable
-keep public class * extends java.lang.Exception
-keepresourcexmlelements manifest/application/meta-data@name=io.fabric.ApiKey
-keep class com.crashlytics.**  *; 
-dontwarn com.crashlytics.**
#############################################################################

以下是我在发布版本中使用 proguard-project.txt 的方式:

buildTypes
    debug
        proguardFile getDefaultDexGuardFile('dexguard-debug-shrink.pro')
        proguardFile 'proguard-project.txt'
    
    release
        proguardFile getDefaultDexGuardFile('dexguard-release.pro')
        proguardFile 'proguard-project.txt'
        proguardFile 'dexguard-project.txt'
        if(new File("$projectDir/../local.properties").exists())
            signingConfig signingConfigs.release
        
    

但是当在发布版本中遇到崩溃时,发生崩溃的文件名丢失了,但其他一切都正常工作并且堆栈跟踪几乎可以理解。这是一个示例崩溃报告:

正如您在崩溃报告中看到的,堆栈跟踪中仅缺少文件名。行号、方法名等其他描述完全OK。

虽然使用完整的方法名称,如 ir.X.ui.XMainActivity.throwSomethingUnknown Source 前面的行号,但我可以得出发生错误的文件名,我希望我的堆栈跟踪显示文件名和完全是描述性的。我已经尝试了许多选项和许多试验和错误,但问题仍然存在。

我有什么遗漏吗?我该如何解决这个问题?

我正在使用 Dexguard 的 8.1.0.7 版本、Fabric 插件的 1.21.7 版本和 Crashlytics 库的 2.9.0 版本。

我将 Fabric 插件更新到版本 1.25.1,并将 Crashlytics 库更新到版本 2.9.1,但问题仍然存在。

我将Fabric插件更新为1.25.2,构建工具版本更新为27.0.3,gradle插件版本更新为3.1.0,但问题依然存在。

【问题讨论】:

来自 Fabric 的 Mike。感谢有据可查的问题。我注意到的一件事是您使用的是非常旧的 Gradle 插件的 1.21.7。尝试更新到 1.25.1,如果有任何改变,请告诉我。 感谢 Mike,我将 gradle 插件更新到了 1.25.1 版,将 Crashlytics 库更新到了 2.9.1,但仍然存在问题。更诡异的是,第一行显示:ir.resid.ui.ResidMainActivity.throwSomething (Unknown Source:87469) 请注意,问题始于 XposedBridge - 它是 Xposed 框架(基本上是恶意软件框架)的一部分,它将组件和挂钩扩展到事件中。我看到它的主要用途是免费进行应用内购买或在游戏中作弊。这取决于您自己的看法,但根据我的经验,它会导致许多应用程序出现大量崩溃报告,如果在未受感染的设备上使用这些应用程序并不需要修复。 问题不在于崩溃报告,而是出现在堆栈跟踪中的“未知来源”部分而不是类名,并且它在问题内联的图片中可见。 请不要发布代码图片。 【参考方案1】:

您可以对去混淆的崩溃报告采取以下步骤。 引用自firebase crashlytics documentation

 1. 要保留 Crashlytics 可读崩溃报告所需的信息,请添加 将以下行添加到您的配置文件中:

 -keepattributes *Annotation*
 -keepattributes SourceFile,LineNumberTable
 -keep public class * extends java.lang.Exception

2. 要让 Crashlytics 自动上传 ProGuard 或 DexGuard 映射文件,请从配置文件中删除此行:

 -printmapping mapping.txt

【讨论】:

谢谢,但正如我在问题中解释的那样,我从一开始就完成了这两项工作,结果如问题所示。 @HoneyShah 你能解释一下第 2 点吗?它在哪里自动上传映射文件?【参考方案2】:

Dexguard 加密代码并混淆文件和崩溃报告

根据问题,所有正确定义的东西都可以启用崩溃报告,没有什么可以改变的。在我的项目场景中也一样,使用带有 Fabric 的 Dexguard。

在项目中集成 Dexguard 时,Dexguard 会加密代码并混淆文件和其他库的崩溃报告。

但是,如果您还使用 google Firebase Crashlytics,则无法在 Firebase 控制台中看到日志。您将获得 Fabric 提供的相同报告。

这些 Crashlytics 将在 Google 控制台中提供崩溃报告。您可以在 Android Vitals 的 ANR 和崩溃部分中查看崩溃日志。

该部分显示从用户已选择自动共享使用情况和诊断数据的 Android 设备收集的所有 ANR 和崩溃。只有未混淆的堆栈跟踪才能检测到异常。

谷歌解释了这个部分https://support.google.com/googleplay/android-developer/answer/6083203

【讨论】:

【参考方案3】:

按照以下步骤在 Crashlytics 中正确获取堆栈跟踪

    登录您的 Play 管理中心。 选择一个应用程序。 在左侧菜单中,点击 Android Vitals > 反混淆文件。 在您的应用版本旁边,点击上传。 为您的应用版本上传 ProGuard 映射文件。

检查此链接: https://support.google.com/googleplay/android-developer/answer/6295281?hl=en

【讨论】:

以上是关于启用 Dexguard 时,Crashlytics 的堆栈跟踪将文件名显示为未知来源的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 应用程序运行时启用/禁用 Crashlytics

在运行时禁用/启用 Firebase Crashlytics

Firebase Crashlytics 在手动启用时不报告崩溃

如何在 Flutter 中启用/禁用 Firebase Crashlytics

使用 dexguard 加密时,在运行时加载本机库需要更多时间

使用 firebase-crashlytics-gradle 的 Crashlytics 上传失败