TGEA 1.7.1 Bugs: Atlas MatInstance unload error
by Bill Vee · in Torque Game Engine Advanced · 07/24/2008 (3:14 pm) · 31 replies
I have not seen this reported yet but it seems to have been in since 1.7.0.
When I load a mission with an atlas file then exit the mission then exit the program I consistently get an access violation in MatInstance::~MatInstance() at the line containing
In the debugger mMatInstList[i] come up as expression cannot be evaluated.
Call Stack
> CannonBattle_DEBUG.exe!MatInstance::~MatInstance() Line 87 + 0xe bytes C++
CannonBattle_DEBUG.exe!MatInstance::'scalar deleting destructor'() + 0x14 bytes C++
CannonBattle_DEBUG.exe!AtlasLightingPlugin::~AtlasLightingPlugin() Line 44 + 0x24 bytes C++
CannonBattle_DEBUG.exe!'dynamic atexit destructor for 'p_AtlasLightingPlugin''() + 0x13 bytes C++
CannonBattle_DEBUG.exe!doexit(int code=0, int quick=0, int retcaller=0) Line 553 C
CannonBattle_DEBUG.exe!exit(int code=0) Line 398 + 0xd bytes C
CannonBattle_DEBUG.exe!__tmainCRTStartup() Line 333 C
CannonBattle_DEBUG.exe!WinMainCRTStartup() Line 196 C
In debug I get the error every time but in a release build it will randomly crash the program on exit.
When I load a mission with an atlas file then exit the mission then exit the program I consistently get an access violation in MatInstance::~MatInstance() at the line containing
if( mMatInstList[i] == this )
In the debugger mMatInstList[i] come up as expression cannot be evaluated.
Call Stack
> CannonBattle_DEBUG.exe!MatInstance::~MatInstance() Line 87 + 0xe bytes C++
CannonBattle_DEBUG.exe!MatInstance::'scalar deleting destructor'() + 0x14 bytes C++
CannonBattle_DEBUG.exe!AtlasLightingPlugin::~AtlasLightingPlugin() Line 44 + 0x24 bytes C++
CannonBattle_DEBUG.exe!'dynamic atexit destructor for 'p_AtlasLightingPlugin''() + 0x13 bytes C++
CannonBattle_DEBUG.exe!doexit(int code=0, int quick=0, int retcaller=0) Line 553 C
CannonBattle_DEBUG.exe!exit(int code=0) Line 398 + 0xd bytes C
CannonBattle_DEBUG.exe!__tmainCRTStartup() Line 333 C
CannonBattle_DEBUG.exe!WinMainCRTStartup() Line 196 C
In debug I get the error every time but in a release build it will randomly crash the program on exit.
#2
Ran it 5 times and no error.
Thats gotta be a bug fix record.
07/24/2008 (3:39 pm)
That seems to have done it.Ran it 5 times and no error.
Thats gotta be a bug fix record.
#4
Ok, then, will take a more thorough look.
07/24/2008 (3:57 pm)
Dang... no record. Would've been too easy.Ok, then, will take a more thorough look.
#6
Can you take a look and see if mMatInstList is still valid? (your first post above hints that it is not)
07/24/2008 (4:45 pm)
S**t... just occured to me that it may be a global dtor ordering problem. There is no ordering guaranteed for global dtors (usually it's determined by the arrangement of object files), so it may be that the global material instance list may be destructed before the lighting plugin.Can you take a look and see if mMatInstList is still valid? (your first post above hints that it is not)
#7
and see if the problem goes away.
07/24/2008 (4:49 pm)
Note: you could also add some cleanup to the vector dtor like sotemplate<class T> inline Vector<T>::~Vector()
{
dFree(mArray);
mArray = 0;
mElementCount = mArraySize = 0;
}and see if the problem goes away.
#8
Not really my expertise. :)
07/29/2008 (5:08 pm)
I think I will defer the vector dtor stuff to someone else.Not really my expertise. :)
#9
08/08/2008 (10:44 am)
Anyone have defacto fix for this? It is annoying.
#10
08/08/2008 (12:39 pm)
So far, I had no luck reproducing the problem at all. Which is why my stuff is mostly guesswork based on the information that Bill provided.
#11
Built the debug version and ran it.
It didn't crash on the first exit from the demo but on the second it crashed with the following

