Skip to main content
gamedev.net
🔒 Locked

D3D Debugging

Started by BillOB1 9 replies 1.9k views
Original Post
BillOB1
BillOB1
I am working under VS.NET 2003 with DX9c Octorber release.I found a weird problem with my program.Once I hit 'start without debugging' then my program just crashed.But it runs fine in debug mode.Has anyone encounted this kind of problem before?
BillOB1
BillOB1
I do not quite get it,but one thing i remembered is that when i run in release mode ,one of my objects is not initialize at all.Can you give some example code show how this can be happenning?Thanx a lot...
Mezz
Mezz
It can happen when, say, you don't properly initialise a variablee before using it:

LPDIRECT3DVERTEXBUFFER9 *myVB;// later...if(myVB != NULL){   myVB->Lock(...);}


The point is that in debug mode you might get lucky and the myVB pointer will be initialised to NULL for you, however in Release it will not be which means your check will fall through and you end up calling a class method on an object which does not exist, causing an error. This happens in other cases too, sometimes in class constructors/destructors if things aren't done properly.

Does that help explain it?

-Mezz
Endurion
Endurion
In Debug variables are NOT initalized to NULL. There's different values for global and local vars, one being 0xcdcdcdcd. In release variables aren't initialized at all. You might get lucky to have zero but usually it will be random values.

Just initialize all your variables properly.

You might also check for buffer overflows. In debug mode allocated memory gets buffers in front and the back for safety checking, in release that doesn't happen.
Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>
Mezz
Mezz
Quote:
Original post by Endurion
In Debug variables are NOT initalized to NULL. There's different values for global and local vars, one being 0xcdcdcdcd.


Yes, I was mistaken about that (or maybe it varies by compiler) I just tested what happens...

0xcccccccc is what an unallocated pointer gets set to if not initialised.

e.g.

int *myPtr;

0xcdcdcdcd is the value of what the pointer points at after allocated but before writing.

e.g.

int *myPtr = new int;

// *myPtr is 0xcdcdcdcd

0xfeeefeee is the value after the pointer has been deleted.


int *myPtr = new int;

// *myPtr is 0xcdcdcdcd

delete myPtr;

// myPtr is whatever address it was allocated
// *myPtr is now 0xfeeefeee

In release it seems 0xcdcdcdcd becomes 0xbaadf00d.

This is all on Visual C++ .NET 2003

On the note of global variables, they are always initialised to 0 regardless of debug or release status.

-Mezz
Namethatnobodyelsetook
Namethatnobodyelsetook
Quote:
Original post by Mezz
On the note of global variables, they are always initialised to 0 regardless of debug or release status.

No, they should be initialized to 0 if you expect them to be 0.
Donavon Keithley
Donavon Keithley
Quote:
Original post by Namethatnobodyelsetook
Quote:
Original post by Mezz
On the note of global variables, they are always initialised to 0 regardless of debug or release status.

No, they should be initialized to 0 if you expect them to be 0.

If you expect the value to be 0 then you can omit the initializer; C and C++ guarantee that variables with static duration will be initialized to 0 by default.
Mezz
Mezz
Quote:
Original post by Namethatnobodyelsetook
Quote:
Original post by Mezz
On the note of global variables, they are always initialised to 0 regardless of debug or release status.

No, they should be initialized to 0 if you expect them to be 0.


I was simply relaying what the compiler does when you don't initialise them, not what is good or bad coding practice.

EDIT:
I realise this actually has several interpretations. It depends on the type of global as to what it gets initialised to, primitive types and pointers will usually be zero but classes have their constructor executed.

-Mezz
BillOB1
BillOB1
I finally found my problem:

Original code:

ActorInfo* curAI;
curAI=new ActorInfo;
curAI->num2rect=new RECR[NUM_FRAMES];
curAI->num2rect[0]=...
curAI->num2rect[1]=...
curAI->num2rect[2]=...
curAI->num2rect[NUM_FRAMES-1]=...

//then we try to execute some code,say

this->mActors->insert(pair(1001,curAI));//release failed to execute the code

Modified code:

ActorInfo* curAI;
curAI=new ActorInfo;
curAI->num2rect=new RECT[NUM_FRAMES*sizeof(RECT)];
curAI->num2rect[0]=...
curAI->num2rect[1]=...
curAI->num2rect[2]=...
curAI->num2rect[NUM_FRAMES-1]=...

//then we try to execute some code,say

this->mActors->insert(pair(1001,curAI));//succeed to execute this line and all following code

note that num2rect is a field of ActorInfo struct and is defined:
RECT* num2rect;

So in debug,maybe it detects we have violated other memory since we did not allocate enought memory to contain all RECT infomation,so it automatically allocates more .But in release,it does not care about memory overflow,so other parts of the code in memory is overwritten,thus results in crashing the program.
Namethatnobodyelsetook
Namethatnobodyelsetook
"new x[y]" should declare enough space for "y" objects of type "x". You don't need to use "new x[y*sizeof(x)]". Odds are you're accessing more than NUM_FRAMES number of objects. While throwing in the "*sizeof(RECT)" may be "fixing" it, it's not a real fix. You've got a bug somewhere else, causing your to exceed NUM_FRAMES. You're just masking your bug by allocating a LOT more RAM than needed.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.