# iOS進階 # 崩潰與日志分析

在iOS開發(fā)中經(jīng)常需要靠記錄日志來調(diào)試應(yīng)用程序、解決崩潰問題等坐梯,整理常用的日志輸出和崩潰日志分析。

最新更新:2018-11-30

基于CocoaLumberjack 的 Swift使用封裝庫

一瓤逼、崩潰的捕獲

1勺馆、崩潰日志產(chǎn)生原因

1、應(yīng)用中有Bug拗秘。

2圣絮、Watchdog 超時機制

3、用戶強制退出

4雕旨、低內(nèi)存終止

5扮匠、其他違反系統(tǒng)規(guī)則的操作,大部分是內(nèi)存問題

發(fā)生崩潰奸腺,系統(tǒng)會生成一份崩潰日志在本地餐禁,或者上傳 ITC

2、崩潰的類型(異常突照、信號錯誤)

異常類

NSRangeException等 NSException類

信號錯誤類

信號中斷(SGIABRT)、非法指令信號(SIGILL)氧吐、總線錯誤信號(SIGBUS)讹蘑、段錯誤信號(SIGSEGV)末盔、訪問一個已經(jīng)釋放的對象(EXC_BAD_ACCESS)

3、捕獲異常崩潰信息

只能捕獲一些異常崩潰座慰,如 unrecognized selector陨舱、NSRangeException beyond bounds越界等Exception屬錯誤

Appdelegate

在Appdelegate 的 didFinishLaunchingWithOptions 中 添加
NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);

方法實現(xiàn)如下
void UncaughtExceptionHandler(NSException *exception) {
    /**
     *  獲取異常崩潰信息
     */
    NSArray *callStack = [exception callStackSymbols];
    NSString *reason = [exception reason];
    NSString *name = [exception name];
    NSString *content = [NSString stringWithFormat:@"========異常錯誤報告========\nname:%@\nreason:\n%@\ncallStackSymbols:\n%@",name,reason,[callStack componentsJoinedByString:@"\n"]];
    
    //將崩潰信息持久化在本地,下次程序啟動時版仔、或者后臺游盲,將崩潰信息作為日志發(fā)送給開發(fā)者。
    [[NSUserDefaults standardUserDefaults] setObject:content forKey:@"ExceptionContent"];
}

測試

數(shù)組越界錯誤

NSMutableArray *array = [NSMutableArray array];
NSLog(@"%@",array[1]);

4蛮粮、捕獲信號錯誤崩潰信息

信號類型崩潰捕獲益缎,測試的時候如果測試Signal類型的崩潰,不要在xcode下的debug模式進行測試然想。因為系統(tǒng)的debug會優(yōu)先去攔截莺奔。應(yīng)該build好應(yīng)用之后直接點擊運行app進行測試。

1变泄、什么是信號

在計算機科學中令哟,信號(英語:Signals)是Unix、類Unix以及其他POSIX兼容的操作系統(tǒng)中進程間通訊的一種有限制的方式妨蛹。它是一種異步的通知機制屏富,用來提醒進程一個事件已經(jīng)發(fā)生。當一個信號發(fā)送給一個進程蛙卤,操作系統(tǒng)中斷了進程正常的控制流程狠半,此時,任何非原子操作都將被中斷表窘。如果進程定義了信號的處理函數(shù)典予,那么它將被執(zhí)行,否則就執(zhí)行默認的處理函數(shù)乐严。

在iOS中就是未被捕獲的Objective-C異常(NSException)瘤袖,導致程序向自身發(fā)送了SIGABRT信號而崩潰。

SIGABRT–程序中止命令中止信號
SIGALRM–程序超時信號
SIGFPE–程序浮點異常信號
SIGILL–程序非法指令信號
SIGHUP–程序終端中止信號
SIGINT–程序鍵盤中斷信號
SIGKILL–程序結(jié)束接收中止信號
SIGTERM–程序kill中止信號
SIGSTOP–程序鍵盤中止信號
SIGSEGV–程序無效內(nèi)存中止信號
SIGBUS–程序內(nèi)存字節(jié)未對齊中止信號
SIGPIPE–程序Socket發(fā)送失敗中止信號

更多信號

2昂验、捕獲方法

Appdelegate 的 didFinishLaunchingWithOptions 中 添加

signal(SIGHUP, SignalHandler);
signal(SIGINT, SignalHandler);
signal(SIGQUIT, SignalHandler);

signal(SIGABRT, SignalHandler);
signal(SIGILL, SignalHandler);
signal(SIGSEGV, SignalHandler);
signal(SIGFPE, SignalHandler);
signal(SIGBUS, SignalHandler);
signal(SIGPIPE, SignalHandler);

方法實現(xiàn)如下

void SignalHandler(int signal){
    
    int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount);
    if (exceptionCount > UncaughtExceptionMaximum)
    {
        return;
    }
    
    void* callstack[128];
    int frames = backtrace(callstack, 128);
    char **strs = backtrace_symbols(callstack, frames);
    
    int i;
    NSMutableArray *backtrace = [NSMutableArray arrayWithCapacity:frames];
    for (
         i = UncaughtExceptionHandlerSkipAddressCount;
         i < UncaughtExceptionHandlerSkipAddressCount +
         UncaughtExceptionHandlerReportAddressCount;
         i++)
    {
        [backtrace addObject:[NSString stringWithUTF8String:strs[i]]];
    }
    free(strs);
    NSLog(@"%@",backtrace);
    NSLog(@"%@", [NSString stringWithFormat:
                  NSLocalizedString(@"Signal %d was raised.", nil),
                  signal]);
}

3捂敌、測試

UIView *tempView = [[UIView alloc]init];
[tempView release];

//對象已經(jīng)被釋放,內(nèi)存不合法既琴,此塊內(nèi)存地址又沒被覆蓋占婉,所以此內(nèi)存內(nèi)垃圾內(nèi)存,所以調(diào)用方法的時候會導致SIGSEGV的錯誤
[tempView setNeedsDisplay];

或者說 我在堆內(nèi)存中找棧內(nèi)存地址

id x_id = [self performSelector:@selector(createNum)];

- (int)createNum {
    return 10;
}

這種情況也是會導致SIGSEGV的錯誤的


如果在內(nèi)存中釋放不存在的空間甫恩,就會導致SIGABRT錯誤

Test * test = {1, 2};

free(test);


內(nèi)存地址不對齊會導致SIGBUS錯誤

char *s = "hello world";
*s = 'H';

4逆济、問題

信號捕獲后 app卡死了

大部分這類型的錯誤會報錯 EXC_BAD_ACCESS ,而這種錯誤都是發(fā)生在內(nèi)存問題,例如

1奖慌、訪問數(shù)據(jù)為空抛虫、數(shù)據(jù)類型不對

2、操作了不該操作的對象简僧,野指針

5建椰、EXC_BAD_ACCESS錯誤的調(diào)試

1、xcode可以用僵尸模式打印出對象 然后通過對象查找對應(yīng)的代碼位置

1岛马、Edit Scheme - Diagnositics - Memory Management 勾選 Zombie Objects 和 Malloc Stack

2棉姐、會打印出 
cyuyan[7756:17601127] *** -[UIViewController respondsToSelector:]: message sent to deallocated instance 0x7fe71240d390

這句開啟僵尸模式后打出來的輸出,包含了我們需要的 進程pid啦逆、崩潰地址伞矩,終端通過下面命令查看堆棧日志來找到崩潰代碼

3、查找日志
sudo malloc_history 7756 0x7fe71240d390

2蹦浦、覆寫一個object的respondsToSelector方法

在 other c flags中加入-D FOR_DEBUG(記住請只在Debug Configuration下加入此標記)扭吁。這樣當你程序崩潰時,Xcode的console上就會準確地記錄了最后運行的object的方法盲镶。重寫一個object的respondsToSelector方法侥袜,打印報錯前的

#ifdef _FOR_DEBUG_  
-(BOOL) respondsToSelector:(SEL)aSelector {  
    printf("SELECTOR: %s\n", [NSStringFromSelector(aSelector) UTF8String]);  
    return [super respondsToSelector:aSelector];  
}  
#endif

3、通過instruments的Zombies

引申:怎么定位到野指針的地方溉贿。如果還沒定位到枫吧,這個對象被提前釋放了,怎么知道該對象在什么地方釋放的

一種是多線程宇色,一種是野指針九杂。這兩種Crash都帶隨機性,我們要讓隨機crash變成不隨機

把這一隨機的過程變成不隨機的過程宣蠕。對象釋放后在內(nèi)存上填上不可訪問的數(shù)據(jù)例隆,其實這種技術(shù)其實一直都有,xcode的Enable Scribble就是這個作用抢蚀。

1镀层、Edit Scheme - Diagnositics - Memory Management 勾選 Malloc Scribble

但是此方法測試后暫時未解決

6、可能崩潰的一些場景

1皿曲、野指針

1唱逢、對象釋放后內(nèi)存沒被改動過,原來的內(nèi)存保存完好屋休,可能不Crash或者出現(xiàn)邏輯錯誤(隨機Crash)坞古。

2、對象釋放后內(nèi)存沒被改動過劫樟,但是它自己析構(gòu)的時候已經(jīng)刪掉某些必要的東西痪枫,可能不Crash织堂、Crash在訪問依賴的對象比如類成員上、出現(xiàn)邏輯錯誤(隨機Crash)听怕。

3捧挺、對象釋放后內(nèi)存被改動過虑绵,寫上了不可訪問的數(shù)據(jù)尿瞭,直接就出錯了很可能Crash在objc_msgSend上面(必現(xiàn)Crash,常見)翅睛。

4声搁、對象釋放后內(nèi)存被改動過,寫上了可以訪問的數(shù)據(jù)捕发,可能不Crash疏旨、出現(xiàn)邏輯錯誤、間接訪問到不可訪問的數(shù)據(jù)(隨機Crash)扎酷。

5檐涝、對象釋放后內(nèi)存被改動過,寫上了可以訪問的數(shù)據(jù)法挨,但是再次訪問的時候執(zhí)行的代碼把別的數(shù)據(jù)寫壞了谁榜,遇到這種Crash只能哭了(隨機Crash,難度大凡纳,概率低)G灾病!

6荐糜、對象釋放后再次release(幾乎是必現(xiàn)Crash巷怜,但也有例外,很常見)暴氏。
image

2延塑、內(nèi)存處理不當、內(nèi)存泄露

3答渔、主線程UI長時間卡死关带,系統(tǒng)強制銷毀app

死鎖?

4研儒、多線程切換訪問引起的crash

多線程搶寫數(shù)據(jù)庫豫缨?

5、和服務(wù)端約定的數(shù)據(jù)結(jié)構(gòu)變更導致操作數(shù)據(jù)類型問題端朵、或者操作空

二好芭、崩潰日志的獲取

1、iOS設(shè)備可以直接查看

路徑:
ios 10之后:設(shè)置 -> 隱私 -> 分析 -> 數(shù)據(jù)分析
ios 10之前:設(shè)置 -> 隱私 -> 診斷與用量

2冲呢、鏈接設(shè)備到電腦 Itunes同步后舍败,日志會保存在電腦上

mac路徑:~/Library/Logs/CrashReporter/MobileDevice/
可以看到所有和該電腦同步過的設(shè)備的崩潰日志(.crash文件)

為什么有部分crash無法收集到?

3、xcode獲取

xcode查看設(shè)備日志并導出日志  

Window - Devices - 選擇設(shè)備 - 點擊View Device Logs -> All logs可以看到所有的崩潰日志邻薯。

4裙戏、線上的崩潰,沒有設(shè)備

1厕诡、三方:bugly累榜、crashlytics

