Crash日誌解析

SunshineBrother發表於2018-11-03

當應用程式崩潰時,會建立一個崩潰報告,這對於瞭解導致崩潰的原因非常有用。本文件包含有關如何表示,理解和解釋崩潰報告的基本資訊。

  • 1、介紹
  • 2、獲取崩潰和低記憶體報告
  • 3、象徵性的奔潰報告
    • 1、位碼(bitCode)
    • 2、確定奔潰報告是否符號化
    • 3、用Xcode標記iOS奔潰報告
    • 4、用atos表示崩潰報告
    • 5、符號故障排除
  • 4、崩潰報告分析
    • 1、頭
    • 2、例外資訊
    • 3、其他診斷資訊
    • 4、回溯
    • 5、執行緒狀態
    • 6、二進位制影像
  • 5、瞭解低記憶體報告

介紹

當應用程式崩潰時,會建立崩潰報告並將其儲存在裝置上。崩潰報告描述了應用程式終止的條件,在大多數情況下包括每個執行執行緒的完整回溯,並且通常對於除錯應用程式中的問題非常有用。您應該檢視這些崩潰報告,以瞭解您的應用程式崩潰了什麼,然後嘗試修復它們。

帶有回溯的崩潰報告需要在進行分析之前進行符號化。符號化用人類可讀的函式名稱和行號替換記憶體地址。如果您通過Xcode的裝置視窗從裝置上獲取崩潰日誌,那麼幾秒鐘後它們將自動被符號化。否則,您需要通過將.crash檔案匯入Xcode Devices視窗來自行符號化。有關詳細資訊,請參閱符號崩潰報告。

一個低記憶體報告不同之處在於有這型別的報告沒有回溯其他的崩潰報告。當發生低記憶體崩潰時,您必須調查記憶體使用模式以及對低記憶體警告的響應。

獲取崩潰和低記憶體報告

除錯已部署的iOS應用程式討論瞭如何直接從iOS裝置檢索崩潰和低記憶體報告。

分析“ 應用程式分發指南”中的崩潰報告討論瞭如何檢視從TestFlight beta測試人員和從App Store下載應用程式的使用者收集的聚合崩潰報告。

象徵性的崩潰報告

符號化是將回溯地址解析為原始碼方法或函式名稱(稱為符號)的過程。如果沒有首先表示崩潰報告,則很難確定崩潰發生的位置。

注意:  低記憶體報告不需要進行符號化。
注意:  macOS的崩潰報告通常在生成時被符號化或部分符號化。本節重點介紹iOS,watchOS和tvOS的崩潰報告,但整個過程與macOS類似。
複製程式碼

Crash日誌.png

1、當編譯器將原始碼轉換為機器程式碼時,它還會生成除錯符號,這些符號將編譯後的二進位制檔案中的每個機器指令對映回源自它的原始碼行。根據Debug Information Format(DEBUG_INFORMATION_FORMAT)構建設定,這些除錯符號儲存在二進位制檔案或伴隨的Debug Symbol(dSYM)檔案中。預設情況下,應用程式的除錯版本將除錯符號儲存在已編譯的二進位制檔案中,而應用程式的釋出版本將除錯符號儲存在配套dSYM檔案中以減小二進位制檔案大小。 除錯符號檔案和應用程式二進位制檔案通過構建UUID在每個構建的基礎上繫結在一起。為應用程式的每個構建生成一個新的UUID,並唯一標識該構建。即使從相同的原始碼重建功能相同的可執行檔案,使用相同的編譯器設定,它也將具有不同的構建UUID。除錯來自後續版本的符號檔案,即使是來自相同的原始檔,也不會與來自其他版本的二進位制檔案互操作。

  • 2、歸檔應用程式以進行分發時,Xcode將收集應用程式二進位制檔案以及。dSYM將檔案儲存並儲存在主資料夾內的某個位置

  • 3、如果您通過App Store分發應用程式,或使用Test Flight進行beta測試,您可以選擇dSYM在將存檔上傳到iTunes Connect時包含該檔案。在提交對話方塊中,選中“為您的應用程式包含應用程式符號...”。上傳dSYM檔案對於接收從TestFlight使用者和選擇共享診斷資料的客戶收集的崩潰報告是必要的

  • 4、當您的應用程式崩潰時,會建立一個非符號化的崩潰報告並將其儲存在裝置上。

  • 5、使用者可以按照除錯已部署的iOS應用程式中的步驟直接從其裝置檢索崩潰報告。如果您通過AdHoc或Enterprise分發分發了應用程式,則這是從使用者獲取崩潰報告的唯一方法。

  • 6、從裝置檢索到的崩潰報告是非符號化的,需要使用Xcode進行符號化。Xcode使用dSYM與應用程式二進位制檔案關聯的檔案將回溯中的每個地址替換為原始碼中的原始位置。結果是一個符號化的崩潰報告。

  • 7、如果使用者選擇與Apple共享診斷資料,或者使用者已通過TestFlight安裝了應用程式的測試版,則崩潰報告將上載到App Store

  • 8、App Store表示崩潰報告,並將其與類似的崩潰報告分組。這種類似崩潰報告的彙總稱為崩潰點。

  • 9、Xcode的Crashes組織者可以使用符號化的崩潰報告。

