fwrite bug in gcc 4.4.0.

Todd Plessel plessel.todd@epa.gov
Wed Dec 10 21:13:00 GMT 2008


2008-12-10
plessel.todd@epa.gov

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 plessel.todd@epa.gov
/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?

plessel.todd@epa.gov




More information about the Gcc-bugs mailing list