2、后臺灵嫌、異步線程將上面描述的捕獲到的崩潰上傳服務(wù)器

3壹罚、線上的ITC上可能會有部分日志,可以通過Xcode同步下來崩潰與能耗日志

Xcode Window - Organizer - Crashes 

image

三寿羞、崩潰日志的解析

1猖凛、崩潰日志的實例

下面是一份測試過程產(chǎn)生的崩潰日志

//進程信息
Incident Identifier: 3C3F8BF8-3099-4E82-92E1-8690212E8FF9
CrashReporter Key:   bb5f9839ae661ab755f25eff65fee8fd41369628
Hardware Model:      iPod5,1
Process:             demo [973]
Path:                /private/var/containers/Bundle/Application/0D3657DE-DE1E-4FF0-A0F7-C09EBC002763/demo.app/demo
Identifier:          com.yanghuang.demo
Version:             17 (1.1.9)
Code Type:           ARM (Native)
Parent Process:      launchd [1]
//基本信息
Date/Time:           2017-08-22 16:11:49.49 +0800
Launch Time:         2017-08-22 16:11:40.40 +0800
OS Version:          iOS 9.3.5 (13G36)
Report Version:      104
//異常
Exception Type:  EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x00000000e7ffdefe
Triggered by Thread:  0

Filtered syslog:
None found
//線程回溯
Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   libswiftCore.dylib              0x0033788c 0x1ac000 + 1620108
1   ...wiftSwiftOnoneSupport.dylib  0x009b4830 0x9ac000 + 34864
2   demo                            0x00029288 0x24000 + 21128
3   demo                            0x00029414 0x24000 + 21524
4   UIKit                           0x25cd2754 0x25c87000 + 309076
5   UIKit                           0x25cd26e0 0x25c87000 + 308960
6   UIKit                           0x25cba6d2 0x25c87000 + 210642
7   UIKit                           0x25cd2004 0x25c87000 + 307204
8   UIKit                           0x25cd1c7e 0x25c87000 + 306302
9   UIKit                           0x25cca68e 0x25c87000 + 276110
10  UIKit                           0x25c9b124 0x25c87000 + 82212
11  UIKit                           0x25c996d2 0x25c87000 + 75474
12  CoreFoundation                  0x216e1dfe 0x21626000 + 769534
13  CoreFoundation                  0x216e19ec 0x21626000 + 768492
14  CoreFoundation                  0x216dfd5a 0x21626000 + 761178
15  CoreFoundation                  0x2162f228 0x21626000 + 37416
16  CoreFoundation                  0x2162f014 0x21626000 + 36884
17  GraphicsServices                0x22c1fac8 0x22c16000 + 39624
18  UIKit                           0x25d03188 0x25c87000 + 508296
19  demo                            0x0002ff48 0x24000 + 48968
20  libdyld.dylib                   0x212d7872 0x212d5000 + 10354

Thread 1 name:  Dispatch queue: com.apple.libdispatch-manager
Thread 1:
0   libsystem_kernel.dylib          0x213ac2f8 0x21396000 + 90872
1   libdispatch.dylib               0x212a1d60 0x2128b000 + 93536
2   libdispatch.dylib               0x212a1abe 0x2128b000 + 92862

... 省略部分內(nèi)容

//二進制映像
Binary Images
0x24000 - 0x33fff demo armv7  <aa31c8c1f8cb333596dbfe056b120673> /var/containers/Bundle/Application/0D3657DE-DE1E-4FF0-A0F7-C09EBC002763/demo.app/demo
0x140000 - 0x15bfff Masonry armv7  <9615e97c54d335f7821568396c65d324> /var/containers/Bundle/Application/0D3657DE-DE1E-4FF0-A0F7-C09EBC002763/demo.app/Frameworks/Masonry.framework/Masonry

1.進程信息

第一部分是閃退進程的相關(guān)信息。

Incident Identifier 是崩潰報告的唯一標識符绪穆。