位碼

Bitcode是編譯程式的中間表示。當您使用bitcode存檔應用程式時,編譯器會生成包含bitcode而不是機器程式碼的二進位制檔案。將二進位制檔案上傳到App Store後,bitcode將編譯為機器程式碼。App Store可能會在將來再次編譯bitcode,以利用未來的編譯器改進,而無需您採取任何操作

Crash日誌1.png

由於二進位制檔案的最終編譯發生在App Store上,因此Mac不會包含用於表示dSYM從App Review收到的崩潰報告或從其裝置向您傳送崩潰報告的使用者所需的除錯符號()檔案。雖然dSYM歸檔應用程式時會生成一個檔案,但它是用於bitcode二進位制檔案,不能用於表示崩潰報告。App Store使dSYM您可以從Xcode或iTunes Connect網站下載bitcode編譯期間生成的檔案。您必須下載這些dSYM檔案,以便表示從App Review或從其裝置向您傳送崩潰報告的使用者收到的崩潰報告。通過崩潰報告服務收到的崩潰報告將自動進行符號化。

App Store編譯的二進位制檔案將具有與最初提交的二進位制檔案不同的UUID。

複製程式碼

從Xcode下載dSYM檔案

  • 1、在Archives管理器中,選擇最初提交到App Store的存檔
  • 2、單擊“下載dSYMs”按鈕。 Xcode下載dSYM檔案並將其插入選定的存檔。

從iTunes Connect網站下載dSYM檔案

  • 1、開啟“應用詳情”頁面。
  • 2、單擊活動。
  • 3、從“所有構建”列表中,選擇一個版本。
  • 4、單擊“ 下載dSYM”連結

將“隱藏”符號名稱翻譯回原始名稱

當您將帶有bitcode的應用程式上傳到App Store時,您可以選擇不通過取消選中“上傳您的應用程式的符號以從Apple接收符號化報告”框來傳送應用程式的符號。如果您選擇不將應用程式的符號資訊傳送給Apple,Xcode將替換您應用程式中的符號。dSYM在將應用程式傳送到iTunes Connect之前,帶有模糊符號的檔案,例如“_hidden#109”。Xcode在原始符號和“隱藏”符號之間建立對映,並將此對映儲存.bcsymbolmap在應用程式歸檔內的檔案中。每個。dSYM檔案將有一個相應的.bcsymbolmap檔案。

在對崩潰報告進行符號化之前,您需要對符號中的符號進行去混淆。dSYM從iTunes Connect下載的檔案。如果您使用Xcode中的下載dSYMs按鈕,將自動執行此去混淆。但是,如果您使用iTunes Connect網站下載。dSYM檔案,開啟終端並使用以下命令對符號進行反模糊處理(用您自己的存檔替換示例路徑和從iTunes Connect下載的dSYMs資料夾):

xcrun dsymutil -symbol-map~ / Library / Developer / Xcode / Archives / 2017-11-23 / MyGreatApp \ 11-23-17 \,\ 12.00 \ PM.xcarchive / BCSymbolMaps~ / Downloads / dSYMs / 3B15C133-88AA-35B0 -B8BA-84AF76826CE0.dSYM

複製程式碼

為每個執行此命令。dSYM您下載的dSYMs資料夾中的檔案。

確定崩潰報告是否符號化

崩潰報告可以是非符號化的,完全符號化的或部分符號化的。非符號化的崩潰報告將不包含回溯中的方法或函式名稱。相反,您在載入的二進位制影像中具有可執行程式碼的十六進位制地址。在完全符號化的崩潰報告中,回溯的每一行中的十六進位制地址將替換為相應的符號。在部分符號化的崩潰報告中,只有回溯中的某些地址已替換為其相應的符號。

顯然,您應該嘗試完全符合您收到的任何崩潰報告,因為它將提供有關崩潰的最深入見解。部分符號化的崩潰報告可能包含足夠的資訊來了解崩潰,具體取決於崩潰的型別以及成功符號化的回溯的哪些部分。非符號化的崩潰報告很少有用

Crash日誌2.png

用Xcode標記iOS崩潰報告

Xcode將自動嘗試表示它遇到的所有崩潰報告。您需要為符號化做的只是將崩潰報告新增到Xcode Organizer。

