IOS Crash Log 分析

來源:互聯網
上載者:User

標籤:http   aaaaa   clang   armv7   順序   count   code   use   define   

上架AppStroe 被打回來了,原因是:

Your app crashed on iPad running iOS 11.3.1 connected to an IPv6 network when we tapped on profile image. 

We have attached detailed crash logs to help troubleshoot this issue.

崩潰日誌

一、Crash檔案結構

當程式運行Crash的時候,系統會把啟動並執行最後時刻的運行資訊記錄下來,儲存到一個檔案中,也就是我們所說的Crash檔案。iOS的Crash日誌通常由以下6各部分組成。

1、Process Information(進程資訊)

Incident Idnetifier 崩潰報告的唯一識別碼,不同的Crash
CrashReporter Key 裝置標識相對應的唯一索引值(並非真正的裝置的UDID,蘋果為了保護使用者隱私iOS6以後已經無法擷取)。通常同一個裝置上同一版本的App發生Crash時,該值都是一樣的。
Hardware Model 代表發生Crash的裝置類型,中的“iPad4,4”代表iPad Air
Process 代表Crash的進程名稱,通常都是我們的App的名字, []裡面是當時進程的ID
Path 可執行程式在手機上的儲存位置,注意路徑時到XXX.app/XXX,XXX.app其實是作為一個Bundle的,真正的可執行檔其實是Bundle裡面的XXX,感興趣的可以自己查一下相關資料,有機會我後面也會介紹到
Identifier 你的App的Indentifier,通常為“com.xxx.yyy”,xxx代表你們公司的網域名稱,yyy代表某一個App
Version 當前App的版本號碼,由Info.plist中的兩個欄位組成,CFBundleShortVersionString and CFBundleVersion
Code Type 當前App的CPU架構
Parent Process 當前進程的父進程,由於iOS中App通常都是單進程的,一般父進程都是launchd

 

 

 

 

 

 

 

2、Basic Information

Date/Time Crash發生的時間,可讀的字串
OS Version 系統版本,()內的數字代表的時Bulid號
Report Version Crash日誌的格式,目前基本上都是104,不同的version裡麵包含的欄位可能有不同

 

 

 

3、Exception(非常重要)

Exception Type 異常類型
Exception Subtype: 異常子類型
Crashed Thread 發生異常的線程號

 

 

 

4、Thread Backtrace

發生Crash的線程的Crash調用棧,從上到下分別代表調用順序,最上面的一個表示拋出異常的位置,依次往下可以看到API的調用順序。的資訊表明本次Crash出現xxxViewController的323行,出錯的函數調用為orderCountLoadFailed。

 

5、Thread State

Crash時發生時刻,線程的狀態,通常我們根據Crash棧即可擷取到相關資訊,這部分一般不用關心。

6、Binary Images

Crash時刻App載入的所有的庫,其中第一行是Crash發生時我們App可執行檔的資訊,可以看出為armv7,可執行檔的包得uuid位c0f……cd65,解析Crash的時候dsym檔案的uuid必須和這個一樣才能完成Crash的符號化解析。

二、常見的Crash類型

1、Watchdog timeout

Exception Code:0x8badf00d, 不太直觀,可以讀成“eat bad food”,意思是don‘t block main thread

緊接著下面會有一段描述:

Application Specific Information:

com.xxx.yyy   failed to resume in time

對於此類Crash,我們應該去審視自己App初始化時做的事情是否正確,是否在主線程請求了網路,或者其他耗時的事情卡住了正常初始化流程。

通常系統允許一個App從啟動到可以相應使用者事件的時間最多為5S,如果超過了5S,App就會被系統終止掉。在Launch,resume,suspend,quit時都會有相應的時間要求。在Highlight Thread裡面我們可以看到被終止時調用到的位置,xxxAppDelegate加上行號。 

PS. 在串連Xcode調試時為了便於調試,系統會暫時禁用掉Watchdog,所以此類問題的發現需要使用正常的啟動模式。

