天天看點

在系統抛出異常處設定斷點

在網上看到一些方法, 試了一下, 效果不理想, 不過還是記在這裡如果遇到系統抛出異常時可以死馬當活馬醫。

環境設定:

先随便建立一個項目, 在viewDidLoad中寫如下代碼:

- (void)viewDidLoad

{

    [super viewDidLoad];

    NSString *str = [NSString stringWithFormat:@"Hello"];

    UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];

    btn.frame = CGRectMake(50, 50, 200, 40);

    [self.view addSubview:btn];

    [str release];

    NSLog(@"happy.");

}

運作, 程式會崩潰,因為上面的str是不能被release的, 但是程式并沒有在這裡停住,以表示是在這裡崩潰的, 而是在main()函數中, 并且從崩潰時的堆棧中也沒有看到有說執行到哪裡才崩潰的,堆棧資訊如圖:

在系統抛出異常處設定斷點

再上Console列印的資訊如下:

GNU gdb 6.3.50-20050815 (Apple version gdb-1708) (Thu Nov  3 21:59:02 UTC 2011)

Copyright 2004 Free Software Foundation, Inc.

GDB is free software, covered by the GNU General Public License, and you are

welcome to change it and/or distribute copies of it under certain conditions.

Type "show copying" to see the conditions.

There is absolutely no warranty for GDB.  Type "show warranty" for details.

This GDB was configured as "x86_64-apple-darwin".sharedlibrary apply-load-rules all

Attaching to process 498.

Pending breakpoint 1 - "objc_exception_throw" resolved

2012-06-14 11:17:25.829 steisnio[498:f803] happy.

(gdb) 

如果你想根據Console資訊來找, 恐怕就會偏離方向, 因為console顯示, happy居然被正常列印出來了, 按慣常邏輯, 列印出happy就意味着程式是執行過 NSLog(@"happy.");  都還沒有報錯 , 事實上确不是這樣子的。 

按網上的方法

有時候我們的程式不知道跑到哪個地方就 crash 了,而 crash 又很難重制。保守的做法是在系統抛出異常之前設定斷點,具體來說是在 objc_exception_throw處設定斷點。設定步驟為:首先在 XCode 按 CMD + 6,進入斷點管理視窗;然後點選右下方的 +,增加新的 Symbolic Breakpoint,在 Symbol 一欄輸入:objc_exception_throw,然後點選 done,完成。 這樣在 Debug 模式下,如果程式即将抛出異常,就能在抛出異常處中斷了。比如在前面的代碼中,我讓 [firstObjctcrashTest]; 抛出異常。在 objc_exception_throw 處設定斷點之後,程式就能在該代碼處中斷了,我們進而知道代碼在什麼地方出問題了。

做了後, 發現一樣的, 程式還是停在main()那裡, 并且堆棧資訊也沒有是以而顯示更多的資訊。 

當然網上這個辦法在某些情況下應該也能解決一些問題, 是以權當死馬當活馬醫吧。

如果有高人路過, 可否告知為什麼在我的試驗中這是行不能的。先謝謝了。