大文件内存映射读写报错 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);

 

posted @ 2022-04-08 10:27  mcdull^0^  阅读(3947)  评论(0编辑  收藏  举报