免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: kouu
打印 上一主题 下一主题

通过mmap读文件, 进程收到SIGBUS而退出 [复制链接]

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
11 [报告]
发表于 2010-04-19 11:15 |只看该作者
1, 这种现象有可能避免吗?
我只想到给文件加强制锁的方法, 避免文件被其他进程修改. 还有其他什么办法吗?

2, 进程在读p+n的内存时, 内核为什么要发出SIGBUG信号呢? 考虑到p+n的内存是处在合法的map之内, 内核如果给进程映射一个零页面(或其他), 让进程读到一些无用的数据. 这样会有什么问题呢?

还望Godbach兄指点~


指点不敢当啊。
其实对于第1个问题,我能想到的也是文件加锁的方法了。
至于第二个问题,是不是需要深入的看一下内核态的代码。

论坛徽章:
0
12 [报告]
发表于 2010-04-20 14:55 |只看该作者
高手啊。。。。

论坛徽章:
0
13 [报告]
发表于 2010-04-21 23:22 |只看该作者
想到一个让用户程序忽略SIGBUS的办法,使用sigsetjmp+siglongjmp。

把之前的代码改造如下:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <fcntl.h>
  6. #include <signal.h>
  7. #include <sys/mman.h>
  8. #include <unistd.h>
  9. #include <setjmp.h>
  10. #define FILESIZE 8192
  11. sigjmp_buf env;
  12. void handle_sigbus(int sig)
  13. {
  14.         printf("SIGBUS!\n");
  15.         siglongjmp(env, 1);
  16. }
  17. void main()
  18. {
  19.         int i;
  20.         char *p, tmp;
  21.         int fd = open("tmp.ttt", O_RDWR);
  22.         p = (char*)mmap(NULL,
  23.                 FILESIZE, PROT_READ|PROT_WRITE,
  24.                 MAP_SHARED, fd, 0);
  25.         signal(SIGBUS, handle_sigbus);
  26.         getchar();
  27.         if (!sigsetjmp(env, 1)) {
  28.                 for (i=0; i<FILESIZE; i++) {
  29.                 tmp = p[i];
  30.                 }
  31.         }
  32.         else {
  33.                 printf("fault cached when i=%d\n", i);
  34.         }
  35.         printf("ok\n");
  36. }
复制代码
按照同样的流程,先执行程序、再将文件缩小、再进行内存访问。得到的输出结果如下:
  1. kouu@kouu-one:~/test$ ./a.out

  2. SIGBUS!
  3. fault cached when i=4096
  4. ok
复制代码

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
14 [报告]
发表于 2010-04-22 10:35 |只看该作者
想到一个让用户程序忽略SIGBUS的办法,使用sigsetjmp+siglongjmp

请教kouu兄这个地方应该是因为内核态把这个错误信息传递给了用户态吧,那么你在用户态忽略,但实际这个错误还是发生了吧。

论坛徽章:
0
15 [报告]
发表于 2010-04-22 13:29 |只看该作者
回复 14# Godbach

是的,错误还是发生了,只是在用户态规避掉。

论坛徽章:
0
16 [报告]
发表于 2010-04-22 13:37 |只看该作者
1,楼主在mmap的时候,为啥要用MAP_SHARED了?试试MAP_PRIVATE,就不会了
既然是共享,双方就要有游戏规则哦.
那避免的话,就需要指定规则,具体规则我也不知道...

2,楼主是什么版本的代码了?
2的问题和第一个问题,怎么看起来像是一个问题了...

论坛徽章:
0
17 [报告]
发表于 2010-04-22 15:29 |只看该作者
1,楼主在mmap的时候,为啥要用MAP_SHARED了?试试MAP_PRIVATE,就不会了
既然是共享,双方就要有游戏规则哦.
...
augustusqing 发表于 2010-04-22 13:37


感谢你的回答~

1、MAP_PRIVATE 和 MAP_SHARED 都是一样的效果。这应该是POSIX的规定:

The mmap() function can be used to map a region of memory that is larger than the current size of the object. Memory access within the mapping but beyond the current end of the underlying objects may result in SIGBUS signals being sent to the process. The reason for this is that the size of the object can be manipulated by other processes and can change at any moment. The implementation should tell the application that a memory reference is outside the object where this can be detected; otherwise, written data may be lost and read data may not reflect actual data in the object.

见:http://www.opengroup.org/onlinepubs/000095399/functions/mmap.html

2、我的两个问题应该不是一样的吧~
1, 这种现象有可能避免吗?
2, 内核为什么要发出SIGBUG信号呢?

论坛徽章:
0
18 [报告]
发表于 2010-04-23 13:18 |只看该作者
1、MAP_PRIVATE 和 MAP_SHARED 都是一样的效果

你用代码试验了MAP_PRIVATE?
惊恐中......



你是哪个版本内核了?

论坛徽章:
0
19 [报告]
发表于 2010-04-23 13:50 |只看该作者
试过了,2.6.9、2.6.29试过两个版本。

你用代码试验了MAP_PRIVATE?
惊恐中...... too

论坛徽章:
0
20 [报告]
发表于 2010-04-23 14:00 |只看该作者
MAP_PRIVATE 和 MAP_SHARED  有什么区别?

按我的理解,只有对map进行写了以后才有区别。
MAP_SHARED  对应的页表项还是指向文件的cache,读写都还是作用在文件的cache上;
MAP_PRIVATE 分配新的内存,对应的页表项切换到这些新内存上来。以后对对应位置的读写就跟文件cache没有关系了;

如果我的这个理解没错,那么在本例中,既然没有写,MAP_PRIVATE 和 MAP_SHARED 也就没有什么区别了。

如果我理解有误,还望指点。非常感谢~
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP