大文件内存映射读写报错 Bus error (core dumped)
应对大文件读写,采用mmap内存映射可以减少IO访问,提高读写效率。
int open(const char *pathname, int flags); void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); int msync(void *addr, size_t length, int flags); int munmap(void *addr, size_t length); int close(int fd);
实际测试中出现Bus error错误
Bus error (core dumped)
使用valgrind 调试工具
valgrind ./pack_tool pack AirFly.fw kernel.img rootfs.img ==4308== Memcheck, a memory error detector ==4308== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. ==4308== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info ==4308== Command: ./pack_tool pack AirFly.fw kernel.img rootfs.img ==4308== ========ota_fw_name:[AirFly.fw]====== ==4308== ==4308== Process terminating with default action of signal 7 (SIGBUS) ==4308== Non-existent physical address at address 0x4027000 ==4308== at 0x401AF8: pack_fw (in /home/liuxueneng/code_exercise/ota_tool/fw_file/pack_tool) ==4308== by 0x4021D0: main (in /home/liuxueneng/code_exercise/ota_tool/fw_file/pack_tool) ==4308== ==4308== HEAP SUMMARY: ==4308== in use at exit: 0 bytes in 0 blocks ==4308== total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated ==4308== ==4308== All heap blocks were freed -- no leaks are possible ==4308== ==4308== For counts of detected and suppressed errors, rerun with: -v ==4308== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) Bus error (core dumped)
查看man mmap的说明 有关SIGBUS有如下解释
ERRORS EACCES A file descriptor refers to a non-regular file. Or a file mapping was requested, but fd is not open for reading. Or MAP_SHARED was requested and PROT_WRITE is set, but fd is not open in read/write (O_RDWR) mode. Or PROT_WRITE is set, but the file is append-only. EAGAIN The file has been locked, or too much memory has been locked (see setrlimit(2)). EBADF fd is not a valid file descriptor (and MAP_ANONYMOUS was not set). EINVAL We don't like addr, length, or offset (e.g., they are too large, or not aligned on a page boundary). EINVAL (since Linux 2.6.12) length was 0. EINVAL flags contained neither MAP_PRIVATE or MAP_SHARED, or contained both of these values. ENFILE The system-wide limit on the total number of open files has been reached. ENODEV The underlying filesystem of the specified file does not support memory mapping. ENOMEM No memory is available. ENOMEM The process's maximum number of mappings would have been exceeded. This error can also occur for munmap(2), when unmapping a region in the middle of an existing mapping, since this results in two smaller mappings on either side of the region being unmapped. EPERM The prot argument asks for PROT_EXEC but the mapped area belongs to a file on a filesystem that was mounted no-exec. EPERM The operation was prevented by a file seal; see fcntl(2). ETXTBSY MAP_DENYWRITE was set but the object specified by fd is open for writing. EOVERFLOW On 32-bit architecture together with the large file extension (i.e., using 64-bit off_t): the number of pages used for length plus number of pages used for offset would overflow unsigned long (32 bits). Use of a mapped region can result in these signals: SIGSEGV Attempted write into a region mapped as read-only. 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).
出现Bus error (core dumped)错误
出现了SIBUS错误,原因是beyond the end of the file ,因为新建的文件的size实际是0,必须先ftruncate大于将要写入文件中大小的size,然后调用mmap进行映射,后开始访问内存写入数据。
int ftruncate(int fd, off_t length);
深圳宝安华美居