Crash when accessing hkMonitorStream from worker thread

Crash when accessing hkMonitorStream from worker thread


I don't have much of a callstack because I'm just calling hkMonitorStream::getInstance().resize( 2 * 1024 * 1024 ) from my code. This is on a background thread, not the main thread.

Looking at the assembly, I see that hkMonitorStream__m_instance::m_slotID is 43. The call to TlsGetValue returns 0 and the program crashes inside hkMonitorStream::resize (access violation reading 0x00000000).

If I try this earlier on the main thread, the slot ID is still 43 but TlsGetValue resolves to a valid hkMonitorStream pointer (obviously, each thread has its own pointer). I have no actual need to resize the monitor stream on the background thread, but further access to the monitor stream on this thread also crashes (for example, simply adding a rigid body to the world).

Havok is basically working right now in the multithreaded way we're using it. I've just uncovered this problem as I'm trying to hook up the visual debugger.

Can anyone tell me how a hkMonitorStream is allocated and assigned to the thread-local storage slot? That info would help me track down what we're doing wrong.


5 post / 0 nuovi
Ultimo contenuto
Per informazioni complete sulle ottimizzazioni del compilatore, consultare l'Avviso sull'ottimizzazione

Sounds like you're not callinghkBaseSystem::initThread() in your background thread. This is where hkMonitorStream::init is done. If you're not calling initThread you may be missing the memory system init for that thread as well.

Check the 650 docs under: 'Common Havok Components > Havok Base Library > The Base System > Initialization in a Multithreaded Mode' for more details on setting up and shutting down background threads that use Havok.


Thanks for the info, Tyler.

There *was* a problem with how we were calling initThread (we were simply giving all threads the same hkThreadMemory). I'm trying to fix that and here's where I'm at:

We call initThread from MainGame.exe!Init_Havok(). We later try to allocate a Havok object from Engine.dll!Create_Rigid_Body(). I notice that hkThreadMemory__s_threadMemoryInstance is different in these two functions, and it leads to a null hkThreadMemory pointer inside Create_Rigid_Body.

hkThreadMemory__s_threadMemoryInstance is a global and I guess two instances are created, one for MainGame.exe and one for Engine.dll. The debug watch window shows this variable at 2 different memory addresses depending on where I'm at in the callstack (MainGame.exe or Engine.dll). I'm not yet sure exactly what's going on here. I'm linking with win32_net_9-0\debug_multithreaded_dll and I'd expect there to be just one instance of this variable, living in one of the Havok dlls.

UPDATE: I didn't figure out this issue with hkThreadMemory__s_threadMemoryInstance living in two places. Instead, I moved my Init_Havok() call into Engine.dll. Luckily, it appears that all Havok work is now being done in Engine.dll, so everything works now. Unless/until I figure out the above issue, I'm just going to make it a policy that nobody should call into Havok from outside Engine.dll.

I'm glad to hear it sounds like you've got this worked out. The policy you're taking here is correct. The free Havok binaries we provide are built for static linking only. That means that if you are building two dlls then only one of them can link to Havok libs(*). Otherwise you get the same problems you're seeing where you have two copies of the Havok library loaded for each dll that links them in.

* You might want to double check the license on this as I believe linking the free Havok libs in to a dll is not allowed.


Thanks, Tyler. I'll look into the license issue you mentioned.

Lascia un commento

Eseguire l'accesso per aggiungere un commento. Non siete membri? Iscriviti oggi