Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Feb 1st, 2008, 2:25 PM   #1
dr.p
Programmer
 
dr.p's Avatar
 
Join Date: Feb 2006
Location: Ohio
Posts: 93
Rep Power: 3 dr.p is on a distinguished road
Read Access Violation

Big problem here.

I have a function WriteBmpPkgFile declared as:
DWORD WriteBmpPkgFile (const char *szFileName, LPBMPPKGFILE lpBmpPkg)

In that function, I have a file write call:
  fwrite(&(lpBmpPkg->dwCount), sizeof(BYTE), sizeof(DWORD), outfile);

A BMPPKGFILE is a struct that contains one or more bitmap files. The dwCount member is the number of bitmaps in the package.

When I get to that quoted fwrite line, and the program tries to write the dwCount member to outfile, I get a "Read Access Violation" exception and the program crashes.

BUT... this only happens when the bitmap is less than 4x4 pixels in size!

I allocate memory for the BMPPKGFILE struct when a bitmap is added, and I update the dwCount member, but I NEVER get any allocation errors or read/write access violations when adding a bitmap to a package.

Anyone have any idea why this would be happening? Or a suggestion on how to debug it better in MSVC++ Express 2005?

Here are the struct definitions, in case they help:
typedef struct tagBMPPKGFILE {
  DWORD          dwCount;          // How many images are in this file?
  BMPPKGENTRY   *pEntries;        // pEntries[0..(nCount-1)] = &BMPPKGENTRY
} BMPPKGFILE, *LPBMPPKGFILE;

typedef struct tagBMPPKGENTRY {
  DWORD        dwEntrySize;         // size of this entire entry, in bytes
  DWORD        dwNameSize;          // size of the szName field, in bytes (+\0)
  DWORD        dwFileSize;          // size of the bitmap data, in bytes
  char        *szName;              // pointer to the name
  BYTE        *pRawBmpFile;         // pointer to the raw bitmap file data
} BMPPKGENTRY, *LPBMPPKGENTRY;

Also, the BMPPKGFILE struct I'm using is created and initialized in this fashion:
  BMPPKGFILE bmppkg;
  ZeroMemory(&bmppkg, sizeof(BMPPKGFILE));
__________________
Neeley.org
dr.p is offline   Reply With Quote
Old Feb 1st, 2008, 5:02 PM   #2
Salem
Programmer
 
Join Date: Nov 2007
Posts: 33
Rep Power: 0 Salem is on a distinguished road
Re: Read Access Violation

A breakpoint on the fwrite call would be a start.
Then examine the variables in detail.

> this only happens when the bitmap is less than 4x4 pixels in size!
Are you taking into account the various ways in which bitmap data is padded/aligned to 4-byte boundaries.
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
Salem is offline   Reply With Quote
Old Feb 1st, 2008, 5:20 PM   #3
grumpy
Programming Guru
 
grumpy's Avatar
 
Join Date: Jun 2005
Location: Adelaide, South Australia
Posts: 1,198
Rep Power: 5 grumpy is on a distinguished road
Re: Read Access Violation

Three issues.

First, what are you trying to output? Your fwrite() line will output sizeof(BYTE)*sizeof(DWORD) characters in a binary format to the file. Depending on what a BYTE is, it may have a size greater than 1. If you are trying to output lpBmpPkg->dwCount then the call would be better off as fwrite(&(lpBmpPkg->dwCount), sizeof(DWORD), 1, outfile);.

The second issue is that, if you want to output a data structure using fwrite, it is not a good idea to output structures containing pointers. The pointers, however, they are initialised will probably not contain sense when the struct is read back in. So, doing fwrite(lpBmpPkg, sizeof(BMPPKGFILE), 1, outfile); will output the pointer, but the corresponding fread() call is not guaranteed to give back a useful data structure.

The third issue is that there's are a couple of practical rules you're probably ignoring.
1) the real cause of a crash is any code executed at or before the line where the crash occurs.
2) declaring a pointer does not magically create something for that pointer to point at. You must ensure that any pointers are initialised sensibly so they point at something valid.

