Crash日誌解析

當應用程序崩潰時,會建立一個崩潰報告,這對於瞭解致使崩潰的緣由很是有用。本文檔包含有關如何表示,理解和解釋崩潰報告的基本信息。html

  • 一、介紹
  • 二、獲取崩潰和低內存報告
  • 三、象徵性的奔潰報告
    • 一、位碼(bitCode)
    • 二、肯定奔潰報告是否符號化
    • 三、用Xcode標記iOS奔潰報告
    • 四、用atos表示崩潰報告
    • 五、符號故障排除
  • 四、崩潰報告分析
    • 一、頭
    • 二、例外信息
    • 三、其餘診斷信息
    • 四、回溯
    • 五、線程狀態
    • 六、二進制圖像
  • 五、瞭解低內存報告

介紹

當應用程序崩潰時,會建立崩潰報告並將其存儲在設備上。崩潰報告描述了應用程序終止的條件,在大多數狀況下包括每一個執行線程的完整回溯,而且一般對於調試應用程序中的問題很是有用。您應該查看這些崩潰報告,以瞭解您的應用程序崩潰了什麼,而後嘗試修復它們。node

帶有回溯的崩潰報告須要在進行分析以前進行符號化。符號化用人類可讀的函數名稱和行號替換內存地址。若是您經過Xcode的設備窗口從設備上獲取崩潰日誌,那麼幾秒鐘後它們將自動被符號化。不然,您須要經過將.crash文件導入Xcode Devices窗口來自行符號化。有關詳細信息,請參閱符號崩潰報告。ios

一個低內存報告不一樣之處在於有這類型的報告沒有回溯其餘的崩潰報告。當發生低內存崩潰時,您必須調查內存使用模式以及對低內存警告的響應。git

獲取崩潰和低內存報告

調試已部署的iOS應用程序討論瞭如何直接從iOS設備檢索崩潰和低內存報告。github

分析「 應用程序分發指南」中的崩潰報告討論瞭如何查看從TestFlight beta測試人員和從App Store下載應用程序的用戶收集的聚合崩潰報告。sql

象徵性的崩潰報告

符號化是將回溯地址解析爲源代碼方法或函數名稱(稱爲符號)的過程。若是沒有首先表示崩潰報告,則很難肯定崩潰發生的位置。數據庫

注意:  低內存報告不須要進行符號化。
注意:  macOS的崩潰報告一般在生成時被符號化或部分符號化。本節重點介紹iOS,watchOS和tvOS的崩潰報告,但整個過程與macOS相似。
複製代碼

Crash日誌.png

一、當編譯器將源代碼轉換爲機器代碼時,它還會生成調試符號,這些符號將編譯後的二進制文件中的每一個機器指令映射回源自它的源代碼行。根據Debug Information Format(DEBUG_INFORMATION_FORMAT)構建設置,這些調試符號存儲在二進制文件或伴隨的Debug Symbol(dSYM)文件中。默認狀況下,應用程序的調試版本將調試符號存儲在已編譯的二進制文件中,而應用程序的發佈版本將調試符號存儲在配套dSYM文件中以減少二進制文件大小。 調試符號文件和應用程序二進制文件經過構建UUID在每一個構建的基礎上綁定在一塊兒。爲應用程序的每一個構建生成一個新的UUID,並惟一標識該構建。即便從相同的源代碼重建功能相同的可執行文件,使用相同的編譯器設置,它也將具備不一樣的構建UUID。調試來自後續版本的符號文件,即便是來自相同的源文件,也不會與來自其餘版本的二進制文件互操做。xcode

  • 二、歸檔應用程序以進行分發時,Xcode將收集應用程序二進制文件以及。dSYM將文件存儲並保存在主文件夾內的某個位置安全

  • 三、若是您經過App Store分發應用程序,或使用Test Flight進行beta測試,您能夠選擇dSYM在將存檔上傳到iTunes Connect時包含該文件。在提交對話框中,選中「爲您的應用程序包含應用程序符號...」。上傳dSYM文件對於接收從TestFlight用戶和選擇共享診斷數據的客戶收集的崩潰報告是必要的bash

  • 四、當您的應用程序崩潰時,會建立一個非符號化的崩潰報告並將其存儲在設備上。

  • 五、用戶能夠按照調試已部署的iOS應用程序中的步驟直接從其設備檢索崩潰報告。若是您經過AdHoc或Enterprise分發分發了應用程序,則這是從用戶獲取崩潰報告的惟一方法。

  • 六、從設備檢索到的崩潰報告是非符號化的,須要使用Xcode進行符號化。Xcode使用dSYM與應用程序二進制文件關聯的文件將回溯中的每一個地址替換爲源代碼中的原始位置。結果是一個符號化的崩潰報告。

  • 七、若是用戶選擇與Apple共享診斷數據,或者用戶已經過TestFlight安裝了應用程序的測試版,則崩潰報告將上載到App Store

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

  • 九、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文件

  • 一、在Archives管理器中,選擇最初提交到App Store的存檔
  • 二、單擊「下載dSYMs」按鈕。 Xcode下載dSYM文件並將其插入選定的存檔。

