Microsoft Knowledge Base Article
This article contents is Microsoft Copyrighted material.
©2005-©2007 Microsoft Corporation. All rights reserved.
Terms
of Use |
Trademarks
Article ID: 939969 - Last Review: October 31, 2007 - Revision: 2.3
The debugger may stop responding when mixed-mode debugging a debuggee that uses more than 63 thread local storage slots
Consider the following scenario. An application is running under a mixed mode debugger, also known as an "interop-debugger." The debuggee has not loaded the common language runtime (CLR). The debuggee allocates more than 63 thread local storage (TLS) slots, and then the debuggee loads the CLR. In this scenario, the debugger stops responding, and the debugger may consume 100 percent of the CPU usage. If the debuggee is stopped by using Task Manager, the debugger becomes responsive again.
Note This problem may also occur with any mixed-mode debugger that uses the
ICorDebug interfaces (specifically Microsoft Visual Studio .NET 2002, Visual Studio .NET 2003, and Visual Studio 2005) for those corresponding runtimes.
This problem occurs because the CLR uses TLS slots. The mixed-mode debugger must read the CLR’s TLS slots from out of process, and the mixed-mode debugger does not correctly read slots that have an index above 63.
To work around this problem, use one of the following methods:
- Use the managed-only debugger or the native-only debugger instead of the mixed-mode debugger.
- Modify the debuggee to load the CLR early. TLS slots are allocated based on a first-come, first-served basis. Therefore, if the debuggee loads the CLR early, fewer slots will be allocated.
- Modify the debuggee to reserve fewer TLS slots for the CLR. You can allocate several slots, and then free these slots before the CLR is loaded. To do this, use the following sample code.
#include "stdafx.h"
#include "windows.h"
const int NumSlots = 20;
DWORD g_slots[NumSlots];
// Call this from Main
// This "reserves" the low TLS slots for the CLR.
void AllocateSlots()
{
for(int i = 0; i < NumSlots; i++)
{
g_slots[i] = TlsAlloc();
}
}
// Call this after your application finishes allocating its own TLS slots, but
// before you load any managed code.
void FreeSlots()
{
for(int i =0; i < NumSlots; i++)
{
TlsFree(g_slots[i]);
g_slots[i] = 0;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
AllocateSlots();
// these are exactly like the slots that are allocated by the application.
DWORD i1 = TlsAlloc();
DWORD i2 = TlsAlloc();
DWORD i3 = TlsAlloc();
DWORD i4 = TlsAlloc();
FreeSlots();
// ....pretend we load the CLR...
// This should now be a low slot
DWORD i5 = TlsAlloc();
return 0;
}
APPLIES TO
- Microsoft .NET Framework 2.0
- Microsoft .NET Framework 1.1
- Microsoft .NET Framework 1.0
| kbtshoot kbprb kbexpertiseadvanced KB939969 |
Community Feedback System
Very often, it takes hours to solve a problem. Very often, you've looked high
and low, and have tried a lot of solutions. When you finally found it, chances
are, it was because someone else helped you. Here's your chance to give back.
Use our community feedback tool to let others know what worked for you and what
didn't.
Please also understand that the community feedback system is not warranted to be
correct, it's simply a system that we've built to let people try and help each
other. If something in a feedback response doesn't make sense to you, or you're
not comfortable making changes that the feedback talks about (like registry
edits), please consult a professional.
Thank you for using kbAlertz.com Feedback System.
-- Scott Cate