-
September 30th, 2008, 05:03 PM
#1
Baffling memory error
I’ve been tasked with porting an MFC Visual Studio 6 C++ app to VS2005 and have run into a baffling memory error. The program is quite large (1,000,000 lines) so this is turning into a needle in a haystack quandary.
The first indication of trouble currently comes from Boundschecker reporting a memory overrun during program instantiation. The code triggering the overrun is fine (an array of simple structures being initialized). If I move the code to a simple test project it executes flawlessly. So I have to assume that this is a symptom of an existing problem, rather than the problem itself.
Another frustrating thing is that _CrtCheckMemory( ) report no problems when called before or immediately after this line of code.
The code below is from the CTOR of an object owned by the App. It is not dynamically allocated. The element that is failing is definitely within the array bounds.
_ASSERTE(_CrtCheckMemory()); // ok
data[24][35].eventListIdx = 1; // boundschecker reports a memory write overrun
_ASSERTE(_CrtCheckMemory()); // still ok
Originally the object that contained this array was defined globally (instead of being owned by the App). The same behavior was noted except that it failed on an earlier element of the array).
If I comment out the offending code I simply get a memory error somewhere else later during instantiation. Eventually _CrtCheckMemory() will return an error, but this does me little good at that point.
At present I am baffled as to where to go from here. The program is huge and poorly encapsulated (so I can’t build it up module by module).
I would deeply appreciate any ideas or strategies from those who have seen this sort of thing themselves. I understand this isn’t much to go on, but I’m mainly looking for a place to start. Thankyou.
-
September 30th, 2008, 05:37 PM
#2
Re: Baffling memory error
Originally Posted by AndrewRD
The code below is from the CTOR of an object owned by the App. It is not dynamically allocated. The element that is failing is definitely within the array bounds.
Okay, but - the _CrtCheckMemory() call not failing here doesn't say much. You say the index is definitely within the array bounds - are you really sure? I'd start by having a look at where and how the array is declared and created... Is is a member variable of the object you mentioned here? And... What does the definition of the struct that the array holds look like?
-
September 30th, 2008, 06:07 PM
#3
Re: Baffling memory error
Originally Posted by AndrewRD
The first indication of trouble currently comes from Boundschecker reporting a memory overrun during program instantiation. .
I would not rely on Boundschecker memory leak or hanging pointers reports. I have not worked with Boundschecker recently but I remember false positives.
Is there any other indication that memory is leaking?
There are only 10 types of people in the world:
Those who understand binary and those who do not.
-
October 1st, 2008, 09:39 AM
#4
Re: Baffling memory error
Originally Posted by gstercken
Okay, but - the _CrtCheckMemory() call not failing here doesn't say much. You say the index is definitely within the array bounds - are you really sure? I'd start by having a look at where and how the array is declared and created... Is is a member variable of the object you mentioned here? And... What does the definition of the struct that the array
holds look like?
Thanks for the reply. It's possible that I'm seriously confused, but the code looks good to me. Take a look.
Here is the struct definition. It is defined as shown below. An object of CMyClass is declared in the App's header. The code that is generating the error is contained in the constructor of CMyClass.
#define MAX_NUM_GROUPS 32
#define MAX_NUM_CHANNELS 256
class CMyClass
{
...
struct _data
{
long eventListIdx;
double tot;
} data[MAX_NUM_GROUPS][MAX_NUM_CHANNELS+1];
...
};
CMyClass::CMyClass()
{
for ( int g=0; g<MAX_NUM_GROUPS; g++ )
{
for ( int c=0; c<MAX_NUM_CHANNELS+1; c++ )
{
data[g][c].eventListIdx = -1;
data[g][c].tot = 0.0;
}
}
}
-
October 1st, 2008, 09:48 AM
#5
Re: Baffling memory error
Originally Posted by AndrewRD
Thanks for the reply. It's possible that I'm seriously confused, but the code looks good to me. Take a look.
We don't know if those macros, MAX_NUM_GROUPS and MAX_NUM_CHANNELS, were not redefined when that code is executed.
Unless you change those to const variables instead of macros, there is still that doubt.
Regards,
Paul McKenzie
-
October 1st, 2008, 09:51 AM
#6
Re: Baffling memory error
Also, you could have a memory overwrite bug somewhere else in your code, effecting what is going on in the constructor.
Regards,
Paul McKenzie
-
October 1st, 2008, 09:51 AM
#7
Re: Baffling memory error
On a lark I decided to dynamically instantiate CMyClass within my App. The header has just a pointer to an object now. When I 'new' it in the App's constructor I get a different error instead. Declared in CMyClass's header is:
bool channelWasFirstHit[MAX_NUM_CHANNELS+1];
In the constructor I set all of it's elements to false. When it attempts to set the first element (0) to false, BoundsChecker reports "Bad Write Pointer: Pointer 0x071DF9AE is invalid."
channelWasFirstHit[0] = false;
Note that this happens in the same loop as shown before so the call to (data[0][0].eventListIdx = -1 has already happened and succeeded.
Very odd.
-
October 1st, 2008, 09:57 AM
#8
Re: Baffling memory error
Originally Posted by AndrewRD
On a lark I decided to dynamically instantiate CMyClass within my App. The header has just a pointer to an object now. When I 'new' it in the App's constructor I get a different error instead. Declared in CMyClass's header is:
bool channelWasFirstHit[MAX_NUM_CHANNELS+1];
In the constructor I set all of it's elements to false. When it attempts to set the first element (0) to false, BoundsChecker reports "Bad Write Pointer: Pointer 0x071DF9AE is invalid."
If BoundsChecker is correct, you have many more problems than what you're posting, and no one can solve it without seeing the whole picture.
Unless we see something complete, this is not odd. Read my previous message -- if you have a memory overwrite anywhere in your code, the final result of it is that other parts of the code become affected.
Regards,
Paul McKenzie
-
October 1st, 2008, 09:58 AM
#9
Re: Baffling memory error
Originally Posted by Paul McKenzie
Also, you could have a memory overwrite bug somewhere else in your code, effecting what is going on in the constructor.
Regards,
Paul McKenzie
Quite possibly. This is the assumption I've been working under for awhile now. Actually finding it is what has me ripping my hair out.
It's unlikely that MAX_NUM_* have been redefined. The debugger shows values for the proper array limits. But to make sure, I will change them to constant values and see.
-
October 1st, 2008, 10:43 AM
#10
Re: Baffling memory error
Originally Posted by JohnCz
I would not rely on Boundschecker memory leak or hanging pointers reports. I have not worked with Boundschecker recently but I remember false positives.
Is there any other indication that memory is leaking?
Thanks for the reply. The error I described is the 'first' reported by Boundschecker in a debug session but not the only. If I ignore it I then get:
"Overrun Detected During Execution: In block 0x07FE1050 (256) allocated by HeapAlloc."
This error is reported to be in user32.dll and gives no other information.
If this one is ignored I get another overrun during instantiation of a class that seems to be fine. This error pops up only when a second object of it's type is instantiated.
I can keep 'ignoring' these errors but others pop up as other objects are instantiated. Every one I've looked at seems ok. I can't help but think there is something else going wrong before the first error is reported.
Does it make sense to spend time debugging the 2nd, 3rd or Nth memory overrun if the first one is still unexplained?
I've tried removing 3rd party libraries from use. Perhaps I need to find out exactly what modules (including globals) instantiate before the first error is reported and go through all of them with a fine tooth comb. (ouch)
I fully understand that nobody can solve this for me. But if you or anyone else has ideas or strategies on how to attack this kind of problem on a large program I'd really appreciate it.
Thanks.
-
October 1st, 2008, 11:35 AM
#11
Re: Baffling memory error
Originally Posted by AndrewRD
Thanks for the reply. The error I described is the 'first' reported by Boundschecker in a debug session but not the only. If I ignore it I then get:
"Overrun Detected During Execution: In block 0x07FE1050 (256) allocated by HeapAlloc."
This error is reported to be in user32.dll and gives no other information.
If this one is ignored I get another overrun during instantiation of a class that seems to be fine. This error pops up only when a second object of it's type is instantiated.
I can keep 'ignoring' these errors but others pop up as other objects are instantiated. Every one I've looked at seems ok. I can't help but think there is something else going wrong before the first error is reported.
Does it make sense to spend time debugging the 2nd, 3rd or Nth memory overrun if the first one is still unexplained?
Most of us do not have BoundsChecker -- all of those messages could be false and could be ignored.
I fully understand that nobody can solve this for me. But if you or anyone else has ideas or strategies on how to attack this kind of problem on a large program I'd really appreciate it.
Debug the program, and while debugging, know what you are expecting to look for.
Also, you mention global variables. Are these simple global variables (i.e. ints, doubles, arrays, etc.) or are they objects that have constructors? If it is the latter, and you're relying on global objects to be initialized in a certain order, then that is an issue.
Regards,
Paul McKenzie
-
October 1st, 2008, 01:13 PM
#12
Re: Baffling memory error
Does BoundsChecker output a call stack along with each error? Or is there a way to turn that on?
-
October 1st, 2008, 02:35 PM
#13
Re: Baffling memory error
Originally Posted by Lindley
Does BoundsChecker output a call stack along with each error? Or is there a way to turn that on?
Yes, it has a call stack integrated in it's "Program Error Detected" dialog box that pops up. It's fairly useful, similar to that in the debugger.
-
October 1st, 2008, 02:58 PM
#14
Re: Baffling memory error
When you allocate memory, are you using new or malloc?
If using new, what happens if you turn off Boundschecker and run the app under the debugger (ie. VS IDE). When you close the app, do you get any memory leak spew in the output window.
If not, it is unlikely you have a memory leak.
-
October 2nd, 2008, 09:40 AM
#15
Re: Baffling memory error
Originally Posted by Arjay
When you allocate memory, are you using new or malloc?
If using new, what happens if you turn off Boundschecker and run the app under the debugger (ie. VS IDE). When you close the app, do you get any memory leak spew in the output window.
If not, it is unlikely you have a memory leak.
I am using 'new'. And I see no evidence of a memory leak in the output window.
When I debug without boundschecker I get:
"Unhandled exception at 0x00b1eaa5 in myApp.exe: 0xC0000005: Access violation writing location 0x03e4e48e".
Now if I comment out the code that calls the initialization in the CTOR and initialize it later (in the App right after it instantiated the object) I get a different error:
"Windows has triggered a breakpoint in myApp.exe. This may be due to a corruption of the heap, and indicates a bug in AEwin.exe or any of the DLL’s it has loaded".
Last edited by AndrewRD; October 2nd, 2008 at 09:42 AM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|