08/08/2008 (2:18 pm)
I just tried this on a clean 1.7.1 install using the atlasdemo with VC++ 2005 Express EditionBuilt the debug version and ran it.
It didn't crash on the first exit from the demo but on the second it crashed with the following
#12
08/09/2008 (7:02 pm)
I've seen the error from time to time when exiting in debug mode also.
#13
JPaxson and J.C. Smith, are you using VC2005, like Bill, too? If so, it may be that VC2005 handles global deconstruction differently compared to 2008 which would then explain why I'm not seeing the error.
Has anyone of you tried and applied the modification to the Vector deconstructor above? (that's inserting two lines and recompiling) I'd be interested if it solves the issue. If so, it's quite positively the case that the material list vector gets deconstructed before the Atlas instance.
08/10/2008 (9:50 am)
Again, no luck reproducing this on my end. No crash even after re-starting and exiting AtlasDemo several times.JPaxson and J.C. Smith, are you using VC2005, like Bill, too? If so, it may be that VC2005 handles global deconstruction differently compared to 2008 which would then explain why I'm not seeing the error.
Has anyone of you tried and applied the modification to the Vector
#14

I decided to try your fix from above.
After 10 tries in a row without the error I believe it is fixed now.
I will recompile with 2005 and see if it fixed it as well.
08/10/2008 (12:26 pm)
@ Rene Damm - I tried it with VC Express 2008 and got the same result.I decided to try your fix from above.
template<class T> inline Vector<T>::~Vector()
{
dFree(mArray);
mArray = 0;
mElementCount = mArraySize = 0;
}After 10 tries in a row without the error I believe it is fixed now.
I will recompile with 2005 and see if it fixed it as well.
#15
08/10/2008 (12:49 pm)
10 times without errors on 2005.
#16
Let me know if my stuff turns out to again only masquerade as a fix like with the initial quick shot above :)
08/10/2008 (1:23 pm)
Cool! Thanks, Bill, for putting the time into this. Kind of strange that VC2008 produced the same error if it really is a destructor ordering problem (the only possible cause I see ATM). But if letting Vector clean up properly solves the issue, then fine.Let me know if my stuff turns out to again only masquerade as a fix like with the initial quick shot above :)
#17
AtlasLightingPlugin should register with GFXDevice::getDeviceEventSignal() and when it gets a deDestroy, then it can do its cleanup. That's something I missed the first time I did that. Sorry ya'll! ;)
Second, the Vector<> destructor should look like this:
The problem with just freeing mArray is that the class destructors for the items won't get called. So that could cause issues with more complex types.
Hope this helps a bit!
08/10/2008 (2:10 pm)
I think Rene is right about the dtor ordering issue. A couple of notes:AtlasLightingPlugin should register with GFXDevice::getDeviceEventSignal() and when it gets a deDestroy, then it can do its cleanup. That's something I missed the first time I did that. Sorry ya'll! ;)
Second, the Vector<> destructor should look like this:
template<class T> inline Vector<T>::~Vector()
{
setSize(0);
dFree(mArray);
}The problem with just freeing mArray is that the class destructors for the items won't get called. So that could cause issues with more complex types.
Hope this helps a bit!
#18
08/10/2008 (6:28 pm)
Thanks, Brian, for the clarification and the corrected Vector dtor.
#19
08/10/2008 (6:32 pm)
Brian's fix appears to work fine for the 2005 and 2008 solutions.
#20
08/10/2008 (7:50 pm)
Yes I was using VS2005. Will try this fix later, thanks a bunch.
Associate Rene Damm
Do you get a crash, too, if replacing the constructor and destructor in the lighting plugin code with
AtlasLightingPlugin::AtlasLightingPlugin() : mLightMatInst( 0 ), mLightMaskMatInst( 0 ) { AtlasClipMapBatcher::registerRenderPlugin(this); mMatInit = false; mMatOk = true; } AtlasLightingPlugin::~AtlasLightingPlugin() { AtlasClipMapBatcher::unregisterRenderPlugin(this); if( mLightMatInst ) SAFE_DELETE(mLightMatInst); if( mLightMaskMatInst ) SAFE_DELETE(mLightMaskMatInst); }