2、User force-quit

Exception Codes: 0xdeadfa11, deadfall

這個強制退出跟我們平時所說的kill掉背景工作操作還不太一樣,通常在程式bug造成系統無法響應時可以採用長按電源鍵,當螢幕出現關機確認畫面時按下Home鍵即可關閉當前程式。

3、Low Memory termination

跟一般的Crash結構不太一樣,通常有Free pages,Wired Pages,Purgeable pages,largest process 組成,同事會列出當前時刻系統運行所有進程的資訊。

關於Memory warning可以參看我之前寫的一篇文章IOS 記憶體警告 Memory warning level。

App在運行過程中,系統記憶體緊張時通常會先發警告,同時把後台掛起的程式終止掉,最終如果還是記憶體不夠的話就會終止掉當前前台的進程。

當接受到記憶體警告的事後,我們應該釋放儘可能多的記憶體,Crash其實也可以看做是對App的一種保護。

4、Crash due to bugs

因為程式bug導致的Crash通常千奇百怪,很難一概而論。大部分情況通過Crash日誌就可以定位出問題,當然也不排除部分疑難雜症看半天都不值問題出在哪兒。這個就只能看功底了,一點點找,總是能發現蛛絲馬跡。是在看不出來時還可以求助於Google大神,總有人遇到和你一樣的Bug 

三、常見的Exception Type & Exception Code

1、Exception Type

1)EXC_BAD_ACCESS

此類型的Excpetion是我們最長碰到的Crash,通常用於訪問了不改訪問的記憶體導致。一般EXC_BAD_ACCESS後面的"()"還會帶有補充資訊。

SIGSEGV: 通常由於重複釋放對象導致,這種類型在切換了ARC以後應該已經很少見到了。

SIGABRT:  收到Abort訊號退出,通常Foundation庫中的容器為了保護狀態正常會做一些檢測,例如插入nil到數組中等會遇到此類錯誤。

SEGV:(Segmentation  Violation),代表無效記憶體位址,比如null 指標,未初始化指標,棧溢出等;

SIGBUS:匯流排錯誤,與 SIGSEGV 不同的是,SIGSEGV 訪問的是無效地址,而 SIGBUS 訪問的是有效地址,但匯流排訪問異常(如地址對齊問題)

SIGILL:嘗試執行非法的指令,可能不被識別或者沒有許可權

2)EXC_BAD_INSTRUCTION

此類異常通常由於線程執行非法指令導致

3)EXC_ARITHMETIC

除零錯誤會拋出此類異常

2、Exception Code

0xbaaaaaad 此種類型的log意味著該Crash log並非一個真正的Crash,它僅僅只是包含了整個系統某一時刻的運行狀態。通常可以通過同時按Home鍵和音量鍵,可能由於使用者不小心觸發
0xbad22222 當VOIP程式在後台太過頻繁的啟用時,系統可能會終止此類程式
0x8badf00d 這個前面已經介紹了,程式啟動或者恢復過長被watch dog終止
0xc00010ff 程式執行大量耗費CPU和GPU的運算,導致裝置過熱,觸發系統過熱保護被系統終止
0xdead10cc 程式退到後台時還佔用系統資源,如通訊錄被系統終止
0xdeadfa11 前面也提到過,程式無響應使用者強制關閉

  

三、擷取Crash的途徑

1、本機

通過xCode串連測試機器,直接在Device中即可讀取到該機器上發生的所有Crash log。

2、itunes connect

通過itunes connect後台擷取到使用者上報的Crash日誌。

3、第三方的Crash收集系統

有很多優秀的第三方Crash收集系統大大的方便了我們收集Crash,甚至還帶了符號化Crash日誌的功能。比較常用的有Crashlytics,Flurry等。

三、Xcode內建工具symbolicatecrash解析iOS Crash檔案

 

