Signal 13 was raised(SIGPIPE管道破裂)

简介: Signal 13 was raised(SIGPIPE管道破裂)

管道另一端没有进程接收数据,导致管道破裂而崩溃。

socket或管道,当自己主动关闭,资源被苹果系统回收,对方关闭时,当再次通过socket或pipe的文件描述符发送消息会出现系统级别的崩溃(管道破裂,signal 13。它的级别和内存使用或释放异常一直,由于是系统级别崩溃,所以不能通过@try{}@catch (NSException *exception) {

}捕获到异常,而是直接app崩溃)。

如果尝试send到一个已关闭的 socket上两次,就会出现此信号,也就是用协议TCP的socket编程,服务器是不能知道客户机什么时候已经关闭了socket,导致还在向该已关 闭的socket上send,导致SIGPIPE。

而系统默认产生SIGPIPE信号的措施是关闭进程,所以出现了服务器也退出。

在苹果手机上尝试过重新定义遇到SIGPIPE的措施,signal(SIGPIPE, SIG_IGN);虽然xcode还是会捕获SIGPIPE,但是程序不会崩溃,继续后可以执行。所以若是苹果系统回收io资源的情况下,没有办法通过这种方案解决。只需要发现这种情况忽略这种异常(setsockopt(sd, SOL_SOCKET, SO_NOSIGPIPE, SIG_IGN, sizeof(int));,使用使用 signal(SIGPIPE, SIG_IGN) 忽略SIGPIPE或是 自己设置handle处理函数。经实验在ios7模拟器上虽然xcode还是会捕获SIGPIPE,但是程序不会崩溃,继续后可以执行。有人说在真机上依然会崩溃。我测试没有发现崩溃,只是通过xcode捕获到SIGPIPE,但是没有崩溃)在前台时,重建线程,重新申请管道就可以。注意:苹果在后台断网8分钟以后,无法申请io资源,再使用管道或socket前用(setsockopt(sd, SOL_SOCKET, SO_NOSIGPIPE, SIG_IGN, sizeof(int));来忽略管道破裂消息,最好关闭后置为-1,使用时判断下是否为-1,防止使用已经关闭的管道或socket。当然玩管道或socket没有一个喜欢自己的应用因为管道破裂而崩溃(程序健壮性问题),还是在初始化时用signal(SIGPIPE, SIG_IGN);来一下整体的全体忽略,然后再用(setsockopt(sd, SOL_SOCKET, SO_NOSIGPIPE, SIG_IGN, sizeof(int));来下具体对象具体对待。

signal 13 对应就是 SIGPIPE ,网上对与这个Signal 的解释是这样的:

管道破裂。这个信号通常在进程间通信产生,比如采用FIFO(管道)通信的两个进程,读管道没打开或者意外终止就往管道写,写进程会收到SIGPIPE信号。此外用Socket通信的两个进程,写进程在写Socket的时候,读进程已经终止。

网上了解到的情况是使用socket的时候一般都会收到这个SIGPIPE 信号,处理方法大部分都是忽略,毕竟没有一个人希望自己的应用不明不白的挂掉。

不光在send,write时会引起管道破裂,关闭socket,管道时也会出现管道破裂。所以关闭文件描述符时,要判断文件描述符的有效性,忽略SIGPIPE,关闭完毕要把它置为无效的-1。

我们需要在send的时候检测到服务器已经关闭连接,进行重新连接。正常情况下send函数返回-1表示发送失败,但是在IOS上SIGPIPE在send返回之前就终止了进程,所以我们需要忽略SIGPIPE,让send正常返回-1,然后重新连接服务器。

这个是实际的例子及XCode用debug模式打印的控制台异常日志:

当守护线程由于应用切换到后台8分钟及以上,无网络时,苹果系统挂起了守护线程和长连接。当然也有低概率出现,当应用切换到后台立刻切换到前台,正在进行io操作的线程被杀死,已经通过打印日志打印出了这种小概率事件。当切换到前台,检查出长连接线程异常,重启了长连接线程,新的长连接线程通过本地管道向守护线程发送监控消息,由于守护线程已经挂起(被系统回收资源,本地管道被系统关闭),导致发生管道破裂类型的崩溃,app的运行。

控制台打印的崩溃日志:

Message from debugger: Terminated due to memory issue


目录
相关文章
|
4月前
|
存储 自然语言处理 数据处理
有效的函数
有效的函数
24 0
|
7月前
|
算法 Java 开发者
解密CollectGarbage函数
解密CollectGarbage函数
|
7月前
|
算法 程序员 编译器
函数(2)
函数(2)
27 0
|
数据库 索引
pginspect几个函数
pginspect几个函数
93 0
|
8月前
|
数据库
什么是纯函数
纯函数是指在相同的输入下,总是返回相同的输出,且没有副作用的函数。具体来说,纯函数不会改变任何传入的参数,也不会在函数外部改变全局变量、文件系统、数据库等状态,它只是接收输入并返回输出,不会产生任何可观察的副作用。
87 0
|
编译器 C语言
对函数的剖析一
对函数的剖析一
42 0
|
程序员 C语言 C++
函函函函函函函函函函函数——one
函函函函函函函函函函函数——one
95 0
|
自然语言处理 C++
C/C++ 中的 atol()、atoll() 和 atof() 函数
1.atol(): 此函数将作为参数传递给函数调用的 C 类型字符串转换为长整数。它解析 C 字符串 str 并将其内容解释为整数,该整数作为 long int 类型的值返回。该函数会丢弃字符串开头的空白字符,直到找到非空白字符。如果 C 字符串 str 中的非空白字符序列不是有效的整数,或者如果因为 str 为空或仅包含空白字符而不存在这样的序列,则不执行任何转换并返回零。
259 0
函数(二)
今天我们来学习函数(二)的相关内容,视频我已经传到b站上了,现在把链接发给大家,大家可以在b站上观看。关于函数我在为大家补充变量作用域的知识点。它分为两个部分:1.局部变量 2.全局变量
119 0
函数(二)
|
Python
函数
函数
98 0