我正在使用Bugfender(这很了不起),用于一些远程错误,信息和崩溃日志记录。我想知道发生崩溃,错误或事件的文件和行号,因此对于每个日志,我都会检查stacktrace并将其包括在日志中。这是在调试模式下运行时的样子,无保护,且未发布:
在发行版中,文件名和行号被混淆。在下面,请注意文件名已被替换为'',并且行号为'-1':
为了解决这个问题,我在这里加入了保护规则:
## De-obfusicate stack traces
-keepattributes SourceFile,LineNumberTable
不幸的是,文件名现在正确,但是行号仍然被混淆,或者至少非常错误。
在我添加keepattributes之前,文件名(MainActivity.kt)和行号分别被混淆为一个空字符串和'-1':
此问题不是重复的,因为它与the main solution on SO不同,因为成功保存了源文件行号are。以下是我的gradle和proguard文件的片段:
build.gradle
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
proguard-rules.pro
## De-obfusicate stack traces
-keepattributes SourceFile,LineNumberTable
proguard-android.txt
## De-obfusicate stack traces
-keepattributes SourceFile,LineNumberTable
编辑:唯一起作用的不是混淆...而是破坏了目标。我们应该能够混淆并保留行号,否则调试将非常困难。我已经在gradle中尝试了shrinkResources false
,在proguard中尝试了-dontshrink
,但唯一有效的方法是禁用混淆,这无法达到目的。
如何混淆类名,变量名,但仍保留行号?确实需要行号!
您很可能使用R8作为收缩/缩小工具(默认为since AGP 3.4.0启用),而不是Proguard。
R8混淆了您的代码后,了解堆栈跟踪就是困难(如果不是不可能的话),因为类和方法的名称可能已更改。除了重命名,R8 也可以更改行数字出现在堆栈跟踪中以节省更多空间写入DEX文件时。幸运的是,R8创建了一个mapping.txt文件每次运行时,其中包含混淆的类,方法和字段名称映射到原始名称。此映射文件也包含信息以将行号映射回原始源文件行号。
如您所见:R8可能会更改行号,并且您可以使用映射文件将它们映射回您的源文件。 this issue中的讨论针对该决定背后的原因进行了更详细的讨论。它生成的映射文件如下所示:
com.example.MainActivity -> com.example.MainActivity:
1:1:void <init>():9:9 -> <init>
1:7:void onCreate(android.os.Bundle):12:18 -> onCreate
在此示例中,源文件中onCreate
的第12-18行映射到DEX文件中的第1-7行。可以使用Proguard ReTrace的latest version映射堆栈跟踪(SDK捆绑的版本不支持行号映射)。
[如果您查看R8 source code,您会发现在发行版本中禁用行号优化的唯一方法是禁用优化和缩小。
那你有什么选择呢?
android.enableR8=false
文件中指定gradle.properties
,切换回Proguard。