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

时间:2012-04-20 07:58:42

标签: linux segmentation-fault bsd

我很好奇什么样的缓冲区大小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;
}

这使我能够测试在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

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

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

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

1 个答案:

答案 0 :(得分: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;
}