Xcode不接受沒有.crash副檔名的崩潰報告。如果您收到沒有擴充套件程式或擴充套件程式的崩潰報告,請在執行下面列出的步驟之前.txt將其重新命名為.crash擴充套件程式。
複製程式碼
  • 1、將iOS裝置連線到Mac
  • 2、從“視窗”選單中選擇“裝置”
  • 3、 在左列的“裝置”部分下,選擇一個裝置
  • 4、單擊右側皮膚“裝置資訊”部分下的“檢視裝置日誌”按鈕
  • 5、將崩潰報告拖到所顯示皮膚的左列
  • 6、Xcode將自動錶示崩潰報告並顯示結果

為了表示崩潰報告,Xcode需要能夠找到以下內容

  • 1、崩潰的應用程式的二進位制dSYM檔案和檔案。
  • 2、dSYM應用程式連結的所有自定義框架的二進位制檔案和檔案。對於使用應用程式從源構建的框架,它們的dSYM檔案將與應用程式的dSYM檔案一起復制到存檔中。對於由第三方構建的框架,您需要向作者詢問該dSYM檔案。
  • 3、崩潰時該應用程式執行的作業系統的符號。這些符號包含特定作業系統版本(例如iOS 9.3.3)中包含的框架的除錯資訊。OS符號是特定於體系結構的 - 用於64位裝置的iOS版本不包含armv7符號。Xcode將自動從連線到Mac的每個裝置複製OS符號。

如果缺少任何這些,Xcode可能無法表示崩潰報告,或者可能只是部分地表示崩潰報告。

用atos表示崩潰報告

該 ATOS命令將數字地址轉換為其符號等效項。如果有完整的除錯符號資訊,則輸出atos將包括檔名和源行號資訊。該atos命令可用於在非符號化或部分符號化的崩潰報告的回溯中表示各個地址。使用atos以下命令表示崩潰報告的一部分:

  • 1、在回溯中找到要符號化的行。請注意第二列中二進位制影像的名稱,以及第三列中的地址。
  • 2、在崩潰報告底部的二進位制影像列表中查詢具有該名稱的二進位制影像。請注意二進位制映像的體系結構和載入地址。

Crash日誌3.png

符號故障排除

如果Xcode未能完全符合崩潰報告,可能是因為您的Mac缺少dSYM應用程式二進位制dSYM檔案的檔案,應用程式連結的一個或多個框架的檔案,或者應用程式執行的OS的裝置符號它墜毀了。以下步驟顯示如何使用Spotlight確定dSYM在Mac上是否存在表示二進位制影像中的回溯地址所需的檔案。

Crash日誌4.png

  • 1、在回溯中找到Xcode無法符號化的行。請注意第二列中二進位制影像的名稱
  • 2、在崩潰報告底部的二進位制影像列表中查詢具有該名稱的二進位制影像。此列表包含崩潰時載入到程式中的每個二進位制映像的UUID。
您可以使用grep命令列工具快速查詢二進位制映像列表中的條目。
$ grep --after-context = 1000“二進位制影像:”<崩潰報告的路徑> | grep <二進位制名稱>
複製程式碼
  • 3、將二進位制映像的UUID轉換為以8-4-4-4-12(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)為一組分隔的32個字串。請注意,所有字母必須是大寫的。
  • 4、使用mdfind命令列工具使用查詢搜尋UUID "com_apple_xcode_dsym_uuids == "(包括引號)。
使用mdfind命令列工具搜尋dSYM具有給定UUID的檔案。
$ mdfind“com_apple_xcode_dsym_uuids == <UUID>”

複製程式碼
  • 5、如果Spotlight找到dSYMUUID 的檔案,mdfind將列印該dSYM檔案的路徑,並可能列印其包含的存檔。如果dSYM找不到UUID 的檔案, mdfind將退出而不列印任何內容。

分析崩潰報告

每個崩潰報告都以標題開頭。

Incident Identifier(事件識別符號): B6FD1E8E-B39F-430B-ADDE-FC3A45ED368C
CrashReporter Key(金鑰): f04e68ec62d3c66057628c9ba9839e30d55937dc
Hardware Model(硬體型號): iPad6,8
Process(程式): TheElements [303]
Path(路徑): /private/var/containers/Bundle/Application/888C1FA2-3666-4AE2-9E8E-62E2F787DEC1/TheElements.app/TheElements
Identifier(識別符號): com.example.apple-samplecode.TheElements
Version(版本): 1.12
Code Type(程式碼型別): ARM-64 (Native)
Role: Foreground
Parent Process: launchd [1]
Coalition: com.example.apple-samplecode.TheElements [402]

