免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3253 | 回复: 5
打印 上一主题 下一主题

SIGSEGV啥时候开始可以被忽略了??? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-04-15 16:20 |只看该作者 |倒序浏览

  1. #include <unistd.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <signal.h>

  6. int main(void)
  7. {
  8.         struct sigaction act;

  9.         memset(&act, '\0', sizeof(act));
  10.         act.sa_handler = SIG_IGN;
  11.         act.sa_flags   = SA_RESTART;
  12.         sigemptyset(&act.sa_mask);
  13.         if (sigaction(SIGSEGV, &act, NULL) == -1)
  14.                 perror("sigaction");

  15.         kill(getpid(), SIGSEGV);

  16.         for (;;) {
  17.                 printf("hello world\n");
  18.                 sleep(2);
  19.         }

  20.         return 0;
  21. }

复制代码
我记得SIGSEGV如果被忽略的情况下,程序是无法向下执行的啊,上面怎么可以继续执行啊??

论坛徽章:
0
2 [报告]
发表于 2010-04-15 17:56 |只看该作者
http://zh.wikipedia.org/zh-cn/SIGSEGV
对于不正确的内存处理(见段错误),计算机程序可能抛出SIGSEGV。操作系统可能使用信号栈向一个处于自然状态的应用程序通告错误,由此,开发者可以使用它来调试程序或处理错误。

在一个程序接收到SIGSEGV时的默认动作是异常终止。这个动作也许会结束进程,但是可能生成一个内核文件以帮助调试,或者执行一些其他特定于某些平台的动作。例如,使用了grsecurity补丁的Linux系统可能记录 SIGSEGV信号以监视可能的使用缓存溢出的攻击尝试。

SIGSEGV可以被捕获。也就是说,应用程序可以请求它们想要的动作,以替代默认发生的动作。这样的动作可以是忽略它、调用一个函数,或恢复默认的动作。在一些情形下,忽略SIGSEGV导致未定义的行为。[2]

一个应用程序可能处理SIGSEGV的例子是调试器,它可能检查信号栈并通知开发者目前所发生的,以及程序终止的位置。

SIGSEGV通常由操作系统生成,但是有适当权限的用户可以在需要时使用kill系统调用或kill命令(一个用户级程序,或者一个shell内建命令)来向一个进程发送信号。

论坛徽章:
0
3 [报告]
发表于 2010-04-15 18:05 |只看该作者
试试
  1. #include <unistd.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <signal.h>

  6. int main(void)
  7. {
  8.     struct sigaction act;

  9.     memset(&act, '\0', sizeof(act));
  10.     act.sa_handler = SIG_IGN;
  11.     act.sa_flags   = SA_RESTART;
  12.     sigemptyset(&act.sa_mask);
  13.     if (sigaction(SIGSEGV, &act, NULL) == -1)
  14.       perror("sigaction";

  15. //  kill(getpid(), SIGSEGV);
  16.     int* p = 0;
  17.     *p = 1;
  18.     for (; {
  19.         printf("hello world\n";
  20.         sleep(2);
  21.     }

  22.     return 0;
  23. }
复制代码

论坛徽章:
0
4 [报告]
发表于 2010-04-17 21:50 |只看该作者
楼上的代码是对的,你的代码忽略了SIGSEGV,你只发了一次信号,程序当然不会退出了

论坛徽章:
0
5 [报告]
发表于 2010-04-17 22:04 |只看该作者
好像只有sigkill和sigstop不能忽略把

论坛徽章:
0
6 [报告]
发表于 2010-04-18 07:16 |只看该作者
The Design of the UNIX Operating System一书中给出了范例代码,你的程序确实可以增加一段信号处理程序,在接收到SIGSEGV之后增加数据段的大小,来让程序继续执行下去。

但SIGSEGV表示你的程序有问题,在实际的代码中应当认真分析造成Segmentation Fault的原因,然后把编码错误消除掉。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP