Thread Local Storage (TLS) crash

Thread Local Storage (TLS) crash

Anonymous
Not applicable
658 Views
7 Replies
Message 1 of 8

Thread Local Storage (TLS) crash

Anonymous
Not applicable
Hi,
do any body know How to create a thread local variable?

__declspec(thread) int i;

When I declare this variable, MAX 8 isn't able to load my dll plugin module. It reports this error message:
"Error code is 998: Invalid access to memory location"
Any idea?
Thx
0 Likes
659 Views
7 Replies
Replies (7)
Message 2 of 8

Anonymous
Not applicable
That's one way yes (using compiler support). You can also use TlsAlloc to do it via the WinAPI.

I doubt that simply declaring that variable caused any crash. You should run a debugger and get a backtrace of where the crash occurred and debug it properly.

One thing you could do is provide a mini-dump and your .pdb file, so others in the forum can debug your crash and perhaps find the problem.
0 Likes
Message 3 of 8

Anonymous
Not applicable
This TLS variables are used in an engine core. So I am not able to rewrite this declaration to TlsAlloc:-(.
This declaration works properly without 3dsmax - even when we use the gcc compiler (__thread).
I am not able to debug this problem, because it crashes during loading DLL modul...
0 Likes
Message 4 of 8

Anonymous
Not applicable
Ok. And where are you declaring and using this variable? Perhaps you could post some more code.

Note, you should still be able to debug it, even if it occurs during module load. (More likely during module initialization).

You could be doing something very evil in DllMain. I'd have to see more code (or a crashdump) to offer any further advice.

Note #2, all crashes can get your a crashdump. These are useful. Better with a PDB.
0 Likes
Message 5 of 8

Anonymous
Not applicable
I have tried to write a simple example, but I can't make the same crash. It works and I don't know why....
I can't send you any orig. codes because it is strictly prohibited by my company.
I wrote:

class C_X
{
int x;
};
__declspec(thread) C_X* xxx;

We use an own memory manager, but is not initialized during modul loading.
Interesting is when I remove this declaration from a global variable it works properly.
0 Likes
Message 6 of 8

Anonymous
Not applicable
This sample produces my crash:-).

class C_X { int x; };

__declspec(thread) C_X* xxx;

C_X& GetGlobal()
{
C_X* rnd = xxx;
if (!rnd) rnd = xxx = new C_X();
return *rnd;
}

C_X& g = GetGlobal();

The attachment contains whole example.

9145_ioqpDaabAq0tpGEBv8gy.zip

0 Likes
Message 7 of 8

Anonymous
Not applicable
Ok. Your code has 2 main problems:

1) You should *not* call any CRT memory management functions (malloc, new) from DLLMain. (You are calling it during global initialization, which is implemented in DllMainCRTStartup). The reason is that if the CRT DLL has not initialized, the behaviour is undefined. DLL initialization order is not guaranteed.

2) This one is the actual reason for your crash. You cannot use __declspec(thread) in a DLL that is explicitly linked. (I.e. one that is loaded via LoadLibrary by the host application). This is documented at MSDN at:

- The last paragraph: http://msdn.microsoft.com/en-us/library/2s9wt68x.aspx
- and http://support.microsoft.com/kb/118816

Their recommendation is you use TlsAlloc.

You should also read:
http://www.microsoft.com/whdc/driver/kernel/DLL_bestprac.mspx

for more information about DLL best practises.

Just a note: This limitation no longer applies to Windows Vista. So you actually *can* use static TLS with explicitly linked DLLs and the OS will handle the dirty work for you. But if you're using anything prior to Vista (XP, 2000, etc) you have to use TlsAlloc.
0 Likes
Message 8 of 8

Anonymous
Not applicable
Thank you very much. It was very useful!
0 Likes