10.17 abort函数

我们早些时候提到函数abort能够造成程序的非正常终止。

  1. #include <stdlib.h>
  2. void abort(void);
  3. This function never returns.

该函数会发送一个信号SIGABRT到调用进程。(进程不应该忽略这一信号),ISO C指出调用函数abort将会通过调用函数raise(SIGABRT)向主机环境发送一个不成功的终止通知。(ISO C states that calling abort will deliver an successful termination notification to the host environment by calling raise(SIGABRT)).

ISO C要求如果信号SIGABRT被捕获并且信号处理函数返回,abort仍然不会返回到其调用进程。如果该信号被捕获,如果该信号被捕获,信号处理函数不返回的唯一的方法是调用函数exit,_exit,_Exit,longjmp,siglongjmp.POSIX.1也指出abort将会重写信号的阻塞或者是忽略处理。

让进程捕获信号SIGABRT的目的是允许进程在终止之前执行清理工作,如果进程在信号处理函数中不终止自身进程,那么当信号处理函数返回的时候,abort将会终止进程。

ISO C将输出流是否被清空以及临时文件是否被删除交给了实现来处理,POSIX.1对此作了改变,其允许实现调用函数fclose在进程终止之前关闭已经打开的标准IO流。

早期的System V版本在abort函数中产生SIGIOT信号,进程可以捕获或者忽略该信号,并且可以从信号处理函数中返回,在这种情况下abort将会返回到其调用进程中去。

4.3BSD产生SIGILL信号,在发出信号之前,4.3BSD解除了该信号的阻塞并将其处理修改为SIG_DFL(终止并保存core文件)。这可以防止进程忽略或者是捕获该信号。

历史上,abort函数的实现对于标准IO流的处理在不同实现上有差异,为了提升程序的防御能力以及改善其可移植性,如果我们想要标准IO流被清空,我们需要在调用函数abort之前执行,我们将在err_dump函数中实现这一处理。

因为很多UNIX系统的函数tmpfile的实现在创建文件之后会立即调用unlink函数,ISO C对于临时文件的提醒我们并不需要担心。

Example

图10.25展示了POSIX.1指定的abort函数的一个实现:

  1. #include <signal.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. void abort(void) /*POSIX-style abort() function */
  6. {
  7. sigset_t mask;
  8. struct sigaction action;
  9. /*Caller can‘t ignore SIGABRT, if so reset to defualt */
  10. sigaction(SIGABRT, NULL, &action);
  11. if(action.sa_handler == SIG_IGN)
  12. {
  13. action.sa_handler = SIG_DFL;
  14. sigaction(SIGABRT, &action, NULL);
  15. }
  16. if(action.sa_handler == SIG_DFL)
  17. {
  18. fflush(NULL); /* flush all open stdio streams */
  19. }
  20. /* Caller can‘t block SIGABRT; make sure it‘s unblocked. */
  21. sigfillset(&mask);
  22. sigdelset(&mask, SIGABRT); /*mask has only SIGABRT turned off .*/
  23. sigprocmask(SIG_SETMASK, &mask, NULL);
  24. kill(getpid(), SIGABRT); /*send the signal*/
  25. /*If we‘re here,process caught SIGABRT and returned */
  26. fflush(NULL); /*flush all open stdio streams.*/
  27. action.sa_handler = SIG_DFL;
  28. sigaction(SIGABRT, &action, NULL); /*reset to default*/
  29. sigprocmask(SIG_SETMASK, &mask, NULL); /*just in case ... */
  30. kill(getpid(), SIGABRT); /*and one more time*/
  31. exit(1); /*this should never be excuted*/
  32. }

Figure 10.25 POSIX.1的abort函数的实现

首先检查信号是不是默认处理函数,如果是的话就flush所有IO流,注意这与fclose不同,因为fflush只是flush文件流但是并不关闭它们,当进程终止的时候,系统会关闭所有已经打开的文件。如果进程捕获到信号并且返回到abort函数中来,我们需要再一次flush文件流,因为进程可能再次产生了更多的输出内容,我们不需要处理的确情况是:进程捕获到信号以后调用了函数_exit或者是_Exit.在这种情况下,内存中所有没有flush的缓冲区将会被丢弃,我们假设这样做的用户是不想要缓冲区中的内容被flush的。

在10.9中我们已经了解到kill函数会产生信号,并且如果信号没有被阻塞(图10.25中的程序我们可以保证没有被阻塞),那么信号将在kill函数返回之前被发送到进程,因为我们阻塞了所有的信号除了SIGABRT,因此我们知道如果kill调用返回到abort,那么进程就已经捕获到了信号并且信号处理函数已经返回了。

来自为知笔记(Wiz)

时间: 2024-10-08 19:34:59

10.17 abort函数的相关文章

10.14 sigaction函数

函数sigaction允许我们获取或者是修改(或者获取并修改)与特定信号相关联的处理函数,该函数替代了早期的UNIX系统发布版中的函数signal,实际上,在本节末尾,我们将会使用sigaction来实现一个signal函数. #include <signal.h> int sigaction(int signo, const struct sigaction *restrict act, struct sigaction *restrict oact); Returns: 0 if OK,

10.15 iptables filter表案例 10.16/10.17/10.18 iptables nat表应用

10.15 iptables filter表案例 10.16/10.17/10.18 iptables nat表应用 扩展 iptables应用在一个网段 http://www.aminglinux.com/bbs/thread-177-1-1.html sant,dnat,masquerade http://www.aminglinux.com/bbs/thread-7255-1-1.html iptables限制syn速率 http://www.aminglinux.com/bbs/thre

10.12 sigprocmask函数

在10.8节中我们提到进程的掩码是一个当前阻塞信号发送到进程的信号集合.一个进程可以查看其信号掩码,改变其信号掩码,或者同时执行这两个操作,通过调用函数sigprocmask来实现上述要求. #include <signal.h> int sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict oset); return:0 if OK, -1 on error. 首先,如果oset是一个非空指针,那么当前进程

分享PHP中的10个实用函数

PHP的功能越来越强大,里面有着非常丰富的内置函数.资深的PHP程序员对它们可能都很熟悉,但很多参加PHP培训的PHP初学者,仍然对一些非常有用的函数不太熟悉.这篇摘抄自兄弟连的文章里,我们就列举10个你或许不了解但实用的PHP函数,供大家参考和学习. 1. php_check_syntax 这个函数可以用来检查特定文件中的PHP语法是否正确. 使用方法: <?php $error_message = ""; $filename = "./php_script.php&

PHP中的10个实用函数

PHP的功能越来越强大,里面有着非常丰富的内置函数.资深的PHP程序员对它们可能都很熟悉,但很多的PHP学习者,仍然对一些非常有用的函数不太熟悉.这篇文章里,我们就列举10个你或许不了解但实用的PHP函数,供大家参考和学习. 1.php_check_syntax 这个函数可以用来检查特定文件中的PHP语法是否正确. 使用方法: php$error_message ="";$filename ="./php_script.php";if(!php_check_synt

10.15 iptables filter表案例 10.16/10.17/10.18 iptable

七周四次课 10.15 iptables filter表案例 10.16/10.17/10.18 iptables nat表应用 10.15 iptables filter表案例 10.16/10.17/10.18 iptables nat表应用 打开端口转发, 调整内核参数 增加一条规则 所添加的规则 B机器设置默认网关 设置公共DNS C设备与A通信,通过端口转换的形式,将原有iptables清空 上面为进来的包进行转换,下面为出去的包进行转换 原文地址:http://blog.51cto.

abort函数,自定义错误处理方法

abort函数 from flask import Flask,url_for,abort,Response app = Flask(__name__) @app.route("/index") def index(): #使用abort函数可以立即终止视图函数的运行 #传递并返回标准状态码 if 1: abort(404) #传递并返回响应题信息 if 1: abort(Response("ooooo")) return "false" if

10.C#匿名函数的变量捕获(五章5.5)

小分享:我有几张阿里云优惠券,用券购买或者升级阿里云相应产品最多可以优惠五折!领券地址:https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=ohmepe03 首先感谢园友的指定,后续的文章一定会多码多想,出来的文章才有说服力.那今天接上篇我们来聊一聊匿名函数,对于匿名函数,我们知道使用delegate关键字,那我们来需要知道匿名函数在变量是的处理方式,先说两个术语,外部变量和捕获的外部变量,可以看出

MySQL学习笔记10(MySQL函数)

MySQL学习笔记10 MySQL函数 MySQL数据库中提供了很丰富的函数.MySQL函数包括数学函数.字符串函数.日期和时间函数.条件判断函数.系统信息函数.加密函数.格式化函数等.通过这些函数,可以简化用户的操作.SELECT语句及其条件表达式都可以使用这些函数.同时,INSERT.UPDATE.DELECT语句及其条件表达式也可以使用这些函数. 1:数学函数 数学函数是M有SQL中常用的一类函数.主要用于处理数字,包括整型.浮点数等.数学函数包括绝对值函数.正弦函数.余弦函数.获取随机数