一、找到.app檔案和.app.dSYM檔案

 

  • 在案頭建立一個crash檔案夾,然後Xcode->Window->Organizer找到Archives找到App->右擊Show in 
    Finder

  • 複製.app和.app.dSYM到crash夾檔案:右擊.xcarchive檔案->顯示包內容 
    在dSYMs檔案夾中找到.app.dSYM 
    在Products->Applications檔案夾中找到*.app

 

二、找到symbolicatecrash

 

  • 1 find /Applications/Xcode.app -name symbolicatecrash -type f

 

  • 稍等一會就會有路徑輸出,這個路徑就是symbolicatecrash的路徑

 

  • 1 /Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash

 

  • 用命令將symbolicatecrash拷貝到案頭的crash檔案夾裡面,與.app和.app.dSYM放一起(手動找到symbolicatecrash,拷貝出來也行)

 

  • 1 cp /Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash /Users/你的電腦名稱/Desktop/crash

 

三、執行symbolicatecrash

 

  • 開啟終端用命令切換到案頭的crash目錄下:

 

  • 1 cd /Users/你的電腦名稱/Desktop/crash

 

  • 執行命令

 

  • 1 ./symbolicatecrash /Users/angelseahappiness/Desktop/crash/Control_2014-01-13-111838_Lynns-iPad3.crash /Users/angel/Desktop/crash/Control.app.dSYM > Control_symbol.crash

 

  • 這時候終端有可能會出現:

 

  • 1 Error: "DEVELOPER_DIR" is not defined at ./symbolicatecrash line 69.

 

  • 輸入命令:

 

  • 1 export DEVELOPER_DIR="/Applications/XCode.app/Contents/Developer"

 

    • 再執行,這時候終端將會進行處理了
    • 將終端完成以後,在crash檔案夾裡面會多出一個檔案Control_symbol.crash:這個就是最終的檔案,可以查看bug所在的位置。

 

 因為上面的崩潰日誌看不懂查看都是十六進位的地址不知道是哪裡出了問題

 

分析需要用到在上傳應用時的.app 和。dSYM 檔案。切記每次發送新版本都要保留這兩個檔案,不然沒有辦法解析Crash Log的,可以先把這兩個檔案拷貝到案頭的某一個檔案夾中,然後把.crash的檔案也拷貝的同一個檔案夾下。

這一解析過程需要使用Symbolicatecrash來完成,首先要找到Symbolicatecrash檔案

Symbolicatecrash檔案獨立於Xcode,可以拷到剛才放crash log的檔案夾中使用,在開始解析之前需要先進行一些校正:

1. 查看xx.app檔案的uuid的方法,在命令列中輸入:

$ dwarfdump --uuid xxx.app/xxx (xxx工程名)
2. 查看xx.app.dSYM檔案的uuid的方法,在命令列輸入:
$ dwarfdump --uuid xxx.app.dSYM (xxx工程名)
3.查看.crash的uuid,位於crash日誌中的Binary Images:中的第一行。如:armv7s  <13760bde0d073f1eb4d596c3df753f4b>
只有三者的uuid相同才能解析.crash檔案,然後在命令列輸入:
$ ./symbolicatecrash xxx.crash xxx.app.dSYM > test.log
這樣可以將.crash日誌轉換成test.log,test.log即可讀的函數檔案。
輸入上述命令可能會出現Error: "DEVELOPER_DIR" is not defined at ./symbolicatecrash line 53.這個錯誤。
如果出現上述錯誤,輸入命令:export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer,
然後繼續執行./symbolicatecrash xxx.crash xxx.app.dSYM > test.log可以成功

