記 Firebase 上無 NDK 符號表解決的過程
背景
在 項目上線之后,Firebase 的后臺收到音視頻上報的崩潰。在項目中音視頻以 so 文件的形式集成近項目。在后臺上報頁面,看不到符號表的匹配。
而這個 bug 占據了我們 bug 的 Top 1 位置。
解決過程
第一步 重新檢查集成 Firebase 的過程
出現問題的時候,我們第一步是去官網重新看集成 Firebase 的過程
檢查了發現沒有問題。
第二步 重新查看官網文檔
經過第一步的檢查,集成的步驟是沒有問題的, 我們再次看看官網文檔,有沒有新的發現。
在官網的 Get Android NDK crash reports 的這個章節發現了新的線索。
我們的音視頻 so 是自己開發的,用 gradle 的方式集成到工程里面。這個相當于外部獨立的依賴,所以,需要用 Firebase 提供的 unstrippedNativeLibsDir 的屬性上傳未剝離符號表的 so.
在第三步 Step 3(optinal): Upload symbols for external dependencies 中
// …
android {
// ...
buildTypes {
release {
firebaseCrashlytics {
nativeSymbolUploadEnabled true
unstrippedNativeLibsDir ‘path/to/unstripped/parent/dir’
}
}
}
}
并且需要對應的 so 架構
unstrippedNativeLibsDir/
+- x86/
|
+- libfoo.so
+- libbar.so
+- arm64/
|
+- libfoo.so
+- libbar.so
加了之后用命令執行 task 上傳符號表
./gradlew app:assembleDebug app:uploadCrashlyticsSymbolFileDebug -debug | grep "\[com.google.firebase.crashlytics\]"
上面的命令跑了,之后發現我們上傳符號表失敗了,是因為網絡的原因
第三步 Android Studio 配置代理上網
我們在國內需要為 Android Studio 的 gradle 設置代理。
設置 Android Studio 的代理
查看 SS 的端口
設置代理
- 1.找到 HTTP Proxy 設置選項
- 2.選擇 Manual proxy configuration
- 3.填寫 ss 的 ip 和端口
- 4.檢測是否設置成功 check connection
輸入 google 的網址,檢測是否設置成功,如果成功了,會彈窗連接成功的彈窗
第四步 去 Firebas 的github 上看 issues
經過上面三步還是不行,我們就去 Firebase 的 github 上看看其他人有沒有遇到同樣的問題。
這里順便說一句,如果是開源的項目,遇到問題,查看它的 issues 也是解決問題的切入點,你遇到的問題,別人也會遇到,看看 issues 或許能找到解決辦法或者提示。
在 Firebase 的 issues 中搜索 ndk symbol,可以找到相關 ndk 符號表的內容。然后在一條中找到相關的內容 Native crash reports missing symbol information (file name, line number, function name) #1978,有人也遇到相應的問題,就是在 Firebase 上沒有看到相應的符號表。
他的解決辦法,就是把已剝離和未剝離符號表的 so 都放到對于的目錄下,用于上傳符號表
debug {
minifyEnabled false
signingConfig signingConfigs.debugsign
firebaseCrashlytics {
nativeSymbolUploadEnabled true
strippedNativeLibsDir 'nativelibs/stripped' // 剝離符號表的 so
unstrippedNativeLibsDir 'nativelibs/unstripped' // 未剝離符號表的 so
}
}
然后再執行命令
./gradlew app:assembleDebug app:uploadCrashlyticsSymbolFileDebug -debug | grep "\[com.google.firebase.crashlytics\]"
這次命令執行的結果顯示,上傳符號表成功了
Crashlytics symbol file uploaded successfully
經過測試 native 的崩潰后,發現符號表打印是上傳成功了,但是還是沒有顯示出來。
到這來,我們已經沒有辦法。為什么明明符號表已經上傳成功了,但是還是解析不到呢。
第四步 配對 So 和項目 NDK 版本
至此,唯一的可能性是我們上傳的符號表和 native 的崩潰對不上,導致 Firebase 無法解析。
通過一番查找,發現我們構建 SO 用的 NDK 版本是 19, 構建項目是的 NDK 是 21 版本。
我們將項目的 NDK 版本也改成 19。
最后發現可以了。
總結
上傳非工程直接編譯 so 的符號表
第一 按照官方文檔集成 Firebase
在項目級別的 build.gradle 中,添加 firebase
dependencies {
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.1.1'
}
在 app 的 build.gradle 中添加
apply plugin: 'com.google.firebase.crashlytics'
....
buildTypes {
release {
...
firebaseCrashlytics {
nativeSymbolUploadEnabled true
strippedNativeLibsDir 'nativelibs/stripped'
unstrippedNativeLibsDir 'nativelibs/unstripped'
}
}
debug {
...
firebaseCrashlytics {
nativeSymbolUploadEnabled true
strippedNativeLibsDir 'nativelibs/stripped'
unstrippedNativeLibsDir 'nativelibs/unstripped'
}
}
strippedNativeLibsDir 是放已經剝離符號表的 so, unstrippedNativeLibsDir 是放未剝離符號表的 so
在 module 的 build.gradle 中添加依賴
dependencies {
// google 崩潰上報
implementation 'com.google.firebase:firebase-analytics-ktx:17.4.4'
// Add the Firebase Crashlytics SDK.
implementation 'com.google.firebase:firebase-crashlytics:17.1.1'
implementation 'com.google.firebase:firebase-crashlytics-ndk:17.1.1'
}
第二步 確保網絡沒有問題
如果是在國內,要設置Android studio 代理上網
第三步 確保編譯 so 的 NDK 和項目的 NDK 版本一致
第三步 用命令行上傳符號表
用命令行上傳符號表
./gradlew app:assembleDebug app:uploadCrashlyticsSymbolFileDebug -debug | grep "\[com.google.firebase.crashlytics\]"
跑命令的時候觀察打印,如果打印出
Crashlytics symbol file uploaded successfully
則說明已經上傳成功
第四步 測試 bug
打開 firebase 的 log 打印
adb shell setprop log.tag.FirebaseCrashlytics DEBUG
adb logcat -s FirebaseCrashlytics