segfault при записи() с буфером ~8 МБ (OSX, Linux)

Мне было любопытно, с какими размерами буфера 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;
}

Это позволило меня, чтобы проверить, насколько близко к кажущемуся «барьеру в 8 МБ» я мог бы подойти, прежде чем segfaulting. Где-то на отметке 8 МБ моя программа умирает, вот пример вывода:

(8) 8373248
(8) 8374272
(8) 8375296
(8) 8376320
(8) 8377344
(8) 8378368
(8) 8379392
(8) 8380416
(8) 8381440
(8) 8382464
Segmentation fault: 11

Это то же самое в OSX и Linux, однако моя виртуальная машина FreeBSD не только намного быстрее выполняет этот тест, но и может продолжаться довольно долго. ! Я успешно протестировал его до 511 МБ, что является просто смехотворным объемом данных для записи за один вызов.

Что делает вызов write() segfault, и как я могу вычислить максимальную сумму, которую я могу написать() за один вызов, не делая при этом чего-то нелепого, как я делаю сейчас?

(Примечание: все три операционные системы 64-разрядные, OSX 10.7.3, Ubuntu 11.10, FreeBSD 9.0)

5
задан staticfloat 20 April 2012 в 07:58
поделиться