{"app_name":"MHdoctor","timestamp":"2018-05-22 11:08:48.28 -0700","app_version":"1.3.0","slice_uuid":"d19af238-ed08-32c2-9882-d9d17f4a3add","adam_id":1110258767,"build_version":"1.9","bundleID":"com.md.MHdoctor","share_with_app_devs":false,"is_first_party":false,"bug_type":"109","os_version":"iPhone OS 11.3.1 (15E302)","incident_id":"12CC75F6-9064-4A47-9D7E-E9B6B4D0D69E","name":"MHdoctor"}
Incident Identifier: 12CC75F6-9064-4A47-9D7E-E9B6B4D0D69E
CrashReporter Key: 467949c45077b22197dba2880a7275a842d5dbf8
Hardware Model: xxx1
Process: MHdoctor [4393]
Path: /private/var/containers/Bundle/Application/B3AF5423-5751-4EFF-B9E6-44F5FA6CFEBA/MHdoctor.app/MHdoctor
Identifier: com.md.MHdoctor
Version: 1.9 (1.3.0)
Code Type: ARM-64 (Native)
Role: Foreground
Parent Process: launchd [1]
Coalition: com.md.MHdoctor [2305]


Date/Time: 2018-05-22 11:08:48.1360 -0700
Launch Time: 2018-05-22 11:07:56.9302 -0700
OS Version: iPhone OS 11.3.1 (15E302)
Baseband Version: n/a
Report Version: 104

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

Application Specific Information:
abort() called

Filtered syslog:
None found

Last Exception Backtrace:
0 CoreFoundation 0x18108ad8c 0x180f45000 + 1334668
1 libobjc.A.dylib 0x1802445ec 0x18023c000 + 34284
2 CoreFoundation 0x18108abf8 0x180f45000 + 1334264
3 Foundation 0x181a7afa0 0x1819bd000 + 778144
4 UIKit 0x18ac806e0 0x18ac14000 + 444128
5 MHdoctor 0x102f9451c UserDataViewController.imageViewTouch() + 3589404 (UserDataViewController.swift:466)
6 MHdoctor 0x102f95410 @objc UserDataViewController.viewDidLoad+ 3593232 () + 27
7 UIKit 0x18ae3a750 0x18ac14000 + 2254672
8 UIKit 0x18b3a72a4 0x18ac14000 + 7942820
9 UIKit 0x18af9ce6c 0x18ac14000 + 3706476
10 UIKit 0x18ae397a8 0x18ac14000 + 2250664
11 UIKit 0x18b398ac4 0x18ac14000 + 7883460
12 UIKit 0x18ae33540 0x18ac14000 + 2225472
13 UIKit 0x18ae33078 0x18ac14000 + 2224248
14 UIKit 0x18ae328dc 0x18ac14000 + 2222300
15 UIKit 0x18ae31238 0x18ac14000 + 2216504
16 UIKit 0x18b612c0c 0x18ac14000 + 10480652
17 UIKit 0x18b6151b8 0x18ac14000 + 10490296
18 UIKit 0x18b60e258 0x18ac14000 + 10461784

 

這時候發現之前的一些行首為項目名 後面的地址變成的方面調用+行號。

解析ios Crash Log(根據位址解析內容)

此外,還可以在上面三個uuid對應的情況下解析某一個地址的內容

$ xcrun atos -o xxx.app/xxx -arch armv7 0x38ad42f9 0x38ad42f9 0x38ad42f9(多個16進位地址,使用空格分開)---方法一$ dwarfdump -–lookup 0x000036d2 -–arch armv6 xxx.app.dSYM ---方法二

 如果根據以上方法操作,均提示找不到地址的話,可以使用必殺了:

比如尋找以下內容所對應的地址:
(當前程式碼地址 = 當前地址 + 地址位移量,地址位移量為十進位數值,公式是這樣寫的,但不知道具體表達是不是這個意思,如果相同的crash,相同位置後面的地址位移量相同,前面兩個數值可能會有變動)
10  TestTransform                     0x00057132 0x4f000 + 33074
1.先說第一種比較簡單的方法利用 "當前地址" 和 "當前程式碼地址"
$ xcrun atos -o TestTransform.app/TestTransform -l 0x3d000 0x0004fc5c//輸出結果:baidudeMacBook-Pro:1 baidu$ xcrun atos -o /Users/baidu/Desktop/1/TestTransform.app/TestTransform -l 0x3d000 0x0004fc5cgot symbolicator for /Users/baidu/Desktop/1/TestTransform.app/TestTransform, base address 4000main (in TestTransform) (main.m:16)

