Sign in to follow this  
d000hg

Nasty wierd bugs (Part2)

Recommended Posts

In a previous thread I mentioned that my renderstate manager was sometimes causing crashes in debug builds. I was advised to investigate it, but it now doesn't crash there anymore. Instead I'm getting similar problems elsewhere in my code! These are not happening every time, or always in the same place (but in the same few locations). I either get an access violation reported, or the message "User breakpoint called from code at 0x7c901230". I'm also getting debug output like: First-chance exception in 4E4_RTS.exe (NTDLL.DLL): 0xC0000005: Access Violation. HEAP[4E4_RTS.exe]: HEAP[4E4_RTS.exe]: HEAP: Free Heap block 9b50880 modified at 9b50890 after it was freed HEAP: Free Heap block 9b51000 modified at 9b51010 after it was freed The kind of place where this occurs is for instance
LODSize = (1<<(mLODCount - LOD))+1;
//build the vertex data container; we have twice the vertex count
// for transparent & opaque vertices
mVertexData[LOD]  = new TERRAIN_FVF_VERTEX1[ (LODSize-2)*(LODSize-2) * 2 ];
mGroundTypeTriangleCount[LOD]	= new unsigned short[mNumGroundTypes*2];
mGroundTypeIndexOffset[LOD]		= new unsigned short[mNumGroundTypes*2];
I've checked the size of the array being created and other values to see they are in range. The call stack is along the lines of: My function operator_new(unsigned int) _nh_malloc . . . _heap_alloc_dbg _heap_alloc_base I don't really know where to look to fix this and it's slowly driving me mad!

Share this post


Link to post
Share on other sites
I think I have the same problem!
I've been recently porting my GNU GCC code to VS 2005 Express edition and then it started!

It occurs at a certain point in the code and always on a "new" operator. If you put another new in front of it, like "new int", it just goes to the next line and crashes on the other "new" allocator. BUT, if you do "new int[1000]" (and so you allocate more), it doés crash.

Suppose it crashes here:
Object* crash = new Object;

Then it doesn't crash on the first line, but on the seconde line of this code:
int* a = new int;
Object* crash = new Object;

But, if you use thís code, it doés crash on the first line, because you allocate more memory:
int* a = new int[1000];
Object* crash = new Object;

The project itself consists out of a static library with system independant tools, also a static graphics lib that uses the previous lib and then the application that uses the graphics lib.
It even crashes when allocating a member from a std::vector when you add items to it.

Share this post


Link to post
Share on other sites
Hi,

Sounds like a memory corruption error of some sort.

Try using _CrtCheckMemory() to check the validity of the debug heap from time to time:

assert(_CrtCheckMemory())
or
_ASSERTE(_CrtCheckMemory())


_CrtCheckMemory() simply checks that everything is in order in the debug heap (only compiles to code if _DEBUG is defined).

Hopefully, this way you should be able to track down if memory is becoming corrupted and where it is being corrupted.

To be extra millitant you can turn on the debug flag _CRTDBG_CHECK_ALWAYS_DF to tell the debug runtime to call _CrtCheckMemory() each time an allocation is made:

int curFlags = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
curFlags |= _CRTDBG_CHECK_ALWAYS_DF;
_CrtSetDbgFlag(curFlags);


You could also try out one of the numerous debug memory managers available (google should find a few), but sometimes integration can be awkward.

Hope this helps!

Mike.

Share this post


Link to post
Share on other sites
Give what MIkeWW said a go, but also remember that you don't have to wait until the next allocation is done to catch the error. That could be somewhere unrelated, making it difficult to track down the real problem.

Make sure you use assert()'s elsewhere in your program as well, especially to validate that the expressions used inside square brackets are >= 0 and < the array size.

Share this post


Link to post
Share on other sites
Quote:
Original post by iMalc
Give what MIkeWW said a go, but also remember that you don't have to wait until the next allocation is done to catch the error. That could be somewhere unrelated, making it difficult to track down the real problem.

Make sure you use assert()'s elsewhere in your program as well, especially to validate that the expressions used inside square brackets are >= 0 and < the array size.


Thanks, but I already do that. I have asserts and other error checking for any pointer or init that is called, for as far as I know.
My guess is that there's a problem with one of the references, but that's just a guess off course.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
My errors are basically because for some reason new is returning 0.

I think I may have found the cause though, possibly I should feel ashamed: I think it's a threading issue. I have one extra thread which is used to let me have an animated load screen while levels are loaded etc. I think the problems are caused by code running in this aditional thread. I remember when you create a new project in VS6 you can choose between single/multi-threaded; are the standard libraries multi-thread safe or do I need to change the libraries I link to? If so how can I tell which - or maybe I should just create a new project with different settings?
I think I've got DX set to be multithreaded, but I haven't initialised COM this way.

Share this post


Link to post
Share on other sites
new also likes to return 0 (or throw that exception crap) when the amound to be allocated is ridiculously high (as in 0xcdcdcdcd for example).

Check the size variable you pass to new.

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
My errors are basically because for some reason new is returning 0.

I think I may have found the cause though, possibly I should feel ashamed: I think it's a threading issue. I have one extra thread which is used to let me have an animated load screen while levels are loaded etc. I think the problems are caused by code running in this aditional thread. I remember when you create a new project in VS6 you can choose between single/multi-threaded; are the standard libraries multi-thread safe or do I need to change the libraries I link to? If so how can I tell which - or maybe I should just create a new project with different settings?
I think I've got DX set to be multithreaded, but I haven't initialised COM this way.


To set which version of the C and C++ runtime you link against, go into your project's properties, C++, Code Generation and there will be an option for what version of the runtime to link to.

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
AFAIK, when new returns 0 that means your program cannot allocate any memory, usualy because it is out of memory.


That depends from compiler to compiler. Some compilers give a random pointer.

Share this post


Link to post
Share on other sites
According to the C++ Standard (or the final draft, at least) any allocation that fails to allocate storage may only indicate such a failure by throwing std::bad_alloc or an exception of a class derived from std::bad_alloc, with the exception of nothrow allocation functions, which indicate failure by returning a null pointer. Visual C++ 6.0, being an obsolete prehistoric compiler, has a nonstandard new operator which returns a null pointer to indicate failure.

Enigma

Share this post


Link to post
Share on other sites
Quote:
Original post by Endurion
new also likes to return 0 (or throw that exception crap) when the amound to be allocated is ridiculously high (as in 0xcdcdcdcd for example).

Check the size variable you pass to new.
Since the debugger let me see inside one the alloc functions, I know that's not it (and I viewed the variables being used). Last crash I remember, it was 64 bytes!

trevaaar:Sounds handy, I'll try it out. Can anyone speculate on how likely this is to be the problem, since it only crashes when I use multithreading (and there's no way I set the project up initially with any MT otions enabled unless they were on by default)?

Share this post


Link to post
Share on other sites
d000hg,

The 'User breakpoint called' is some kind of memory leak problem. I'm not sure of the details, but after I handled all my new/delete calls properly, that message went away. If you need a way to check for memory leaks, grab 'MMGR' from www.fluidstudios.com, it works wonderfully well and is simple to use (just include the file). If you decide to use it, make sure that you read the instructions ;)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this