1. 程式人生 > >避免SIGPIPE導致的iOS應用閃退/Avoiding SIGPIPE signal crash in iOS(mach_msg_trap、SIGPIPE信號)

避免SIGPIPE導致的iOS應用閃退/Avoiding SIGPIPE signal crash in iOS(mach_msg_trap、SIGPIPE信號)

sig and 連接 mac os 找到 option sock ram round

問題描述:

應用運行時,鎖屏後再打開有一定幾率閃退。通過真機調試發現程序會中斷在此處:

libsystem_kernel.dylib`mach_msg_trap:

解決思路:

  • 通過這篇文章了解是進程收到 SIGPIPE 信號,該信號默認行為是終止進程。

The process received a SIGPIPE . The default behaviour for this signal is to end the process.

A SIGPIPE is sent to a process if it tried to write to a socket that had been shutdown for writing or isn‘t connected (anymore).

To avoid that the program ends in this case, you could either

  • make the process ignore SIGPIPE or
  • install an explicit handler for SIGPIPE (typically doing nothing).

In both cases send*()/ write() would return -1 and set errno to EPIPE.

SIGPIPE相關信息

  • 蘋果文檔中已指出:

當連接關閉後,進程默認會收到 SIGPIPE 信號。如果這個信號沒有被處理或者忽略,程序就會立刻退出。

文檔中給出兩套解決方案:

When a connection closes, by default, your process receives a SIGPIPE signal. If your program does not handle or ignore this signal, your program will quit immediately. You can handle this in one of two ways:

  • Ignore the signal globally with the following line of code:
signal(SIGPIPE, SIG_IGN);
  • Tell the socket not to send the signal in the first place with the following lines of code (substituting the variable containing your socket in place of sock):
int value = 1;
setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, &value, sizeof(value));

For maximum compatibility, you should set this flag on each incoming socket immediately after calling accept in addition to setting the flag on the listening socket itself.

Avoiding Common Networking Mistakes中內容(源自APPLE)

  • 在著名的棧溢出stackoverflow網站中找到第三種解決方案(因Mac OS中未定義MSG_NOSIGNAL故無法測試):

If you‘re using the send() call, another option is to use the MSG_NOSIGNAL option, which will turn the SIGPIPE behavior off on a per call basis. Note that not all operating systems support the MSG_NOSIGNAL flag.

參考鏈接:

1.iOS異常處理:mach_msg_trap處異常 - http://www.jianshu.com/p/2b3f58c61d7d

2.如何在 iOS 上避免 SIGPIPE 信號導致的 crash (Avoiding SIGPIPE signal crash in iOS) - http://www.jianshu.com/p/1957d2b18d2c

3.Program received signal SIGPIPE, Broken pipe.? - https://stackoverflow.com/questions/18935446/program-received-signal-sigpipe-broken-pipe

4.How to prevent SIGPIPEs (or handle them properly) - https://stackoverflow.com/questions/108183/how-to-prevent-sigpipes-or-handle-them-properly

5.Avoiding Common Networking Mistakes - https://developer.apple.com/library/content/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/CommonPitfalls/CommonPitfalls.html

避免SIGPIPE導致的iOS應用閃退/Avoiding SIGPIPE signal crash in iOS(mach_msg_trap、SIGPIPE信號)