Crash我們不得不面對的問題,但是好多人在遇到Crash的時候都無從下手,很多的時候都是憑著感覺找問題。今天我做了5篇文章來幫助我們更加清晰的認清iOS中的Crash
想要了解更詳細的內容可以點擊這里
當應用程序崩潰時,會創建一個崩潰報告,這對于了解導致崩潰的原因非常有用。本文檔包含有關如何表示,理解和解釋崩潰報告的基本信息。
- 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類似。
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,以利用未來的編譯器改進,而無需您采取任何操作
由于二進制文件的最終編譯發生在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文件夾中的文件。
確定崩潰報告是否符號化
崩潰報告可以是非符號化的,完全符號化的或部分符號化的。非符號化的崩潰報告將不包含回溯中的方法或函數名稱。相反,您在加載的二進制圖像中具有可執行代碼的十六進制地址。在完全符號化的崩潰報告中,回溯的每一行中的十六進制地址將替換為相應的符號。在部分符號化的崩潰報告中,只有回溯中的某些地址已替換為其相應的符號。
顯然,您應該嘗試完全符合您收到的任何崩潰報告,因為它將提供有關崩潰的最深入見解。部分符號化的崩潰報告可能包含足夠的信息來了解崩潰,具體取決于崩潰的類型以及成功符號化的回溯的哪些部分。非符號化的崩潰報告很少有用
用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、在崩潰報告底部的二進制圖像列表中查找具有該名稱的二進制圖像。請注意二進制映像的體系結構和加載地址。
符號故障排除
如果Xcode未能完全符合崩潰報告,可能是因為您的Mac缺少dSYM應用程序二進制dSYM文件的文件,應用程序鏈接的一個或多個框架的文件,或者應用程序運行的OS的設備符號它墜毀了。以下步驟顯示如何使用Spotlight確定dSYM在Mac上是否存在表示二進制圖像中的回溯地址所需的文件。
- 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 == <UUID>"(包括引號)。
使用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 Key
CrashReporter密鑰:匿名的每設備標識符。來自同一設備的兩個報告將包含相同的值。 - 3、
Beta Identifier
Beta標識符:崩潰應用程序的設備和供應商組合的唯一標識符。來自同一供應商和同一設備的兩個應用程序報告將包含相同的值。此字段僅存在于為通過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]:由于其他原因,該過程被拋棄了。
想要更加詳細的了解,可以參考一下的一些文章