Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么有关mmap的代码在(16384+;1)字节处获取段错误,而不是(4096+;1)字节?_C_Linux_Segmentation Fault_Shared Memory_Mmap - Fatal编程技术网

C 为什么有关mmap的代码在(16384+;1)字节处获取段错误,而不是(4096+;1)字节?

C 为什么有关mmap的代码在(16384+;1)字节处获取段错误,而不是(4096+;1)字节?,c,linux,segmentation-fault,shared-memory,mmap,C,Linux,Segmentation Fault,Shared Memory,Mmap,操作系统是Ubuntu。 在我看来,页面大小是4096,它应该在第(4096+1)个字节出现段错误,但在写入第(16384+1)个字节时会出现段错误 输出:。。。16383 a分段故障 #include <sys/mman.h> // memory management. #include <sys/stat.h> // file stat. man 2 stat #include <fcntl.h> // O_CREAT #include

操作系统是Ubuntu。 在我看来,页面大小是4096,它应该在第(4096+1)个字节出现段错误,但在写入第(16384+1)个字节时会出现段错误

输出:。。。16383 a分段故障

#include <sys/mman.h>   // memory management.
#include <sys/stat.h>   // file stat. man 2 stat
#include <fcntl.h>      // O_CREAT
#include <unistd.h>

#include <errno.h>
#include <stdio.h>

int main(int argc, char* argv[]) {
    const int page_size = getpagesize();
    printf("page_size: %d\n", page_size);

    int shm_fd = open("shm.temp", O_CREAT | O_RDWR, S_IRWXU);
    ftruncate(shm_fd, 1);

    char* begin = (char *)mmap(NULL, 1, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_NORESERVE, shm_fd, 0);
    perror("mmap");

    begin[0] = 'a';
    for(int i = 1023;/*i < .. */ ; i += 1024) {
        begin[i] = 'a';
        printf("%d %c\n", i, begin[i] );

        begin[i+1] = 'a';
        printf("%d %c\n", i+1, begin[i] );
    }

    return 0;
}
a.out&
的输出:

pid: 3929
begin: b78a5000
begin+4096: b78a6000
begin+16384: b78a9000
cat/proc/pid/maps的输出

b78a5000-b78a6000 rw-p 00000000 08:01 285615     /home/.../Try/shm.temp
b78a6000-b78a9000 rw-p 00000000 00:00 0 
bfb04000-bfb19000 rw-p 00000000 00:00 0          [stack]
多亏了巴兹尔的观点


现在问题变为
为什么会有b78a6000-b78a9000
。我在想办法。欢迎提供更多信息。

在我使用
cat/proc/pid/maps
之后,我确实发现了一些其他的mmap ed段。 然后我使用
strace a.out
。我确实知道为什么会有b78a6000-b78a9000

它来自主函数之前的加载程序和运行时环境

execve("./a.out", ["./a.out"], [/* 38 vars */]) = 0
brk(0)                                  = 0x85d8000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77f8000
... and something like it.
相关要点:

g++ -static option!

现在我想我得到了这个问题的答案。谢谢你的评论,特别是巴兹尔的观点,让我想得更多。

也许你还有其他的
mmap
-ed片段。如果您的进程是1234,请使用
cat/proc/1234/maps
进行检查。为什么要使用
MAP\u NORESERVE
?映射文件时通常是错误的。未定义的行为再次出现?@BasileStarynkevitch:嗯?在Linux中,对于可写的文件备份文件来说,映射通常是合理的,否则映射将被限制为可用RAM+交换的大小。这可能是因为如果进程的磁盘空间不足,它会被
SIGSEGV
信号终止,而不是得到
ENOSPC
错误?我不认为这本身就是错的。。不过,它确实施加了一些设计限制;不能保证您会得到预期的错误。请注意,当需要溢出检测时,保护页(不可读、不可写的页;
PROT_NONE
)就是为此目的而设置的。至于您看到的行为的原因,可能底层文件系统上的基本块大小是16k,即
bash-c'stat-f-c%S.
报告16384?
g++ -static option!