总线错误
问题描述:
语境总线错误
- 的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)
答
,如果你的文件外部访问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的倍数,即页面大小。它简化了所有的内存管理。 –
'的typedef字节bytes_t'被missleading。还要注意,POSIX保留以'_t'结尾的名字;你不能使用它们。如果你需要字节,直接使用'unsigned char',不要使用'typedef'来掩盖像这样的别名。如果您需要8位类型,请使用固定宽度类型'uint8_t'。说:有近10k的代表,你应该知道[问]并提供[mcve]!函数返回什么?错误怎么样? ... – Olaf