How are these concerns relevant? Your code for initialising bmppkg will set all the characters within bmppkg to zero and, in practice, that will have the effect of setting bmppkg.dwCount to zero and bmppkg.pEntries to a null pointer. If you dereference bmppkg.pEntries (and you are presumably doing that if other code is setting bmppkg.dwCount to a non-zero value) then you are dereferencing a NULL pointer. If I had to guess, you are doing something like this;
  BMPPKGFILE bmppkg;
  ZeroMemory(&bmppkg, sizeof(BMPPKGFILE));
   // other things
   bmppkg.dwCount = some_value;
   for (DWORD i = 0; i < bmppkg.dwCount; ++i)
   {
         bmppkg.pEntries[i].dwEntrySize = something();
          // more manipulation of bmppkg.pEntries[i]
    }
and, since bmppkg.pEntries is a NULL pointer, all accesses of bmppkg.pEntries[i] give you undefined behaviour. You haven't provided such code, but I'll bet code where you manipulate data stored in bmppkg is the root cause of your problem. If it's not that, there is probably some other innocent pointer being molested in your code
grumpy is offline   Reply With Quote
Old Feb 1st, 2008, 5:28 PM   #4
dr.p
Programmer
 
dr.p's Avatar
 
Join Date: Feb 2006
Location: Ohio
Posts: 93
Rep Power: 3 dr.p is on a distinguished road
Re: Read Access Violation

Quote:
Originally Posted by Salem View Post
A breakpoint on the fwrite call would be a start.
Then examine the variables in detail.
That was how I found the line where the problem occurred.

Quote:
Originally Posted by Salem View Post
> this only happens when the bitmap is less than 4x4 pixels in size!
Are you taking into account the various ways in which bitmap data is padded/aligned to 4-byte boundaries.
More or less. I'm reading in the bitmaps as a whole, based on the header information. I did a separate test on my bitmap library to see if the read function was causing the problem, and it's not. My test app reads in the same 1x1 256bpp bitmap and divulges the necessary info perfectly.

This problem is... very odd. The BMPPKGFILE pointer passed to the WriteBmpPkgFile is correct, and the data in the memory it points to is also correct.

And fwrite even fails if I do this instead:
  DWORD dwcount = lpBmpPkg->dwCount;
    // write the dwCount member
  fwrite(&dwcount, sizeof(DWORD), 1, outfile);

And this:
  DWORD dwcount = 0x01;  //lpBmpPkg->dwCount;
    // write the dwCount member
  fwrite(&dwcount, sizeof(DWORD), 1, outfile);

Strange, no?
__________________
Neeley.org
dr.p is offline   Reply With Quote
Old Feb 1st, 2008, 5:42 PM   #5
dr.p
Programmer
 
dr.p's Avatar
 
Join Date: Feb 2006
Location: Ohio
Posts: 93
Rep Power: 3 dr.p is on a distinguished road
Re: Read Access Violation

Grumpy,

My reply to Salem should answer your question about what I'm trying to output... just a DWORD variable. At least, in the line that's causing trouble.

As for your comments about misuses of pointers in a struct, the functions I'm using to manage those structures are pretty meticulous. They do properly allocate and reallocate memory for the bitmaps stored in the packages. I've been developing and using them for about a year now, and they are pretty solid.

Thanks.
__________________
Neeley.org
dr.p is offline   Reply With Quote
Old Feb 1st, 2008, 5:46 PM   #6
dr.p
Programmer
 
dr.p's Avatar
 
Join Date: Feb 2006
Location: Ohio
Posts: 93
Rep Power: 3 dr.p is on a distinguished road
Re: Read Access Violation

Quote:
Originally Posted by grumpy View Post
1) the real cause of a crash is any code executed at or before the line where the crash occurs.
This caught my attention, btw... I wonder, is it possible that an earlier file read/write problem (somewhere in some other function, which does not report an error) could cause this particular fwrite failure?
__________________
Neeley.org
dr.p is offline   Reply With Quote
Old Feb 2nd, 2008, 1:01 AM   #7
Salem
Programmer
 
