/******************************************************************************************************************
参考:结合以前学习的C语言,现在学习了signo通信。
说明:主要是在程序中的合适地方访问非法内存让系统发SIGSEGV信号。
******************************************************************************************************************/
主要方案就是printf一个系统保护的指针,这个指针是不能访问也不能写的,就会达到SIGSEGV要的效果:试图访问未分配给自己的内存,或试图往没有写权限的内存地址写数据。
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <math.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
void my_func(int sign_no)
{
if(sign_no == SIGSEGV)
{
printf("I have get SIGSEGV\n");
exit(0);//不加这个会不停的打印上边这句话
}
}
int main(void)
{
int *p = (int*)5;
signal(SIGSEGV, my_func);
printf("一大波 SIGEGV is coming...\n");
printf("%d\n", *p);
return 0;
}
当然,不用这个signal的话,编译能过,运行时就一个经典的 “段错误”了。不过用上这个出现如下结果:
[root@localhost gcc]# ./a.out
一大波 SIGEGV is coming...
I have get SIGSEGV
[root@localhost gcc]#
可见没有那个“段错误”提示了,有这里可以联想到如果不自己注册这个信号,系统默认用的也是这个信号,还默认打印它的“段错误”。
另外把信号处理函数中的不加exit(0)的打印结果也帖出来,有空有时间再来找找原因:
[root@localhost gcc]# ./a.out
一大波 SIGEGV is coming...
I have get SIGSEGV
I have get SIGSEGV
I have get SIGSEGV
I have get SIGSEGV
I have get SIGSEGV
I have get SIGSEGV
I have get SIGSEGV
I have get SIGSEGV
.......
.......
.......
I have get SIGSEGV
I have get SIGSEGV
I have get SIGSEGV
I have get SIGSEGV
I have get SIGSEGV
I have get SIGSEGV
I have get SIGSEGV
I have get SIGSEGV
I have get SIGSEGV
^C
[root@localhost gcc]#
关于最后一个问题,老师给出了答案:段错误发生后如果在处理函数中不exit的话,执行完之后会再回到这个指针,然后这个指针还是非法的,就会再次发出SIGSEGV这个信号,不能看到系统默认是怎么处理的,如果能看到,系统应该也是exit()这样的处理的。