Unhandled exception on m_physicsData->createWorld()

Unhandled exception on m_physicsData->createWorld()

Hello all,

From the WorldSnapshotDemo, I have taken the loadWorld function as an example of how to load an hkx file, as per the recommendation of other postings on this forum.

The chunk of code that does the loading for me at the moment is as follows:
--------------------------------
hkIstream inFile(""); <-- that is not literal. My code does have a proper path specified.
HK_ASSERT(0, inFile.isOk());

m_physicsData = hkpHavokSnapshot::load(inFile.getStreamReader(), &m_loadedData);

m_World = m_physicsData->createWorld(); <-- exception occurs in here
--------------------------------

When I execute the last line, I get an unhandled exception.

My question is this: What are some techniques for debugging this since I am dealing with a binary library? The error report function is not getting called. The inFile is opening properly, it seems, since the assert is passing. The m_physicsData object seems to be valid after the load function is called. It certainly isn't a null pointer anymore.

I do not necessarily suspect the init code as being the problem because I was able to programatically create a world and add rigid bodies to it.

I am using the Create World filter when I export this hkx file from Maya.

Any ideas or suggestions anyone?

Thanks,
Matt

17 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Hey Matt,
Are you running with Debug / FullDebug libraries that have Asserts enabled?
You should get something of a callstack when it falls over.
Thanks,
Ross

Hello Ross,

Thank you for your response.

I am building against the debug_multithreaded_dll Havok libraries. I am getting a callstack, which I will post below, but unfortunately I am not getting an assert.

Here is the partial callstack. DisplayNif::CreatHavokScene() is the function that I described above in my original posting:

DisplayNif.exe!hkpTypedBroadPhaseDispatcher::addPairs(hkpTypedBroadPhaseHandlePair * newPairs=0x01d08b50, int numNewPairs=1, const hkpCollidableCollidableFilter * filter=0x01d63c48) Line 45 + 0x2 bytes C++
DisplayNif.exe!hkpWorldOperationUtil::addPhantomBP(hkpWorld * world=0x01d6d8c0, hkpPhantom * phantom=0x01d72800) Line 184 C++
DisplayNif.exe!hkpWorld::addPhantom(hkpPhantom * phantom=0x01d72800) Line 1550 C++
DisplayNif.exe!hkpBroadPhaseBorder::hkpBroadPhaseBorder(hkpWorld * world=0x01d6d8c0, hkpWorldCinfo::BroadPhaseBorderBehaviour type=BROADPHASE_BORDER_ASSERT) Line 60 C++
DisplayNif.exe!hkpWorld::hkpWorld(const hkpWorldCinfo & info={...}, unsigned int sdkversion=50500) Line 3002 + 0x30 bytes C++
DisplayNif.exe!hkpPhysicsData::createWorld(hkBool registerAllAgents={...}) Line 76 + 0x39 bytes C++
> DisplayNif.exe!DisplayNif::CreateHavokScene() Line 29 + 0x1e bytes C++

So, from this, I would say the problem has something to do with the BroadPhase border being created. I don't see any NULL pointers being passed it to any of these functions.

I am not really sure how to get deeper into the issue from here. Any suggestions would be welcomed.

Thanks!
-Matt

Hi Matt,

Sorry for the delay on this one. I've dug into the code and still haven't found anything that could be causing this. Is there any more information at all you could provide? Does the exception say "access violation" and give an address or anything else?

Thanks,
Daniel

Hello Daniel,

Thank you for your response.

The exact text of the error is as follows:

"Unhandled exception at 0x00d761b0 in DisplayNif.exe: 0xC0000005:
Access violation reading location 0x00000004"

So, yes, there is an access violation and an address.

I am kind of unsure what additional information is going to be useful, and i don't think you want to dig through a huge code drop of unrelated code. The only other function that I think contains code that should matter is the function that does all the Havok initialization. Here is the meat of it:

...
hkMemory* kMemoryManager = new hkPoolMemory();
hkThreadMemory* kThreadMemory = new hkThreadMemory(kMemoryManager, 16);

hkBaseSystem::init(kMemoryManager, kThreadMemory, errorReportFunction);

int stackSize = 0x40000; // ensure 16 byte aligned
char* stackBuffer = hkAllocate( stackSize, HK_MEMORY_CLASS_BASE);
hkThreadMemory::getInstance().setStackArea( stackBuffer, stackSize);
...

Please let me know if anything there looks awkward. It would be worth noting that with this exact initialization code, I was able to programatically create a world and several rigid bodies in that world, and run the simulation. I wonder if the problem could be with the HKX asset I have exported from Maya?

Thank you for your time,
Matt

Hi agenttex,

Still looking into this and still not seeing what's going wrong. Your initialization code looks fine. As does your snapshot loading code.

Seeing as your asset gets so far into the loading process I'd be surprised if that was causing the problem but it's worth investigating anyway. Does this also fail when you create a single box rigid body and export the asset with just a "create rigid bodies" filter and a "write to platform" filter?

Thanks,
Daniel

Hello Daniel,

I created a new scene in Maya 8.5 with a single box rigid body. I exported this asset using only the Create Rigid Bodies filter and the Write to Platform filters. My application still crashes inside createWorld(), but the callstack seems odd:

> DisplayNif.exe!hkpWorld::addEntityBatch(hkpEntity * const * entityBatch=0x00ae93e4, int numEntities=-125809115, hkpEntityActivation initialActivationState=14128771) Line 884 + 0x2 bytes C++
DisplayNif.exe!hkPoolMemory::allocateChunkBatch(void * * blocksOut=0xdddddddd, int nblocks=-572662307, int nbytes=-572662307) Line 790 C++
dddddddd()

Any thoughts on this?

Thank you,
-Matt

Hi Matt,

In this case, it looks like the blocksOut pointer has been freed so it is no longer valid. The other parameters also appear to be totally wrong. The addEntityBatch() call's numEntities and initialActivationState parameters are also invalid. Can I get a more complete callstack from you on this crash? It really looks like something is going wrong in your code. Perhaps a variable is getting out of scope or you're calling removeReference() one time too many?

Thanks,
Daniel

Hello Daniel,

Well, the weird thing about it is, that is the complete call stack. It looks corrupt.

So, maybe I am misunderstanding what this function does. I was under the impression that it would create a world from the data contained in an hkx file that was exported from a DCC tool, in my case, Maya. But for this test, you instructed me to use only the CreateRigidBodies filter and the Write To Platform filter. Would that not cause problems?

Any ideas why the call stack would not be intact?

I am not calling removeReference() anywhere in my code. The code that I listed above is literally all of the Havok code that is in my project, not counting all the #includes and the error reporting function.

Any suggestions would be welcomed. In the meantime, I am going to attempt to isolate this issue into a super small sample that does nothing but demonstrates the problem. This issue is currently mixed in with a larger application, and I am thinking that the issue will be more obvious if there is less to look at.

Thanks,
Matt

Hi Matt,

Yeah, at this stage a repro is the best way forward. Whenever you have some sample code with a sample asset that can reproduce the problem I'll be happy to look into it for you.

Thanks,
Daniel

Hello Daniel,

I have created a very simple sample that demonstrates the issue. For the most part, it is exactly the same as what I have been working with, except most everything is in the WinMain function, and nearly all unnecessary code was removed. I have a zip file ready to send to you that contains the following:

-Visual Studio 2005 Solution
-Visual Studio 2005 project file
-the_problem.cpp
-hkTypeRegistration.cpp
-a media folder with two Maya files, both identical, though I exported from one with the Create World filter, and the other without, and the two resulting hkx files.

Do you have a solution for how to transmit this zip file, like an FTP server maybe? It is 44KB in size. I could also email it to you if you care to do it that way.

Thank you for your continued assistance.

-Matt

Hi Matt,

If you don't mind others seeing your code/assets, you can upload to mediafire.com or some other free file hosting service. Otherwise, my email is daniel dot heffernan at havok.com.

Daniel

Hello Daniel,

I have made the zip file available at the following URL so that it can be viewed by anybody who may benefit:

http://www.mediafire.com/?acxvzyb9bhq

Please let me know if you need anything else, and I look forward to seeing what I did wrong. ^_^

Matt

Hi Matt,

  1. hkTypeRegistration.h has #defines in it. I'm not sure why yet but this was breaking it but am investigating right now.
  2. hkTypeRegistration.h needs to include #include for hkpPhysicsData. You'll need to add hkpUtilities.lib to your project too.
  3. The memory manager isn't being cleaned up. This is done like so:
    	world->removeReference();
    	physicsData->removeReference();
    	loadedData->removeReference();
    
    	// Deallocate stack area
    	kThreadMemory->setStackArea(0, 0);
    	hkDeallocate(stackBuffer);
    
    	kThreadMemory->removeReference();
    
  4. hkIstream is being destroyed after the memory manager has been cleaned up. As hkIstream's constructor/destructor uses heap allocations, this will cause it to break. Restrict scope so it's destroyed before the memory manager is destroyed like so:
    	// attempt to load a world
    	hkPackfileReader::AllocatedData* loadedData;
    	hkpPhysicsData* physicsData;
    	{
    		hkIstream inFile("./media/with_world.hkx");
    		HK_ASSERT(0, inFile.isOk());
    		physicsData = hkpHavokSnapshot::load(inFile.getStreamReader(), &loadedData);
    	}
    	hkpWorld* world = physicsData->createWorld();
    

Hope this helps you out :-)

Daniel

Hello Daniel,

Thank you for taking your time to look into this.

I added those #defines out of habit, but I suppose the use of the file could have been a hint that the #defines were not needed.

After removing the #defines in my type registration file, my application actually compiled and made it past the createWorld() call without crashing before I added the hkpUtilitiesClasses.h into my type registration file. Supposing that you had not mentioned the need for this additional include, at what point would I have started seeing problems?

These memory management problems actually are being taken care of in my main application. I did not include that code in the sample because I just wanted to get to the point that you could see the problem, with as little overhead code as possible. I do, however, appreciate the pointers. ^_^

Again, thanks for the help.
Matt

Hi Matt,

I've looked into this a bit and the reason why the #defines break it is that it's not used as a normal include file and ends up being required multiple times, so ensuring that it's only even included once with those defines make the SDK fail.

Daniel

Hello Daniel,

Thanks again for all the help.

Matt

Leave a Comment

Please sign in to add a comment. Not a member? Join today