1,程式某處拋了乙個異常,卻未**獲,會導致std::terminate
函式被呼叫,std::terminate
呼叫std::terminate_handler
型別的終止處理器,預設的終止處理器呼叫abort
函式終止程式
2,程序收到乙個預設終止程序的訊號,大多數訊號的預設行為都是終止程序
針對第一種情況,可以安裝乙個終止處理器來來執行異常資訊收集
針對第二種情況,可以安裝訊號處理器來執行訊號資訊收集
void terminate_handler()
catch(const n***ception *e)
catch(const
std::exception &e)
catch(...)
}// send exception info
// ...
raise(sigkill);
}
std::set_terminate(terminate_handler);
在終止處理器裡把異常重新丟擲來,分別捕獲兩個異常基類,從基類裡獲取異常資訊,然後傳送給server。
首先設定訊號處理器的執行棧,如果不設定訊號處理器的執行棧的話,當程序棧溢位時(比如無窮遞迴),訊號處理器就沒法執行了。
void setup_stack()
安裝訊號處理器
void install_sig_handler(int signo, void (*handler)(int, siginfo_t *, void *))
void sig_handler(int signo, siginfo_t *info, void *context)
install_sig_handler(sigsys, sig_handler);
install_sig_handler(sigpipe, sig_handler);
install_sig_handler(sigterm, sig_handler);
install_sig_handler(sigbus, sig_handler);
install_sig_handler(sigfpe, sig_handler);
install_sig_handler(sigtrap, sig_handler);
install_sig_handler(sigill, sig_handler);
install_sig_handler(sigsegv, sig_handler);
install_sig_handler(sigabrt, sig_handler);
把常見導致奔潰的訊號都捕獲了
看一下訊號處理器的函式原型:
void sig_handler(int signo, siginfo_t *info, void *context);
引數說明:
signo: 捕獲的 signal number
info
typedef
struct __siginfo siginfo_t;
其中 si_addr 是奔潰的位址
// arm32
struct __darwin_arm_thread_state ;
// arm64
struct __darwin_arm_thread_state64 ;
這些暫存器儲存了程式奔潰時的值,其中比較重要的兩個暫存器是lr
和fp
lr
是link register
,即函式的返回位址
fp
是frame pointer
,即當前棧幀的指標
arm32的fp
是r7
ios 上函式呼叫棧的棧幀結構如下:
/**
* stack frame
* * ----------
* | |
* ----------
* | lr | <- fp[1]
* ----------
* | old fp | <- fp
* ----------
* | |
* ----------
* | |
* ----------
*/
每乙個棧幀中都儲存了old fp
和lr
,可以通過棧幀指標回溯整個backtrace
然後通過lr
和dladdr
函式查詢函式符號名等資訊
dl_info dlinfo;
dladdr(lr, &dlinfo);
dl_info dlinfo;
void **fp = reinterpret_cast
(__fp);
while (fp)
這樣就可以拿到崩潰時的函式backtrace
注意,通過c庫函式backtrace
,backtrace_symbols
或(objc的[nsthread callstacksymbols]
)拿到的backtrace是不對的,庫函式是拿不到奔潰時的棧回溯資訊的。在異常資訊收集時也是一樣,捕獲異常時通過庫函式backtrace
,backtrace_symbols
也是拿不到拋異常時的棧回溯資訊的,除非在拋異常前呼叫backtrace
,backtrace_symbols
拿到棧回溯資訊,然後儲存到即將要丟擲的異常物件中,就像n***ception那樣。
奔潰資訊收集,主要是收集奔潰時的奔潰位址,以及棧回溯資訊等。
像原始c陣列越界會產生訊號
而objc的陣列越界會丟擲異常
iOS奔潰日誌資訊統計使用筆記
1.bugly的整合很簡單,直接乙個pod就可以搞定 pod bugly 2.在官網上註冊賬號 3.初始化sdk 匯入標頭檔案 import 如果是swift工程,請在對應bridging header.h中匯入3.1 objective c return yes 3.2 swift return ...
如何核心奔潰???
while 1 fork 和任何死迴圈都不能崩潰啊。只是無法跳出而已啊。空指標倒是讓記憶體溢位可以產生segmentation fault的錯誤,但是不會重啟。用alt sysrq c前需要先啟用這個功能 echo 1 proc sys kernel sysrq 也可以直接 echo c proc ...
free奔潰原因
執行時程式崩潰的問題,定位到了是free p 這個語句出錯誤,找了半天資料解決了,現在寫下一點自己的總結。這個問題有可能是以下4個原因構成,一一排查一般都可以解決 釋放乙個空指標,這個就不用多說了,短點除錯不會也會列印吧 printf x p 可以列印出16進製制數 重複釋放,這個問題也很好解決,在...