深入剖析Sgementation fault原理( 二 )

现在我们执行这个程序然后看看当我们输入ctrl+z和ctrl+c会出现有什么输出 。

深入剖析Sgementation fault原理

文章插图
从上面的输出我们可以看到实现了我们想要的输出结果 , 说明我们的函数重写生效了 。
段错误的魔幻这里有另外一个会产生SIGSEGV信号的程序,我们看看这个程序的输出是什么:
#include <stdio.h>#include <unistd.h>#include <signal.h>void sig(int n) {write(STDOUT_FILENO, "a", 1); // 这个函数就是向标准输出输出一个字符 a}int main() {signal(SIGSEGV, sig); // 这个是注册一个 SIGSEGV 错误的处理函数 当操作系统给进程发送一个 SIGSEGV 信号之后这个函数就会被执行int* p;printf("%d\n", *p); // 解引用一个没有定义的指针 造成 segementation faultreturn 0;}我们知道上面的程序肯定会产生 segmentation fault 错误,会收到 SIGSGEV 信号 , 肯定会执行到函数sig 。但是上面的程序会不断的输出a产生死循环 。
深入剖析Sgementation fault原理

文章插图
上面程序的结果是不是有点难以理解,如果想要了解这个程序的行为,我们就需要了解操作系统是如何处理 segmentation fault 的,了解这个处理过程之后对上面程序的输出就很容易理解了 。
信号处理函数的执行过程当我们的进程接收到信号会去执行我们重写的信号处理函数,如果在我们的信号处理函数当中没有退出程序或者转移程序的执行流(可以使用setjmp和longjmp实现),即调用函数正常返回 。信号处理函数返回之后会重新执行信号发生位置的指令,也就是说哪条指令导致操作系统给进程发送信号 , 那条条指令在信号处理函数返回的时候仍然会被执行 , 因此我们才看到了上面的输出结果,因为系统会不断的执行那条发生了 segmentation fault 的指令 。
那么我们如何修正我们的代码 , 让程序不进入死循环,让程序能够得到我们的接管呢 。有两种办法:
  • 一种是在信号处理函数当中进行一些逻辑处理之后然后,使用系统调用_exit直接退出 。
  • 另外一种使用setjmp和longjmp进行执行流的跳转 。
直接使用_exit退出#include <stdio.h>#include <signal.h>#include <unistd.h>void sig(int n) {printf("直接在这里退出\n");_exit(1); // 使用系统调用直接退出}int main() {signal(SIGSEGV, sig);*(int*) NULL = 0;printf("结束\n"); // 这个打印不会输出return 0;}
深入剖析Sgementation fault原理

文章插图
使用控制流跳转#include <stdio.h>#include <signal.h>#include <setjmp.h>jmp_buf env;void sig(int n) {printf("准备回到主函数\n");longjmp(env, 1);}int main() {signal(SIGSEGV, sig);if(!setjmp(env)) {printf("产生段错误\n");*(int*) NULL = 0;}else {printf("回到了主函数\n");}return 0;}
深入剖析Sgementation fault原理

文章插图
总结在本篇文章当中主要给大家介绍了Sgementation fault 的原理,并且自己动手写了他的信号处理函数,在信号处理函数当中发现如果信号处理函数正常退出的话,那么程序会进入一个死循环,永远不会停止,会不断的产生Sgementation fault,因此我们使用了两种方式让程序结束,一种是在信号处理函数当中不进行返回直接退出,但是这种情况会有一个弊端,如果我们原来的程序在后面还有一些操作的话就不能够执行了,如果有些程序很重要的,这就可能会造成很多错误 。第二种方式是我们可以使用setjmp和longjmp转移控制流,再次回到主函数执行 。
以上就是本篇文章的所有内容了 , 我是LeHung,我们下期再见?。。「嗑誓谌莺霞煞梦氏钅浚篽ttps://github.com/Chang-LeHung/CSCore
关注公众号:一无是处的研究僧,了解更多计算机(Java、Python、计算机系统基础、算法与数据结构)知识 。
深入剖析Sgementation fault原理

文章插图
【深入剖析Sgementation fault原理】

推荐阅读