從iTunes Connect網站下載dSYM文件

  • 一、打開「應用詳情」頁面。
  • 二、單擊活動。
  • 三、從「全部構建」列表中,選擇一個版本。
  • 四、單擊「 下載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擴展程序。
複製代碼
  • 一、將iOS設備鏈接到Mac
  • 二、從「窗口」菜單中選擇「設備」
  • 三、 在左列的「設備」部分下,選擇一個設備
  • 四、單擊右側面板「設備信息」部分下的「查看設備日誌」按鈕
  • 五、將崩潰報告拖到所顯示面板的左列
  • 六、Xcode將自動錶示崩潰報告並顯示結果

爲了表示崩潰報告,Xcode須要可以找到如下內容

  • 一、崩潰的應用程序的二進制dSYM文件和文件。
  • 二、dSYM應用程序連接的全部自定義框架的二進制文件和文件。對於使用應用程序從源構建的框架,它們的dSYM文件將與應用程序的dSYM文件一塊兒複製到存檔中。對於由第三方構建的框架,您須要向做者詢問該dSYM文件。
  • 三、崩潰時該應用程序運行的操做系統的符號。這些符號包含特定操做系統版本(例如iOS 9.3.3)中包含的框架的調試信息。OS符號是特定於體系結構的 - 用於64位設備的iOS版本不包含armv7符號。Xcode將自動從鏈接到Mac的每一個設備複製OS符號。

若是缺乏任何這些,Xcode可能沒法表示崩潰報告,或者可能只是部分地表示崩潰報告。

用atos表示崩潰報告

該 ATOS命令將數字地址轉換爲其符號等效項。若是有完整的調試符號信息,則輸出atos將包括文件名和源行號信息。該atos命令可用於在非符號化或部分符號化的崩潰報告的回溯中表示各個地址。使用atos如下命令表示崩潰報告的一部分:

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

Crash日誌3.png

符號故障排除

若是Xcode未能徹底符合崩潰報告,多是由於您的Mac缺乏dSYM應用程序二進制dSYM文件的文件,應用程序連接的一個或多個框架的文件,或者應用程序運行的OS的設備符號它墜毀了。如下步驟顯示如何使用Spotlight肯定dSYM在Mac上是否存在表示二進制圖像中的回溯地址所需的文件。

Crash日誌4.png

  • 一、在回溯中找到Xcode沒法符號化的行。請注意第二列中二進制圖像的名稱
  • 二、在崩潰報告底部的二進制圖像列表中查找具備該名稱的二進制圖像。此列表包含崩潰時加載到進程中的每一個二進制映像的UUID。
您可使用grep命令行工具快速查找二進制映像列表中的條目。
$ grep --after-context = 1000「二進制圖像:」<崩潰報告的路徑> | grep <二進制名稱>
複製代碼
  • 三、將二進制映像的UUID轉換爲以8-4-4-4-12(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)爲一組分隔的32個字符串。請注意,全部字母必須是大寫的。
  • 四、使用mdfind命令行工具使用查詢搜索UUID "com_apple_xcode_dsym_uuids == "(包括引號)。
使用mdfind命令行工具搜索dSYM具備給定UUID的文件。
$ mdfind「com_apple_xcode_dsym_uuids == <UUID>」

複製代碼
  • 五、若是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
複製代碼
  • 一、Incident Identifier事件標識符:報告的惟一標識符。兩個報告永遠不會共享相同的事件標識符。
  • 二、CrashReporter KeyCrashReporter密鑰:匿名的每設備標識符。來自同一設備的兩個報告將包含相同的值。
  • 三、Beta IdentifierBeta標識符:崩潰應用程序的設備和供應商組合的惟一標識符。來自同一供應商和同一設備的兩個應用程序報告將包含相同的值。此字段僅存在於爲經過TestFlight分發的應用程序生成的崩潰報告中,並替換CrashReporter Key字段。
  • 四、Process進程:崩潰進程的可執行文件名稱。這與CFBundleExecutable應用程序的信息屬性列表中的鍵值匹配。
  • 五、Version版本:崩潰的進程版本。該字段的值是崩潰的應用程序CFBundleVersion和的串聯CFBundleVersionString。
  • 六、Code Type代碼類型:崩潰的進程的目標體系結構。這將是一ARM-64,ARM,x86-64,或x86。
  • 七、Role角色:終止時分配給進程的task_role。
  • 八、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
