Matthew Mitchell
Matthew Mitchell

Reputation: 5393

fread() fails for some unknown reason

EDIT: It works when I change the working directory, thus the files are created in a different directory. The only odd thing about the directory I was using previously was that it is a shared directory used with VirtualBox. Is this a VirtualBox bug all along? I better start using a separate directory.

I've got an extremely weird problem. Somewhere in my program I have this code. I've modified it to print out some information to demonstrate the problem:

uint8_t section[9];
long pos = ftell(rd);
fseek(rd, 0, SEEK_END);
printf("%li\n",ftell(rd));
fseek(rd, pos, SEEK_SET);
printf("%li\n",ftell(rd));
clearerr(rd);
int i = fread(section, 1, 9, rd);
if (i != 9){
    printf("%i - %i - %i\n",i,feof(rd),ferror(rd));

The output is this:

23
14
0 - 0 - 1

So the length of the file at this point is 23 and the cursor is at 14. I want 9 bytes but fread gives zero and presents an error. I get this problem with Linux Mint and not on OSX. Someone else does not seem to have this problem on debian. I have no idea what could cause this problem. Is there no way to diagnose the cause of the error further? ferror() gives zero information.

The file is opened with the "wb+" mode.

Edit:

I found this obscure error with valgrind:

==22141== Syscall param write(buf) points to uninitialised byte(s)
==22141==    at 0x5B68900: __write_nocancel (syscall-template.S:82)
==22141==    by 0x5AFB882: _IO_file_write@@GLIBC_2.2.5 (fileops.c:1289)
==22141==    by 0x5AFB749: new_do_write (fileops.c:543)
==22141==    by 0x5AFCEB4: _IO_do_write@@GLIBC_2.2.5 (fileops.c:516)
==22141==    by 0x5AFDD3E: _IO_switch_to_get_mode (genops.c:189)
==22141==    by 0x5AFBA96: _IO_file_seekoff@@GLIBC_2.2.5 (fileops.c:999)
==22141==    by 0x5AF4F25: rewind (rewind.c:37)
==22141==    by 0x567D149: CBFileAppend (CBFileEC.c:69)
==22141==    by 0x5473AFA: CBDatabaseCreateDeletionIndex (CBDatabase.c:270)
==22141==    by 0x5473195: CBInitDatabase (CBDatabase.c:112)
==22141==    by 0x54721A1: CBNewAddressStorage (CBAddressStorage.c:37)
==22141==    by 0x401F67: main (testCBAddressManager.c:226)
==22141==  Address 0x402a009 is not stack'd, malloc'd or (recently) free'd
==22141==  Uninitialised value was created by a stack allocation
==22141==    at 0x546F750: ??? (in /media/sf_BitEagle_Projects/cbitcoin/bin/libcbitcoin-storage.2.0.so)

I don't know where ??? is obviously, so I have no luck in debugging this further. It's odd as it's complaining in rewind().

Thanks.

Upvotes: 0

Views: 2362

Answers (2)

Matthew Mitchell
Matthew Mitchell

Reputation: 5393

You probably wont believe this but it was indeed a problem with VirtualBox and the shared directory. The build process works fine on a normal directory. Thanks to everyone that tried to help. I've not used strace before but I'll keep that one in mind! And I did get strace-plus to work in the end which might prove useful someday.

Upvotes: 0

Stephen Niedzielski
Stephen Niedzielski

Reputation: 2637

"wb+" destroys the contents of an existing file, according the to the docs: http://en.cppreference.com/w/c/io/fopen. When you attempt to use "rb+", you must first recreate the file or you'll appear to have the same problem as if you had opened it with "wb+" for that invocation.

EDIT: Is this what your full example code looks like?

int main()
{
  typedef unsigned char uint8_t;

  FILE * rd = fopen("foo.tmp", "wb+");
  uint8_t section[9] = {0};
  long pos = 0;

  fprintf(rd, "01234567890123456789012");

  fseek(rd, 14, SEEK_SET);
  pos = ftell(rd);
  fseek(rd, 0, SEEK_END);
  printf("%li\n",ftell(rd));
  fseek(rd, pos, SEEK_SET);
  printf("%li\n",ftell(rd));
  clearerr(rd);
  int i = fread(section, 1, 9, rd);
  if (i != 9){
    printf("%i - %i - %i\n",i,feof(rd),ferror(rd));
  }

  return 0;
}

Upvotes: 2

Related Questions