signal 11信号的处理

本文展示了一个程序如何创建只读内存映射区域并尝试对其写入,导致SIGSEGV错误,随后通过改变访问权限成功写入。重点讨论了信号处理、内存映射和权限管理在程序中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <signal.h>
#include <setjmp.h>
    

 char *buf;
 struct stat statbuf;

void handler(int signo)
{
      printf("permission denied/n");

/*  

     if(mprotect(buf, statbuf.st_size, PROT_READ|PROT_WRITE)==-1) //改变内存映射区访问权限
       {
                 perror("fail to alter permission");
                 exit(1);
       }
        printf("modify/n");

*/
}

int main(void)
{
     int fd;


     if((signal(SIGSEGV, handler)) == SIG_ERR)     //设置SIGSEGV信号处理程序

     {
              printf("can't set handler for SIGALRM");
              exit(0);
      }

      if(stat("test.txt", &statbuf) == -1) //得到文件状态信息
      {
               perror("fail to get stat");
               exit(1);
       }

       fd = open("test.txt", O_RDWR); //以读写方式打开文件
      if(fd == -1)
      {
               perror("fail to open");
               exit(1);
       }

       buf = (char *)mmap(NULL,statbuf.st_size,PROT_READ,MAP_SHARED,fd,0); //建立内存映射区,访问权限为只读

       printf("try to write/n");
       memcpy(buf, "china/n", 6); // 企图写一个只读的映射区,造成SIGSEGV错误


       if(mprotect(buf, statbuf.st_size, PROT_READ|PROT_WRITE)==-1) //改变内存映射区访问权限
       {
                 perror("fail to alter permission");
                 exit(1);
       }

       printf("write again/n");
       memcpy(buf, "china/n", 6); //再次写内存映射区

       if(munmap(buf, statbuf.st_size) == -1) //撤销内存映射
      {
             perror("fail to munmap");
             exit(1);
       }

             close(fd);

            return 0;

}

程序打印结果:

try to write
permission denied
permission denied
permission denied
permission denied
permission denied
permission denied
permission denied
permission denied

分析:

程序本意:该程序演示越权访问一个内存映射区。首先创建一个只读的内存映射区,之后对其进行写操作。该越权访问造成程序收到SIGSEGV信号。应用程序接收该信号,并输出提示信息不能关切输出提示信息。接下来程序调用mprotect函数改变映射区的访问权限为可读写。此时,再次向映射区进行写操作就可以成功了。

但是:当程序捕捉到SIGSEGV信号时,本意是希望捕获信号输出提示信息后,程序能继续运行。但是,中断返回点仍旧在非法访问处,如此则进入一个“非法访问--信号--处理--非法访问”的死循环中。

改进方法:

把红色的代码注掉,将蓝色的代码放开(把mprotect(...)的调用放在信号处理函数中)
打印结果:

try to write
permission denied
modify
write again

此时紫色的代码可以去掉,因为signal信号处理函数,会返回到memcpy函数调用处执行

### SIG 的定义和技术背景 在信息技术领域,SIG 是 **Special Interest Group**(特别兴趣小组)的缩写。它通常指由一群具有共同兴趣的技术爱好者组成的团体,专注于某一特定技术主题的研究和发展[^1]。这些小组可能围绕 ROS2、云计算、编程语言或其他具体技术展开活动。 #### 特别兴趣小组的作用 特别兴趣小组的主要功能在于促进社区内的协作与交流。例如,在 ROS2 社区中,可能会有专门针对 DDS(Data Distribution Service)、导航栈或机器人仿真工具的兴趣小组。这种形式有助于集中资源解决特定问题并推动技术创新。 #### 编程中的其他含义 除了作为 Special Interest Group 使用外,“sig”也可能出现在不同上下文中表示其他概念: - 在操作系统信号处理机制里指的是 Signal (e.g., `SIGINT`, `SIGTERM`); - 部分框架或者库会利用 sig 前缀命名函数来代表某种签名(Signature),比如加密算法生成的数据验证串等[^2]; ```python import signal def handler(signum, frame): print('Signal handled:', signum) signal.signal(signal.SIGINT, handler) print("Waiting for Ctrl+C...") while True: pass ``` 上述代码展示了如何捕捉 Linux 或 Unix 平台上的中断信号 (`SIGINT`)[^2]。 ### 结论 综上所述,当提到“SIG”时需考虑其所在环境以确定确切意义——既可以是指向专业技术群体(SIGs),也可能是计算机科学里的其它术语如系统调用标志位等等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值