避免SIGPIPE导致的iOS应用闪退/Avoiding SIGPIPE signal crash in iOS(mach_msg_trapSIGPIPE信号)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了避免SIGPIPE导致的iOS应用闪退/Avoiding SIGPIPE signal crash in iOS(mach_msg_trapSIGPIPE信号)相关的知识,希望对你有一定的参考价值。

问题描述:

应用运行时,锁屏后再打开有一定几率闪退。通过真机调试发现程序会中断在此处:

libsystem_kernel.dylib`mach_msg_trap:

 

解决思路:

  • 通过这篇文章了解是进程收到 SIGPIPE  信号,该信号默认行为是终止进程。

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

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_trapSIGPIPE信号)的主要内容,如果未能解决你的问题,请参考以下文章

iOS:应用程序从后台返回后访问 EAOutputStream 时的 SIGPIPE

忽略 SIGPIPE 不起作用 iOS

调试 X11 程序时如何避免 SIGPIPE(由于超时?)?

iOS 10 因苹果健康导致闪退 crash

iOS 10 因苹果健康导致闪退 crash

uniapp苹果端ios在线消息点击闪退