Chinaunix首页 | 论坛 | 博客
  • 博客访问: 445141
  • 博文数量: 138
  • 博客积分: 4114
  • 博客等级: 上校
  • 技术积分: 1341
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-14 20:41
文章分类

全部博文(138)

文章存档

2014年(1)

2013年(2)

2012年(78)

2011年(13)

2010年(34)

2009年(10)

我的朋友

分类: LINUX

2012-05-18 17:29:13

今天写一个小程序遇到来bus error, 
感觉挺新鲜的, 于是google之,原来是这样子阿
如果没有  
write(fd, " ", 1);
这两句话,下面的程序就会有bus error, 
具体原因是因为, mmap。。。  这个。。 看man把

  1. SIGBUS Attempted access to a portion of the buffer that does not correspond to the file (for example, beyond the end of the file, including the case where another process has truncated the file).
就是“你过界了”


下面这个小程序没有使用信号量来进行同步, 用的最二的方式
让子进程sleep 10s, 这种处理方式不推荐用到生产环境中,权当例子讲解使用。

  1. #include <sys/mman.h>
  2. #include <unistd.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <fcntl.h>

  8. #define FILE_NAME "/root/test.test"

  9. void child_work()
  10. {
  11.     //getchar();
  12.     int fd = open(FILE_NAME, O_RDWR);
  13.     if (fd == -1) {
  14.         perror("open file failed");
  15.     }
  16.     char *addr = NULL;
  17.     addr = (char *)mmap(NULL, 100, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  18.     printf("%s", addr);
  19. }

  20. int main(void)
  21. {
  22.     int res = -1;
  23.     int fd = -1;
  24.     if ( (fd = open(FILE_NAME, O_CREAT|O_RDWR)) == -1){
  25.         perror("open file failed");
  26.         return -1;
  27.     }

  28.     /*settle bus error*/
  29.     lseek(fd, 100, SEEK_SET);
  30.     write(fd, " ", 1);

  31.     char * addr = NULL;
  32.     addr = (char *)mmap(NULL, 100, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  33.     if (addr == MAP_FAILED) {
  34.         perror("mmap failed ");
  35.         close(fd);
  36.         return -1;
  37.     }
  38.     switch(fork()) {
  39.         case -1:
  40.             perror("fork error");
  41.             return -1;
  42.             break;
  43.         case 0:
  44.             /* child */
  45.             sleep(10);
  46.             child_work();
  47.             return;
  48.         default:
  49.             break;
  50.     }
  51.     /* parent */
  52.     sprintf(addr, "hello child!\n\0");
  53.     wait(0);

  54.     return 0;
  55. }

这里有个小程序写的更好


  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <unistd.h>
  6. #include <fcntl.h>
  7. #include <sys/mman.h>

  8. #define FILEPATH "/tmp/mmapped.bin"
  9. #define NUMINTS (1000)
  10. #define FILESIZE (NUMINTS * sizeof(int))

  11. int main(int argc, char *argv[])
  12. {
  13.     int i;
  14.     int fd;
  15.     int result;
  16.     int *map; /* mmapped array of int's */

  17.     /* Open a file for writing.
  18.      * - Creating the file if it doesn't exist.
  19.      * - Truncating it to 0 size if it already exists. (not really needed)
  20.      *
  21.      * Note: "O_WRONLY" mode is not sufficient when mmaping.
  22.      */
  23.     fd = open(FILEPATH, O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600);
  24.     if (fd == -1) {
  25.     perror("Error opening file for writing");
  26.     exit(EXIT_FAILURE);
  27.     }

  28.     /* Stretch the file size to the size of the (mmapped) array of ints
  29.      */
  30.     result = lseek(fd, FILESIZE-1, SEEK_SET);
  31.     if (result == -1) {
  32.     close(fd);
  33.     perror("Error calling lseek() to 'stretch' the file");
  34.     exit(EXIT_FAILURE);
  35.     }
  36.     
  37.     /* Something needs to be written at the end of the file to
  38.      * have the file actually have the new size.
  39.      * Just writing an empty string at the current file position will do.
  40.      *
  41.      * Note:
  42.      * - The current position in the file is at the end of the stretched
  43.      * file due to the call to lseek().
  44.      * - An empty string is actually a single '\0' character, so a zero-byte
  45.      * will be written at the last byte of the file.
  46.      */
  47.     result = write(fd, "", 1);
  48.     if (result != 1) {
  49.     close(fd);
  50.     perror("Error writing last byte of the file");
  51.     exit(EXIT_FAILURE);
  52.     }

  53.     /* Now the file is ready to be mmapped.
  54.      */
  55.     map = mmap(0, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  56.     if (map == MAP_FAILED) {
  57.     close(fd);
  58.     perror("Error mmapping the file");
  59.     exit(EXIT_FAILURE);
  60.     }
  61.     
  62.     /* Now write int's to the file as if it were memory (an array of ints).
  63.      */
  64.     for (i = 1; i <=NUMINTS; ++i) {
  65.     map[i] = 2 * i;
  66.     }

  67.     /* Don't forget to free the mmapped memory
  68.      */
  69.     if (munmap(map, FILESIZE) == -1) {
  70.     perror("Error un-mmapping the file");
  71.     /* Decide here whether to close(fd) and exit() or not. Depends... */
  72.     }

  73.     /* Un-mmaping doesn't close the file, so we still need to do that.
  74.      */
  75.     close(fd);
  76.     return 0;
  77. }

reading

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <unistd.h>
  6. #include <fcntl.h>
  7. #include <sys/mman.h>

  8. #define FILEPATH "/tmp/mmapped.bin"
  9. #define NUMINTS (1000)
  10. #define FILESIZE (NUMINTS * sizeof(int))

  11. int main(int argc, char *argv[])
  12. {
  13.     int i;
  14.     int fd;
  15.     int *map; /* mmapped array of int's */

  16.     fd = open(FILEPATH, O_RDONLY);
  17.     if (fd == -1) {
  18.     perror("Error opening file for reading");
  19.     exit(EXIT_FAILURE);
  20.     }

  21.     map = mmap(0, FILESIZE, PROT_READ, MAP_SHARED, fd, 0);
  22.     if (map == MAP_FAILED) {
  23.     close(fd);
  24.     perror("Error mmapping the file");
  25.     exit(EXIT_FAILURE);
  26.     }
  27.     
  28.     /* Read the file int-by-int from the mmap
  29.      */
  30.     for (i = 1; i <=NUMINTS; ++i) {
  31.     printf("%d: %d\n", i, map[i]);
  32.     }

  33.     if (munmap(map, FILESIZE) == -1) {
  34.     perror("Error un-mmapping the file");
  35.     }
  36.     close(fd);
  37.     return 0;
  38. }

阅读(3561) | 评论(0) | 转发(0) |
0

上一篇:算法面试题 搜集

下一篇:nginx 列表

给主人留下些什么吧!~~