Date/Time: 2016-08-22 10:43:07.5806 -0700
Launch Time: 2016-08-22 10:43:01.0293 -0700
OS Version: iPhone OS 10.0 (14A5345a)
Report Version: 104
複製程式碼
  • 1、Incident Identifier事件識別符號:報告的唯一識別符號。兩個報告永遠不會共享相同的事件識別符號。
  • 2、CrashReporter KeyCrashReporter金鑰:匿名的每裝置識別符號。來自同一裝置的兩個報告將包含相同的值。
  • 3、Beta IdentifierBeta識別符號:崩潰應用程式的裝置和供應商組合的唯一識別符號。來自同一供應商和同一裝置的兩個應用程式報告將包含相同的值。此欄位僅存在於為通過TestFlight分發的應用程式生成的崩潰報告中,並替換CrashReporter Key欄位。
  • 4、Process程式:崩潰程式的可執行檔名稱。這與CFBundleExecutable應用程式的資訊屬性列表中的鍵值匹配。
  • 5、Version版本:崩潰的程式版本。該欄位的值是崩潰的應用程式CFBundleVersion和的串聯CFBundleVersionString。
  • 6、Code Type程式碼型別:崩潰的程式的目標體系結構。這將是一ARM-64,ARM,x86-64,或x86。
  • 7、Role角色:終止時分配給程式的task_role。
  • 8、OS Version作業系統版本:發生崩潰的作業系統版本,包括內部版本號。

由於未捕獲的Objective-C異常導致程式終止時生成的崩潰報告中的Exception Codes部分的摘錄。

Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Triggered by Thread: 0

複製程式碼

當程式因為取消引用NULL指標而終止時生成的崩潰報告中的Exception Codes部分的摘錄。

Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000000
Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [0]
Triggered by Thread: 0
複製程式碼
  • 1、Exception Codes異常程式碼:有關異常的處理器特定資訊,編碼為一個或多個64位十六進位制數。通常,此欄位將不存在,因為Crash Reporter會解析異常程式碼以將其作為人類可讀的描述呈現在其他欄位中。
  • 2、Exception Subtype異常子型別:異常程式碼的人類可讀名稱。
  • 3、Exception Message異常訊息:從異常程式碼中提取的其他人類可讀資訊。
  • 4、Exception Note異常注意:非特定於一種異常型別的附加資訊。如果該欄位包含,SIMULATED (this is NOT a crash)那麼程式沒有崩潰,但是在系統請求時被殺死,通常是看門狗
  • 5、Termination Reason終止原因:終止程式時指定的退出原因資訊。程式內部和外部的關鍵系統元件將在遇到致命錯誤時終止程式(例如,錯誤的程式碼簽名,缺少的依賴庫,或在沒有適當權利的情況下訪問隱私敏感資訊)。macOS Sierra,iOS 10,watchOS 3和tvOS 10採用了新的基礎設施來記錄這些錯誤,這些作業系統生成的崩潰報告列出了終止原因欄位中的錯誤訊息
  • 6、Triggered by Thread由執行緒觸發:發生異常的執行緒。

記憶體訪問不良[EXC_BAD_ACCESS // SIGSEGV // SIGBUS]

該程式嘗試訪問無效記憶體,或者嘗試以記憶體保護級別不允許的方式訪問記憶體(例如,寫入只讀記憶體)。該例外子型別欄位包含一個kern_return_t描述錯誤,並且被錯誤地訪問的儲存器的地址。

以下是除錯錯誤記憶體訪問崩潰的一些提示:

  • 1、如果崩潰執行緒的Backtraces頂部objc_msgSend或objc_release附近,則該程式可能已嘗試向已釋放的物件傳送訊息。您應該使用Zombies工具對應用程式進行概要分析,以便更好地瞭解此崩潰的情況。
  • 2、如果在崩潰執行緒gpus_ReturnNotPermittedKillClient的Backtraces頂部附近,則該程式被終止,因為它在後臺嘗試使用OpenGL ES或Metal進行渲染。請參閱QA1766:如何在移動到後臺時修復OpenGL ES應用程式崩潰。
  • 3、啟用Address Sanitizer執行您的應用程式。地址清理程式在已編譯的程式碼中新增了有關記憶體訪問的附加檢測。當您的應用程式執行時,如果以可能導致崩潰的方式訪問記憶體,Xcode將提醒您。

異常退出[EXC_CRASH // SIGABRT]

該過程異常退出。使用此異常型別導致崩潰的最常見原因是未被​​捕獲的Objective-C / C ++ 異常和呼叫abort()。

如果App Extensions花費太多時間進行初始化(看門狗終止),它將以此異常型別終止。如果由於啟動時掛起而導致副檔名被終止,則生成的崩潰報告的異常子型別將是LAUNCH_HANG。由於擴充套件沒有main函式,因此初始化所花費的時間都發生在+load擴充套件和依賴庫中的靜態建構函式和方法中。你應該儘可能多地推遲這項工作。

跟蹤陷阱[EXC_BREAKPOINT // SIGTRAP]

與異常退出類似,此異常旨在為附加的偵錯程式提供在其執行的特定點中斷程式的機會。您可以使用該__builtin_trap()函式從您自己的程式碼中觸發此異常。如果未附加偵錯程式,則終止該過程並生成崩潰報告。

較低階別的庫(例如libdispatch)會在遇到致命錯誤時捕獲程式。有關錯誤的其他資訊可以在崩潰報告的“ 其他診斷資訊”部分或裝置的控制檯中找到。

如果在執行時遇到意外情況,則Swift程式碼將以此異常型別終止,例如:

  • 1、具有nil值的非可選型別
  • 2、強制型別轉換失敗

非法指令[EXC_BAD_INSTRUCTION // SIGILL] 該程式試圖執行非法或未定義的指令。該程式可能試圖通過配置錯誤的函式指標跳轉到無效地址。

在Intel處理器上,ud2操作碼會導致EXC_BAD_INSTRUCTION異常,但通常用於捕獲程式以進行除錯。如果在執行時遇到意外情況,則Intel處理器上的Swift程式碼將以此異常型別終止。有關詳細資訊,請參閱跟蹤陷阱

退出[SIGQUIT]

該程式在另一個程式的請求下終止,並具有管理其生命週期的許可權。SIGQUIT並不意味著該過程崩潰,但它確實可能以可檢測的方式行為不端。

在iOS上,如果載入時間過長,主機應用將退出鍵盤擴充套件。崩潰報告中顯示的Backtraces不太可能指向負責的程式碼。最有可能的是,擴充套件的啟動路徑上的一些其他程式碼需要很長時間才能完成,但在時間限制之前完成,並且當擴充套件退出時執行移動到Backtraces中顯示的程式碼。您應該對擴充套件進行概要分析,以便更好地瞭解啟動期間大多數工作的位置,並將該工作移至後臺執行緒或將其推遲到以後(擴充套件載入後)。

被殺[SIGKILL]

該過程在系統請求時終止。檢視“ 終止原因”欄位以更好地瞭解終止原因。

該終止原因欄位將包含一個名稱空間,然後一個程式碼。以下程式碼特定於watchOS:

  • 1、終止程式碼0xc51bad01表示監視應用程式已終止,因為它在執行後臺任務時使用了太多CPU時間。要解決此問題,請優化執行後臺任務的程式碼以提高CPU效率,或減少應用程式在後臺執行時執行的工作量。
  • 2、終止程式碼0xc51bad02表示監視應用程式因未能在分配的時間內完成後臺任務而終止。要解決此問題,請減少應用在後臺執行時執行的工作量。
  • 3、終止程式碼0xc51bad03表示監視應用程式未能在分配的時間內完成後臺任務,並且系統整體上非常繁忙,以至於應用程式可能沒有多少CPU時間來執行後臺任務。雖然應用程式可以通過減少它在後臺任務中執行的工作量來避免此問題,0xc51bad03但並不表示該應用程式執行了任何錯誤操作。更有可能的是,由於整體系統負載,應用程式無法完成其工作

保護資源違規[EXC_GUARD]

該過程違反了受保護的資源保護。系統庫可能會將某些檔案描述符標記為保護,之後對這些描述符的正常操作將觸發EXC_GUARD異常(當它想要對這些檔案描述符進行操作時,系統使用特殊的“保護”私有API)。這有助於您快速跟蹤問題,例如關閉系統庫開啟的檔案描述符。例如,如果某個應用程式關閉了用於訪問支援Core Data儲存的SQLite檔案的檔案描述符,那麼Core Data將在以後神祕地崩潰。保護異常會更快地發現這些問題,從而使它們更容易除錯。

來自較新版本的iOS的崩潰報告包括有關EXC_GUARD在異常子型別和異常訊息欄位中導致異常的操作的人類可讀詳細資訊。在來自macOS或舊版iOS的崩潰報告中,此資訊被編碼為第一個異常程式碼,作為位域,按如下方式分解:

資源限制[EXC_RESOURCE]

該過程超出了資源消耗限制。這是來自作業系統的通知,該程式使用了​​太多資源。確切的資源列在Exception Subtype欄位中。如果包含“ 異常備註”欄位NON-FATAL CONDITION,則即使生成了崩潰報告,也不會終止該程式。

  • 1、異常子型別MEMORY表示程式已超過系統強加的記憶體限制。這可能是終止超額記憶體使用的先兆。
  • 2、異常子型別WAKEUPS表示程式中的執行緒每秒被喚醒太多次,這迫使CPU經常喚醒並消耗電池壽命。

通常,這是由執行緒到執行緒的通訊(通常使用peformSelector:onThread:或者dispatch_async)引起的,這種通訊在不知不覺中發生的頻率遠遠超過它應該發生的頻率。因為觸發此異常的通訊型別經常發生,所以通常會有多個具有非常相似的Backtraces的後臺執行緒- 指示通訊的來源。

其他異常型別 某些崩潰報告可能包含未命名的異常型別,它將列印為十六進位制值(例如00000020)。如果您收到其中一個崩潰報告,請直接檢視“ 例外程式碼”欄位以獲取更多資訊。

  • 1、異常程式碼0xbaaaaaad表示日誌是整個系統的堆疊,而不是崩潰報告。要拍攝疊印,請同時按側面按鈕和兩個音量按鈕。這些日誌通常是由使用者意外建立的,並不表示錯誤。
  • 2、異常程式碼0xbad22222表示iOS已終止VoIP應用程式,因為它過於頻繁地恢復。
  • 3、異常程式碼0x8badf00d表示iOS已終止應用程式,因為發生了監視程式超時。應用程式啟動,終止或響應系統事件花費的時間太長。其中一個常見原因是在主執行緒上進行同步網路連線。無論什麼操作都Thread 0需要移動到後臺執行緒,或者以不同的方式處理,以便它不會阻塞主執行緒。
  • 4、異常程式碼0xc00010ff表示應用程式被作業系統殺死以響應熱事件。這可能是由於發生此崩潰的特定裝置或其執行環境的問題。有關使您的應用程式更高效執行的提示,請參閱iOS效能和使用Instruments WWDC會話進行功耗優化。
  • 5、異常程式碼0xdead10cc表示應用程式已被作業系統終止,因為它在掛起期間保留了檔案鎖或sqlite資料庫鎖。如果您的應用程式在掛起時對鎖定檔案或sqlite資料庫執行操作,則它必須請求額外的後臺執行時間來完成這些操作並在掛起之前放棄鎖定。
  • 6、異常程式碼0x2bad45ec表示由於安全違規而導致應用程式被iOS終止。終止描述“在安全模式下檢測到進行不安全繪製的過程”表示應用程式試圖在不允許的情況下繪製到螢幕,例如螢幕被鎖定時。使用者可能不會注意到此終止,因為螢幕關閉或發生此終止時會顯示鎖定螢幕。
使用應用切換器終止暫停的應用不會生成崩潰報告。應用程式暫停後,它有資格隨時被iOS終止,因此不會生成崩潰報告。


複製程式碼

其他診斷資訊 本節包括特定於終止型別的其他診斷資訊,其中可能包括:

  • 1、特定於應用程式的資訊:在程式終止之前捕獲的框架錯誤訊息
  • 2、核心訊息:有關程式碼簽名問題的詳細資訊
  • 3、Dyld錯誤訊息:動態連結器發出的錯誤訊息

流程終止時生成的崩潰報告中的“應用程式特定資訊”部分的摘錄,因為找不到連結的框架

Dyld Error Message:
Dyld Message: Library not loaded: @rpath/MyCustomFramework.framework/MyCustomFramework
Referenced from: /private/var/containers/Bundle/Application/CD9DB546-A449-41A4-A08B-87E57EE11354/TheElements.app/TheElements
Reason: no suitable image found.

複製程式碼

流程終止時生成的崩潰報告中的“特定於應用程式的資訊”部分的摘錄,因為它無法快速載入其初始檢視控制器

Application Specific Information:
com.example.apple-samplecode.TheElements failed to scene-create after 19.81s (launch took 0.19s of total time limit 20.00s)

Elapsed total CPU time (seconds): 7.690 (user 7.690, system 0.000), 19% CPU
Elapsed application CPU time (seconds): 0.697, 2% CPU

複製程式碼

回溯

崩潰報告中最有趣的部分是它終止時每個程式執行緒的回溯。這些跟蹤中的每一條都與將程式與偵錯程式暫停時看到的類似

Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   TheElements                       0x000000010006bc20 -[AtomicElementViewController myTransitionDidStop:finished:context:] (AtomicElementViewController.m:203)
1   UIKit                             0x0000000194cef0f0 -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 312
2   UIKit                             0x0000000194ceef30 -[UIViewAnimationState animationDidStop:finished:] + 160
3   QuartzCore                        0x0000000192178404 CA::Layer::run_animation_callbacks(void*) + 260
4   libdispatch.dylib                 0x000000018dd6d1c0 _dispatch_client_callout + 16
5   libdispatch.dylib                 0x000000018dd71d6c _dispatch_main_queue_callback_4CF + 1000
6   CoreFoundation                    0x000000018ee91f2c __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
7   CoreFoundation                    0x000000018ee8fb18 __CFRunLoopRun + 1660
8   CoreFoundation                    0x000000018edbe048 CFRunLoopRunSpecific + 444
9   GraphicsServices                  0x000000019083f198 GSEventRunModal + 180
10  UIKit                             0x0000000194d21bd0 -[UIApplication _run] + 684
11  UIKit                             0x0000000194d1c908 UIApplicationMain + 208
12  TheElements                       0x00000001000653c0 main (main.m:55)
13  libdyld.dylib                     0x000000018dda05b8 start + 4

Thread 1:
0   libsystem_kernel.dylib            0x000000018deb2a88 __workq_kernreturn + 8
1   libsystem_pthread.dylib           0x000000018df75188 _pthread_wqthread + 968
2   libsystem_pthread.dylib           0x000000018df74db4 start_wqthread + 4
複製程式碼

第一行列出了執行緒號和當前正在執行的排程佇列的識別符號。其餘行列出了有關回溯中各個堆疊幀的詳細資訊。從左到右:

  • 1、堆疊幀號。堆疊幀以呼叫順序呈現,其中第0幀是在執行暫停時執行的函式。第一幀是在第0幀呼叫函式的函式,依此類推。
  • 2、堆疊幀的執行函式所在的二進位制檔案的名稱。
  • 3、對於第0幀,執行停止時執行的機器指令的地址。對於剩餘的堆疊幀,當控制返回到堆疊幀時將下一次執行的機器指令的地址。
  • 4、在符號化崩潰報告中,堆疊框架中函式的方法名稱。

來自非符號化崩潰報告的Last Exception Backtrace部分的摘錄。

Last Exception Backtrace:
(0x18eee41c0 0x18d91c55c 0x18eee3e88 0x18f8ea1a0 0x195013fe4 0x1951acf20 0x18ee03dc4 0x1951ab8f4 0x195458128 0x19545fa20 0x19545fc7c 0x19545ff70 0x194de4594 0x194e94e8c 0x194f47d8c 0x194f39b40 0x194ca92ac 0x18ee917dc 0x18ee8f40c 0x18ee8f89c 0x18edbe048 0x19083f198 0x194d21bd0 0x194d1c908 0x1000ad45c 0x18dda05b8)
複製程式碼

必須對包含僅包含十六進位制地址的Last Exception Backtrace的崩潰日誌進行符號化,以生成可用的回溯

號化崩潰報告中的Last Exception Backtrace部分的摘錄。在應用程式的故事板中載入場景時引發了此異常。缺少用於連線到場景中元素的相應IBOutlet

Last Exception Backtrace:
0   CoreFoundation                    0x18eee41c0 __exceptionPreprocess + 124
1   libobjc.A.dylib                   0x18d91c55c objc_exception_throw + 56
2   CoreFoundation                    0x18eee3e88 -[NSException raise] + 12
3   Foundation                        0x18f8ea1a0 -[NSObject(NSKeyValueCoding) setValue:forKey:] + 272
4   UIKit                             0x195013fe4 -[UIViewController setValue:forKey:] + 104
5   UIKit                             0x1951acf20 -[UIRuntimeOutletConnection connect] + 124
6   CoreFoundation                    0x18ee03dc4 -[NSArray makeObjectsPerformSelector:] + 232
7   UIKit                             0x1951ab8f4 -[UINib instantiateWithOwner:options:] + 1756
8   UIKit                             0x195458128 -[UIStoryboard instantiateViewControllerWithIdentifier:] + 196
9   UIKit                             0x19545fa20 -[UIStoryboardSegueTemplate instantiateOrFindDestinationViewControllerWithSender:] + 92
10  UIKit                             0x19545fc7c -[UIStoryboardSegueTemplate _perform:] + 56
11  UIKit                             0x19545ff70 -[UIStoryboardSegueTemplate perform:] + 160
12  UIKit                             0x194de4594 -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1352
13  UIKit                             0x194e94e8c -[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 268
14  UIKit                             0x194f47d8c _runAfterCACommitDeferredBlocks + 292
15  UIKit                             0x194f39b40 _cleanUpAfterCAFlushAndRunDeferredBlocks + 560
16  UIKit                             0x194ca92ac _afterCACommitHandler + 168
17  CoreFoundation                    0x18ee917dc __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32
18  CoreFoundation                    0x18ee8f40c __CFRunLoopDoObservers + 372
19  CoreFoundation                    0x18ee8f89c __CFRunLoopRun + 1024
20  CoreFoundation                    0x18edbe048 CFRunLoopRunSpecific + 444
21  GraphicsServices                  0x19083f198 GSEventRunModal + 180
22  UIKit                             0x194d21bd0 -[UIApplication _run] + 684
23  UIKit                             0x194d1c908 UIApplicationMain + 208
24  TheElements                       0x1000ad45c main (main.m:55)
25  libdyld.dylib                     0x18dda05b8 start + 4

複製程式碼

64位iOS使用“零成本”異常實現。在“零成本”系統中,每個函式都有附加資料,這些資料描述瞭如果在函式中丟擲異常,如何展開堆疊。如果在沒有展開資料的堆疊幀中丟擲異常,則異常處理無法繼續,程式將停止。堆疊上可能有一個異常處理程式,但如果沒有一個框架的展開資料,那麼就無法從丟擲異常的堆疊框架到達那裡。指定該-no_compact_unwind標誌意味著您沒有獲得該程式碼的展開表,因此您不能在這些函式之間丟擲異常。

此外,如果要在應用程式或庫中包含純C程式碼,則可能需要指定該-funwind-tables標誌以包含該程式碼中所有函式的展開表。

執行緒狀態

本節列出了崩潰執行緒的執行緒狀態。這是一個暫存器列表及其執行停止時的值。在閱讀崩潰報告時,無需瞭解執行緒狀態,但您可以使用此資訊更好地瞭解崩潰的情況

來自ARM64裝置的崩潰報告的“執行緒狀態”部分的摘錄。

Thread 0 crashed with ARM Thread State (64-bit):
x0: 0x0000000000000000   x1: 0x000000019ff776c8   x2: 0x0000000000000000   x3: 0x000000019ff776c8
x4: 0x0000000000000000   x5: 0x0000000000000001   x6: 0x0000000000000000   x7: 0x00000000000000d0
x8: 0x0000000100023920   x9: 0x0000000000000000  x10: 0x000000019ff7dff0  x11: 0x0000000c0000000f
x12: 0x000000013e63b4d0  x13: 0x000001a19ff75009  x14: 0x0000000000000000  x15: 0x0000000000000000
x16: 0x0000000187b3f1b9  x17: 0x0000000181ed488c  x18: 0x0000000000000000  x19: 0x000000013e544780
x20: 0x000000013fa49560  x21: 0x0000000000000001  x22: 0x000000013fc05f90  x23: 0x000000010001e069
x24: 0x0000000000000000  x25: 0x000000019ff776c8  x26: 0xee009ec07c8c24c7  x27: 0x0000000000000020
x28: 0x0000000000000000  fp: 0x000000016fdf29e0   lr: 0x0000000100017cf8
sp: 0x000000016fdf2980   pc: 0x0000000100017d14 cpsr: 0x60000000

複製程式碼

崩潰報告的二進位制映像部分中應用程式條目的摘錄

Binary Images:
0x100060000 - 0x100073fff TheElements arm64 <2defdbea0c873a52afa458cf14cd169e> /var/containers/Bundle/Application/888C1FA2-3666-4AE2-9E8E-62E2F787DEC1/TheElements.app/TheElements
...
複製程式碼

每行包括單個二進位制影像的以下詳細資訊:

  • 程式中的二進位制映像的地址空間。
  • 二進位制檔案的二進位制名稱或包識別符號(僅限macOS)。在來自macOS的崩潰報告中,如果二進位制檔案是作業系統的一部分,則字首為(+)。
  • (僅限macOS)二進位制檔案的短版本字串和包版本,用短劃線分隔。
  • (僅限iOS)二進位制影像的體系結構。二進位制檔案可能包含多個“切片”,每個“切片”支援一個體繫結構。這些切片中只有一個載入到過程中。
  • 唯一標識二進位制映像的UUID。此值隨二進位制的每個構建而變化,用於在表示崩潰報告時定位相應的dSYM檔案。
  • 磁碟上二進位制檔案的路徑

瞭解低記憶體報告

當檢測到低記憶體條件時,iOS中的虛擬記憶體系統依賴於應用程式的協作來釋放記憶體。低記憶體通知作為釋放記憶體的請求傳送到所有正在執行的應用程式和程式,希望減少使用的記憶體量。如果記憶體壓力仍然存在,系統可以終止後臺程式以減輕記憶體壓力。如果可以釋放足夠的記憶體,您的應用程式將繼續執行。如果沒有,您的應用程式將被iOS終止,因為沒有足夠的記憶體來滿足應用程式的需求,並且將生成低記憶體報告並將其儲存在裝置上。

低記憶體報告的格式與其他崩潰報告的不同之處在於,應用程式執行緒沒有回溯。低記憶體報告以類似於崩潰報告的標頭的標頭開頭。標題後面是列出系統範圍記憶體統計資訊的欄位集合。記下“ 頁面大小”欄位的值。低記憶體報告中每個程式的記憶體使用量按記憶體頁數報告。

低記憶體報告中最重要的部分是程式表。此表列出了生成低記憶體報告時所有正在執行的程式,包括系統守護程式。如果一個過程被“拋棄”,原因將列在[reason]列下。一個過程可能會被拋棄

  • 1、[per-process-limit]:該程式超過了系統強加的記憶體限制。駐留記憶體的每程式限制由系統為所有應用程式建立。越過此限制使該過程有資格終止。
  • 2、[vm-pageshortage] / [vm-thrashing] / [vm]:由於記憶體壓力,該程式被終止。
  • 3、[vnode-limit]:開啟的檔案太多。
  • 4、[highwater]:系統守護程式越過其高水位標記以便使用記憶體。
  • 5、[jettisoned]:由於其他原因,該過程被拋棄了。

文章轉載自:iOS crash官方文件

想要更加詳細的瞭解,可以參考一下的一些文章

相關文章