CrashReporter Key 是與設(shè)備標識相對應(yīng)的唯一鍵值辨泳。雖然它不是真正的設(shè)備標識符,但也是一個非常有用的情報:如果你看到100個崩潰日志的CrashReporter Key值都是相同的玖院,或者只有少數(shù)幾個不同的CrashReport值菠红,說明這不是一個普遍的問題,只發(fā)生在一個或少數(shù)幾個設(shè)備上司恳。

Hardware Model 標識設(shè)備類型途乃。 如果很多崩潰日志都是來自相同的設(shè)備類型,說明應(yīng)用只在某特定類型的設(shè)備上有問題扔傅。上面的日志里耍共,崩潰日志產(chǎn)生的設(shè)備是iPhone 4s。

Process 是應(yīng)用名稱猎塞。中括號里面的數(shù)字是閃退時應(yīng)用的進程ID试读。

2.基本信息

這部分給出了一些基本信息,包括閃退發(fā)生的日期和時間荠耽,設(shè)備的iOS版本钩骇。如果有很多崩潰日志都來自iOS 6.0,說明問題只發(fā)生在iOS 6.0上铝量。

Version: 崩潰進程的版本號. 這個值包含在 CFBundleVersion and CFBundleVersionString中.

Code Type: 崩潰日志所在設(shè)備的架構(gòu). 會是ARM-64, ARM, x86-64, or x86中的一個.

OS Version: 崩潰發(fā)生時的系統(tǒng)版本

3.異常信息

異常信息會列出異常的類型倘屹、位置。

在這部分慢叨,你可以看到閃退發(fā)生時拋出的異常類型纽匙。還能看到異常編碼和拋出異常的線程。根據(jù)崩潰報告類型的不同拍谐,在這部分你還能看到一些另外的信息烛缔。

Exception Codes: 處理器的具體信息有關(guān)的異常編碼成一個或多個64位進制數(shù)馏段。通常情況下,這個區(qū)域不會被呈現(xiàn)践瓷,因為將異常代碼解析成人們可以看懂的描述是在其它區(qū)域進行的院喜。

Exception Subtype: 供人們可讀的異常代碼的名字

Exception Message: 從異常代碼中提取的額外的可供人們閱讀的信息.

Exception Note: 不是特定于一個異常類型的額外信息.如果這個區(qū)域包含SIMULATED (這不是一個崩潰)然后進程沒有崩潰,但是被watchdog殺掉了

Termination Reason: 當一個進程被終止的時的原因晕翠。

Triggered by Thread: 異常所在的線程.

4.線程回溯

這部分提供應(yīng)用中所有線程的回溯日志喷舀。 回溯是閃退發(fā)生時所有活動幀清單。它包含閃退發(fā)生時調(diào)用函數(shù)的清單崖面≡看下面這行日志:

2   demo     0x00029288 0x24000 + 21128

它包括四列:

幀編號—— 此處是2。

二進制庫的名稱 ——此處是 demo.

調(diào)用方法的地址 ——此處是 0x00029288.

第四列分為兩個子列巫员,一個基本地址和一個偏移量。此處是0×0x24000 + 21128, 第一個數(shù)字指向文件甲棍,第二個數(shù)字指向文件中的代碼行简识。

5.二進制映像

這部分列出了閃退時已經(jīng)加載的二進制文件。

2感猛、符號化Symbolication

image

第一次看到崩潰日志上的回溯時七扰,你或許會覺得它沒什么意義。我們習慣使用方法名和行數(shù)陪白,而非像這樣的神秘位置:

2   demo     0x00029288 0x24000 + 21128

將這些十六進制地址轉(zhuǎn)化成方法名稱和行數(shù)的過程稱之為符號化颈走。

從Xcode的Organizer窗口獲取崩潰日志后過幾秒鐘,崩潰日志將被自動符號化咱士。上面那行被符號化后的版本如下 :

2   demo     0x00029288 ViewController.crashAction(Any) -> () (ViewController.swift:36)