2. 第二種相對複雜一點,涉及到地址的位移,使用首先查看起始地址,即使每次iOS app啟動都會載入(main module)主模組在不同的記憶體位址,但是dSYM檔案假設你的main module載入在地址0x1000(大多數情況是這個,也有0x4000的)。

擷取此地址的方法:

$ otool -arch armv7 -l /Users/cnstar-tech/crash/xxx.app/xxx  | grep -B 1 -A 10 "LC_SEGM" | grep -B 3 -A 8 "__TEXT"
調用以上方法返回結果如下:
Load command 1      cmd LC_SEGMENT  cmdsize 600  segname __TEXT   vmaddr 0x00004000   vmsize 0x00014000  fileoff 0 filesize 81920  maxprot 0x00000005 initprot 0x00000005   nsects 8    flags 0x0

看到vmaddr顯示為0x00004000。

然後查看  "TestTransform 0x00057132 0x4f000 + 33074"  使用 起始地址+地址位移量如:
0x4000 + 33074 = 0xc132   (注意:前面為前面為16進位後面為10進位相加,要都轉換成10進位相加,把得出的結果轉換成16進位)
就可以使用 "0xc132" 地址查看內容了:

//方法一:$ dwarfdump --lookup 0xc132 --arch armv7 MHdoctor.app.DSYM//輸出結果:---------------------------------------------------------------------- File: TestTransform.app.DSYM/Contents/Resources/DWARF/
MHdocto
(armv7) ---------------------------------------------------------------------- Looking up address: 0x000000000000c132 in .debug_info... found! 0x00003947: Compile Unit: length = 0x00007b6e version = 0x0002 abbr_offset = 0x00000000 addr_size = 0x04 (next CU at 0x0000b4b9) 0x00003952: TAG_compile_unit [1] * AT_producer( "Apple LLVM version 5.1 (clang-503.0.38) (based on LLVM 3.4svn)" ) AT_language( DW_LANG_ObjC ) AT_name( "/Users/baidu/Desktop/MHdoctor/MHdoctor/ViewController.m" ) AT_low_pc( 0x0000a950 ) AT_stmt_list( 0x0000089f ) AT_comp_dir( "/Users/baidu/Desktop/TestTransform" ) AT_APPLE_major_runtime_vers( 0x02 ) 0x00003c22: TAG_subprogram [39] * AT_name( "__29-[ViewController aaaaaaaaaa:]_block_invoke" ) AT_decl_file( "/Users/baidu/Desktop/MHdoctor/MHdoctor/ViewController.m" ) AT_decl_line( 191 ) AT_prototyped( 0x01 ) AT_APPLE_isa( 0x01 ) AT_accessibility( DW_ACCESS_public ) AT_low_pc( 0x0000c09c ) AT_high_pc( 0x0000c182 ) AT_frame_base( r7 ) 0x00003c46: TAG_lexical_block [34] * AT_low_pc( 0x0000c0d6 ) AT_high_pc( 0x0000c17e ) Line table dir : ‘/Users/baidu/Desktop/MHdoctor/MHdoctor‘ Line table file: ‘ViewController.m‘ line 193, column 0 with start address 0x000000000000c11e Looking up address: 0x000000000000c132 in .debug_frame... found! 0x00000160: FDE length: 0x0000000c CIE_pointer: 0x00000000 start_addr: 0x0000c09c __29-[ViewController aaaaaaaaaa:]_block_invoke range_size: 0x000000e6 (end_addr = 0x0000c182) Instructions: 0x0000c09c: CFA=4294967295+4294967295 //方法二: $ xcrun atos -o /Users/baidu/Desktop/1/
MHdocto
.app/
MHdocto
0xc132 //輸出結果: __29-[ViewController aaaaaaaaaa:]_block_invoke (in
MHdocto
) (ViewController.m:193)

 

IOS Crash Log 分析

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.