2017-05-29 121 views
2

语境总线错误

  • 的Linux 4.4.0-57泛型#78,Ubuntu的SMP周五12月9日23时50分32秒UTC 2016 x86_64的x86_64的x86_64的GNU/Linux的
  • 法国区域设置

代码

#include <stdio.h> 
#include <string.h> 
#include <fcntl.h> 
#include <sys/mman.h> 

int main() { 
    int fd = open("/tmp/mapped.bin", O_CREAT|O_RDWR|O_SYNC, 0666); 
    perror("open"); 
    unsigned char * dst = 
     (unsigned char *)mmap(
     NULL, 64*1024, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); 
    perror("mmap"); 
    static unsigned char src[] = { 1, 3, 5, 7 }; 
    printf("memcpy(%p, {%d,%d,%d,%d}, %zd)\n", dst, src[0], src[1], src[2], src[3], sizeof(src)); 
    memcpy(dst, src, sizeof(src)); 
    perror("memcpy"); 
    return 0; 
} 

生产

$ gcc -W -Wall -std=c11 src/org/hpms/filemap/BusError.c -o bin/BusError 
(no warning, no error) 

执行

$ bin/BusError 
open: Success 
mmap: Success 
memcpy(0x7f51291fe000, {1,3,5,7}, 4) 
Erreur du bus 

GDB

(gdb) run 
Starting program: /home/aubin/Dev/Java/2017/org.hpms.filemap/bin/BusError 
open: Success 
mmap: Success 
memcpy(0x7ffff7fe6000, {1,3,5,7}, 4) 

Program received signal SIGBUS, Bus error. 
0x00000000004005ac in main() at src/org/hpms/filemap/BusError.c:15 
15  memcpy(dst, src, sizeof(src)); 
(gdb) 
+2

'的typedef字节bytes_t'被missleading。还要注意,POSIX保留以'_t'结尾的名字;你不能使用它们。如果你需要字节,直接使用'unsigned char',不要使用'typedef'来掩盖像这样的别名。如果您需要8位类型,请使用固定宽度类型'uint8_t'。说:有近10k的代表,你应该知道[问]并提供[mcve]!函数返回什么?错误怎么样? ... – Olaf

回答

2

,如果你的文件外部访问mmaped记忆你会得到SIGBUS。换句话说,如果你想写4个字节,文件需要至少4个字节大。

在您的例子,你可以用ftruncate解决的问题:

#include <stdio.h> 
#include <string.h> 
#include <fcntl.h> 
#include <sys/mman.h> 
#include <unistd.h> 

int main() { 
    int fd = open("/tmp/mapped.bin", O_CREAT|O_RDWR|O_SYNC, 0666); 
    perror("open"); 
    unsigned char * dst = 
     (unsigned char *)mmap(
     NULL, 64*1024, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); 
    perror("mmap"); 
    static unsigned char src[] = { 1, 3, 5, 7 }; 
    ftruncate(fd, sizeof src); 
    perror("ftruncate"); 
    printf("memcpy(%p, {%d,%d,%d,%d}, %zd)\n", dst, src[0], src[1], src[2], src[3], sizeof(src)); 
    memcpy(dst, src, sizeof(src)); 
    perror("memcpy"); 
    return 0; 
} 
+2

如果可以的话,您应该将文件大小设置为4K的倍数,即页面大小。它简化了所有的内存管理。 –