複製代碼
  • 一、Exception Codes異常代碼:有關異常的處理器特定信息,編碼爲一個或多個64位十六進制數。一般,此字段將不存在,由於Crash Reporter會解析異常代碼以將其做爲人類可讀的描述呈如今其餘字段中。
  • 二、Exception Subtype異常子類型:異常代碼的人類可讀名稱。
  • 三、Exception Message異常消息:從異常代碼中提取的其餘人類可讀信息。
  • 四、Exception Note異常注意:非特定於一種異常類型的附加信息。若是該字段包含,SIMULATED (this is NOT a crash)那麼進程沒有崩潰,可是在系統請求時被殺死,一般是看門狗
  • 五、Termination Reason終止緣由:終止進程時指定的退出緣由信息。進程內部和外部的關鍵系統組件將在遇到致命錯誤時終止進程(例如,錯誤的代碼簽名,缺乏的依賴庫,或在沒有適當權利的狀況下訪問隱私敏感信息)。macOS Sierra,iOS 10,watchOS 3和tvOS 10採用了新的基礎設施來記錄這些錯誤,這些操做系統生成的崩潰報告列出了終止緣由字段中的錯誤消息
  • 六、Triggered by Thread由線程觸發:發生異常的線程。

內存訪問不良[EXC_BAD_ACCESS // SIGSEGV // SIGBUS]

該進程嘗試訪問無效內存,或者嘗試之內存保護級別不容許的方式訪問內存(例如,寫入只讀內存)。該例外子類型字段包含一個kern_return_t描述錯誤,而且被錯誤地訪問的存儲器的地址。

如下是調試錯誤內存訪問崩潰的一些提示:

  • 一、若是崩潰線程的Backtraces頂部objc_msgSend或objc_release附近,則該進程可能已嘗試向已釋放的對象發送消息。您應該使用Zombies工具對應用程序進行概要分析,以便更好地瞭解此崩潰的狀況。
  • 二、若是在崩潰線程gpus_ReturnNotPermittedKillClient的Backtraces頂部附近,則該進程被終止,由於它在後臺嘗試使用OpenGL ES或Metal進行渲染。請參閱QA1766:如何在移動到後臺時修復OpenGL ES應用程序崩潰。
  • 三、啓用Address Sanitizer運行您的應用程序。地址清理程序在已編譯的代碼中添加了有關內存訪問的附加檢測。當您的應用程序運行時,若是以可能致使崩潰的方式訪問內存,Xcode將提醒您。

異常退出[EXC_CRASH // SIGABRT]

該過程異常退出。使用此異常類型致使崩潰的最多見緣由是未被​​捕獲的Objective-C / C ++ 異常和調用abort()。

若是App Extensions花費太多時間進行初始化(看門狗終止),它將以此異常類型終止。若是因爲啓動時掛起而致使擴展名被終止,則生成的崩潰報告的異常子類型將是LAUNCH_HANG。因爲擴展沒有main函數,所以初始化所花費的時間都發生在+load擴展和依賴庫中的靜態構造函數和方法中。你應該儘量多地推遲這項工做。

跟蹤陷阱[EXC_BREAKPOINT // SIGTRAP]

與異常退出相似,此異常旨在爲附加的調試器提供在其執行的特定點中斷進程的機會。您可使用該__builtin_trap()函數從您本身的代碼中觸發此異常。若是未附加調試器,則終止該過程並生成崩潰報告。

較低級別的庫(例如libdispatch)會在遇到致命錯誤時捕獲進程。有關錯誤的其餘信息能夠在崩潰報告的「 其餘診斷信息」部分或設備的控制檯中找到。

若是在運行時遇到意外狀況,則Swift代碼將以此異常類型終止,例如:

  • 一、具備nil值的非可選類型
  • 二、強制類型轉換失敗

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

在Intel處理器上,ud2操做碼會致使EXC_BAD_INSTRUCTION異常,但一般用於捕獲進程以進行調試。若是在運行時遇到意外狀況,則Intel處理器上的Swift代碼將以此異常類型終止。有關詳細信息,請參閱跟蹤陷阱

退出[SIGQUIT]

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

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

被殺[SIGKILL]

該過程在系統請求時終止。查看「 終止緣由」字段以更好地瞭解終止緣由。

該終止緣由字段將包含一個名稱空間,而後一個代碼。如下代碼特定於watchOS:

  • 一、終止代碼0xc51bad01表示監視應用程序已終止,由於它在執行後臺任務時使用了太多CPU時間。要解決此問題,請優化執行後臺任務的代碼以提升CPU效率,或減小應用程序在後臺運行時執行的工做量。
  • 二、終止代碼0xc51bad02表示監視應用程序因未能在分配的時間內完成後臺任務而終止。要解決此問題,請減小應用在後臺運行時執行的工做量。
  • 三、終止代碼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,則即便生成了崩潰報告,也不會終止該進程。

  • 一、異常子類型MEMORY表示進程已超過系統強加的內存限制。這多是終止超額內存使用的先兆。
  • 二、異常子類型WAKEUPS表示進程中的線程每秒被喚醒太屢次,這迫使CPU常常喚醒並消耗電池壽命。

一般,這是由線程到線程的通訊(一般使用peformSelector:onThread:或者dispatch_async)引發的,這種通訊在不知不覺中發生的頻率遠遠超過它應該發生的頻率。由於觸發此異常的通訊類型常常發生,因此一般會有多個具備很是類似的Backtraces的後臺線程- 指示通訊的來源。

其餘異常類型 某些崩潰報告可能包含未命名的異常類型,它將打印爲十六進制值(例如00000020)。若是您收到其中一個崩潰報告,請直接查看「 例外代碼」字段以獲取更多信息。

  • 一、異常代碼0xbaaaaaad表示日誌是整個系統的堆棧,而不是崩潰報告。要拍攝疊印,請同時按側面按鈕和兩個音量按鈕。這些日誌一般是由用戶意外建立的,並不表示錯誤。
  • 二、異常代碼0xbad22222表示iOS已終止VoIP應用程序,由於它過於頻繁地恢復。
  • 三、異常代碼0x8badf00d表示iOS已終止應用程序,由於發生了監視程序超時。應用程序啓動,終止或響應系統事件花費的時間太長。其中一個常見緣由是在主線程上進行同步網絡鏈接。不管什麼操做都Thread 0須要移動到後臺線程,或者以不一樣的方式處理,以便它不會阻塞主線程。
  • 四、異常代碼0xc00010ff表示應用程序被操做系統殺死以響應熱事件。這多是因爲發生此崩潰的特定設備或其運行環境的問題。有關使您的應用程序更高效運行的提示,請參閱iOS性能和使用Instruments WWDC會話進行功耗優化。
  • 五、異常代碼0xdead10cc表示應用程序已被操做系統終止,由於它在掛起期間保留了文件鎖或sqlite數據庫鎖。若是您的應用程序在掛起時對鎖定文件或sqlite數據庫執行操做,則它必須請求額外的後臺執行時間來完成這些操做並在掛起以前放棄鎖定。
  • 六、異常代碼0x2bad45ec表示因爲安全違規而致使應用程序被iOS終止。終止描述「在安全模式下檢測到進行不安全繪製的過程」表示應用程序試圖在不容許的狀況下繪製到屏幕,例如屏幕被鎖定時。用戶可能不會注意到此終止,由於屏幕關閉或發生此終止時會顯示鎖定屏幕。
使用應用切換器終止暫停的應用不會生成崩潰報告。應用程序暫停後,它有資格隨時被iOS終止,所以不會生成崩潰報告。


複製代碼

其餘診斷信息 本節包括特定於終止類型的其餘診斷信息,其中可能包括:

  • 一、特定於應用程序的信息:在進程終止以前捕獲的框架錯誤消息
  • 二、內核消息:有關代碼簽名問題的詳細信息
  • 三、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
複製代碼

第一行列出了線程號和當前正在執行的調度隊列的標識符。其他行列出了有關回溯中各個堆棧幀的詳細信息。從左到右:

  • 一、堆棧幀號。堆棧幀以調用順序呈現,其中第0幀是在執行暫停時執行的函數。第一幀是在第0幀調用函數的函數,依此類推。
  • 二、堆棧幀的執行函數所在的二進制文件的名稱。
  • 三、對於第0幀,執行中止時執行的機器指令的地址。對於剩餘的堆棧幀,當控制返回到堆棧幀時將下一次執行的機器指令的地址。
  • 四、在符號化崩潰報告中,堆棧框架中函數的方法名稱。

來自非符號化崩潰報告的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]列下。一個過程可能會被拋棄

  • 一、[per-process-limit]:該進程超過了系統強加的內存限制。駐留內存的每進程限制由系統爲全部應用程序創建。越過此限制使該過程有資格終止。
  • 二、[vm-pageshortage] / [vm-thrashing] / [vm]:因爲內存壓力,該進程被終止。
  • 三、[vnode-limit]:打開的文件太多。
  • 四、[highwater]:系統守護進程越過其高水位標記以便使用內存。
  • 五、[jettisoned]:因爲其餘緣由,該過程被拋棄了。

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

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

相關文章
相關標籤/搜索