2008-12-10 [EMAIL PROTECTED] The following report demonstrates a bug in fwrite(): when attempting to write 8GB, it silently only writes 3.7GB yet issues no errors. There is plenty of disk space and free memory. Platform: Mac OS X 10.5.5, gcc version 4.4.0, compiled -m64 for 64-bit (x86_64).
/* fwrite_bug.c - Show bug in fwrite: silently only writes 3.7GB instead of 8GB. 2008-12-10 [EMAIL PROTECTED] /usr/local/bin/gcc -v -m64 -g -o fwrite_bug fwrite_bug.c file fwrite_bug fwrite_bug ls -l junk */ #include <stdlib.h> /* For malloc(), free(). */ #include <string.h> /* For memset(). */ #include <stdio.h> /* For FILE, printf(), perror(). */ int main( void ) { const size_t bytes = 8000000000UL; /* 8GB file. */ int ok = 0; char* array = malloc( bytes ); printf( "sizeof (size_t) = %lu, bytes = %lu, array = %p\n", sizeof (size_t), bytes, array ); if ( array ) { FILE* file = fopen( "junk", "wb" ); memset( array, 0, bytes ); if ( file ) { const size_t bytes_written = fwrite( array, 1, bytes, file ); int fclose_result = 0; printf( "Bytes written = %lu\n", bytes_written ); if ( bytes_written == bytes ) { const int flush_result = fflush( file ); ok = flush_result == 0; } printf( "ferror = %d\n", ferror( file ) ); fclose_result = fclose( file ); ok = ok && fclose_result == 0; file = 0; } free( array ); array = 0; } if ( ! ok ) { perror( "Failed because " ); } return ! ok; } $/usr/local/bin/gcc -v -m64 -g -o fwrite_bug fwrite_bug.c Using built-in specs. Target: i386-apple-darwin9.4.0 Configured with: ../gcc-4.4-20080801/configure --enable-languages=fortran,c++ Thread model: posix gcc version 4.4.0 20080801 (experimental) (GCC) COLLECT_GCC_OPTIONS='-mmacosx-version-min=10.5.5' '-v' '-m64' '-g' '-o' 'fwrite_bug' '-mtune=generic' /usr/local/libexec/gcc/i386-apple-darwin9.4.0/4.4.0/cc1 -quiet -v -imultilib x86_64 -D__DYNAMIC__ fwrite_bug.c -fPIC -feliminate-unused-debug-symbols -quiet -dumpbase fwrite_bug.c -mmacosx-version-min=10.5.5 -m64 -mtune=generic -auxbase fwrite_bug -g -version -o /var/tmp//ccbd2VJl.s ignoring nonexistent directory "/usr/local/lib/gcc/i386-apple-darwin9.4.0/4.4.0/../../../../i386-apple-darwin9.4.0/include" #include "..." search starts here: #include <...> search starts here: /usr/local/include /usr/local/lib/gcc/i386-apple-darwin9.4.0/4.4.0/include /usr/local/lib/gcc/i386-apple-darwin9.4.0/4.4.0/include-fixed /usr/include /System/Library/Frameworks /Library/Frameworks End of search list. GNU C (GCC) version 4.4.0 20080801 (experimental) (i386-apple-darwin9.4.0) compiled by GNU C version 4.4.0 20080801 (experimental), GMP version 4.2.1, MPFR version 2.2.1. GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096 Compiler executable checksum: e18605928a7028ba0647a6828b0edd07 COLLECT_GCC_OPTIONS='-mmacosx-version-min=10.5.5' '-v' '-m64' '-g' '-o' 'fwrite_bug' '-mtune=generic' as -arch x86_64 -force_cpusubtype_ALL -o /var/tmp//ccq6skQ8.o /var/tmp//ccbd2VJl.s COMPILER_PATH=/usr/local/libexec/gcc/i386-apple-darwin9.4.0/4.4.0/:/usr/local/libexec/gcc/i386-apple-darwin9.4.0/4.4.0/:/usr/local/libexec/gcc/i386-apple-darwin9.4.0/:/usr/local/lib/gcc/i386-apple-darwin9.4.0/4.4.0/:/usr/local/lib/gcc/i386-apple-darwin9.4.0/ LIBRARY_PATH=/usr/local/lib/gcc/i386-apple-darwin9.4.0/4.4.0/x86_64/:/usr/local/lib/gcc/i386-apple-darwin9.4.0/4.4.0/../../../x86_64/:/usr/local/lib/gcc/i386-apple-darwin9.4.0/4.4.0/:/usr/local/lib/gcc/i386-apple-darwin9.4.0/4.4.0/../../../:/usr/lib/ COLLECT_GCC_OPTIONS='-mmacosx-version-min=10.5.5' '-v' '-m64' '-g' '-o' 'fwrite_bug' '-mtune=generic' /usr/local/libexec/gcc/i386-apple-darwin9.4.0/4.4.0/collect2 -dynamic -arch x86_64 -macosx_version_min 10.5.5 -weak_reference_mismatches non-weak -o fwrite_bug -lcrt1.10.5.o -L/usr/local/lib/gcc/i386-apple-darwin9.4.0/4.4.0/x86_64 -L/usr/local/lib/gcc/i386-apple-darwin9.4.0/4.4.0/../../../x86_64 -L/usr/local/lib/gcc/i386-apple-darwin9.4.0/4.4.0 -L/usr/local/lib/gcc/i386-apple-darwin9.4.0/4.4.0/../../.. /var/tmp//ccq6skQ8.o -lgcc_s.10.5 -lgcc -lSystem COLLECT_GCC_OPTIONS='-mmacosx-version-min=10.5.5' '-v' '-m64' '-g' '-o' 'fwrite_bug' '-mtune=generic' dsymutil fwrite_bug $file fwrite_bug fwrite_bug: Mach-O 64-bit executable x86_64 $fwrite_bug sizeof (size_t) = 8, bytes = 8000000000, array = 0x100200000 Bytes written = 8000000000 ferror = 0 $ls -l junk -rw-rw-r-- 1 plessel staff 3705032704 Dec 10 15:12 junk Note how the call to fwrite() reports that it wrote 8GB and fflush() did not fail and ferror() reports no problems and fclose() did not fail yet the file is only 3.7GB instead of 8GB! What is the fix? [EMAIL PROTECTED]