如何用代碼收集分析崩潰日志

iOS CrashLog分析詳細(xì)分析了iOS崩潰日志的非代碼層面的收集和解析朝群。這篇文章分析一下如何用純代碼來(lái)收集分析程序崩潰。

問(wèn)題一:平時(shí)程序遇到崩潰的本質(zhì)值纱?

引發(fā)崩潰的代碼本質(zhì)上就兩類:
1.一個(gè)是c++語(yǔ)言層面的錯(cuò)誤,比如野指針,除零其馏,內(nèi)存訪問(wèn)異常等等。無(wú)論是iOS還是android系統(tǒng)爆安,其底層都是unix或者是類unix系統(tǒng),都可以通過(guò)信號(hào)機(jī)制來(lái)獲取 signal或者是sigaction.設(shè)置一個(gè)回調(diào)函數(shù).

2.另一類是未捕獲異常(Uncaught Exception)叛复,iOS下面最常見(jiàn)的就是objective-c的NSException(通過(guò)@throw拋出,比如扔仓,NSArray訪問(wèn)元素越界)褐奥,android下面就是java拋出的異常了。這些異常如果沒(méi)有在最上層try住翘簇,那么程序就崩潰了.可以使用NSUncaughtExceptionHandler來(lái)進(jìn)行抓取撬码。這種取到的日志是已經(jīng)符號(hào)化過(guò)后的。

使用NSUncaughtExceptionHandler抓取NSException

NSSetUncaughtExceptionHandler(&ExceptionHandler);
void ExceptionHandler(NSException *exception)
{
    //NSString *reason = [exception reason];
    //NSString *name = [exception name];
    NSLog(@"%@",exception.userInfo);
    NSString* ret=[NSString stringWithFormat:@"異常名稱:\n%@\n\n異常原因:\n%@\n\n出錯(cuò)堆棧內(nèi)容:\n%@\n",name,reason,[exception callStackSymbols] ];
    NSLog(@"%@",ret);
}
寫成文件后

抓取Signal消息

signal信號(hào)是Unix系統(tǒng)中的,是一種異步通知機(jī)制.信號(hào)傳遞給進(jìn)程后,在沒(méi)有處理函數(shù)的情況下,程序可以指定三種行為,

  1. 忽略該信號(hào),但是對(duì)于信號(hào)SIGKILL和SIGSTOP不可忽略
  2. 使用默認(rèn)的處理函數(shù)SIG_DFL,大多數(shù)信號(hào)的默認(rèn)動(dòng)作是終止進(jìn)程.
    捕獲信號(hào),執(zhí)行用戶定義的函數(shù).
  3. 有兩個(gè)特殊的常量:

SIG_IGN,向內(nèi)核表示忽略此信號(hào).對(duì)于不能忽略的兩個(gè)信號(hào)SIGKILL和SIGSTOP,調(diào)用時(shí)會(huì)報(bào)錯(cuò).
SIG_DFL,執(zhí)行該信號(hào)的系統(tǒng)默認(rèn)動(dòng)作.
還有兩個(gè)常用的函數(shù)

int kill(pid_t pid, int signo); //發(fā)送信號(hào)到指定的進(jìn)程
int raise(int signo); //發(fā)送信號(hào)給自己.

UNIX系統(tǒng)中常用的信號(hào)有

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

抓取Signal的代碼

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

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

void SignalExceptionHandler(int sig)
{
    NSMutableString *stackInfo = [[NSMutableString alloc] init];
    [stackInfo appendString:@"Last Exception Backtrace:\n\n"];
    void* callstack[128];
    int i, frames = backtrace(callstack, 128);
    char** strs = backtrace_symbols(callstack, frames);
    for (i = 0; i <frames; ++i) {
        [stackInfo appendFormat:@"%s\n", strs[i]];
    }
}

但這里會(huì)將信號(hào)不斷的發(fā)向該處理函數(shù),導(dǎo)致應(yīng)用無(wú)法正常崩潰,因?yàn)橐话愕南⑻幚頃?huì)向進(jìn)程終結(jié),但是這里沒(méi)有,所以還會(huì)有同樣地信號(hào)不斷的發(fā)過(guò)來(lái)并被處理.所以處理函數(shù)后要終結(jié)該處理函數(shù)的處理,并將其由系統(tǒng)默認(rèn)處理,即:

signal(sig, SIG_DFL);

而對(duì)于有些時(shí)候,在iOS中,在應(yīng)用崩潰后,保持運(yùn)行狀態(tài)而不退出:

CFRunLoopRef runLoop = CFRunLoopGetCurrent();
CFArrayRef allModes = CFRunLoopCopyAllModes(runLoop);

