1. 程式人生 > >iOS中的崩潰類型

iOS中的崩潰類型

truct enable 進行 http arc product 包含 產生 abr

http://blog.csdn.net/womendeaiwoming/article/details/44243571

OS中的崩潰類型

在這裏了解一下XCode用來表示各種崩潰類型的術語,補充一些這方面的各知識。崩潰通常是指操作系統向正在運行的程序發送的信號,所以我們在查看崩潰日誌時,常常看到如下錯誤摘要:Application received signal SIGSEGV。一般來說,常見的崩潰類型有以下幾種:

1、 EXC_BAD_ACCESS

在訪問一個已經釋放的對象或向它發送消息時,EXC_BAD_ACCESS就會出現。造成EXC_BAD_ACCESS最常見的原因是,在初始化方法中初始化變量時用錯了所有權修飾符,這會導致對象過早地被釋放。舉個例子,在viewDidLoad方法中為UIViewController創建了一個包含元素的NSArray,卻將該數組的所有權修飾符設成了assign而不是strong。現在在viewWillAppear中,若要訪問已經釋放掉的對象時,就會得到名為EXC_BAD_ACCESS的崩潰。

這個崩潰發生時,查看崩潰日誌,卻往往得不到有用的棧信息。還好,有一個方法用來解決這個問題:NSZombieEnabled。

這是一個環境變量,用來調試與內存相關的問題,跟蹤對象的釋放過程。啟用了NSZombieEnabled的話,它會用一個僵屍實現來去你的默認的dealloc實現,也就是在引用計數降到0時,該僵屍實現會將該對象轉換成僵屍對象。僵屍對象的作用是在你向它發送消息時,它會顯示一段日誌並自動跳入調試器。

所以,當在應用中啟用NSZombie而不是讓應用直接崩潰時,一個錯誤的內存訪問就會變成一條無法識別的消息發送給僵屍對象。僵屍對象會顯示接收到的消息,然後跳入調試器,這樣你就可以查看到底哪時出了問題。

可以在Xcode的scheme頁面中設置NSZombieEnabled環境變量。點擊Product-àEdit Scheme打開該頁面,然後勾選Enable Zombie Objects復選框,如圖所示:

技術分享

僵屍在RAC出現以前作用很大。但自從有了ARC,如果你在對象的所有權方面比較註意,那麽通常不會碰到內存相關的崩潰。

2、 SIGSEGV

段錯誤信息(SIGSEGV)是操作系統產生的一個更嚴重的問題。當硬件出現錯誤、訪問不可讀的內存地址或向受保護的內存地址寫入數據時,就會發生這個錯誤。

硬件錯誤這一情況並不常見。當要讀取保存在RAM中的數據,而該位置的RAM硬件有問題時,你會收到SIGSEGV。SIGSEGV更多是出現在後兩種情況。默認情況下,代碼頁不允許進行寫操作,而數據而不允許進行執行操作。當應用中的某個指針指向代碼頁並試圖修改指向位置的值時,你會收到SIGSEGV。當要讀取一個指針的值,而它被初始化成指向無效內存地址的垃圾值時,你也會收到SIGSEGV。

SIGSEGV錯誤調試起來更困難,而導致SIGSEGV的最常見原因是不正確的類型轉換。要避免過度使用指針或嘗試手動修改指針來讀取私有數據結構。如果你那樣做了,而在修改指針時沒有註意內存對齊和填充問題,就會收到SIGSEGV。

3、 SIGBUS

總線錯誤信號(SIGBUG)代表無效內存訪問,即訪問的內存是一個無效的內存地址。也就是說,那個地址指向的位置根本不是物理內存地址(它可能是某個硬件芯片的地址)。SIGSEGV和SIGBUS都羽毛球EXC_BAD_ACCESS的子類型。

4、 SIGTRAP

SIGTRAP代表陷阱信號。它並不是一個真正的崩潰信號。它會在處理器執行trap指令發送。LLDB調試器通常會處理此信號,並在指定的斷點處停止運行。如果你收到了原因不明的SIGTRAP,先清除上次的輸出,然後重新進行構建通常能解決這個問題。

5、 EXC_ARITHETIC

當要除零時,應用會收到EXC_ARITHMETIC信號。這個錯誤應該很容易解決。

6、 SIGILL

SIGILL代表signal illegal instruction(非法指令信號)。當在處理器上執行非法指令時,它就會發生。執行非法指令是指,將函數指針會給另外一個函數時,該函數指針由於某種原因是壞的,指向了一段已經釋放的內存或是一個數據段。有時你收到的是EXC_BAD_INSTRUCTION而不是SIGILL,雖然它們是一回事,不過EXC_*等同於此信號不依賴體系結構。

7、 SIGABRT

SIGABRT代表SIGNAL ABORT(中止信號)。當操作系統發現不安全的情況時,它能夠對這種情況進行更多的控制;必要的話,它能要求進程進行清理工作。在調試造成此信號的底層錯誤時,並沒有什麽妙招。Cocos2d或UIKit等框架通常會在特定的前提條件沒有滿足或一些糟糕的情況出現時調用C函數abort(由它來發送此信號)。當SIGABRT出現時,控制臺通常會輸出大量的信息,說明具體哪裏出錯了。由於它是可控制的崩潰,所以可以在LLDB控制臺上鍵入bt命令打印出回溯信息。

8、 看門狗超時

這種崩潰通常比較容易分辨,因為錯誤碼是固定的0x8badf00d。(程序員也有幽默的一面,他們把它讀作Ate Bad Food。)在iOS上,它經常出現在執行一個同步網絡調用而阻塞主線程的情況。因此,永遠不要進行同步網絡調用。

iOS中的崩潰類型