mmap报错Invalid argument的解决办法

mmap这个函数到处都用到,很多问题都是用perror("mmap")出来的结果是Invalid argument

这个问题,我遇到有两种可能导致

1. open文件时的用的访问模式如O_RDONLY, O_WRONLY, or O_RDWR和你mmap的模式如

 PROT_EXEC  Pages may be executed.

 PROT_READ  Pages may be read.

 PROT_WRITE Pages may be written.

 PROT_NONE  Pages may not be accessed.

不匹配。

 

2. 你mmap的文件所属的文件系统,如果是网络上的文件,linux是无法保证文件的一致性的,那么MAP_SHARED所要求的语义就不能够达到,这时就看你所需要的一致性要求了,如果你只需要在内存上操作,不需要保证munmap时把内存flush回文件的话,可以采用MAP_PRIVATE模式,而如果需要保证这种强的一致性要求的话,就必须要用到MAP_SHARED。

我发现我对VIRTUAL BOX共享文件夹下的文件进行mmap操作就不能够保证这个MAP_SHARED,perror的出错信息也报的是Invalid argument,实际上对于其他linux本机文件目录上的文件,这个一致性是可以保证的,也就是说只要除了这种共享的文件,对其他文件进行这个操作是可以正常执行的。

 

下面附上一个我自己调好的例子

1. mywriteread.c

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

       #define handle_error(msg) \
           do { perror(msg); exit(EXIT_FAILURE); } while (0)

int main(int argc, char * argv[])
{
        char * addr;
        int fd;
        int i;
        struct stat sb;
        off_t offset, pa_offset;
        size_t length;
        ssize_t s;
        char * buf = "123456789abcdefghijkl";

           if (argc < 3 || argc > 4) {
               fprintf(stderr, "%s file offset [length]\n", argv[0]);
               exit(EXIT_FAILURE);
           }


        fd = open(argv[1],O_RDWR);
        if(fd ==-1)
                handle_error("open");

        if(fstat(fd,&sb) == -1)
                handle_error("fstat");

        offset = atoi(argv[2]);
        pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE)-1);

  if(offset >= sb.st_size){
                fprintf(stderr,"offset is past end if file \n");
                exit(EXIT_FAILURE);
        }

        if(argc == 4){
                length = atoi(argv[3]);
                if(offset + length > sb.st_size)
                        length = sb.st_size - offset;
        }
        else{
                length = sb.st_size - offset;
        }

        printf("\tfile size is %d\n",sb.st_size);
        printf("length = %d\t, mapped memory length = %d\t, pa_offset = %d\n",length,length + offset -pa_offset, pa_offset);
        addr = mmap(NULL,length + offset - pa_offset, PROT_READ|PROT_WRITE,
                        MAP_SHARED,fd,pa_offset);

        if(addr == MAP_FAILED)
                handle_error("mmap");


        memcpy(addr,buf,10);
        printf("check write!\n");
        for(i = 0;i<10 ; i++){
        printf("new mem[%d] = %c\n",i, *(addr+i));
        }

        printf("string test = %s\n",(char *)addr);

        munmap(addr,length + offset - pa_offset);
return 0;


2. b.data

aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaa


 [root@localhost tryrw]# ./mywr b.data 0 10
        file size is 120                                                                                                                     
length = 10     , mapped memory length = 10     , pa_offset = 0                                                                              
check write!                                                                                                                                 
new mem[0] = 1                                                                                                                               
new mem[1] = 2                                                                                                                               
new mem[2] = 3                                                                                                                               
new mem[3] = 4                                                                                                                               
new mem[4] = 5                                                                                                                               
new mem[5] = 6                                                                                                                               
new mem[6] = 7                                                                                                                               
new mem[7] = 8                                                                                                                               
new mem[8] = 9                                                                                                                               
new mem[9] = a                                                                                                                               
string test = 123456789aaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaa

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
mmap()函数在创建映射区时可能会出现错误。根据引用\[1\]中的代码,报错的原因可能是在调用mmap()函数时传入了无效的参数。具体来说,可能是传入的文件描述符(a->fd)无效或者请求的虚拟地址(a->requested_va)无效。这可能是由于文件描述符无效或者请求的虚拟地址不符合要求导致的。 引用\[2\]中提到了一些关于mmap()函数的注意事项。其中,注意事项2指出当使用MAP_SHARED标志时,映射区的权限应该小于等于文件打开的权限。而使用MAP_PRIVATE标志则没有这个限制。注意事项3指出映射区的释放与文件关闭无关,即映射区建立成功后,文件可以立即关闭。注意事项4提到了当映射文件大小为0时,无法创建映射区。因此,用于映射的文件必须有实际大小。 引用\[3\]中提到了一个可能导致mmap()函数失败的原因。如果映射的文件所属的文件系统是网络上的文件,Linux无法保证文件的一致性。这时,MAP_SHARED所要求的语义就无法满足。如果只需要在内存上操作而不需要将内存刷新回文件,可以使用MAP_PRIVATE模式。但如果需要保证强一致性要求,就必须使用MAP_SHARED模式。 综上所述,mmap()函数失败的原因可能是传入了无效的参数,如无效的文件描述符或请求的虚拟地址。此外,还可能是由于文件所属的文件系统是网络上的文件,无法满足MAP_SHARED的要求。 #### 引用[.reference_title] - *1* [mmap()报Invalid argument的错误](https://blog.csdn.net/choumin/article/details/122539286)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [【unix系统编程】mmap创建映射区,提示mmap:invalid argument!](https://blog.csdn.net/m0_57168310/article/details/129785825)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [mmap报错Invalid argument解决办法](https://blog.csdn.net/zgl07/article/details/8866987)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值