大文件內存映射讀寫報錯 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);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM