Monday, December 12, 2011

iOS底下啓動Code Trace Stack的方法

XCode4以後,以往的Code Stack變成了一堆address map,所以當Unhandled exception被Throw, 就會出現象如下圖一般的悲慘畫面

Origin

 

這些Trace顯然對追bug幾乎一點幫助都沒有,inspect crashed thread又只能看到一堆assembly,以前那些親切的Exception Stack跑哪去了呢?

其實Stack trace在exception裡面一直都是存在的,我們要做的只是讓unhandled exception被印出來而已。為了達到這個目的,所以我們必須做個小小的手腳。

首先先介紹一個基本的觀念,在C裡面,所有的unhandled exception都有一個最終處理函數,這個函數是可以經由指標切換的。原始預設的函數就是印出一堆有的沒有的以後,執行exit()。我們要做的就是寫一個函數取代掉它

 

void uncaughtExceptionHandler(NSException *exception) {

NSLog(@"CRASH: %@", exception);

NSLog(@"Stack Trace: %@", [exception callStackSymbols]);

// Internal error reporting

}

 

接下來我們必須要告訴系統,預設的處理unhandled exception handler函數更改為這個函數

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

// Override point for customization after application launch.

NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);

 

return YES;

}

 

當然,我們有很多地方可以放NSSetUncaughtExceptionHandler,不過我們選擇放在application:didFinishLaunchWithOptions:裡面

 

然後我們就可以得到下面的結果 :

XCode4_ST_Fixed

 

看,是不是好除錯多了嗎? 至少可以知道exception是從哪裡丟出來的了