while (!dismissed)
{
    for (NSString *mode in (__bridge NSArray *)allModes)
    {
        CFRunLoopRunInMode((__bridge CFStringRef)mode, 0.001, false);
    }
}

CFRelease(allModes);
寫成文件

應(yīng)用以上代碼,可以做到崩潰時(shí)彈框提示應(yīng)用,以讓用戶還是可以正常操作,讓響應(yīng)更加友好.Demo

這里最關(guān)鍵的一步版保,SignalHandler不要在debug環(huán)境下測(cè)試呜笑。因?yàn)橄到y(tǒng)的debug會(huì)優(yōu)先去攔截。我們要運(yùn)行一次后彻犁,關(guān)閉debug狀態(tài)叫胁。應(yīng)該直接在模擬器上點(diǎn)擊我們build上去的app去運(yùn)行。而UncaughtExceptionHandler可以在調(diào)試狀態(tài)下捕捉汞幢。

多個(gè)Crash日志收集服務(wù)共存的坑

自己的程序里集成多個(gè)Crash日志收集服務(wù)實(shí)在不是明智之舉驼鹅。通常情況下,第三方功能性SDK都會(huì)集成一個(gè)Crash收集服務(wù)森篷,以及時(shí)發(fā)現(xiàn)自己SDK的問(wèn)題输钩。如果同時(shí)有多方通過(guò)NSSetUncaughtExceptionHandler注冊(cè)異常處理程序,會(huì)導(dǎo)致程序發(fā)生exception的時(shí)候不知道調(diào)用了哪一個(gè)handler而導(dǎo)致錯(cuò)誤疾宏。

參考:

1张足、iOS異常捕獲

2、獲取 iOS crash log(分析得很詳細(xì))

3坎藐、漫談iOS Crash收集框架

4为牍、iOS崩潰信息收集

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市岩馍,隨后出現(xiàn)的幾起案子碉咆,更是在濱河造成了極大的恐慌,老刑警劉巖蛀恩,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件疫铜,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡双谆,警方通過(guò)查閱死者的電腦和手機(jī)壳咕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門席揽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人谓厘,你說(shuō)我怎么就攤上這事幌羞。” “怎么了竟稳?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵属桦,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我他爸,道長(zhǎng)聂宾,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任诊笤,我火速辦了婚禮系谐,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘盏混。我一直安慰自己蔚鸥,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布许赃。 她就那樣靜靜地躺著,像睡著了一般馆类。 火紅的嫁衣襯著肌膚如雪混聊。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,301評(píng)論 1 301
  • 那天乾巧,我揣著相機(jī)與錄音句喜,去河邊找鬼。 笑死沟于,一個(gè)胖子當(dāng)著我的面吹牛咳胃,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播旷太,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼展懈,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了供璧?” 一聲冷哼從身側(cè)響起存崖,我...
    開(kāi)封第一講書(shū)人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎睡毒,沒(méi)想到半個(gè)月后来惧,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡演顾,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年供搀,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了隅居。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡葛虐,死狀恐怖军浆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情挡闰,我是刑警寧澤乒融,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站摄悯,受9級(jí)特大地震影響赞季,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜奢驯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一申钩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧瘪阁,春花似錦撒遣、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至豁跑,卻和暖如春廉涕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背艇拍。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工狐蜕, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人卸夕。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓层释,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親快集。 傳聞我的和親對(duì)象是個(gè)殘疾皇子贡羔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

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

  • 比較好的轉(zhuǎn)載:http://www.cocoachina.com/ios/20151218/14748.html轉(zhuǎn)...
    liudhkk閱讀 930評(píng)論 0 2
  • 1、信號(hào)的理解 信號(hào)的概念:信號(hào)(本人關(guān)于signal的一篇博客) http://www.reibang.com/...
    好雨知時(shí)節(jié)浩宇閱讀 6,306評(píng)論 0 17
  • iOS 崩潰信息收集 最近項(xiàng)目要求收集應(yīng)用使用過(guò)程中的崩潰信息碍讨,在網(wǎng)上搜索了一番后治力,了解目前崩潰信息收集有如下幾種...
    rgcyc閱讀 5,755評(píng)論 5 15
  • [這是第14篇] 序: iOS Crash問(wèn)題是iOS開(kāi)發(fā)中難以忽視的存在,本文就捕獲iOS Crash勃黍、Cras...
    南華coder閱讀 9,881評(píng)論 21 116
  • KSCrash 是一個(gè)異常收集的開(kāi)源框架宵统。 它可以捕獲到Mach級(jí)內(nèi)核異常、信號(hào)異常、C++異常马澈、Objectiv...
    sincere_bs閱讀 9,836評(píng)論 11 41