Message from debugger: Terminated due to signal 13

25zhixun發表於2020-11-30

Message from debugger: Terminated due to signal 13

 

最近Xcode編譯時,總是發生這樣一個錯誤,程式異常退出,並且不會留下其它資訊判斷是什麼問題。因為之前出錯,也是類似這樣一個錯誤,百度並沒有得到什麼有用的資訊,所以這次直接硬剛,因為每次程式都是結束在傳送資料傳送失敗那裡。。。。。。

後面才發現,之前那個類似的錯誤,是signal 9


http://www.voidcn.com/article/p-agnkvxam-xu.html

最後百度,在上面這個連結找到了原因:

錯誤產生的原因:嘗試send到一個已關閉的socket上兩次

這個錯誤,不能通過try catch捕捉和避免

管道另一端沒有程式接收資料,導致管道破裂而崩潰。
socket或管道,當自己主動關閉,資源被蘋果系統回收,對方關閉時,當再次通過socket或pipe的檔案描述符傳送訊息會出現系統級別的崩潰
(管道破裂,signal 13。它的級別和記憶體使用或釋放異常一直,由於是系統級別崩潰,所以不能通過@try{}@catch (NSException *exception) {}捕獲到異常,而是直接app崩潰)。

如果嘗試send到一個已關閉的 socket上兩次,就會出現此訊號
也就是用協議TCP的socket程式設計,伺服器是不能知道客戶機什麼時候已經關閉了socket,導致還在向該已關閉的socket上send,導致SIGPIPE。
而系統預設產生SIGPIPE訊號的措施是關閉程式,所以出現了伺服器也退出。

在蘋果手機上嘗試過重新定義遇到SIGPIPE的措施,signal(SIGPIPE,   SIG_IGN);結果仍舊崩潰
所以若是蘋果系統回收io資源的情況下,沒有辦法通過這種方案解決。只需要發現這種情況忽略這種異常(int set = 1;  
setsockopt(sd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));

使用使用 signal(SIGPIPE, SIG_IGN) 忽略SIGPIPE或是 自己設定handle處理函式。
經實驗在ios7模擬器上雖然xcode還是會捕獲SIGPIPE,但是程式不會崩潰,繼續後可以執行。但是在真機上依然會崩潰。)
在前臺時,重建執行緒,重新申請管道就可以。注意:蘋果在後臺斷網8分鐘以後,無法申請io資源。
signal 13 對應就是 SIGPIPE ,網上對與這個Signal 的解釋是這樣的:管道破裂。
這個訊號通常在程式間通訊產生,比如採用FIFO(管道)通訊的兩個程式,讀管道沒開啟或者意外終止就往管道寫,寫程式會收到SIGPIPE訊號。
此外用Socket通訊的兩個程式,寫程式在寫Socket的時候,讀程式已經終止。

網上了解到的情況是使用socket的時候一般都會收到這個SIGPIPE 訊號,處理方法大部分都是忽略。

我們需要在send的時候檢測到伺服器已經關閉連線,進行重新連線。
正常情況下send函式返回-1表示傳送失敗,但是在IOS上SIGPIPE在send返回之前就終止了程式
所以我們需要忽略SIGPIPE,讓send正常返回-1,然後重新連線伺服器。

這個是實際的例子及XCode用debug模式列印的控制檯異常日誌:
當守護執行緒由於應用切換到後臺8分鐘及以上,無網路時,蘋果系統掛起了守護執行緒和長連線。
當然也有低概率出現,當應用切換到後臺立刻切換到前臺,正在進行io操作的執行緒被殺死,已經通過列印日誌列印出了這種小概率事件。
當切換到前臺,檢查出長連線執行緒異常,重啟了長連線執行緒,新的長連線執行緒通過本地管道向守護執行緒傳送監控訊息
由於守護執行緒已經掛起(被系統回收資源,本地管道被系統關閉),導致發生管道破裂型別的崩潰,app的執行。

相關文章