write()上的段错误,带有~8MB缓冲区(OSX,Linux)

sta*_*oat 5 linux bsd segmentation-fault

我很好奇什么样的缓冲区大小write()和read()可以在Linux/OSX/FreeBSD上处理,所以我开始玩下面的哑项目:

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

int main( void ) {
    size_t s = 8*1024*1024 - 16*1024;
    while( 1 ) {
        s += 1024;
        int f = open( "test.txt", O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IXUSR );
        char mem[s];
        size_t written = write( f, &mem[0], s );
        close( f );
        printf( "(%ld) %lu\n", sizeof(size_t), written );
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这让我可以测试在segfaulting之前我能得到的看似"8MB障碍"的接近程度.在大约8MB标记处,我的程序死了,这是一个示例输出:

(8) 8373248
(8) 8374272
(8) 8375296
(8) 8376320
(8) 8377344
(8) 8378368
(8) 8379392
(8) 8380416
(8) 8381440
(8) 8382464
Segmentation fault: 11
Run Code Online (Sandbox Code Playgroud)

这在OSX和Linux上是一样的,但是我的FreeBSD VM不仅运行这个测试的速度要快得多,它还可以在很多方面继续使用!我已成功测试了高达511MB,这只是一次调用中写入的大量数据.

是什么让write()调用segfault,如何在一次调用中找出我可能写入的最大量(),而不是像我现在正在做的那样做一些荒谬的事情?

(注意,所有三种操作系统都是64位,OSX 10.7.3,Ubuntu 11.10,FreeBSD 9.0)

tro*_*foe 5

故障不在范围write(),这是一个堆栈溢出.试试这个:

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

int main( void )
{
    void *mem;
    size_t s = 512*1024*1024 - 16*1024;
    while( 1 )
    {
        s += 1024;
        int f = open( "test.txt", O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IXUSR );
        mem = malloc(s);
        size_t written = write( f, mem, s );
        free(mem);
        close( f );
        printf( "(%ld) %lu\n", sizeof(size_t), written );
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)