Join Date: Nov 2007
Posts: 33
Rep Power: 0 Salem is on a distinguished road
Re: Read Access Violation

Given your tests in post #4, the only possible culprit would seem to be a problem with outfile
- it isn't open.
- it's already been closed.
- it's been trashed.

FWIW, I would put the *outfile into a watch window as soon as you've opened the file, then compare with what you get when you reach the fwrite call which breaks.

If you do see that change "mysteriously", then you can (in some debuggers at least) set up a watch breakpoint which will trap whenever a memory location is read or modified. Sometimes, this is the only way to figure out random memory overrun problems for example.
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
Salem is offline   Reply With Quote
Old Feb 2nd, 2008, 5:01 AM   #8
grumpy
Programming Guru
 
grumpy's Avatar
 
Join Date: Jun 2005
Location: Adelaide, South Australia
Posts: 1,198
Rep Power: 5 grumpy is on a distinguished road
Re: Read Access Violation

Quote:
Originally Posted by dr.p View Post
This caught my attention, btw... I wonder, is it possible that an earlier file read/write problem (somewhere in some other function, which does not report an error) could cause this particular fwrite failure?
I would still bet fairly good money that the problem is a pointer molestation in previous code. Yes, I realise you consider that code to be "solid". With the symptoms you are seeing, I will bet it is not as solid as you believe.

One of the most effective causes of frustration when debugging is to overlook the actual offending code because of a mistaken belief it is "solid".

Yes, an error with file I/O can cause a subsequent problem with file I/O. However, the symptom you are describing is not a typical I/O error: it is a sign some part of your program is accessing memory it shouldn't. Technically, that can happen in an I/O operation (eg a fwrite(&(lpBmpPkg->dwCount), sizeof(BYTE), sizeof(DWORD), outfile); could do a buffer overrun, depending on the value of sizeof(BYTE)), but that doesn't mean the problem is I/O related.
grumpy is offline   Reply With Quote
Old Feb 2nd, 2008, 1:07 PM   #9
dr.p
Programmer
 
dr.p's Avatar
 
Join Date: Feb 2006
Location: Ohio
Posts: 93
Rep Power: 3 dr.p is on a distinguished road
Re: Read Access Violation

Right on, Grumpy.

I was operating under the assumption that an exception would be thrown immediately if I wrote more data to an allocated buffer than it could hold.

I was adding a bitmap to the package directly before writing the package to disk. In the add function, I was using the biSize member of the BITMAPINFOHEADER structure, instead of biSizeImage. So, when there were fewer than sizeof(BITMAPINFOHEADER) bytes in the bit field, the code failed. Makes sense.

Still, why wouldn't it throw an exception when I copied too many bytes from the bitmap file that was already in memory? And why wouldn't it throw an exception when I wrote more data than the memory space could handle?

Thanks for the push, Grumpy. I likely would have been spinning my wheels for days on this one. And thank you Salem, for your assistance. It is appreciated.
__________________
Neeley.org
dr.p is offline   Reply With Quote
Old Feb 2nd, 2008, 2:05 PM   #10
Salem
Programmer
 
Join Date: Nov 2007
Posts: 33
Rep Power: 0 Salem is on a distinguished road
Re: Read Access Violation

Well you could use a tool like Electric Fence which allocates each block of memory in such a way that if you step off the end at all, then you'll get an exception.
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
Salem is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
1 line if code blocks; easier to read G.I.Josh Perl 5 Nov 6th, 2007 11:30 PM
read access violation backstabber C++ 14 Oct 13th, 2006 3:54 PM
Access to private files. Jhaqen Java 2 Nov 2nd, 2005 2:35 PM
How to connect with VB to an Access database on another computer iown714 Visual Basic 5 Aug 4th, 2005 10:23 AM
Access Violation Error cornish_boy84 Delphi 1 Mar 1st, 2005 4:12 PM




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 12:44 AM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC