本頁面提供 Crashlytics 的疑難排解說明和常見問題解答。如果找不到所需資訊或需要其他協助,請與 Firebase 支援團隊 聯絡。
一般疑難排解/常見問題
未看到導覽標記記錄
如果沒有看到路徑記錄 (iOS+ | Android | Flutter | Unity ),建議檢查應用程式的 Google Analytics 設定。請確認符合下列規定:
您已在 Firebase 專案中啟用Google Analytics 。
您已為「Google Analytics 」啟用「資料共用」 。如要進一步瞭解這項設定,請參閱「管理 Analytics 資料共用設定 」一文。
您已將 Firebase SDK 新增至應用程式:Google Analytics
iOS+ |
Android |
Flutter |
Unity 。
您必須 在 Crashlytics SDK 之外新增這個 SDK。
您在應用程式中使用的所有產品,都採用最新版 Firebase SDK
(iOS+ |
Android |
Flutter |
Unity )。
如果是 Apple 平台和 Android 應用程式,請特別確認您至少 使用下列版本的 Firebase SDK for Google Analytics :iOS+ - v6.3.1 以上版本 (macOS 和 tvOS 則為 v8.9.0 以上版本) | Android - v17.2.3 以上版本 (BoM v24.7.1 以上版本) 。
未收到當機風險驟升警告
如果沒有看到速度快訊,請確認您使用的是
未看到未發生當機情形的指標 (或看到不可靠的指標)
如果沒有看到未發生當機情形的指標 (例如未發生當機情形的使用者和工作階段),或是看到不可靠的指標,請檢查下列事項:
誰可以查看、撰寫及刪除問題的附註?
專案成員可以在附註中針對特定問題留言,提出疑問或更新狀態等。
專案成員發布附註時,系統會標示他們的 Google 帳戶電子郵件地址。所有有權查看附註的專案成員,都會看到這個電子郵件地址和附註。
以下說明查看、撰寫及刪除記事所需的存取權:
什麼是回歸問題?
如果問題先前已結案,但Crashlytics 收到問題再次發生的新報告,就會視為「迴歸」問題。Crashlytics 會自動重新開啟這些回歸問題,方便您視應用程式情況解決問題。
以下範例情境說明 Crashlytics 如何將問題歸類為迴歸:
Crashlytics 首次收到有關「Crash A」的當機報告。Crashlytics 會為該異常終止事件開啟對應的問題 (問題「A」)。
您迅速修正這個錯誤、關閉「A」問題,然後發布新版應用程式。
Crashlytics 在您關閉問題後,收到有關問題「A」的另一份報告。
如果報告來自Crashlytics 已知 的應用程式版本 (也就是說,該版本已針對任何 當機情況傳送當機報告),則 Crashlytics 不會將該問題視為回歸。問題將維持關閉狀態。
如果報告來自應用程式版本,而該版本在您關閉問題時「不知道」Crashlytics 問題 (也就是說,該版本「從未」 針對任何當機情況傳送「任何」 當機報告),則 Crashlytics 會將問題視為迴歸,並重新開啟問題。
注意: 2022 年 2 月前,如果問題在任何 應用程式版本中再次發生,Crashlytics 就會將問題歸類為回歸,即使是您關閉問題時我們已知的應用程式版本也一樣。這導致Crashlytics 有時會誤判迴歸。我們現在使用上述慣例。
如果問題迴歸,系統會傳送迴歸偵測警報,並在問題中新增迴歸信號,通知您 Crashlytics 已重新開啟問題。如果不想讓問題因迴歸演算法而重新開啟,請「將問題設為靜音」,而非關閉問題。
為什麼舊版應用程式會出現回歸問題?
如果報表來自舊版應用程式,且您關閉問題時,該版本從未傳送任何當機報告,則 Crashlytics 會將問題視為迴歸問題,並重新開啟問題。
如果發生這種情況,可能是因為您已修正錯誤並發布新版應用程式,但仍有使用者使用舊版應用程式,因此無法獲得錯誤修正。如果先前某個版本在您關閉問題時從未 傳送任何當機報告,而這些使用者開始遇到錯誤,那麼這些當機報告就會觸發回歸問題。
如果不想讓問題因迴歸演算法而重新開啟,請「靜音」問題,而非關閉問題。
注意: 2022 年 2 月前,如果問題在任何應用程式版本中再次發生,Crashlytics 就會將問題歸類為迴歸問題,即使您關閉問題時,我們已瞭解該問題。這導致系統有時會誤判迴歸。Crashlytics 我們現在使用上述慣例。 如果發現 2022 年 2 月前有許多誤判的迴歸問題,可以重新關閉這些問題,避免系統再次開啟。
應用程式也使用 Google Mobile Ads SDK,但不會當機
如果您的專案同時使用 Crashlytics 和 Google Mobile Ads SDK,當機報告器很可能在註冊例外狀況處理常式時發生干擾。如要修正這個問題,請呼叫 disableSDKCrashReporting,在 Mobile Ads SDK 中關閉當機報告功能。
我的 BigQuery 資料集位於何處?
連結 Crashlytics 和 BigQuery 後,您建立的新資料集會自動位於美國,無論 Firebase 專案位於何處。
以下各節提供平台專屬的疑難排解和常見問題:
iOS+ |
Android |
Unity 。
缺少 dSYM 或未上傳 dSYM
如要上傳專案的 dSYM 並取得詳細輸出內容,請檢查下列項目:
請確認專案的建構階段包含 Crashlytics 執行指令碼,這樣 Xcode 就能在建構時上傳專案的 dSYM (如需新增指令碼的說明,請參閱「初始化 Crashlytics 」)。更新專案後,請強制當機 ,並確認當機情形會顯示在 Crashlytics 資訊主頁中。
如果 Firebase 控制台中顯示「缺少 dSYM」快訊,請檢查 Xcode,確認是否正確產生建構版本的 dSYM 。
如果 Xcode 正確產生 dSYM,但您仍看到缺少 dSYM,可能是執行指令碼工具在上傳 dSYM 時發生問題。如果發生這種情況,請嘗試下列方法:
確認你使用的是最新版 Crashlytics 。
手動上傳缺少的 dSYM 檔案:
如果系統持續找不到 dSYM,或上傳作業仍失敗,請與 Firebase 支援團隊 聯絡,並附上記錄檔。
當機符號化效果不佳
如果堆疊追蹤記錄的符號化效果不佳,請檢查下列事項:
如果應用程式程式庫中的影格缺少對應用程式程式碼的參照,請確認 -fomit-frame-pointer 未設為編譯標記。
如果應用程式的程式庫出現多個 (Missing) 影格,請檢查Crashlytics 「dSYM」分頁 的Firebase 控制台,看看是否有列出缺少的選用 dSYM (適用於受影響的應用程式版本)。如果是,請按照本頁面「缺少 dSYM 警示」
的缺少/未上傳 dSYM 常見問題 疑難排解步驟操作。請注意,上傳這些 dSYM 無法對已 發生的異常終止進行符號化,但有助於確保未來 的異常終止事件能順利符號化。
為什麼系統只會回報 Android 11 以上版本的 ANR?
Crashlytics 支援從搭載 Android 11 以上版本的裝置,回報 Android 應用程式的 ANR。我們用來收集 ANR 的基礎 API (getHistoricalProcessExitReasons ) 比 SIGQUIT 或監控程式方法更可靠。這個 API 僅適用於 Android 11 以上版本的裝置。
為什麼有些 ANR 缺少 BuildId?
如果部分 ANR 缺少 BuildId,請按照下列步驟排解問題:
請確認您使用的是最新版的 Crashlytics Android SDK 和 Crashlytics Gradle 外掛程式。
如果缺少 Android 11 的 BuildId,以及部分 Android 12 的 ANR,很可能是因為您使用的 SDK 或 Gradle 外掛程式 (或兩者) 已過時。如要正確收集這些 ANR 的 BuildId,您必須使用下列版本:
Crashlytics Android SDK 18.3.5 以上版本 (Firebase BoM 31.2.2 以上版本)
Crashlytics Gradle 外掛程式 2.9.4 以上版本
檢查您是否使用非標準位置存放共用程式庫。
如果應用程式共用程式庫只缺少 BuildId,可能是因為您未使用共用程式庫的標準預設位置。如果是這樣,Crashlytics 可能就無法找到相關聯的 BuildId。建議您考慮使用共用程式庫的標準位置。
確認您在建構程序中未移除 BuildId。
請注意,下列疑難排解提示適用於 ANR 和原生當機。
在二進位檔上執行 readelf -n,檢查 BuildId 是否存在。如果沒有 BuildId,請將 -Wl,--build-id 新增至建構系統的標記。
確認您並非為了縮減 APK 大小,而無意間移除 BuildId。
如果您保留程式庫的已剝除和未剝除版本,請務必在程式碼中指向正確的版本。
Crashlytics 資訊主頁和 Google Play 管理中心的 ANR 報告差異
Google Play 和 Crashlytics 的 ANR 數量可能不一致。這是正常現象,因為收集及回報 ANR 資料的機制不同。Crashlytics 會在應用程式下次啟動時回報 ANR,而 Android Vitals 則會在發生 ANR 後傳送相關資料。
此外,Crashlytics 只會顯示在 Android 11 以上版本裝置上發生的 ANR,而 Google Play 則會顯示在接受 Google Play 服務和資料收集同意聲明的裝置上發生的 ANR。
為什麼我會看到來自 .kt 檔案的當機問題,且標示為 .java 問題?
如果應用程式使用的模糊處理器不會公開副檔名,Crashlytics 預設會為每個問題產生 .java 副檔名。
為確保 Crashlytics 能產生副檔名正確的問題,請確認應用程式使用下列設定:
使用 Android Gradle 4.2.0 以上版本
使用 R8,並開啟模糊化功能。如要將應用程式更新至 R8,請參閱這份文件 。
請注意,更新為上述設定後,您可能會開始看到新的 .kt 問題,這些問題與現有的 .java 問題重複。如要進一步瞭解該情況,請參閱常見問題 。
為什麼我會看到與現有 .java 問題重複的 .kt 問題?
自 2021 年 12 月中起,Crashlytics 將為使用 Kotlin 的應用程式提供更完善的支援。
直到最近,可用的混淆器都不會公開檔案副檔名,因此 Crashlytics 預設會為每個問題產生 .java 檔案副檔名。不過,自 Android Gradle 4.2.0 起,R8 支援副檔名。
更新後,Crashlytics 現在可以判斷應用程式中使用的每個類別是否以 Kotlin 編寫,並在問題簽章中加入正確的檔案名稱。如果應用程式採用下列設定,系統現在會正確將當機問題歸因於 .kt 檔案 (視情況):
您的應用程式使用 Android Gradle 4.2.0 以上版本。
您的應用程式使用 R8,且已開啟模糊處理功能。
由於新版當機問題的簽章現在會包含正確的副檔名,您可能會看到新的 .kt 問題,但這些問題實際上只是現有 .java 標籤問題的副本。在 Firebase 控制台中,如果新的 .kt 問題可能與現有的 .java 標籤問題重複,我們會嘗試識別並通知您。
使用 Dexguard 時不會發生當機問題
如果看到下列例外狀況,表示您使用的 DexGuard 版本可能與 Firebase Crashlytics SDK 不相容:
java.lang.IllegalArgumentException: Transport backend 'cct' is not registered
這項例外狀況不會導致應用程式異常終止,但會阻止應用程式傳送異常終止報告。如要修正這個問題,請按照下列步驟操作:
請確認您使用的是最新版 DexGuard 8.x。最新版本包含 Firebase Crashlytics SDK 必須遵守的規則。
如果不想變更 DexGuard 版本,請嘗試在混淆規則 (位於 DexGuard 設定檔中) 中新增下列指令行:
- keepresourcexmlelements manifest / application / service / meta - data @value = cct
Crashlytics 資訊主頁和 logcat 中的 NDK 堆疊追蹤記錄差異
LLVM 和 GNU 工具鍊對應用程式二進位檔的唯讀區隔有不同的預設值和處理方式,可能會在 Firebase 控制台中產生不一致的堆疊追蹤記錄。為解決這個問題,請在建構程序中新增下列連結器標記:
如果堆疊追蹤仍不一致 (或兩個標記都不適用於工具鍊),請改為在建構程序中加入下列項目:
-fno-omit-frame-pointer
如何使用自己的 Breakpad 符號檔案產生器二進位檔,搭配 NDK 進行偵錯?
Crashlytics 外掛程式會將自訂的 Breakpad 符號檔產生器 設為套件。如果您偏好使用自己的二進位檔產生 Breakpad 符號檔 (例如,您偏好從來源建構建構鏈中的所有原生可執行檔),請使用選用的 symbolGeneratorBinary 擴充功能屬性,指定可執行檔的路徑。
注意: Android 二進位檔必須使用 Linux 版的 Breakpad 符號檔案產生器。
您可以透過下列兩種方式,指定 Breakpad 符號檔案產生器二進位檔的路徑:
方法 1 :透過 build.gradle 檔案中的 firebaseCrashlytics 擴充功能指定路徑
在應用程式層級的 build.gradle.kts 檔案中新增以下內容:
Gradle 外掛程式 3.0.0 以上版本
android {
buildTypes {
release {
configure<CrashlyticsExtension> {
nativeSymbolUploadEnabled = true
// Add these optional fields to specify the path to the executable
symbolGeneratorType = "breakpad"
breakpadBinary = file ( "/PATH/TO/BREAKPAD/DUMP_SYMS " )
}
}
}
}
較舊的外掛程式版本
android {
// ...
buildTypes {
// ...
release {
// ...
firebaseCrashlytics {
// existing; required for either symbol file generator
nativeSymbolUploadEnabled true
// Add this optional new block to specify the path to the executable
symbolGenerator {
breakpad {
binary file ( "/PATH/TO/BREAKPAD/DUMP_SYMS " )
}
}
}
}
}
方法 2 :在 Gradle 屬性檔案中,透過屬性行指定路徑
您可以使用 com.google.firebase.crashlytics.breakpadBinary 屬性指定可執行檔的路徑。
您可以手動更新 Gradle 屬性檔案,也可以透過指令列更新檔案。舉例來說,如要透過指令列指定路徑,請使用類似下列的指令:
./gradlew -Pcom.google.firebase.crashlytics.symbolGenerator=breakpad \
-Pcom.google.firebase.crashlytics.breakpadBinary=/PATH/TO/BREAKPAD/DUMP_SYMS \
app:assembleRelease app:uploadCrashlyticsSymbolFileRelease
Crashlytics 是否支援 armeabi?
Firebase Crashlytics NDK 不支援 ARMv5 (armeabi)。NDK r17 以上版本已不再支援這個 ABI。
在 Crashlytics 資訊主頁中看到 Android 應用程式的未符號化堆疊追蹤記錄
如果您使用 Unity IL2CPP ,且看到未符號化的堆疊追蹤記錄,請嘗試下列做法:
請務必使用 Crashlytics Unity SDK 8.6.1 以上版本。
請確認您已設定並執行 Firebase CLI crashlytics:symbols:upload 指令,產生及上傳符號檔。
每次建立發布版本或任何建構版本時,您都需要執行這個 CLI 指令,才能在 Firebase 控制台中查看符號化的堆疊追蹤記錄。詳情請參閱「取得可讀取的當機報告 」。
是否可搭配使用 IL2CPP 的應用程式使用 Crashlytics ?
可以,Crashlytics 可顯示使用 IL2CPP 的應用程式符號化堆疊追蹤記錄。這項功能適用於在 Android 或 Apple 平台上發布的應用程式。請採取以下行動:
確認您使用的是 Crashlytics Unity SDK 8.6.0 以上版本。
請完成所用平台適用的必要工作:
Apple 平台應用程式 :不需採取任何行動。如果是 Apple 平台應用程式,Firebase Unity 編輯器外掛程式會自動設定 Xcode 專案,以利上傳符號。
Android 應用程式 :請確認您已設定並執行 Firebase CLI crashlytics:symbols:upload 指令,產生及上傳符號檔。
每次建立發布版本或任何建構版本時,您都需要執行這個 CLI 指令,才能在 Firebase 控制台中查看符號化的堆疊追蹤記錄。詳情請參閱「取得可讀取的當機報告 」。
將未偵測到的例外狀況回報為嚴重錯誤
Crashlytics 可以將未偵測到的例外狀況回報為嚴重事件 (從 Unity SDK 的 10.4.0 版 開始)。以下常見問題說明使用這項功能的理由和最佳做法。
為什麼應用程式應將未偵測到的例外狀況回報為嚴重錯誤?
將未處理的例外狀況回報為嚴重錯誤,可更如實地指出哪些例外狀況可能導致遊戲無法執行,即使應用程式持續執行也一樣。
請注意,開始回報嚴重錯誤後,無當機使用者 (CFU) 百分比可能會降低,但 CFU 指標會更貼近使用者實際的應用程式體驗。
重要事項: 將未處理的例外狀況回報為嚴重錯誤,不會 影響Android Vitals 。您只會看到 Crashlytics 中回報的嚴重錯誤,方便您找出並修正應用程式和遊戲中的問題。
哪些例外狀況會回報為嚴重錯誤?
如要讓 Crashlytics 將未偵測到的例外狀況回報為嚴重事件,必須符合下列兩項條件:
啟用將未偵測到的例外狀況回報為嚴重錯誤後,我現在有許多新的嚴重錯誤。如何正確處理這些例外狀況?
當您開始收到未處理例外狀況的報告 (顯示為嚴重錯誤) 時,可以採取下列幾種方式處理這些未處理的例外狀況:
攔截並處理擲回的例外狀況
系統會建立並擲回例外狀況,反映非預期或特殊狀態 。如要解決例外狀況反映的問題,必須將程式還原至已知狀態 (這個程序稱為例外狀況處理 )。
除非程式無法返回已知狀態,否則最佳做法是擷取並處理所有 預期的例外狀況。
如要控管哪些類型的例外狀況會由哪些程式碼擷取及處理,請將可能產生例外狀況的程式碼包裝在 try-catch 區塊中 。請確保 catch 陳述式中的條件盡可能嚴格,以便適當處理特定例外狀況。
在 Unity 或 Crashlytics 中記錄例外狀況
您可以在 Unity 或 Crashlytics 中記錄例外狀況,協助偵錯問題。
使用 Crashlytics 時,最常見且建議採用的兩種選項如下:
不過,如要手動向 Unity Cloud Diagnostics 回報嚴重事件,可以使用 Debug.LogException。這個選項會將例外狀況列印到 Unity 控制台 (如選項 1),但也會擲回例外狀況 (無論是否已擲回或擷取)。系統會擲回非本機錯誤。也就是說,即使是包含 Debug.LogException(exception)
try-catch 區塊的周圍,仍會導致未擷取的例外狀況。
因此,只有在您想同時 執行下列所有操作時,才需要呼叫 Debug.LogException:
將例外狀況列印到 Unity 控制台。
將例外狀況上傳至 Crashlytics 做為嚴重事件。
擲回例外狀況,將其視為未捕捉到的 例外狀況,並回報給 Unity Cloud Diagnostics。
請注意,如要將偵測到的例外狀況列印到 Unity 控制台 並 上傳至 Crashlytics 做為非嚴重事件,請改為執行下列操作:
try
{
methodThatThrowsMyCustomExceptionType ();
}
catch ( MyCustomExceptionType exception )
{
// Print the exception to the Unity console at the error level.
Debug . LogError ( exception );
// Upload the exception to Crashlytics as a non-fatal event.
Crashlytics . LogException ( exception ); // not Debug.LogException
//
// Code that handles the exception
//
}