Xcode符號化崩潰日志時立由,需要訪問與App Store上對應(yīng)的應(yīng)用二進制文件以及生成二進制文件時產(chǎn)生的 .dSYM 文件。必需完全匹配才行序厉。否則锐膜,日志將無法被完全符號化。

所以弛房,保留每個分發(fā)給用戶的編譯版本非常重要道盏。提交應(yīng)用前進行歸檔時,Xcode將保存應(yīng)用的二進制文件文捶『沙眩可以在Xcode Organizer的Archives標簽欄下找到所有已歸檔的應(yīng)用文件。

在發(fā)現(xiàn)崩潰日志時粹排,如果有相匹配的.dSYM文件和應(yīng)用二進制文件种远,Xcode會自動對崩潰日志進行符號化。如果你換到別的電腦或創(chuàng)建新的賬戶恨搓,務(wù)必將所有二進制文件移動到正確的位置院促,使Xcode能找到它們筏养。

注意:

1、你必需同時保留應(yīng)用二進制文件和.dSYM文件才能將崩潰日志完整符號化常拓。每次提交到iTunes Connect的構(gòu)建都必需歸檔渐溶。 .dSYM文件和二進制文件是特定綁定于每一次構(gòu)建和后續(xù)構(gòu)建的,即使來自相同的源代碼文件弄抬,每一次構(gòu)建也與其他構(gòu)建不同茎辐,不能相互替換。如果你使用Build 和 Archive 命令,這些文件會自動放在適當位置掂恕。 如果不是使用Build 和 Archive命令拖陆,放在Spotlight能夠搜索到的位置(比如Home目錄)即可。

2懊亡、xcode debug方式打包默認沒有DSYM文件依啰,只需要修改對應(yīng)的build options即可

build settings -> build options
把debug 項改成 DWARF with dSYM File 即可

如何通過.crash文件反編譯得到明文的crash文件

需要文件:

1、demo.app

2店枣、demo.app.dSYM

3速警、demo.crash (已獲得)

4、symbolicatecrash

符號化前先檢查一下三者的uuid是不是一致的,只有是一致的才能符號化成功鸯两。

查看xx.app文件的uuid的方法:

dwarfdump --uuid xxx.app/xxx (xxx工程名)

查看xx.app.dSYM文件的uuid的方法令:

dwarfdump --uuid xxx.app.dSYM (xxx工程名)

而.crash的uuid位于闷旧,crash日志中的Binary Images:中的第一行尖括號內(nèi)。如:armv7<8bdeaf1a0b233ac199728c2a0ebb4165>
步驟如下:

1钧唐、首先我們找到Archives目錄(/Users/用戶名/Library/Developer/Xcode/Archives/2017-08-22/demo)

2忙灼、找到對應(yīng)app目錄、對應(yīng)的Archives文件钝侠、顯示包內(nèi)容打開该园。在dSYMs文件夾中找到demo.app.dSYM
在Products->Applications文件夾中找到 demo.app

3、找到symbolicatecrash

find /Applications/Xcode.app -name symbolicatecrash -type f
//終端輸入上面命令机错、得到一個路徑爬范,這個路徑就是symbolicatecrash的路徑
拷貝到和上面文件同一目錄

3: 在終端中輸入以下命令

./symbolicatecrash -v demo.crash demo.app.dSYM

如果出現(xiàn)Error: "DEVELOPER_DIR" is not defined 再執(zhí)行下面一句后再次執(zhí)行

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

然后用控制臺打開你的demo.crash文件, 你就會看到編譯后的crash文件, 同Xcode看到的崩潰日志一致。通過查看崩潰日志弱匪,可以輕易的找到崩潰原因并修正青瀑。

Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   libswiftCore.dylib              0x0033788c 0x1ac000 + 1620108
1   ...wiftSwiftOnoneSupport.dylib  0x009b4830 0x9ac000 + 34864
2   demo                            0x00029288 ViewController.crashAction(Any) -> () (ViewController.swift:36)
3   demo                            0x00029414 @objc ViewController.crashAction(Any) -> () (ViewController.swift:0)
4   UIKit                           0x25cd2754 -[UIApplication sendAction:to:from:forEvent:] + 80
5   UIKit                           0x25cd26e0 -[UIControl sendAction:to:forEvent:] + 64
6   UIKit                           0x25cba6d2 -[UIControl _sendActionsForEvents:withEvent:] + 466
7   UIKit                           0x25cd2004 -[UIControl touchesEnded:withEvent:] + 604
8   UIKit                           0x25cd1c7e -[UIWindow _sendTouchesForEvent:] + 646
9   UIKit                           0x25cca68e -[UIWindow sendEvent:] + 642
10  UIKit                           0x25c9b124 -[UIApplication sendEvent:] + 204
11  UIKit                           0x25c996d2 _UIApplicationHandleEventQueue + 5010
12  CoreFoundation                  0x216e1dfe __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 14
13  CoreFoundation                  0x216e19ec __CFRunLoopDoSources0 + 452
14  CoreFoundation                  0x216dfd5a __CFRunLoopRun + 794
15  CoreFoundation                  0x2162f228 CFRunLoopRunSpecific + 520
16  CoreFoundation                  0x2162f014 CFRunLoopRunInMode + 108
17  GraphicsServices                0x22c1fac8 GSEventRunModal + 160
18  UIKit                           0x25d03188 UIApplicationMain + 144
19  demo                            0x0002ff48 main (AppDelegate.swift:13)
20  libdyld.dylib                   0x212d7872 start + 2

3、低內(nèi)存閃退

因為低內(nèi)存崩潰日志與普通崩潰日志略有不同萧诫。

iOS設(shè)備檢測到低內(nèi)存時斥难,虛擬內(nèi)存系統(tǒng)發(fā)出通知請求應(yīng)用釋放內(nèi)存。這些通知發(fā)送到所有正在運行的應(yīng)用和進程帘饶,試圖收回一些內(nèi)存哑诊。

如果內(nèi)存使用依然居高不下,系統(tǒng)將會終止后臺線程以緩解內(nèi)存壓力及刻。如果可用內(nèi)存足夠镀裤,應(yīng)用將能夠繼續(xù)運行而不會產(chǎn)生崩潰報告竞阐。否則,應(yīng)用將被iOS終止暑劝,并產(chǎn)生低內(nèi)存崩潰報告骆莹。

低內(nèi)存崩潰日志上沒有應(yīng)用線程的堆棧回溯担猛。相反幕垦,上面顯示的是以內(nèi)存頁數(shù)為單位的各進程內(nèi)存使用量。

被iOS因釋放內(nèi)存頁終止的進程名稱后面你會看到j(luò)ettisoned 字樣傅联。如果看到它出現(xiàn)在你的應(yīng)用名稱后面先改,說明你的應(yīng)用因使用太多內(nèi)存而被終止了。

低內(nèi)存崩潰日志看起來像這樣:

img

4蒸走、異常編碼

通常仇奶,異常編碼以一些文字開頭,緊接著是一個或多個十六進制值载碌,此數(shù)值正是說明閃退根本性質(zhì)的所在猜嘱。 從這些編碼中,可以區(qū)分出閃退是因為程序錯誤嫁艇、非法內(nèi)存訪問或者是其他原因。

下面是一些常見的異常編碼:

0x8badf00d: 該編碼表示應(yīng)用是因為發(fā)生watchdog超時而被iOS終止的弦撩。  通常是應(yīng)用花費太多時間而無法啟動步咪、終止或響應(yīng)用系統(tǒng)事件。

0xbad22222: 該編碼表示 VoIP 應(yīng)用因為過于頻繁重啟而被終止益楼。

0xdead10cc: 該代碼表明應(yīng)用因為在后臺運行時占用系統(tǒng)資源猾漫,如通訊錄數(shù)據(jù)庫不釋放而被終止 。

0xdeadfa11: 該代碼表示應(yīng)用是被用戶強制退出的感凤。根據(jù)蘋果文檔, 強制退出發(fā)生在用戶長按開關(guān)按鈕直到出現(xiàn) “滑動來關(guān)機”, 然后長按 Home按鈕悯周。強制退出將產(chǎn)生 包含0xdeadfa11 異常編碼的崩潰日志, 因為大多數(shù)是強制退出是因為應(yīng)用阻塞了界面。

EXC_CRASH // SIGABRT: 進程異常退出陪竿。該異常類型崩潰最常見的原因是未捕獲的Objective-C和C++異常和調(diào)用abort()禽翼。如果他們需要太多的時間來初始化,程序?qū)⒈唤K止族跛,因為觸發(fā)了看門狗闰挡。如果是因為啟動的時候被掛起,所產(chǎn)生的崩潰報告異常類型(Exception Subtype)將是launch_hang礁哄。

EXC_BREAKPOINT // SIGTRAP:進程試圖執(zhí)行非法或未定義指令长酗。這個進程可能試圖通過一個配置錯誤的函數(shù)指針,跳到一個無效的地址桐绒。

SIGSEGV夺脾、SIGBUS 這些在前面捕獲異常的內(nèi)容有描述

注意: 在后臺任務(wù)列表中關(guān)閉已掛起的應(yīng)用不會產(chǎn)生崩潰日志之拨。 一旦應(yīng)用被掛起,它何時被終止都是合理的咧叭。所以不會產(chǎn)生崩潰日志蚀乔。

四、線上問題的處理

思考:

1佳簸、工作中是否有遇到過線上反饋回來的問題乙墙,你是如何定位問題處理的

2、如果有特殊賬戶才出現(xiàn)的問題生均,但是又拿不到用戶賬戶听想,該如何處理

符號化

官方文檔

參考文檔

參考文檔

更詳細的參考文檔

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市马胧,隨后出現(xiàn)的幾起案子汉买,更是在濱河造成了極大的恐慌,老刑警劉巖佩脊,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蛙粘,死亡現(xiàn)場離奇詭異,居然都是意外死亡威彰,警方通過查閱死者的電腦和手機出牧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來歇盼,“玉大人舔痕,你說我怎么就攤上這事”海” “怎么了伯复?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長邢笙。 經(jīng)常有香客問我啸如,道長,這世上最難降的妖魔是什么氮惯? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任叮雳,我火速辦了婚禮,結(jié)果婚禮上筐骇,老公的妹妹穿的比我還像新娘债鸡。我一直安慰自己,他們只是感情好铛纬,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布厌均。 她就那樣靜靜地躺著,像睡著了一般告唆。 火紅的嫁衣襯著肌膚如雪棺弊。 梳的紋絲不亂的頭發(fā)上晶密,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天,我揣著相機與錄音模她,去河邊找鬼稻艰。 笑死,一個胖子當著我的面吹牛侈净,可吹牛的內(nèi)容都是我干的尊勿。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼畜侦,長吁一口氣:“原來是場噩夢啊……” “哼元扔!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起旋膳,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤澎语,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后验懊,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體擅羞,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年义图,在試婚紗的時候發(fā)現(xiàn)自己被綠了减俏。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡碱工,死狀恐怖垄懂,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情痛垛,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布桶蛔,位于F島的核電站匙头,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏仔雷。R本人自食惡果不足惜蹂析,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望碟婆。 院中可真熱鬧电抚,春花似錦、人聲如沸竖共。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽走触。三九已至狼电,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間杰刽,已是汗流浹背肺然。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工蔫缸, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人际起。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓拾碌,卻偏偏與公主長得像,于是被迫代替她去往敵國和親街望。 傳聞我的和親對象是個殘疾皇子校翔,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 青春里的那段愛情,憂如咖啡讓人品味其中的無窮滋味…… 我在17歲青春年少的那年它匕,一個明媚晴朗的午后展融,幾個相處比較好...
    綠葉一枚閱讀 372評論 5 5