1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 //*****************************************************************************
9 // Debugger runtime controller routines.
11 //*****************************************************************************
14 #include "debugdebugger.h"
15 #include "../inc/common.h"
17 #include "eeconfig.h" // This is here even for retail & free builds...
18 #include "../../dlls/mscorrc/resource.h"
24 #include "ilformatter.h"
25 #include "typeparse.h"
26 #include "debuginfostore.h"
28 #include "../../vm/methoditer.h"
29 #include "../../vm/encee.h"
30 #include "../../vm/dwreport.h"
31 #include "../../vm/eepolicy.h"
32 #include "../../vm/excep.h"
33 #if defined(FEATURE_DBGIPC_TRANSPORT_VM)
34 #include "dbgtransportsession.h"
35 #endif // FEATURE_DBGIPC_TRANSPORT_VM
37 #ifdef TEST_DATA_CONSISTENCY
39 #endif // TEST_DATA_CONSISTENCY
41 #include "dbgenginemetrics.h"
43 #include "../../vm/rejit.h"
45 #include "threadsuspend.h"
48 #ifdef DEBUGGING_SUPPORTED
51 // Reg key. We can set this and then any debugger-lazy-init code will assert.
52 // This helps track down places where we're caching in debugger stuff in a
53 // non-debugger scenario.
54 bool g_DbgShouldntUseDebugger = false;
58 /* ------------------------------------------------------------------------ *
60 * ------------------------------------------------------------------------ */
62 GPTR_IMPL(Debugger, g_pDebugger);
63 GPTR_IMPL(EEDebugInterface, g_pEEInterface);
64 SVAL_IMPL_INIT(BOOL, Debugger, s_fCanChangeNgenFlags, TRUE);
66 // This is a public export so debuggers can read and determine if the coreclr
67 // process is waiting for JIT debugging attach.
68 GVAL_IMPL_INIT(ULONG, CLRJitAttachState, 0);
70 bool g_EnableSIS = false;
72 // The following instances are used for invoking overloaded new/delete
73 InteropSafe interopsafe;
74 InteropSafeExecutable interopsafeEXEC;
76 #ifndef DACCESS_COMPILE
78 DebuggerRCThread *g_pRCThread = NULL;
81 // Do some compile time checking on the events in DbgIpcEventTypes.h
82 // No one ever calls this. But the compiler should still compile it,
83 // and that should be sufficient.
84 void DoCompileTimeCheckOnDbgIpcEventTypes()
86 _ASSERTE(!"Don't call this function. It just does compile time checking\n");
88 // We use the C_ASSERT macro here to get a compile-time assert.
90 // Make sure we don't have any duplicate numbers.
91 // The switch statements in the main loops won't always catch this
92 // since we may not switch on all events.
94 // store Type-0 in const local vars, so we can use them for bounds checking
95 // Create local vars with the val from Type1 & Type2. If there are any
96 // collisions, then the variables' names will collide at compile time.
97 #define IPC_EVENT_TYPE0(type, val) const int e_##type = val;
98 #define IPC_EVENT_TYPE1(type, val) int T_##val; T_##val = 0;
99 #define IPC_EVENT_TYPE2(type, val) int T_##val; T_##val = 0;
100 #include "dbgipceventtypes.h"
101 #undef IPC_EVENT_TYPE2
102 #undef IPC_EVENT_TYPE1
103 #undef IPC_EVENT_TYPE0
105 // Ensure that all identifiers are unique and are matched with
107 #define IPC_EVENT_TYPE0(type, val) int T2_##type; T2_##type = val;
108 #define IPC_EVENT_TYPE1(type, val) int T2_##type; T2_##type = val;
109 #define IPC_EVENT_TYPE2(type, val) int T2_##type; T2_##type = val;
110 #include "dbgipceventtypes.h"
111 #undef IPC_EVENT_TYPE2
112 #undef IPC_EVENT_TYPE1
113 #undef IPC_EVENT_TYPE0
115 // Make sure all values are subset of the bits specified by DB_IPCE_TYPE_MASK
116 #define IPC_EVENT_TYPE0(type, val)
117 #define IPC_EVENT_TYPE1(type, val) C_ASSERT((val & e_DB_IPCE_TYPE_MASK) == val);
118 #define IPC_EVENT_TYPE2(type, val) C_ASSERT((val & e_DB_IPCE_TYPE_MASK) == val);
119 #include "dbgipceventtypes.h"
120 #undef IPC_EVENT_TYPE2
121 #undef IPC_EVENT_TYPE1
122 #undef IPC_EVENT_TYPE0
124 // Make sure that no value is DB_IPCE_INVALID_EVENT
125 #define IPC_EVENT_TYPE0(type, val)
126 #define IPC_EVENT_TYPE1(type, val) C_ASSERT(val != e_DB_IPCE_INVALID_EVENT);
127 #define IPC_EVENT_TYPE2(type, val) C_ASSERT(val != e_DB_IPCE_INVALID_EVENT);
128 #include "dbgipceventtypes.h"
129 #undef IPC_EVENT_TYPE2
130 #undef IPC_EVENT_TYPE1
131 #undef IPC_EVENT_TYPE0
133 // Make sure first-last values are well structured.
134 static_assert_no_msg(e_DB_IPCE_RUNTIME_FIRST < e_DB_IPCE_RUNTIME_LAST);
135 static_assert_no_msg(e_DB_IPCE_DEBUGGER_FIRST < e_DB_IPCE_DEBUGGER_LAST);
137 // Make sure that event ranges don't overlap.
138 // This check is simplified because L->R events come before R<-L
139 static_assert_no_msg(e_DB_IPCE_RUNTIME_LAST < e_DB_IPCE_DEBUGGER_FIRST);
142 // Make sure values are in the proper ranges
143 // Type1 should be in the Runtime range, Type2 in the Debugger range.
144 #define IPC_EVENT_TYPE0(type, val)
145 #define IPC_EVENT_TYPE1(type, val) C_ASSERT((e_DB_IPCE_RUNTIME_FIRST <= val) && (val < e_DB_IPCE_RUNTIME_LAST));
146 #define IPC_EVENT_TYPE2(type, val) C_ASSERT((e_DB_IPCE_DEBUGGER_FIRST <= val) && (val < e_DB_IPCE_DEBUGGER_LAST));
147 #include "dbgipceventtypes.h"
148 #undef IPC_EVENT_TYPE2
149 #undef IPC_EVENT_TYPE1
150 #undef IPC_EVENT_TYPE0
152 // Make sure that events are in increasing order
153 // It's ok if the events skip numbers.
154 // This is a more specific check than the range check above.
156 /* Expands to look like this:
163 static_assert_no_msg(f);
167 (e_DB_IPCE_RUNTIME_FIRST <=
168 #define IPC_EVENT_TYPE0(type, val)
169 #define IPC_EVENT_TYPE1(type, val) val) && (val <
170 #define IPC_EVENT_TYPE2(type, val)
171 #include "dbgipceventtypes.h"
172 #undef IPC_EVENT_TYPE2
173 #undef IPC_EVENT_TYPE1
174 #undef IPC_EVENT_TYPE0
175 e_DB_IPCE_RUNTIME_LAST)
177 static_assert_no_msg(f1);
180 (e_DB_IPCE_DEBUGGER_FIRST <=
181 #define IPC_EVENT_TYPE0(type, val)
182 #define IPC_EVENT_TYPE1(type, val)
183 #define IPC_EVENT_TYPE2(type, val) val) && (val <
184 #include "dbgipceventtypes.h"
185 #undef IPC_EVENT_TYPE2
186 #undef IPC_EVENT_TYPE1
187 #undef IPC_EVENT_TYPE0
188 e_DB_IPCE_DEBUGGER_LAST)
190 static_assert_no_msg(f2);
195 //-----------------------------------------------------------------------------
196 // Ctor for AtSafePlaceHolder
197 AtSafePlaceHolder::AtSafePlaceHolder(Thread * pThread)
199 _ASSERTE(pThread != NULL);
200 if (!g_pDebugger->IsThreadAtSafePlace(pThread))
202 m_pThreadAtUnsafePlace = pThread;
203 g_pDebugger->IncThreadsAtUnsafePlaces();
207 m_pThreadAtUnsafePlace = NULL;
211 //-----------------------------------------------------------------------------
212 // Dtor for AtSafePlaceHolder
213 AtSafePlaceHolder::~AtSafePlaceHolder()
218 //-----------------------------------------------------------------------------
219 // Returns true if this adjusted the unsafe counter
220 bool AtSafePlaceHolder::IsAtUnsafePlace()
222 return m_pThreadAtUnsafePlace != NULL;
225 //-----------------------------------------------------------------------------
228 // This can be called multiple times.
229 // Calling this makes the dtor a nop.
230 void AtSafePlaceHolder::Clear()
232 if (m_pThreadAtUnsafePlace != NULL)
234 // The thread is still at an unsafe place.
235 // We're clearing the flag to avoid the Dtor() calling DecThreads again.
236 m_pThreadAtUnsafePlace = NULL;
237 g_pDebugger->DecThreadsAtUnsafePlaces();
241 //-----------------------------------------------------------------------------
242 // Is the guard page missing on this thread?
243 // Should only be called for managed threads handling a managed exception.
244 // If we're handling a stack overflow (ie, missing guard page), then another
245 // stack overflow will instantly terminate the process. In that case, do stack
246 // intensive stuff on the helper thread (which has lots of stack space). Only
247 // problem is that if the faulting thread has a lock, the helper thread may
249 // Serves as a hint whether we want to do a favor on the
250 // faulting thread (preferred) or the helper thread (if low stack).
251 // See whidbey issue 127436.
252 //-----------------------------------------------------------------------------
253 bool IsGuardPageGone()
262 Thread * pThread = g_pEEInterface->GetThread();
264 // We're not going to be called for a unmanaged exception.
265 // Should always have a managed thread, but just in case something really
266 // crazy happens, it's not worth an AV. (since this is just being used as a hint)
272 // Don't use pThread->IsGuardPageGone(), it's not accurate here.
273 bool fGuardPageGone = (pThread->DetermineIfGuardPagePresent() == FALSE);
274 LOG((LF_CORDB, LL_INFO1000000, "D::IsGuardPageGone=%d\n", fGuardPageGone));
275 return fGuardPageGone;
278 //-----------------------------------------------------------------------------
279 // LSPTR_XYZ is a type-safe wrapper around an opaque reference type XYZ in the left-side.
280 // But TypeHandles are value-types that can't be directly converted into a pointer.
281 // Thus converting between LSPTR_XYZ and TypeHandles requires some extra glue.
282 // The following conversions are valid:
283 // LSPTR_XYZ <--> XYZ* (via Set/UnWrap methods)
284 // TypeHandle <--> void* (via AsPtr() and FromPtr()).
285 // so we can't directly convert between LSPTR_TYPEHANDLE and TypeHandle.
286 // We must do: TypeHandle <--> void* <--> XYZ <--> LSPTR_XYZ
287 // So LSPTR_TYPEHANDLE is actually for TypeHandleDummyPtr, and then we unsafe cast
288 // that to a void* to use w/ AsPtr() and FromPtr() to convert to TypeHandles.
289 // @todo- it would be nice to have these happen automatically w/ Set & UnWrap.
290 //-----------------------------------------------------------------------------
292 // helper class to do conversion above.
293 class TypeHandleDummyPtr
296 TypeHandleDummyPtr() { }; // should never actually create this.
300 // Convert: VMPTR_TYPEHANDLE --> TypeHandle
301 TypeHandle GetTypeHandle(VMPTR_TypeHandle ptr)
303 return TypeHandle::FromPtr(ptr.GetRawPtr());
306 // Convert: TypeHandle --> LSPTR_TYPEHANDLE
307 VMPTR_TypeHandle WrapTypeHandle(TypeHandle th)
309 return VMPTR_TypeHandle::MakePtr(reinterpret_cast<TypeHandle *> (th.AsPtr()));
312 extern void WaitForEndOfShutdown();
315 // Get the Canary structure which can sniff if the helper thread is safe to run.
316 HelperCanary * Debugger::GetCanary()
318 return g_pRCThread->GetCanary();
322 // Do not call Lock and Unlock directly. Because you might not unlock
323 // if exception takes place. Use DebuggerLockHolder instead!!!
324 // Only AcquireDebuggerLock can call directly.
326 void Debugger::DoNotCallDirectlyPrivateLock(void)
330 LOG((LF_CORDB,LL_INFO10000, "D::Lock acquire attempt by 0x%x\n",
331 GetCurrentThreadId()));
333 // Debugger lock is larger than both Controller & debugger-data locks.
334 // So we should never try to take the D lock if we hold either of the others.
337 // Lock becomes no-op in late shutdown.
338 if (g_fProcessDetach)
345 // If the debugger has been disabled by the runtime, this means that it should block
346 // all threads that are trying to travel thru the debugger. We do this by blocking
347 // threads as they try and take the debugger lock.
351 __SwitchToThread(INFINITE, CALLER_LIMITS_SPINNING);
352 _ASSERTE (!"Can not reach here");
358 // If we were blocked on the lock and the debugging facilities got disabled
359 // while we were waiting, release the lock and park this thread.
364 __SwitchToThread(INFINITE, CALLER_LIMITS_SPINNING);
365 _ASSERTE (!"Can not reach here");
369 // Now check if we are in a shutdown case...
373 BEGIN_GETTHREAD_ALLOWED;
374 pThread = g_pEEInterface->GetThread();
375 fIsCooperative = (pThread != NULL) && (pThread->PreemptiveGCDisabled());
376 END_GETTHREAD_ALLOWED;
377 if (m_fShutdownMode && !fIsCooperative)
379 // The big fear is that some other random thread will take the debugger-lock and then block on something else,
380 // and thus prevent the helper/finalizer threads from taking the debugger-lock in shutdown scenarios.
382 // If we're in shutdown mode, then some locks (like the Thread-Store-Lock) get special semantics.
383 // Only helper / finalizer / shutdown threads can actually take these locks.
384 // Other threads that try to take them will just get parked and block forever.
385 // This is ok b/c the only threads that need to run at this point are the Finalizer and Helper threads.
387 // We need to be in preemptive to block for shutdown, so we don't do this block in Coop mode.
388 // Fortunately, it's safe to take this lock in coop mode because we know the thread can't block
389 // on anything interesting because we're in a GC-forbid region (see crst flags).
390 m_mutex.ReleaseAndBlockForShutdownIfNotSpecialThread();
396 _ASSERTE(m_mutexCount >= 0);
403 _ASSERTE(m_mutexOwner == GetThreadIdHelper(pThread));
408 _ASSERTE(m_mutexOwner == GetCurrentThreadId());
415 m_mutexOwner = GetThreadIdHelper(pThread);
420 m_mutexOwner = GetCurrentThreadId();
423 if (m_mutexCount == 1)
425 LOG((LF_CORDB,LL_INFO10000, "D::Lock acquired by 0x%x\n", m_mutexOwner));
431 // See comment above.
432 // Only ReleaseDebuggerLock can call directly.
433 void Debugger::DoNotCallDirectlyPrivateUnlock(void)
437 // Controller lock is "smaller" than debugger lock.
440 if (!g_fProcessDetach)
443 if (m_mutexCount == 1)
444 LOG((LF_CORDB,LL_INFO10000, "D::Unlock released by 0x%x\n",
447 if(0 == --m_mutexCount)
450 _ASSERTE( m_mutexCount >= 0);
455 // If the debugger has been disabled by the runtime, this means that it should block
456 // all threads that are trying to travel thru the debugger. We do this by blocking
457 // threads also as they leave the debugger lock.
461 __SwitchToThread(INFINITE, CALLER_LIMITS_SPINNING);
462 _ASSERTE (!"Can not reach here");
468 #ifdef TEST_DATA_CONSISTENCY
470 // ---------------------------------------------------------------------------------
471 // Implementations for DataTest member functions
472 // ---------------------------------------------------------------------------------
474 // Send an event to the RS to signal that it should test to determine if a crst is held.
475 // This is for testing purposes only.
477 // input: pCrst - the lock to test
478 // fOkToTake - true iff the LS does NOT currently hold the lock
480 // Notes: The RS will throw if the lock is held. The code that tests the lock will catch the
481 // exception and assert if throwing was not the correct thing to do (determined via the
482 // boolean). See the case for DB_IPCE_TEST_CRST in code:CordbProcess::RawDispatchEvent.
484 void DataTest::SendDbgCrstEvent(Crst * pCrst, bool fOkToTake)
486 DebuggerIPCEvent * pLockEvent = g_pDebugger->m_pRCThread->GetIPCEventSendBuffer();
488 g_pDebugger->InitIPCEvent(pLockEvent, DB_IPCE_TEST_CRST);
490 pLockEvent->TestCrstData.vmCrst.SetRawPtr(pCrst);
491 pLockEvent->TestCrstData.fOkToTake = fOkToTake;
493 g_pDebugger->SendRawEvent(pLockEvent);
495 } // DataTest::SendDbgCrstEvent
497 // Send an event to the RS to signal that it should test to determine if a SimpleRWLock is held.
498 // This is for testing purposes only.
500 // input: pRWLock - the lock to test
501 // fOkToTake - true iff the LS does NOT currently hold the lock
503 // Note: The RS will throw if the lock is held. The code that tests the lock will catch the
504 // exception and assert if throwing was not the correct thing to do (determined via the
505 // boolean). See the case for DB_IPCE_TEST_RWLOCK in code:CordbProcess::RawDispatchEvent.
507 void DataTest::SendDbgRWLockEvent(SimpleRWLock * pRWLock, bool okToTake)
509 DebuggerIPCEvent * pLockEvent = g_pDebugger->m_pRCThread->GetIPCEventSendBuffer();
511 g_pDebugger->InitIPCEvent(pLockEvent, DB_IPCE_TEST_RWLOCK);
513 pLockEvent->TestRWLockData.vmRWLock.SetRawPtr(pRWLock);
514 pLockEvent->TestRWLockData.fOkToTake = okToTake;
516 g_pDebugger->SendRawEvent(pLockEvent);
517 } // DataTest::SendDbgRWLockEvent
519 // Takes a series of locks in various ways and signals the RS to test the locks at interesting
520 // points to ensure we reliably detect when the LS holds a lock. If in the course of inspection, the
521 // DAC needs to execute a code path where the LS holds a lock, we assume that the locked data is in
522 // an inconsistent state. In this situation, we don't want to report information about this data, so
523 // we throw an exception.
524 // This is for testing purposes only.
527 // Return Value: none
528 // Notes: See code:CordbProcess::RawDispatchEvent for the RS part of this test and code:Debugger::Startup
529 // for the LS invocation of the test.
530 // The environment variable TestDataConsistency must be set to 1 to make this test run.
531 void DataTest::TestDataSafety()
533 const bool okToTake = true;
535 SendDbgCrstEvent(&m_crst1, okToTake);
537 CrstHolder ch1(&m_crst1);
538 SendDbgCrstEvent(&m_crst1, !okToTake);
540 CrstHolder ch2(&m_crst2);
541 SendDbgCrstEvent(&m_crst2, !okToTake);
542 SendDbgCrstEvent(&m_crst1, !okToTake);
544 SendDbgCrstEvent(&m_crst2, okToTake);
545 SendDbgCrstEvent(&m_crst1, !okToTake);
547 SendDbgCrstEvent(&m_crst1, okToTake);
550 SendDbgRWLockEvent(&m_rwLock, okToTake);
551 SimpleReadLockHolder readLock(&m_rwLock);
552 SendDbgRWLockEvent(&m_rwLock, okToTake);
554 SendDbgRWLockEvent(&m_rwLock, okToTake);
556 SimpleWriteLockHolder readLock(&m_rwLock);
557 SendDbgRWLockEvent(&m_rwLock, !okToTake);
560 } // DataTest::TestDataSafety
562 #endif // TEST_DATA_CONSISTENCY
565 static DebugEventCounter g_debugEventCounter;
566 static int g_iDbgRuntimeCounter[DBG_RUNTIME_MAX];
567 static int g_iDbgDebuggerCounter[DBG_DEBUGGER_MAX];
569 void DoAssertOnType(DebuggerIPCEventType event, int count)
573 // check to see if we need fire the assertion or not.
574 if ((event & 0x0300) == 0x0100)
576 // use the Runtime array
577 if (g_iDbgRuntimeCounter[event & 0x00ff] == count)
580 _snprintf_s(tmpStr, _countof(tmpStr), _TRUNCATE, "%s == %d, break now!",
581 IPCENames::GetName(event), count);
583 // fire the assertion
584 DbgAssertDialog(__FILE__, __LINE__, tmpStr);
587 // check to see if we need fire the assertion or not.
588 else if ((event & 0x0300) == 0x0200)
590 // use the Runtime array
591 if (g_iDbgDebuggerCounter[event & 0x00ff] == count)
594 _snprintf_s(tmpStr, _countof(tmpStr), _TRUNCATE, "%s == %d, break now!",
595 IPCENames::GetName(event), count);
597 // fire the assertion
598 DbgAssertDialog(__FILE__, __LINE__, tmpStr);
603 void DbgLogHelper(DebuggerIPCEventType event)
609 // we don't need to handle event type 0
610 #define IPC_EVENT_TYPE0(type, val)
611 #define IPC_EVENT_TYPE1(type, val) case type: {\
612 g_debugEventCounter.m_iDebugCount_##type++; \
613 DoAssertOnType(type, g_debugEventCounter.m_iDebugCount_##type); \
616 #define IPC_EVENT_TYPE2(type, val) case type: { \
617 g_debugEventCounter.m_iDebugCount_##type++; \
618 DoAssertOnType(type, g_debugEventCounter.m_iDebugCount_##type); \
621 #include "dbgipceventtypes.h"
622 #undef IPC_EVENT_TYPE2
623 #undef IPC_EVENT_TYPE1
624 #undef IPC_EVENT_TYPE0
639 /* ------------------------------------------------------------------------ *
641 * ------------------------------------------------------------------------ */
643 Debugger *CreateDebugger(void)
645 Debugger *pDebugger = NULL;
649 pDebugger = new (nothrow) Debugger();
653 if (pDebugger != NULL)
659 EX_END_CATCH(RethrowTerminalExceptions);
665 // CorDBGetInterface is exported to the Runtime so that it can call
666 // the Runtime Controller.
669 HRESULT __cdecl CorDBGetInterface(DebugInterface** rcInterface)
673 NOTHROW; // use HRESULTS instead
675 POSTCONDITION(FAILED(RETVAL) || (rcInterface == NULL) || (*rcInterface != NULL));
681 if (rcInterface != NULL)
683 if (g_pDebugger == NULL)
685 LOG((LF_CORDB, LL_INFO10,
686 "CorDBGetInterface: initializing debugger.\n"));
688 g_pDebugger = CreateDebugger();
689 TRACE_ALLOC(g_pDebugger);
691 if (g_pDebugger == NULL)
695 *rcInterface = g_pDebugger;
702 //-----------------------------------------------------------------------------
703 // Send a pre-init IPC event and block.
704 // We assume the IPC event has already been initialized. There's nothing special
705 // here; it just used the standard formula for sending an IPC event to the RS.
706 // This should match up w/ the description in SENDIPCEVENT_BEGIN.
707 //-----------------------------------------------------------------------------
708 void Debugger::SendSimpleIPCEventAndBlock()
713 MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
714 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
718 // BEGIN will acquire the lock (END will release it). While blocking, the
719 // debugger may have detached though, so we need to check for that.
720 _ASSERTE(ThreadHoldsLock());
722 if (CORDebuggerAttached())
724 m_pRCThread->SendIPCEvent();
726 // Stop all Runtime threads
727 this->TrapAllRuntimeThreads();
731 //-----------------------------------------------------------------------------
732 // Get context from a thread in managed code.
733 // See header for exact semantics.
734 //-----------------------------------------------------------------------------
735 CONTEXT * GetManagedStoppedCtx(Thread * pThread)
739 _ASSERTE(pThread != NULL);
741 // We may be stopped or live.
743 // If we're stopped at an interop-hijack, we'll have a filter context,
744 // but we'd better not be redirected for a managed-suspension hijack.
745 if (pThread->GetInteropDebuggingHijacked())
747 _ASSERTE(!ISREDIRECTEDTHREAD(pThread));
751 // Check if we have a filter ctx. This should only be for managed-code.
752 // We're stopped at some exception (likely an int3 or single-step).
753 // Can't have both filter ctx + redirected ctx.
754 CONTEXT *pCtx = g_pEEInterface->GetThreadFilterContext(pThread);
757 _ASSERTE(!ISREDIRECTEDTHREAD(pThread));
761 if (ISREDIRECTEDTHREAD(pThread))
763 pCtx = GETREDIRECTEDCONTEXT(pThread);
764 _ASSERTE(pCtx != NULL);
768 // Not stopped somewhere in managed code.
772 //-----------------------------------------------------------------------------
773 // See header for exact semantics.
774 // Never NULL. (Caller guarantees this is active.)
775 //-----------------------------------------------------------------------------
776 CONTEXT * GetManagedLiveCtx(Thread * pThread)
778 LIMITED_METHOD_CONTRACT;
780 _ASSERTE(pThread != NULL);
782 // We should never be on the helper thread, we should only be inspecting our own thread.
783 // We're in some Controller's Filter after hitting an exception.
784 // We're not stopped.
785 //_ASSERTE(!g_pDebugger->IsStopped()); <-- @todo - this fires, need to find out why.
786 _ASSERTE(GetThread() == pThread);
788 CONTEXT *pCtx = g_pEEInterface->GetThreadFilterContext(pThread);
790 // Note that we may be in a M2U hijack. So we can't assert !pThread->GetInteropDebuggingHijacked()
791 _ASSERTE(!ISREDIRECTEDTHREAD(pThread));
797 // Attempt to validate a GC handle.
798 HRESULT ValidateGCHandle(OBJECTHANDLE oh)
800 // The only real way to do this is to Enumerate all GC handles in the handle table.
801 // That's too expensive. So we'll use a similar workaround that we use in ValidateObject.
802 // This will err on the side off returning True for invalid handles.
816 // Use AVInRuntimeImplOkHolder.
817 AVInRuntimeImplOkayHolder AVOkay;
819 // This may throw if the Object Handle is invalid.
820 Object * objPtr = *((Object**) oh);
822 // NULL is certinally valid...
825 if (!objPtr->ValidateObjectWithPossibleAV())
827 LOG((LF_CORDB, LL_INFO10000, "GAV: object methodtable-class invariant doesn't hold.\n"));
837 LOG((LF_CORDB, LL_INFO10000, "GAV: exception indicated ref is bad.\n"));
840 EX_END_CATCH(SwallowAllExceptions);
846 // Validate an object. Returns E_INVALIDARG or S_OK.
847 HRESULT ValidateObject(Object *objPtr)
861 // Use AVInRuntimeImplOkHolder.
862 AVInRuntimeImplOkayHolder AVOkay;
864 // NULL is certinally valid...
867 if (!objPtr->ValidateObjectWithPossibleAV())
869 LOG((LF_CORDB, LL_INFO10000, "GAV: object methodtable-class invariant doesn't hold.\n"));
879 LOG((LF_CORDB, LL_INFO10000, "GAV: exception indicated ref is bad.\n"));
882 EX_END_CATCH(SwallowAllExceptions);
888 #ifdef FEATURE_DBGIPC_TRANSPORT_VM
892 if (g_pDbgTransport != NULL)
894 g_pDbgTransport->Shutdown();
895 g_pDbgTransport = NULL;
902 if (g_pDbgTransport != NULL)
904 g_pDbgTransport->AbortConnection();
907 #endif // FEATURE_DBGIPC_TRANSPORT_VM
910 /* ------------------------------------------------------------------------ *
912 * ------------------------------------------------------------------------ */
915 // a Debugger object represents the global state of the debugger program.
919 // Constructor & Destructor
922 /******************************************************************************
924 ******************************************************************************/
927 m_fLeftSideInitialized(FALSE),
932 m_trappingRuntimeThreads(FALSE),
934 m_unrecoverableError(FALSE),
935 m_ignoreThreadDetach(FALSE),
936 m_pMethodInfos(NULL),
937 m_mutex(CrstDebuggerMutex, (CrstFlags)(CRST_UNSAFE_ANYMODE | CRST_REENTRANCY | CRST_DEBUGGER_THREAD)),
940 m_tidLockedForEventSending(0),
942 m_threadsAtUnsafePlaces(0),
943 m_jitAttachInProgress(FALSE),
944 m_launchingDebugger(FALSE),
945 m_LoggingEnabled(TRUE),
946 m_pAppDomainCB(NULL),
947 m_dClassLoadCallbackCount(0),
949 m_RSRequestedSync(FALSE),
950 m_sendExceptionsOutsideOfJMC(TRUE),
951 m_pIDbgThreadControl(NULL),
952 m_forceNonInterceptable(FALSE),
960 WRAPPER(GC_TRIGGERS);
965 m_fShutdownMode = false;
967 m_rgHijackFunction = NULL;
970 InitDebugEventCounting();
973 m_processId = GetCurrentProcessId();
975 // Initialize these in ctor because we free them in dtor.
976 // And we can't set them to some safe uninited value (like NULL).
980 //------------------------------------------------------------------------------
981 // Metadata data structure version numbers
983 // 1 - initial state of the layouts ( .Net 4.5.2 )
985 // as data structure layouts change, add a new version number
986 // and comment the changes
987 m_mdDataStructureVersion = 1;
991 /******************************************************************************
993 ******************************************************************************/
994 Debugger::~Debugger()
1005 // We explicitly leak the debugger object on shutdown. See Debugger::StopDebugger for details.
1006 _ASSERTE(!"Debugger dtor should not be called.");
1009 #if defined(FEATURE_HIJACK) && !defined(PLATFORM_UNIX)
1010 typedef void (*PFN_HIJACK_FUNCTION) (void);
1012 // Given the start address and the end address of a function, return a MemoryRange for the function.
1013 inline MemoryRange GetMemoryRangeForFunction(PFN_HIJACK_FUNCTION pfnStart, PFN_HIJACK_FUNCTION pfnEnd)
1015 PCODE pfnStartAddress = (PCODE)GetEEFuncEntryPoint(pfnStart);
1016 PCODE pfnEndAddress = (PCODE)GetEEFuncEntryPoint(pfnEnd);
1017 return MemoryRange(dac_cast<PTR_VOID>(pfnStartAddress), (pfnEndAddress - pfnStartAddress));
1021 MemoryRange Debugger::s_hijackFunction[kMaxHijackFunctions] =
1022 {GetMemoryRangeForFunction(ExceptionHijack, ExceptionHijackEnd),
1023 GetMemoryRangeForFunction(RedirectedHandledJITCaseForGCThreadControl_Stub,
1024 RedirectedHandledJITCaseForGCThreadControl_StubEnd),
1025 GetMemoryRangeForFunction(RedirectedHandledJITCaseForDbgThreadControl_Stub,
1026 RedirectedHandledJITCaseForDbgThreadControl_StubEnd),
1027 GetMemoryRangeForFunction(RedirectedHandledJITCaseForUserSuspend_Stub,
1028 RedirectedHandledJITCaseForUserSuspend_StubEnd)
1029 #if defined(HAVE_GCCOVER) && defined(_TARGET_AMD64_)
1031 GetMemoryRangeForFunction(RedirectedHandledJITCaseForGCStress_Stub,
1032 RedirectedHandledJITCaseForGCStress_StubEnd)
1033 #endif // HAVE_GCCOVER && _TARGET_AMD64_
1035 #endif // FEATURE_HIJACK && !PLATFORM_UNIX
1037 // Save the necessary information for the debugger to recognize an IP in one of the thread redirection
1039 void Debugger::InitializeHijackFunctionAddress()
1041 #if defined(FEATURE_HIJACK) && !defined(PLATFORM_UNIX)
1042 // Advertise hijack address for the DD Hijack primitive
1043 m_rgHijackFunction = Debugger::s_hijackFunction;
1044 #endif // FEATURE_HIJACK && !PLATFORM_UNIX
1047 // For debug-only builds, we'll have a debugging feature to count
1048 // the number of ipc events and break on a specific number.
1049 // Initialize the stuff to do that.
1050 void Debugger::InitDebugEventCounting()
1060 // initialize the debug event counter structure to zero
1061 memset(&g_debugEventCounter, 0, sizeof(DebugEventCounter));
1062 memset(&g_iDbgRuntimeCounter, 0, DBG_RUNTIME_MAX*sizeof(int));
1063 memset(&g_iDbgDebuggerCounter, 0, DBG_DEBUGGER_MAX*sizeof(int));
1065 // retrieve the possible counter for break point
1066 LPWSTR wstrValue = NULL;
1067 // The string value is of the following format
1068 // <Event Name>=Count;<Event Name>=Count;....;
1069 // The string must end with ;
1070 if ((wstrValue = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DebuggerBreakPoint)) != NULL)
1074 cbReq = WszWideCharToMultiByte(CP_UTF8, 0, wstrValue,-1, 0,0, 0,0);
1076 strValue = new (nothrow) char[cbReq+1];
1077 // This is a debug only thingy, if it fails, not worth taking
1078 // down the process.
1079 if (strValue == NULL)
1083 // now translate the unicode to ansi string
1084 WszWideCharToMultiByte(CP_UTF8, 0, wstrValue, -1, strValue, cbReq+1, 0,0);
1085 char *szEnd = (char *)strchr(strValue, ';');
1086 char *szStart = strValue;
1087 while (szEnd != NULL)
1089 // Found a key value
1090 char *szNameEnd = strchr(szStart, '=');
1092 DebuggerIPCEventType eventType;
1093 if (szNameEnd != NULL)
1095 // This is a well form key
1099 // now szStart is the key name null terminated. Translate the counter into integer.
1100 iCount = atoi(szNameEnd+1);
1103 eventType = IPCENames::GetEventType(szStart);
1105 if (eventType < DB_IPCE_DEBUGGER_FIRST)
1107 // use the runtime one
1108 g_iDbgRuntimeCounter[eventType & 0x00ff] = iCount;
1110 else if (eventType < DB_IPCE_DEBUGGER_LAST)
1112 // use the debugger one
1113 g_iDbgDebuggerCounter[eventType & 0x00ff] = iCount;
1116 _ASSERTE(!"Unknown Event Type");
1119 szStart = szEnd + 1;
1120 // try to find next key value
1121 szEnd = (char *)strchr(szStart, ';');
1124 // free the ansi buffer
1126 REGUTIL::FreeConfigString(wstrValue);
1132 // This is a notification from the EE it's about to go to fiber mode.
1133 // This is given *before* it actually goes to fiber mode.
1134 HRESULT Debugger::SetFiberMode(bool isFiberMode)
1141 // Notifications from EE never come on helper worker.
1142 PRECONDITION(!ThisIsHelperThreadWorker());
1147 Thread * pThread = ::GetThread();
1149 m_pRCThread->m_pDCB->m_bHostingInFiber = isFiberMode;
1151 // If there is a debugger already attached, then we have a big problem. As of V2.0, the debugger
1152 // does not support debugging processes with fibers in them. We set the unrecoverable state to
1153 // indicate that we're in a bad state now. The debugger will notice this, and take appropiate action.
1154 if (isFiberMode && CORDebuggerAttached())
1156 LOG((LF_CORDB, LL_INFO10, "Thread has entered fiber mode while debugger attached.\n"));
1160 // We send up a MDA for two reasons: 1) we want to give the user some chance to see what went wrong,
1161 // and 2) we want to get the Right Side to notice that we're in an unrecoverable error state now.
1163 SString szName(W("DebuggerFiberModeNotSupported"));
1164 SString szDescription;
1165 szDescription.LoadResource(CCompRC::Debugging, MDARC_DEBUGGER_FIBER_MODE_NOT_SUPPORTED);
1166 SString szXML(W(""));
1168 // Sending any debug event will be a GC violation.
1169 // However, if we're enabling fiber-mode while a debugger is attached, we're already doomed.
1170 // Deadlocks and AVs are just around the corner. A Gc-violation is the least of our worries.
1171 // We want to at least notify the debugger at all costs.
1172 CONTRACT_VIOLATION(GCViolation);
1174 // As soon as we set unrecoverable error in the LS, the RS will pick it up and basically shut down.
1175 // It won't dispatch any events. So we fire the MDA first, and then set unrecoverable error.
1176 SendMDANotification(pThread, &szName, &szDescription, &szXML, (CorDebugMDAFlags) 0, FALSE);
1178 CORDBDebuggerSetUnrecoverableError(this, CORDBG_E_CANNOT_DEBUG_FIBER_PROCESS, false);
1180 // Fire the MDA again just to force the RS to sniff the LS and pick up that we're in an unrecoverable error.
1181 // No harm done from dispatching an MDA twice. And
1182 SendMDANotification(pThread, &szName, &szDescription, &szXML, (CorDebugMDAFlags) 0, FALSE);
1187 LOG((LF_CORDB, LL_INFO10, "Error sending MDA regarding fiber mode.\n"));
1189 EX_END_CATCH(SwallowAllExceptions);
1195 // Checks if the MethodInfos table has been allocated, and if not does so.
1196 // Throw on failure, so we always return
1197 HRESULT Debugger::CheckInitMethodInfoTable()
1207 if (m_pMethodInfos == NULL)
1209 DebuggerMethodInfoTable *pMethodInfos = NULL;
1213 pMethodInfos = new (interopsafe) DebuggerMethodInfoTable();
1217 pMethodInfos = NULL;
1219 EX_END_CATCH(RethrowTerminalExceptions);
1222 if (pMethodInfos == NULL)
1224 return E_OUTOFMEMORY;
1227 if (InterlockedCompareExchangeT(&m_pMethodInfos, pMethodInfos, NULL) != NULL)
1229 DeleteInteropSafe(pMethodInfos);
1236 // Checks if the m_pModules table has been allocated, and if not does so.
1237 HRESULT Debugger::CheckInitModuleTable()
1243 POSTCONDITION(m_pModules != NULL);
1247 if (m_pModules == NULL)
1249 DebuggerModuleTable *pModules = new (interopsafe, nothrow) DebuggerModuleTable();
1251 if (pModules == NULL)
1253 RETURN (E_OUTOFMEMORY);
1256 if (InterlockedCompareExchangeT(&m_pModules, pModules, NULL) != NULL)
1258 DeleteInteropSafe(pModules);
1265 // Checks if the m_pModules table has been allocated, and if not does so.
1266 HRESULT Debugger::CheckInitPendingFuncEvalTable()
1272 POSTCONDITION(GetPendingEvals() != NULL);
1276 #ifndef DACCESS_COMPILE
1278 if (GetPendingEvals() == NULL)
1280 DebuggerPendingFuncEvalTable *pPendingEvals = new (interopsafe, nothrow) DebuggerPendingFuncEvalTable();
1282 if (pPendingEvals == NULL)
1284 RETURN(E_OUTOFMEMORY);
1287 // Since we're setting, we need an LValue and not just an accessor.
1288 if (InterlockedCompareExchangeT(&(GetLazyData()->m_pPendingEvals), pPendingEvals, NULL) != NULL)
1290 DeleteInteropSafe(pPendingEvals);
1299 #ifdef _DEBUG_DMI_TABLE
1300 // Returns the number of (official) entries in the table
1301 ULONG DebuggerMethodInfoTable::CheckDmiTable(void)
1303 LIMITED_METHOD_CONTRACT;
1305 ULONG cApparent = 0;
1306 ULONG cOfficial = 0;
1308 if (NULL != m_pcEntries)
1310 DebuggerMethodInfoEntry *dcp;
1312 while (i++ <m_iEntries)
1314 dcp = (DebuggerMethodInfoEntry*)&(((DebuggerMethodInfoEntry *)m_pcEntries)[i]);
1316 dcp->pFD != (MethodDesc*)0xcdcdcdcd &&
1321 _ASSERTE( dcp->pFD == dcp->mi->m_fd );
1322 LOG((LF_CORDB, LL_INFO1000, "DMIT::CDT:Entry:0x%p mi:0x%p\nPrevs:\n",
1324 DebuggerMethodInfo *dmi = dcp->mi->m_prevMethodInfo;
1328 LOG((LF_CORDB, LL_INFO1000, "\t0x%p\n", dmi));
1329 dmi = dmi->m_prevMethodInfo;
1331 dmi = dcp->mi->m_nextMethodInfo;
1333 LOG((LF_CORDB, LL_INFO1000, "Nexts:\n", dmi));
1336 LOG((LF_CORDB, LL_INFO1000, "\t0x%p\n", dmi));
1337 dmi = dmi->m_nextMethodInfo;
1340 LOG((LF_CORDB, LL_INFO1000, "DMIT::CDT:DONE\n",
1345 if (m_piBuckets == 0)
1347 LOG((LF_CORDB, LL_INFO1000, "DMIT::CDT: The table is officially empty!\n"));
1351 LOG((LF_CORDB, LL_INFO1000, "DMIT::CDT:Looking for official entries:\n"));
1353 ULONG iNext = m_piBuckets[0];
1355 HASHENTRY *psEntry = NULL;
1358 while (iNext != UINT32_MAX)
1362 psEntry = EntryPtr(iNext);
1363 dcp = ((DebuggerMethodInfoEntry *)psEntry);
1365 LOG((LF_CORDB, LL_INFO1000, "\tEntry:0x%p mi:0x%p @idx:0x%x @bucket:0x%x\n",
1366 dcp, dcp->mi, iNext, iBucket));
1368 iNext = psEntry->iNext;
1371 // Advance to the next bucket.
1372 if (iBucket < m_iBuckets)
1373 iNext = m_piBuckets[iBucket++];
1378 LOG((LF_CORDB, LL_INFO1000, "DMIT::CDT:Finished official entries: ****************"));
1383 #endif // _DEBUG_DMI_TABLE
1386 //---------------------------------------------------------------------------------------
1388 // Class constructor for DebuggerEval. This is the supporting data structure for
1389 // func-eval tracking.
1392 // pContext - The context to return to when done with this eval.
1393 // pEvalInfo - Contains all the important information, such as parameters, type args, method.
1394 // fInException - TRUE if the thread for the eval is currently in an exception notification.
1396 DebuggerEval::DebuggerEval(CONTEXT * pContext, DebuggerIPCE_FuncEvalInfo * pEvalInfo, bool fInException)
1398 WRAPPER_NO_CONTRACT;
1400 // Allocate the breakpoint instruction info in executable memory.
1401 m_bpInfoSegment = new (interopsafeEXEC, nothrow) DebuggerEvalBreakpointInfoSegment(this);
1403 // This must be non-zero so that the saved opcode is non-zero, and on IA64 we want it to be 0x16
1404 // so that we can have a breakpoint instruction in any slot in the bundle.
1405 m_bpInfoSegment->m_breakpointInstruction[0] = 0x16;
1406 #if defined(_TARGET_ARM_)
1407 USHORT *bp = (USHORT*)&m_bpInfoSegment->m_breakpointInstruction;
1408 *bp = CORDbg_BREAK_INSTRUCTION;
1409 #endif // _TARGET_ARM_
1410 m_thread = pEvalInfo->vmThreadToken.GetRawPtr();
1411 m_evalType = pEvalInfo->funcEvalType;
1412 m_methodToken = pEvalInfo->funcMetadataToken;
1413 m_classToken = pEvalInfo->funcClassMetadataToken;
1415 // Note: we can't rely on just the DebuggerModule* or AppDomain* because the AppDomain
1416 // could get unloaded between now and when the funceval actually starts. So we stash an
1417 // AppDomain ID which is safe to use after the AD is unloaded. It's only safe to
1418 // use the DebuggerModule* after we've verified the ADID is still valid (i.e. by entering that domain).
1419 m_debuggerModule = g_pDebugger->LookupOrCreateModule(pEvalInfo->vmDomainFile);
1421 if (m_debuggerModule == NULL)
1423 // We have no associated code.
1424 _ASSERTE((m_evalType == DB_IPCE_FET_NEW_STRING) || (m_evalType == DB_IPCE_FET_NEW_ARRAY));
1426 // We'll just do the creation in whatever domain the thread is already in.
1427 // It's conceivable that we might want to allow the caller to specify a specific domain, but
1428 // ICorDebug provides the debugger with no was to specify the domain.
1429 m_appDomainId = m_thread->GetDomain()->GetId();
1433 m_appDomainId = m_debuggerModule->GetAppDomain()->GetId();
1436 m_funcEvalKey = pEvalInfo->funcEvalKey;
1437 m_argCount = pEvalInfo->argCount;
1438 m_targetCodeAddr = NULL;
1439 m_stringSize = pEvalInfo->stringSize;
1440 m_arrayRank = pEvalInfo->arrayRank;
1441 m_genericArgsCount = pEvalInfo->genericArgsCount;
1442 m_genericArgsNodeCount = pEvalInfo->genericArgsNodeCount;
1443 m_successful = false;
1445 memset(m_result, 0, sizeof(m_result));
1447 m_resultType = TypeHandle();
1448 m_aborting = FE_ABORT_NONE;
1450 m_completed = false;
1451 m_evalDuringException = fInException;
1452 m_rethrowAbortException = false;
1453 m_retValueBoxing = Debugger::NoValueTypeBoxing;
1454 m_requester = (Thread::ThreadAbortRequester)0;
1455 m_vmObjectHandle = VMPTR_OBJECTHANDLE::NullPtr();
1457 // Copy the thread's context.
1458 if (pContext == NULL)
1460 memset(&m_context, 0, sizeof(m_context));
1464 memcpy(&m_context, pContext, sizeof(m_context));
1468 //---------------------------------------------------------------------------------------
1470 // This constructor is only used when setting up an eval to re-abort a thread.
1473 // pContext - The context to return to when done with this eval.
1474 // pThread - The thread to re-abort.
1475 // requester - The type of abort to throw.
1477 DebuggerEval::DebuggerEval(CONTEXT * pContext, Thread * pThread, Thread::ThreadAbortRequester requester)
1479 WRAPPER_NO_CONTRACT;
1481 // Allocate the breakpoint instruction info in executable memory.
1482 m_bpInfoSegment = new (interopsafeEXEC, nothrow) DebuggerEvalBreakpointInfoSegment(this);
1484 // This must be non-zero so that the saved opcode is non-zero, and on IA64 we want it to be 0x16
1485 // so that we can have a breakpoint instruction in any slot in the bundle.
1486 m_bpInfoSegment->m_breakpointInstruction[0] = 0x16;
1488 m_evalType = DB_IPCE_FET_RE_ABORT;
1489 m_methodToken = mdMethodDefNil;
1490 m_classToken = mdTypeDefNil;
1491 m_debuggerModule = NULL;
1492 m_funcEvalKey = RSPTR_CORDBEVAL::NullPtr();
1496 m_genericArgsCount = 0;
1497 m_genericArgsNodeCount = 0;
1498 m_successful = false;
1500 m_targetCodeAddr = NULL;
1501 memset(m_result, 0, sizeof(m_result));
1503 m_resultType = TypeHandle();
1504 m_aborting = FE_ABORT_NONE;
1506 m_completed = false;
1507 m_evalDuringException = false;
1508 m_rethrowAbortException = false;
1509 m_retValueBoxing = Debugger::NoValueTypeBoxing;
1510 m_requester = requester;
1512 if (pContext == NULL)
1514 memset(&m_context, 0, sizeof(m_context));
1518 memcpy(&m_context, pContext, sizeof(m_context));
1524 // Thread proc for interop stress coverage. Have an unmanaged thread
1525 // that just loops throwing native exceptions. This can test corner cases
1526 // such as getting an native exception while the runtime is synced.
1527 DWORD WINAPI DbgInteropStressProc(void * lpParameter)
1529 LIMITED_METHOD_CONTRACT;
1535 // This will ensure that the compiler doesn't flag our 1/0 exception below at compile-time.
1536 if (lpParameter != NULL)
1541 // Note that this thread is a non-runtime thread. So it can't take any CLR locks
1542 // or do anything else that may block the helper thread.
1543 // (Log statements take CLR locks).
1550 // Generate an in-band event.
1553 // Throw a handled exception. Don't use an AV since that's pretty special.
1554 *(int*)lpParameter = 1 / zero;
1563 // Generate the occasional oob-event.
1564 WszOutputDebugString(W("Ping from DbgInteropStressProc"));
1567 // This helps parallelize if we have a lot of threads, and keeps us from
1568 // chewing too much CPU time.
1569 ClrSleepEx(2000,FALSE);
1570 ClrSleepEx(GetRandomInt(1000), FALSE);
1576 // ThreadProc that does everything in a can't stop region.
1577 DWORD WINAPI DbgInteropCantStopStressProc(void * lpParameter)
1579 WRAPPER_NO_CONTRACT;
1581 // This will mark us as a can't stop region.
1582 ClrFlsSetThreadType (ThreadType_DbgHelper);
1584 return DbgInteropStressProc(lpParameter);
1587 // Generate lots of OOB events.
1588 DWORD WINAPI DbgInteropDummyStressProc(void * lpParameter)
1590 LIMITED_METHOD_CONTRACT;
1592 ClrSleepEx(1,FALSE);
1596 DWORD WINAPI DbgInteropOOBStressProc(void * lpParameter)
1598 WRAPPER_NO_CONTRACT;
1606 // Create a dummy thread. That generates 2 oob events
1607 // (1 for create, 1 for destroy)
1609 ::CreateThread(NULL, 0, DbgInteropDummyStressProc, NULL, 0, &id);
1613 // Generate the occasional oob-event.
1614 WszOutputDebugString(W("OOB ping from "));
1617 ClrSleepEx(3000, FALSE);
1623 // List of the different possible stress procs.
1624 LPTHREAD_START_ROUTINE g_pStressProcs[] =
1626 DbgInteropOOBStressProc,
1627 DbgInteropCantStopStressProc,
1628 DbgInteropStressProc
1633 DebuggerHeap * Debugger::GetInteropSafeHeap()
1643 // Lazily initialize our heap.
1644 if (!m_heap.IsInit())
1646 _ASSERTE(!"InteropSafe Heap should have already been initialized in LazyInit");
1648 // Just in case we miss it in retail, convert to OOM here:
1655 DebuggerHeap * Debugger::GetInteropSafeHeap_NoThrow()
1665 // Lazily initialize our heap.
1666 if (!m_heap.IsInit())
1668 _ASSERTE(!"InteropSafe Heap should have already been initialized in LazyInit");
1670 // Just in case we miss it in retail, convert to OOM here:
1676 DebuggerHeap * Debugger::GetInteropSafeExecutableHeap()
1686 // Lazily initialize our heap.
1687 if (!m_executableHeap.IsInit())
1689 _ASSERTE(!"InteropSafe Executable Heap should have already been initialized in LazyInit");
1691 // Just in case we miss it in retail, convert to OOM here:
1695 return &m_executableHeap;
1698 DebuggerHeap * Debugger::GetInteropSafeExecutableHeap_NoThrow()
1708 // Lazily initialize our heap.
1709 if (!m_executableHeap.IsInit())
1711 _ASSERTE(!"InteropSafe Executable Heap should have already been initialized in LazyInit");
1713 // Just in case we miss it in retail, convert to OOM here:
1716 return &m_executableHeap;
1719 //---------------------------------------------------------------------------------------
1721 // Notify potential debugger that the runtime has started up
1725 // Called during startup path
1728 // If no debugger is attached, this does nothing.
1730 //---------------------------------------------------------------------------------------
1731 void Debugger::RaiseStartupNotification()
1733 // Right-side will read this field from OOP via DAC-primitive to determine attach or launch case.
1734 // We do an interlocked increment to gaurantee this is an atomic memory write, and to ensure
1735 // that it's flushed from any CPU cache into memory.
1736 InterlockedIncrement(&m_fLeftSideInitialized);
1738 #ifndef FEATURE_DBGIPC_TRANSPORT_VM
1739 // If we are remote debugging, don't send the event now if a debugger is not attached. No one will be
1740 // listening, and we will fail. However, we still want to initialize the variable above.
1741 DebuggerIPCEvent startupEvent;
1742 InitIPCEvent(&startupEvent, DB_IPCE_LEFTSIDE_STARTUP, NULL, VMPTR_AppDomain::NullPtr());
1744 SendRawEvent(&startupEvent);
1746 // RS will set flags from OOP while we're stopped at the event if it wants to attach.
1747 #endif // FEATURE_DBGIPC_TRANSPORT_VM
1751 //---------------------------------------------------------------------------------------
1753 // Sends a raw managed debug event to the debugger.
1756 // pManagedEvent - managed debug event
1760 // This can be called even if a debugger is not attached.
1761 // The entire process will get frozen by the debugger once we send. The debugger
1762 // needs to resume the process. It may detach as well.
1763 // See code:IsEventDebuggerNotification for decoding this event. These methods must stay in sync.
1764 // The debugger process reads the events via code:CordbProcess.CopyManagedEventFromTarget.
1766 //---------------------------------------------------------------------------------------
1767 void Debugger::SendRawEvent(const DebuggerIPCEvent * pManagedEvent)
1769 #if defined(FEATURE_DBGIPC_TRANSPORT_VM)
1770 HRESULT hr = g_pDbgTransport->SendDebugEvent(const_cast<DebuggerIPCEvent *>(pManagedEvent));
1774 _ASSERTE(!"Failed to send debugger event");
1776 STRESS_LOG1(LF_CORDB, LL_INFO1000, "D::SendIPCEvent Error on Send with 0x%x\n", hr);
1777 UnrecoverableError(hr,
1783 // @dbgtodo Mac - what can we do here?
1786 // We get to send an array of ULONG_PTRs as data with the notification.
1787 // The debugger can then use ReadProcessMemory to read through this array.
1788 ULONG_PTR rgData [] = {
1789 CLRDBG_EXCEPTION_DATA_CHECKSUM,
1790 (ULONG_PTR) g_pMSCorEE,
1791 (ULONG_PTR) pManagedEvent
1794 // If no debugger attached, then don't bother raising a 1st-chance exception because nobody will sniff it.
1795 // @dbgtodo iDNA: in iDNA case, the recorder may sniff it.
1796 if (!IsDebuggerPresent())
1802 // Physically send the event via an OS Exception. We're using exceptions as a notification
1803 // mechanism on top of the OS native debugging pipeline.
1804 // @dbgtodo cross-plat - this needs to be cross-plat.
1808 const DWORD dwFlags = 0; // continuable (eg, Debugger can continue GH)
1809 RaiseException(CLRDBG_NOTIFICATION_EXCEPTION_CODE, dwFlags, NumItems(rgData), rgData);
1811 // If debugger continues "GH" (DBG_CONTINUE), then we land here.
1812 // This is the expected path for a well-behaved ICorDebug debugger.
1816 // If no debugger is attached, or if the debugger continues "GN" (DBG_EXCEPTION_NOT_HANDLED), then we land here.
1817 // A naive (not-ICorDebug aware) native-debugger won't handle the exception and so land us here.
1818 // We may also get here if a debugger detaches at the Exception notification
1819 // (and thus implicitly continues GN).
1821 EX_END_CATCH(SwallowAllExceptions);
1822 #endif // FEATURE_DBGIPC_TRANSPORT_VM
1825 //---------------------------------------------------------------------------------------
1826 // Send a createProcess event to give the RS a chance to do SetDesiredNGENFlags
1829 // pDbgLockHolder - lock holder.
1832 // Lock is initially held. This will toggle the lock to send an IPC event.
1833 // This will start a synchronization.
1836 // In V2, this also gives the RS a chance to intialize the IPC protocol.
1837 // Spefically, this needs to be sent before the LS can send a sync-complete.
1838 //---------------------------------------------------------------------------------------
1839 void Debugger::SendCreateProcess(DebuggerLockHolder * pDbgLockHolder)
1841 pDbgLockHolder->Release();
1843 // Encourage helper thread to spin up so that we're in a consistent state.
1844 PollWaitingForHelper();
1846 // we don't need to use SENDIPCEVENT_BEGIN/END macros that perform the debug-suspend aware checks,
1847 // as this code executes on the startup path...
1848 SENDIPCEVENT_RAW_BEGIN(pDbgLockHolder);
1850 // Send a CreateProcess event.
1851 // @dbgtodo pipeline - eliminate these reasons for needing a CreateProcess event (part of pipeline feature crew)
1852 // This will let the RS know that the IPC block is up + ready, and then the RS can read it.
1853 // The RS will then update the DCB with enough information so that we can send the sync-complete.
1854 // (such as letting us know whether we're interop-debugging or not).
1855 DebuggerIPCEvent event;
1856 InitIPCEvent(&event, DB_IPCE_CREATE_PROCESS, NULL, VMPTR_AppDomain::NullPtr());
1857 SendRawEvent(&event);
1859 // @dbgtodo inspection- it doesn't really make sense to sync on a CreateProcess. We only have 1 thread
1860 // in the CLR and we know exactly what state we're in and we can ensure that we're synchronized.
1861 // For V3,RS should be able to treat a CreateProcess like a synchronized.
1862 // Remove this in V3 as we make SetDesiredNgenFlags operate OOP.
1863 TrapAllRuntimeThreads();
1865 // Must have a thread object so that we ensure that we will actually block here.
1866 // This ensures the debuggee is actually stopped at startup, and
1867 // this gives the debugger a chance to call SetDesiredNGENFlags before we
1868 // set s_fCanChangeNgenFlags to FALSE.
1869 _ASSERTE(GetThread() != NULL);
1870 SENDIPCEVENT_RAW_END;
1872 pDbgLockHolder->Acquire();
1875 #if !defined(FEATURE_PAL)
1877 HANDLE g_hContinueStartupEvent = INVALID_HANDLE_VALUE;
1879 CLR_ENGINE_METRICS g_CLREngineMetrics = {
1880 sizeof(CLR_ENGINE_METRICS),
1881 CorDebugVersion_4_0,
1882 &g_hContinueStartupEvent};
1884 #define StartupNotifyEventNamePrefix W("TelestoStartupEvent_")
1885 const int cchEventNameBufferSize = sizeof(StartupNotifyEventNamePrefix)/sizeof(WCHAR) + 8; // + hex DWORD (8). NULL terminator is included in sizeof(StartupNotifyEventNamePrefix)
1886 HANDLE OpenStartupNotificationEvent()
1888 DWORD debuggeePID = GetCurrentProcessId();
1889 WCHAR szEventName[cchEventNameBufferSize];
1890 swprintf_s(szEventName, cchEventNameBufferSize, StartupNotifyEventNamePrefix W("%08x"), debuggeePID);
1892 return WszOpenEvent(MAXIMUM_ALLOWED | SYNCHRONIZE | EVENT_MODIFY_STATE, FALSE, szEventName);
1895 void NotifyDebuggerOfStartup()
1897 // Create the continue event first so that we guarantee that any
1898 // enumeration of this process will get back a valid continue event
1899 // the instant we signal the startup notification event.
1901 CONSISTENCY_CHECK(INVALID_HANDLE_VALUE == g_hContinueStartupEvent);
1902 g_hContinueStartupEvent = WszCreateEvent(NULL, TRUE, FALSE, NULL);
1903 CONSISTENCY_CHECK(INVALID_HANDLE_VALUE != g_hContinueStartupEvent); // we reserve this value for error conditions in EnumerateCLRs
1905 HANDLE startupEvent = OpenStartupNotificationEvent();
1906 if (startupEvent != NULL)
1908 // signal notification event
1909 SetEvent(startupEvent);
1910 CloseHandle(startupEvent);
1911 startupEvent = NULL;
1913 // wait on continue startup event
1914 // The debugger may attach to us while we're blocked here.
1915 WaitForSingleObject(g_hContinueStartupEvent, INFINITE);
1918 CloseHandle(g_hContinueStartupEvent);
1919 g_hContinueStartupEvent = NULL;
1922 #endif // !FEATURE_PAL
1924 //---------------------------------------------------------------------------------------
1926 // Initialize Left-Side debugger object
1929 // S_OK on successs. May also throw.
1932 // This is called in the startup path.
1935 // Startup initializes any necessary debugger objects, including creating
1936 // and starting the Runtime Controller thread. Once the RC thread is started
1937 // and we return successfully, the Debugger object can expect to have its
1938 // event handlers called.
1940 //---------------------------------------------------------------------------------------
1941 HRESULT Debugger::Startup(void)
1953 _ASSERTE(g_pEEInterface != NULL);
1955 #if !defined(FEATURE_PAL)
1956 // This may block while an attach occurs.
1957 NotifyDebuggerOfStartup();
1958 #endif // !FEATURE_PAL
1960 DebuggerLockHolder dbgLockHolder(this);
1962 // Stubs in Stacktraces are always enabled.
1965 // We can get extra Interop-debugging test coverage by having some auxillary unmanaged
1966 // threads running and throwing debug events. Keep these stress procs separate so that
1967 // we can focus on certain problem areas.
1969 g_DbgShouldntUseDebugger = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DbgNoDebugger) != 0;
1972 // Creates random thread procs.
1973 DWORD dwRegVal = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DbgExtraThreads);
1979 for (i = 0; i < dwRegVal; i++)
1981 int iProc = GetRandomInt(NumItems(g_pStressProcs));
1982 LPTHREAD_START_ROUTINE pStartRoutine = g_pStressProcs[iProc];
1983 ::CreateThread(NULL, 0, pStartRoutine, NULL, 0, &dwId);
1984 LOG((LF_CORDB, LL_INFO1000, "Created random thread (%d) with tid=0x%x\n", i, dwId));
1988 dwRegVal = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DbgExtraThreadsIB);
1991 for (i = 0; i < dwRegVal; i++)
1993 ::CreateThread(NULL, 0, DbgInteropStressProc, NULL, 0, &dwId);
1994 LOG((LF_CORDB, LL_INFO1000, "Created extra thread (%d) with tid=0x%x\n", i, dwId));
1998 dwRegVal = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DbgExtraThreadsCantStop);
2001 for (i = 0; i < dwRegVal; i++)
2003 ::CreateThread(NULL, 0, DbgInteropCantStopStressProc, NULL, 0, &dwId);
2004 LOG((LF_CORDB, LL_INFO1000, "Created extra thread 'can't-stop' (%d) with tid=0x%x\n", i, dwId));
2008 dwRegVal = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DbgExtraThreadsOOB);
2011 for (i = 0; i < dwRegVal; i++)
2013 ::CreateThread(NULL, 0, DbgInteropOOBStressProc, NULL, 0, &dwId);
2014 LOG((LF_CORDB, LL_INFO1000, "Created extra thread OOB (%d) with tid=0x%x\n", i, dwId));
2020 PAL_InitializeDebug();
2021 #endif // FEATURE_PAL
2023 // Lazily initialize the interop-safe heap
2025 // Must be done before the RC thread is initialized.
2026 // @dbgtodo - In V2, LS was lazily initialized; but was eagerly pre-initialized if launched by debugger.
2027 // (This was for perf reasons). But we don't want Launch vs. Attach checks in the LS, so we now always
2028 // init. As we move more to OOP, this init will become cheaper.
2031 DebuggerController::Initialize();
2034 InitializeHijackFunctionAddress();
2036 // Also initialize the AppDomainEnumerationIPCBlock
2037 m_pAppDomainCB = new (nothrow) AppDomainEnumerationIPCBlock();
2039 if (m_pAppDomainCB == NULL)
2041 LOG((LF_CORDB, LL_INFO100, "D::S: Failed to get AppDomain IPC block from IPCManager.\n"));
2045 hr = InitAppDomainIPC();
2046 _ASSERTE(SUCCEEDED(hr)); // throws on error.
2048 // Allows the debugger (and profiler) diagnostics to be disabled so resources like
2049 // the named pipes and semaphores are not created.
2050 if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_EnableDiagnostics) == 0)
2055 // Create the runtime controller thread, a.k.a, the debug helper thread.
2056 // Don't use the interop-safe heap b/c we don't want to lazily create it.
2057 m_pRCThread = new DebuggerRCThread(this);
2058 _ASSERTE(m_pRCThread != NULL); // throws on oom
2059 TRACE_ALLOC(m_pRCThread);
2061 hr = m_pRCThread->Init();
2062 _ASSERTE(SUCCEEDED(hr)); // throws on error
2064 #if defined(FEATURE_DBGIPC_TRANSPORT_VM)
2065 // Create transport session and initialize it.
2066 g_pDbgTransport = new DbgTransportSession();
2067 hr = g_pDbgTransport->Init(m_pRCThread->GetDCB(), m_pAppDomainCB);
2070 ShutdownTransport();
2074 PAL_SetShutdownCallback(AbortTransport);
2075 #endif // FEATURE_PAL
2076 #endif // FEATURE_DBGIPC_TRANSPORT_VM
2078 RaiseStartupNotification();
2080 // See if we need to spin up the helper thread now, rather than later.
2081 DebuggerIPCControlBlock* pIPCControlBlock = m_pRCThread->GetDCB();
2082 (void)pIPCControlBlock; //prevent "unused variable" error from GCC
2084 _ASSERTE(pIPCControlBlock != NULL);
2085 _ASSERTE(!pIPCControlBlock->m_rightSideShouldCreateHelperThread);
2087 // Create the win32 thread for the helper and let it run free.
2088 hr = m_pRCThread->Start();
2090 // convert failure to exception as with old contract
2096 LOG((LF_CORDB, LL_EVERYTHING, "Start was successful\n"));
2099 #ifdef TEST_DATA_CONSISTENCY
2100 // if we have set the environment variable TestDataConsistency, run the data consistency test.
2101 // See code:DataTest::TestDataSafety for more information
2102 if ((g_pConfig != NULL) && (g_pConfig->TestDataConsistency() == true))
2105 dt.TestDataSafety();
2111 // Signal the debugger (via dbgshim) and wait until it is ready for us to
2112 // continue. This needs to be outside the lock and after the transport is
2114 if (PAL_NotifyRuntimeStarted())
2116 // The runtime was successfully launched and attached so mark it now
2117 // so no notifications are missed especially the initial module load
2118 // which would cause debuggers problems with reliable setting breakpoints
2119 // in startup code or Main.
2120 MarkDebuggerAttachedInternal();
2122 #endif // FEATURE_PAL
2124 // We don't bother changing this process's permission.
2125 // A managed debugger will have the SE_DEBUG permission which will allow it to open our process handle,
2126 // even if we're a guest account.
2131 //---------------------------------------------------------------------------------------
2132 // Finishes startup once we have a Thread object.
2135 // pThread - the current thread. Must be non-null
2138 // Most debugger initialization is done in code:Debugger.Startup,
2139 // However, debugger can't block on synchronization without a Thread object,
2140 // so sending IPC events must wait until after we have a thread object.
2141 //---------------------------------------------------------------------------------------
2142 HRESULT Debugger::StartupPhase2(Thread * pThread)
2154 // Must have a thread so that we can block
2155 _ASSERTE(pThread != NULL);
2157 DebuggerLockHolder dbgLockHolder(this);
2159 // @dbgtodo - This may need to change when we remove SetupSyncEvent...
2160 // If we're launching, then sync now so that the RS gets an early chance to dispatch the CreateProcess event.
2161 // This is especially important b/c certain portions of the ICorDebugAPI (like setting ngen flags) are only
2162 // valid during the CreateProcess callback in the launch case.
2163 // We need to send the callback early enough so those APIs can set the flags before they're actually used.
2164 // We also ensure the debugger is actually attached.
2165 if (SUCCEEDED(hr) && CORDebuggerAttached())
2167 StartCanaryThread();
2168 SendCreateProcess(&dbgLockHolder); // toggles lock
2171 // After returning from debugger startup we assume that the runtime might start using the NGEN flags to make
2172 // binding decisions. From now on the debugger can not influence NGEN binding policy
2173 // Use volatile store to guarantee make the value visible to the DAC (the store can be optimized out otherwise)
2174 VolatileStoreWithoutBarrier(&s_fCanChangeNgenFlags, FALSE);
2176 // Must release the lock (which would be done at the end of this method anyways) so that
2177 // the helper thread can do the jit-attach.
2178 dbgLockHolder.Release();
2182 // Give chance for stress harnesses to launch a managed debugger when a managed app starts up.
2183 // This lets us run a set of managed apps under a debugger.
2184 if (!CORDebuggerAttached())
2186 #define DBG_ATTACH_ON_STARTUP_ENV_VAR W("COMPlus_DbgAttachOnStartup")
2188 // We explicitly just check the env because we don't want a switch this invasive to be global.
2189 DWORD fAttach = WszGetEnvironmentVariable(DBG_ATTACH_ON_STARTUP_ENV_VAR, temp) > 0;
2193 // Remove the env var from our process so that the debugger we spin up won't inherit it.
2194 // Else, if the debugger is managed, we'll have an infinite recursion.
2195 BOOL fOk = WszSetEnvironmentVariable(DBG_ATTACH_ON_STARTUP_ENV_VAR, NULL);
2199 // We've already created the helper thread (which can service the attach request)
2200 // So just do a normal jit-attach now.
2202 SString szName(W("DebuggerStressStartup"));
2203 SString szDescription(W("MDA used for debugger-stress scenario. This is fired to trigger a jit-attach")
2204 W("to allow us to attach a debugger to any managed app that starts up.")
2205 W("This MDA is only fired when the 'DbgAttachOnStartup' COM+ knob/reg-key is set on checked builds."));
2206 SString szXML(W("<xml>See the description</xml>"));
2208 SendMDANotification(
2209 NULL, // NULL b/c we don't have a thread yet
2213 ((CorDebugMDAFlags) 0 ),
2214 TRUE // this will force the jit-attach
2226 //---------------------------------------------------------------------------------------
2228 // Public entrypoint into the debugger to force the lazy data to be initialized at a
2229 // controlled point in time. This is useful for those callers into the debugger (e.g.,
2230 // ETW rundown) that know they will need the lazy data initialized but cannot afford to
2231 // have it initialized unpredictably or inside a lock.
2233 // This may be called more than once, and will know to initialize the lazy data only
2237 void Debugger::InitializeLazyDataIfNecessary()
2249 DebuggerLockHolder lockHolder(this);
2250 LazyInit(); // throws
2255 /******************************************************************************
2256 Lazy initialize stuff once we know we are debugging.
2257 This reduces the startup cost in the non-debugging case.
2259 We can do this at a bunch of random strategic places.
2260 ******************************************************************************/
2262 HRESULT Debugger::LazyInitWrapper()
2269 PRECONDITION(ThisMaybeHelperThread());
2275 // Do lazy initialization now.
2278 LazyInit(); // throws on errors.
2282 Exception *_ex = GET_EXCEPTION();
2284 STRESS_LOG1(LF_CORDB, LL_ALWAYS, "LazyInit failed w/ hr:0x%08x\n", hr);
2286 EX_END_CATCH(SwallowAllExceptions);
2291 void Debugger::LazyInit()
2298 PRECONDITION(ThreadHoldsLock()); // ensure we're serialized, requires GC_NOTRIGGER
2300 PRECONDITION(ThisMaybeHelperThread());
2304 // Have knob that catches places where we lazy init.
2305 _ASSERTE(!g_DbgShouldntUseDebugger);
2307 // If we're already init, then bail.
2308 if (m_pLazyData != NULL)
2316 // Lazily create our heap.
2317 HRESULT hr = m_heap.Init(FALSE);
2320 hr = m_executableHeap.Init(TRUE);
2323 m_pLazyData = new (interopsafe) DebuggerLazyInit();
2324 _ASSERTE(m_pLazyData != NULL); // throws on oom.
2326 m_pLazyData->Init();
2330 HelperThreadFavor::HelperThreadFavor() :
2333 m_FavorReadEvent(NULL),
2334 m_FavorLock(CrstDebuggerFavorLock, CRST_DEFAULT),
2335 m_FavorAvailableEvent(NULL)
2339 void HelperThreadFavor::Init()
2346 PRECONDITION(ThisMaybeHelperThread());
2350 // Create events for managing favors.
2351 m_FavorReadEvent = CreateWin32EventOrThrow(NULL, kAutoResetEvent, FALSE);
2352 m_FavorAvailableEvent = CreateWin32EventOrThrow(NULL, kAutoResetEvent, FALSE);
2357 DebuggerLazyInit::DebuggerLazyInit() :
2358 m_pPendingEvals(NULL),
2360 // Major clean up needed for giving the right flag
2361 // There are cases where DebuggerDataLock is taken by managed thread and unmanaged trhead is also trying to take it.
2362 // It could cause deadlock if we toggle GC upon taking lock.
2363 // Unfortunately UNSAFE_COOPGC is not enough. There is a code path in Jit comipling that we are in GC Preemptive
2364 // enabled. workaround by orring the unsafe_anymode flag. But we really need to do proper clean up.
2366 // NOTE: If this ever gets fixed, you should replace CALLED_IN_DEBUGGERDATALOCK_HOLDER_SCOPE_MAY_GC_TRIGGERS_CONTRACT
2367 // with appropriate contracts at each site.
2369 m_DebuggerDataLock(CrstDebuggerJitInfo, (CrstFlags)(CRST_UNSAFE_ANYMODE | CRST_REENTRANCY | CRST_DEBUGGER_THREAD)),
2371 m_exAttachEvent(NULL),
2372 m_exUnmanagedAttachEvent(NULL),
2373 m_DebuggerHandlingCtrlC(NULL)
2377 void DebuggerLazyInit::Init()
2384 PRECONDITION(ThisMaybeHelperThread());
2388 // Caller ensures this isn't double-called.
2390 // This event is only used in the unmanaged attach case. We must mark this event handle as inheritable.
2391 // Otherwise, the unmanaged debugger won't be able to notify us.
2393 // Note that PAL currently doesn't support specifying the security attributes when creating an event, so
2394 // unmanaged attach for unhandled exceptions is broken on PAL.
2395 SECURITY_ATTRIBUTES* pSA = NULL;
2396 SECURITY_ATTRIBUTES secAttrib;
2397 secAttrib.nLength = sizeof(secAttrib);
2398 secAttrib.lpSecurityDescriptor = NULL;
2399 secAttrib.bInheritHandle = TRUE;
2403 // Create some synchronization events...
2404 // these events stay signaled all the time except when an attach is in progress
2405 m_exAttachEvent = CreateWin32EventOrThrow(NULL, kManualResetEvent, TRUE);
2406 m_exUnmanagedAttachEvent = CreateWin32EventOrThrow(pSA, kManualResetEvent, TRUE);
2408 m_CtrlCMutex = CreateWin32EventOrThrow(NULL, kAutoResetEvent, FALSE);
2409 m_DebuggerHandlingCtrlC = FALSE;
2411 // Let the helper thread lazy init stuff too.
2416 DebuggerLazyInit::~DebuggerLazyInit()
2419 USHORT cBlobs = m_pMemBlobs.Count();
2420 void **rgpBlobs = m_pMemBlobs.Table();
2422 for (int i = 0; i < cBlobs; i++)
2424 g_pDebugger->ReleaseRemoteBuffer(rgpBlobs[i], false);
2428 if (m_pPendingEvals)
2430 DeleteInteropSafe(m_pPendingEvals);
2431 m_pPendingEvals = NULL;
2434 if (m_CtrlCMutex != NULL)
2436 CloseHandle(m_CtrlCMutex);
2439 if (m_exAttachEvent != NULL)
2441 CloseHandle(m_exAttachEvent);
2444 if (m_exUnmanagedAttachEvent != NULL)
2446 CloseHandle(m_exUnmanagedAttachEvent);
2452 // RequestFavor gets the debugger helper thread to call a function. It's
2453 // typically called when the current thread can't call the function directly,
2454 // e.g, there isn't enough stack space.
2456 // RequestFavor can be called in stack-overflow scenarios and thus explicitly
2457 // avoids any lazy initialization.
2458 // It blocks until the favor callback completes.
2461 // fp - a non-null Favour callback function
2462 // pData - the parameter passed to the favor callback function. This can be any value.
2465 // S_OK if the function succeeds, else a failure HRESULT
2468 HRESULT Debugger::RequestFavor(FAVORCALLBACK fp, void * pData)
2475 PRECONDITION(fp != NULL);
2479 if (m_pRCThread == NULL ||
2480 m_pRCThread->GetRCThreadId() == GetCurrentThreadId())
2482 // Since favors are only used internally, we know that the helper should alway be up and ready
2483 // to handle them. Also, since favors can be used in low-stack scenarios, there's not any
2484 // extra initialization needed for them.
2485 _ASSERTE(!"Helper not initialized for favors.");
2486 return E_UNEXPECTED;
2489 m_pRCThread->DoFavor(fp, pData);
2493 /******************************************************************************
2494 // Called to set the interface that the Runtime exposes to us.
2495 ******************************************************************************/
2496 void Debugger::SetEEInterface(EEDebugInterface* i)
2498 LIMITED_METHOD_CONTRACT;
2502 // Implements DebugInterface API
2509 /******************************************************************************
2510 // Called to shut down the debugger. This stops the RC thread and cleans
2512 ******************************************************************************/
2513 void Debugger::StopDebugger(void)
2523 // Leak almost everything on process exit. The OS will clean it up anyways and trying to
2524 // clean it up ourselves is just one more place we may AV / deadlock.
2526 #if defined(FEATURE_DBGIPC_TRANSPORT_VM)
2527 ShutdownTransport();
2528 #endif // FEATURE_DBGIPC_TRANSPORT_VM
2530 // Ping the helper thread to exit. This will also prevent the helper from servicing new requests.
2531 if (m_pRCThread != NULL)
2533 m_pRCThread->AsyncStop();
2536 // Also clean up the AppDomain stuff since this is cross-process.
2537 TerminateAppDomainIPC ();
2540 // Tell the VM to clear out all references to the debugger before we start cleaning up,
2541 // so that nothing will reference (accidentally) through the partially cleaned up debugger.
2543 // NOTE: we cannot clear out g_pDebugger before the delete call because the
2544 // stuff in delete (particularly deleteinteropsafe) needs to look at it.
2546 g_pEEInterface->ClearAllDebugInterfaceReferences();
2551 /* ------------------------------------------------------------------------ *
2552 * JIT Interface routines
2553 * ------------------------------------------------------------------------ */
2556 /******************************************************************************
2558 ******************************************************************************/
2559 DebuggerMethodInfo *Debugger::CreateMethodInfo(Module *module, mdMethodDef md)
2567 PRECONDITION(HasDebuggerDataLock());
2572 // <TODO>@todo perf: creating these on the heap is slow. We should use a
2573 // pool and create them out of there since we never free them
2574 // until the AD is unloaded.</TODO>
2576 DebuggerMethodInfo *mi = new (interopsafe) DebuggerMethodInfo(module, md);
2577 _ASSERTE(mi != NULL); // throws on oom error
2581 LOG((LF_CORDB, LL_INFO100000, "D::CreateMethodInfo module=%p, token=0x%08x, info=%p\n",
2585 // Lock a mutex when changing the table.
2587 //@TODO : _ASSERTE(EnC);
2589 hr =InsertToMethodInfoList(mi);
2593 LOG((LF_CORDB, LL_EVERYTHING, "IAHOL Failed!!\n"));
2594 DeleteInteropSafe(mi);
2605 /******************************************************************************
2606 // void Debugger::JITComplete(): JITComplete is called by
2607 // the jit interface when the JIT completes, successfully or not.
2609 // MethodDesc* fd: MethodDesc of the code that's been JITted
2610 // BYTE* newAddress: The address of that the method begins at.
2611 // If newAddress is NULL then the JIT failed. Remember that this
2612 // gets called before the start address of the MethodDesc gets set,
2613 // and so methods like GetFunctionAddress & GetFunctionSize won't work.
2615 // <TODO>@Todo If we're passed 0 for the newAddress param, the jit has been
2616 // cancelled & should be undone.</TODO>
2617 ******************************************************************************/
2618 void Debugger::JITComplete(MethodDesc* fd, TADDR newAddress)
2625 PRECONDITION(!HasDebuggerDataLock());
2626 PRECONDITION(newAddress != NULL);
2627 CALLED_IN_DEBUGGERDATALOCK_HOLDER_SCOPE_MAY_GC_TRIGGERS_CONTRACT;
2631 LOG((LF_CORDB, LL_INFO100000, "D::JITComplete: md:0x%x (%s::%s), address:0x%x.\n",
2632 fd, fd->m_pszDebugClassName, fd->m_pszDebugMethodName,
2636 newAddress = newAddress|THUMB_CODE;
2640 // Can be called on managed thread only
2641 // This API Implements DebugInterface
2643 if (CORDebuggerAttached())
2645 // Populate the debugger's cache of DJIs. Normally we can do this lazily,
2646 // the only reason we do it here is b/c the MethodDesc is not yet officially marked as "jitted",
2647 // and so we can't lazily create it yet. Furthermore, the binding operations may need the DJIs.
2649 // This also gives the debugger a chance to know if new JMC methods are coming.
2650 DebuggerMethodInfo * dmi = GetOrCreateMethodInfo(fd->GetModule(), fd->GetMemberDef());
2655 BOOL jiWasCreated = FALSE;
2656 DebuggerJitInfo * ji = dmi->CreateInitAndAddJitInfo(fd, newAddress, &jiWasCreated);
2659 // we've already been notified about this code, no work remains.
2660 // The JIT is occasionally asked to generate code for the same
2661 // method on two threads. When this occurs both threads will
2662 // return the same code pointer and this callback is invoked
2664 LOG((LF_CORDB, LL_INFO1000000, "D::JITComplete: md:0x%x (%s::%s), address:0x%x. Already created\n",
2665 fd, fd->m_pszDebugClassName, fd->m_pszDebugMethodName,
2670 LOG((LF_CORDB, LL_INFO1000000, "D::JITComplete: md:0x%x (%s::%s), address:0x%x. Created ji:0x%x\n",
2671 fd, fd->m_pszDebugClassName, fd->m_pszDebugMethodName,
2674 // Bind any IL patches to the newly jitted native code.
2676 hr = MapAndBindFunctionPatches(ji, fd, (CORDB_ADDRESS_TYPE *)newAddress);
2677 _ASSERTE(SUCCEEDED(hr));
2680 LOG((LF_CORDB, LL_EVERYTHING, "JitComplete completed successfully\n"));
2686 /******************************************************************************
2687 // Get the number of fixed arguments to a function, i.e., the explicit args and the "this" pointer.
2688 // This does not include other implicit arguments or varargs. This is used to compute a variable ID
2689 // (see comment in CordbJITILFrame::ILVariableToNative for more detail)
2690 // fVarArg is not used when this is called by Debugger::GetAndSendJITInfo, thus it has a default value.
2691 // The return value is not used when this is called by Debugger::getVars.
2692 ******************************************************************************/
2693 SIZE_T Debugger::GetArgCount(MethodDesc *fd,BOOL *fVarArg /* = NULL */)
2703 // Create a MetaSig for the given method's sig. (Easier than
2704 // picking the sig apart ourselves.)
2705 PCCOR_SIGNATURE pCallSig;
2706 DWORD cbCallSigSize;
2708 fd->GetSig(&pCallSig, &cbCallSigSize);
2710 if (pCallSig == NULL)
2712 // Sig should only be null if the image is corrupted. (Even for lightweight-codegen)
2713 // We expect the jit+verifier to catch this, so that we never land here.
2714 // But just in case ...
2715 CONSISTENCY_CHECK_MSGF(false, ("Corrupted image, null sig.(%s::%s)", fd->m_pszDebugClassName, fd->m_pszDebugMethodName));
2719 MetaSig msig(pCallSig, cbCallSigSize, g_pEEInterface->MethodDescGetModule(fd), NULL, MetaSig::sigMember);
2721 // Get the arg count.
2722 UINT32 NumArguments = msig.NumFixedArgs();
2724 // Account for the 'this' argument.
2725 if (!(g_pEEInterface->MethodDescIsStatic(fd)))
2728 // Is this a VarArg's function?
2729 if (msig.IsVarArg() && fVarArg != NULL)
2734 return NumArguments;
2737 #endif // #ifndef DACCESS_COMPILE
2743 /******************************************************************************
2744 DebuggerJitInfo * Debugger::GetJitInfo(): GetJitInfo
2745 will return a pointer to a DebuggerJitInfo. If the DJI
2746 doesn't exist, or it does exist, but the method has actually
2747 been pitched (and the caller wants pitched methods filtered out),
2748 then we'll return NULL.
2750 Note: This will also create a DMI for if one does not exist for this DJI.
2752 MethodDesc* fd: MethodDesc for the method we're interested in.
2753 CORDB_ADDRESS_TYPE * pbAddr: Address within the code, to indicate which
2754 version we want. If this is NULL, then we want the
2755 head of the DebuggerJitInfo list, whether it's been
2757 ******************************************************************************/
2760 // Get a DJI from an address.
2761 DebuggerJitInfo *Debugger::GetJitInfoFromAddr(TADDR addr)
2763 WRAPPER_NO_CONTRACT;
2766 fd = g_pEEInterface->GetNativeCodeMethodDesc(addr);
2769 return GetJitInfo(fd, (const BYTE*) addr, NULL);
2772 // Get a DJI for a Native MD (MD for a native function).
2773 // In the EnC scenario, the MethodDesc refers to the most recent method.
2774 // This is very dangerous since there may be multiple versions alive at the same time.
2775 // This will give back the wrong DJI if we're lookikng for a stale method desc.
2776 // @todo - can a caller possibly use this correctly?
2777 DebuggerJitInfo *Debugger::GetLatestJitInfoFromMethodDesc(MethodDesc * pMethodDesc)
2779 WRAPPER_NO_CONTRACT;
2781 _ASSERTE(pMethodDesc != NULL);
2782 // We'd love to assert that we're jitted; but since this may be in the JitComplete
2783 // callback path, we can't be sure.
2785 return GetJitInfoWorker(pMethodDesc, NULL, NULL);
2789 DebuggerJitInfo *Debugger::GetJitInfo(MethodDesc *fd, const BYTE *pbAddr, DebuggerMethodInfo **pMethInfo )
2796 PRECONDITION(!g_pDebugger->HasDebuggerDataLock());
2800 // Address should be non-null and in range of MethodDesc. This lets us tell which EnC version.
2801 _ASSERTE(pbAddr != NULL);
2803 return GetJitInfoWorker(fd, pbAddr, pMethInfo);
2807 // Internal worker to GetJitInfo. Doesn't validate parameters.
2808 DebuggerJitInfo *Debugger::GetJitInfoWorker(MethodDesc *fd, const BYTE *pbAddr, DebuggerMethodInfo **pMethInfo)
2811 DebuggerMethodInfo *dmi = NULL;
2812 DebuggerJitInfo *dji = NULL;
2814 // If we have a null MethodDesc - we're not going to get a jit-info. Do this check once at the top
2815 // rather than littered throughout the rest of this function.
2818 LOG((LF_CORDB, LL_EVERYTHING, "Debugger::GetJitInfo, addr=0x%p - null fd - returning null\n", pbAddr));
2823 CONSISTENCY_CHECK_MSGF(!fd->IsWrapperStub(), ("Can't get Jit-info for wrapper MDesc,'%s'", fd->m_pszDebugMethodName));
2826 // The debugger doesn't track Lightweight-codegen methods b/c they have no metadata.
2827 if (fd->IsDynamicMethod())
2833 // initialize our out param
2839 LOG((LF_CORDB, LL_EVERYTHING, "Debugger::GetJitInfo called\n"));
2840 // CHECK_DJI_TABLE_DEBUGGER;
2842 // Find the DJI via the DMI
2844 // One way to improve the perf, both in terms of memory usage, number of allocations
2845 // and lookup speeds would be to have the first JitInfo inline in the MethodInfo
2846 // struct. After all, we never want to have a MethodInfo in the table without an
2847 // associated JitInfo, and this should bring us back very close to the old situation
2848 // in terms of perf. But correctness comes first, and perf later...
2850 dmi = GetOrCreateMethodInfo(fd->GetModule(), fd->GetMemberDef());
2854 // If we can't create the DMI, we won't be able to create the DJI.
2858 // TODO: Currently, this method does not handle code versioning properly (at least in some profiler scenarios), it may need
2859 // to take pbAddr into account and lazily create a DJI for that particular version of the method.
2861 // This may take the lock and lazily create an entry, so we do it up front.
2862 dji = dmi->GetLatestJitInfo(fd);
2865 DebuggerDataLockHolder debuggerDataLockHolder(this);
2867 // Note the call to GetLatestJitInfo() will lazily create the first DJI if we don't already have one.
2868 for (; dji != NULL; dji = dji->m_prevJitInfo)
2870 if (PTR_TO_TADDR(dji->m_fd) == PTR_HOST_TO_TADDR(fd))
2875 LOG((LF_CORDB, LL_INFO1000, "D::GJI: for md:0x%x (%s::%s), got dmi:0x%x.\n",
2876 fd, fd->m_pszDebugClassName, fd->m_pszDebugMethodName,
2882 // Log stuff - fd may be null; so we don't want to AV in the log.
2884 LOG((LF_CORDB, LL_INFO1000, "D::GJI: for md:0x%x (%s::%s), got dmi:0x%x, dji:0x%x, latest dji:0x%x, latest fd:0x%x, prev dji:0x%x\n",
2885 fd, fd->m_pszDebugClassName, fd->m_pszDebugMethodName,
2886 dmi, dji, (dmi ? dmi->GetLatestJitInfo_NoCreate() : 0),
2887 ((dmi && dmi->GetLatestJitInfo_NoCreate()) ? dmi->GetLatestJitInfo_NoCreate()->m_fd:0),
2888 (dji?dji->m_prevJitInfo:0)));
2890 if ((dji != NULL) && (pbAddr != NULL))
2892 dji = dji->GetJitInfoByAddress(pbAddr);
2894 // XXX Microsoft - dac doesn't support stub tracing
2895 // so this just results in not-impl exceptions.
2896 #ifndef DACCESS_COMPILE
2897 if (dji == NULL) //may have been given address of a thunk
2899 LOG((LF_CORDB,LL_INFO1000,"Couldn't find a DJI by address 0x%p, "
2900 "so it might be a stub or thunk\n", pbAddr));
2901 TraceDestination trace;
2903 g_pEEInterface->TraceStub((const BYTE *)pbAddr, &trace);
2905 if ((trace.GetTraceType() == TRACE_MANAGED) && (pbAddr != (const BYTE *)trace.GetAddress()))
2907 LOG((LF_CORDB,LL_INFO1000,"Address thru thunk"
2908 ": 0x%p\n", trace.GetAddress()));
2909 dji = GetJitInfo(fd, dac_cast<PTR_CBYTE>(trace.GetAddress()));
2914 _ASSERTE(trace.GetTraceType() != TRACE_UNJITTED_METHOD ||
2915 (fd == trace.GetMethodDesc()));
2916 LOG((LF_CORDB,LL_INFO1000,"Address not thunked - "
2917 "must be to unJITted method, or normal managed "
2918 "method lacking a DJI!\n"));
2922 #endif // #ifndef DACCESS_COMPILE
2930 // DebuggerDataLockHolder out of scope - release implied
2935 DebuggerMethodInfo *Debugger::GetOrCreateMethodInfo(Module *pModule, mdMethodDef token)
2946 DebuggerMethodInfo *info = NULL;
2948 // When dump debugging, we don't expect to have a lock,
2949 // nor would it be useful for anything.
2950 ALLOW_DATATARGET_MISSING_MEMORY(
2951 // In case we don't have already, take it now.
2952 DebuggerDataLockHolder debuggerDataLockHolder(this);
2955 if (m_pMethodInfos != NULL)
2957 info = m_pMethodInfos->GetMethodInfo(pModule, token);
2960 // dac checks ngen'ed image content first, so
2961 // if we didn't find information it doesn't exist.
2962 #ifndef DACCESS_COMPILE
2965 info = CreateMethodInfo(pModule, token);
2967 LOG((LF_CORDB, LL_INFO1000, "D::GOCMI: created DMI for mdToken:0x%x, dmi:0x%x\n",
2970 #endif // #ifndef DACCESS_COMPILE
2975 // This should only happen in an oom scenario. It would be nice to throw here.
2976 STRESS_LOG2(LF_CORDB, LL_EVERYTHING, "OOM - Failed to allocate DJI (0x%p, 0x%x)\n", pModule, token);
2979 // DebuggerDataLockHolder out of scope - release implied
2984 #ifndef DACCESS_COMPILE
2986 /******************************************************************************
2987 * GetILToNativeMapping returns a map from IL offsets to native
2988 * offsets for this code. An array of COR_PROF_IL_TO_NATIVE_MAP
2989 * structs will be returned, and some of the ilOffsets in this array
2990 * may be the values specified in CorDebugIlToNativeMappingTypes.
2991 ******************************************************************************/
2992 HRESULT Debugger::GetILToNativeMapping(PCODE pNativeCodeStartAddress, ULONG32 cMap,
2993 ULONG32 *pcMap, COR_DEBUG_IL_TO_NATIVE_MAP map[])
2999 GC_TRIGGERS_FROM_GETJITINFO;
3003 #ifdef PROFILING_SUPPORTED
3004 // At this point, we're pulling in the debugger.
3007 DebuggerLockHolder lockHolder(this);
3008 LazyInit(); // throws
3011 // Get the JIT info by functionId.
3013 // This function is unsafe to use during EnC because the MethodDesc doesn't tell
3014 // us which version is being requested.
3015 // However, this function is only used by the profiler, and you can't profile with EnC,
3016 // which means that getting the latest jit-info is still correct.
3017 #if defined(PROFILING_SUPPORTED)
3018 _ASSERTE(CORProfilerPresent());
3019 #endif // PROFILING_SUPPORTED
3021 MethodDesc *fd = g_pEEInterface->GetNativeCodeMethodDesc(pNativeCodeStartAddress);
3022 if (fd == NULL || fd->IsWrapperStub() || fd->IsDynamicMethod())
3027 DebuggerMethodInfo *pDMI = GetOrCreateMethodInfo(fd->GetModule(), fd->GetMemberDef());
3033 DebuggerJitInfo *pDJI = pDMI->FindOrCreateInitAndAddJitInfo(fd, pNativeCodeStartAddress);
3035 // Dunno what went wrong
3039 // If they gave us space to copy into...
3042 // Only copy as much as either they gave us or we have to copy.
3043 ULONG32 cpyCount = min(cMap, pDJI->GetSequenceMapCount());
3045 // Read the map right out of the Left Side.
3047 ExportILToNativeMap(cpyCount,
3049 pDJI->GetSequenceMap(),
3050 pDJI->m_sizeOfCode);
3053 // Return the true count of entries
3056 *pcMap = pDJI->GetSequenceMapCount();
3066 //---------------------------------------------------------------------------------------
3068 // This is morally the same as GetILToNativeMapping, except the output is in a different
3069 // format, to better facilitate sending the ETW ILToNativeMap events.
3072 // pMD - MethodDesc whose IL-to-native map will be returned
3073 // cMapMax - Max number of map entries to return. Although
3074 // this function handles the allocation of the returned
3075 // array, the caller still wants to limit how big this
3076 // can get, since ETW itself has limits on how big
3078 // pcMap - [out] Number of entries returned in each output parallel array (next
3080 // prguiILOffset - [out] Array of IL offsets. This function allocates, caller must free.
3081 // prguiNativeOffset - [out] Array of the starting native offsets that correspond
3082 // to each (*prguiILOffset)[i]. This function allocates,
3083 // caller must free.
3086 // HRESULT indicating success or failure.
3089 // * This function assumes lazy data has already been initialized (in order to
3090 // ensure that this doesn't trigger or take the large debugger mutex). So
3091 // callers must guarantee they call InitializeLazyDataIfNecessary() first.
3092 // * Either this function fails, and (*prguiILOffset) & (*prguiNativeOffset) will be
3093 // untouched OR this function succeeds and (*prguiILOffset) & (*prguiNativeOffset)
3094 // will both be non-NULL, set to the parallel arrays this function allocated.
3095 // * If this function returns success, then the caller must free (*prguiILOffset) and
3096 // (*prguiNativeOffset)
3097 // * (*prguiILOffset) and (*prguiNativeOffset) are parallel arrays, such that
3098 // (*prguiILOffset)[i] corresponds to (*prguiNativeOffset)[i] for each 0 <= i < *pcMap
3099 // * If EnC is enabled, this function will return the IL-to-native mapping for the latest
3100 // EnC version of the function. This may not be what the profiler wants, but EnC
3101 // + ETW-map events is not a typical combination, and this is consistent with
3102 // other ETW events like JittingStarted or MethodLoad, which also fire multiple
3103 // events for the same MethodDesc (each time it's EnC'd), with each event
3104 // corresponding to the most recent EnC version at the time.
3107 HRESULT Debugger::GetILToNativeMappingIntoArrays(
3108 MethodDesc * pMethodDesc,
3112 UINT ** prguiILOffset,
3113 UINT ** prguiNativeOffset)
3123 _ASSERTE(pcMap != NULL);
3124 _ASSERTE(prguiILOffset != NULL);
3125 _ASSERTE(prguiNativeOffset != NULL);
3127 // Any caller of GetILToNativeMappingIntoArrays had better call
3128 // InitializeLazyDataIfNecessary first!
3129 _ASSERTE(HasLazyData());
3131 // Get the JIT info by functionId.
3133 DebuggerJitInfo * pDJI = GetJitInfo(pMethodDesc, (const BYTE *)pCode);
3135 // Dunno what went wrong
3139 ULONG32 cMap = min(cMapMax, pDJI->GetSequenceMapCount());
3140 DebuggerILToNativeMap * rgMapInt = pDJI->GetSequenceMap();
3142 NewArrayHolder<UINT> rguiILOffsetTemp = new (nothrow) UINT[cMap];
3143 if (rguiILOffsetTemp == NULL)
3144 return E_OUTOFMEMORY;
3146 NewArrayHolder<UINT> rguiNativeOffsetTemp = new (nothrow) UINT[cMap];
3147 if (rguiNativeOffsetTemp == NULL)
3148 return E_OUTOFMEMORY;
3150 for (ULONG32 iMap=0; iMap < cMap; iMap++)
3152 rguiILOffsetTemp[iMap] = rgMapInt[iMap].ilOffset;
3153 rguiNativeOffsetTemp[iMap] = rgMapInt[iMap].nativeStartOffset;
3156 // Since cMap is the min of cMapMax (and something else) and cMapMax is a USHORT,
3157 // then cMap must fit in a USHORT as well
3158 _ASSERTE(FitsIn<USHORT>(cMap));
3159 *pcMap = (USHORT) cMap;
3160 *prguiILOffset = rguiILOffsetTemp.Extract();
3161 *prguiNativeOffset = rguiNativeOffsetTemp.Extract();
3169 #endif // #ifndef DACCESS_COMPILE
3171 /******************************************************************************
3173 ******************************************************************************/
3174 CodeRegionInfo CodeRegionInfo::GetCodeRegionInfo(DebuggerJitInfo *dji, MethodDesc *md, PTR_CORDB_ADDRESS_TYPE addr)
3186 if (dji && dji->m_addrOfCode)
3188 LOG((LF_CORDB, LL_EVERYTHING, "CRI::GCRI: simple case\n"));
3189 return dji->m_codeRegionInfo;
3193 LOG((LF_CORDB, LL_EVERYTHING, "CRI::GCRI: more complex case\n"));
3194 CodeRegionInfo codeRegionInfo;
3196 // Use method desc from dji if present
3197 if (dji && dji->m_fd)
3199 _ASSERTE(!md || md == dji->m_fd);
3206 addr = dac_cast<PTR_CORDB_ADDRESS_TYPE>(g_pEEInterface->GetFunctionAddress(md));
3211 (addr == dac_cast<PTR_CORDB_ADDRESS_TYPE>(g_pEEInterface->GetFunctionAddress(md))));
3216 PCODE pCode = PINSTRToPCODE(dac_cast<TADDR>(addr));
3217 codeRegionInfo.InitializeFromStartAddress(pCode);
3220 return codeRegionInfo;
3225 #ifndef DACCESS_COMPILE
3226 /******************************************************************************
3227 // Helper function for getBoundaries to get around AMD64 compiler and
3228 // contract holders with PAL_TRY in the same function.
3229 ******************************************************************************/
3230 void Debugger::getBoundariesHelper(MethodDesc * md,
3231 unsigned int *cILOffsets,
3235 // CANNOT ADD A CONTRACT HERE. Contract is in getBoundaries
3239 // Grab the JIT info struct for this method. Create if needed, as this
3240 // may be called before JITComplete.
3242 DebuggerMethodInfo *dmi = NULL;
3243 dmi = GetOrCreateMethodInfo(md->GetModule(), md->GetMemberDef());
3247 LOG((LF_CORDB,LL_INFO10000,"De::NGB: Got dmi 0x%x\n",dmi));
3249 #if defined(FEATURE_ISYM_READER)
3250 // Note: we need to make sure to enable preemptive GC here just in case we block in the symbol reader.
3251 GCX_PREEMP_EEINTERFACE();
3253 Module *pModule = md->GetModule();
3254 (void)pModule; //prevent "unused variable" error from GCC
3255 _ASSERTE(pModule != NULL);
3257 SafeComHolder<ISymUnmanagedReader> pReader(pModule->GetISymUnmanagedReader());
3259 // If we got a reader, use it.
3260 if (pReader != NULL)
3262 // Grab the sym reader's method.
3263 ISymUnmanagedMethod *pISymMethod;
3265 HRESULT hr = pReader->GetMethod(md->GetMemberDef(),
3272 // Get the count of sequence points.
3273 hr = pISymMethod->GetSequencePointCount(&n);
3274 _ASSERTE(SUCCEEDED(hr));
3277 LOG((LF_CORDB, LL_INFO100000,
3278 "D::NGB: Reader seq pt count is %d\n", n));
3287 _ASSERTE(p != NULL); // throws on oom errror
3289 hr = pISymMethod->GetSequencePoints(n, &dummy,
3290 p, NULL, NULL, NULL,
3292 _ASSERTE(SUCCEEDED(hr));
3293 _ASSERTE(dummy == n);
3295 *pILOffsets = (DWORD*)p;
3297 // Translate the IL offets based on an
3298 // instrumented IL map if one exists.
3299 if (dmi->HasInstrumentedILMap())
3301 InstrumentedILOffsetMapping mapping =
3302 dmi->GetRuntimeModule()->GetInstrumentedILOffsetMapping(dmi->m_token);
3304 for (SIZE_T i = 0; i < n; i++)
3306 int origOffset = *p;
3308 *p = dmi->TranslateToInstIL(
3311 bOriginalToInstrumented);
3313 LOG((LF_CORDB, LL_INFO100000,
3314 "D::NGB: 0x%04x (Real IL:0x%x)\n",
3323 for (SIZE_T i = 0; i < n; i++)
3325 LOG((LF_CORDB, LL_INFO100000,
3326 "D::NGB: 0x%04x \n", *p));
3335 pISymMethod->Release();
3342 LOG((LF_CORDB, LL_INFO10000,
3343 "De::NGB: failed to find method 0x%x in sym reader.\n",
3344 md->GetMemberDef()));
3351 LOG((LF_CORDB, LL_INFO100000, "D::NGB: no reader.\n"));
3354 #else // FEATURE_ISYM_READER
3355 // We don't have ISymUnmanagedReader. Pretend there are no sequence points.
3357 #endif // FEATURE_ISYM_READER
3360 LOG((LF_CORDB, LL_INFO100000, "D::NGB: cILOffsets=%d\n", *cILOffsets));
3365 /******************************************************************************
3366 // Use an ISymUnmanagedReader to get method sequence points.
3367 ******************************************************************************/
3368 void Debugger::getBoundaries(MethodDesc * md,
3369 unsigned int *cILOffsets,
3371 ICorDebugInfo::BoundaryTypes *implicitBoundaries)
3373 #ifndef DACCESS_COMPILE
3382 // May be here even when a debugger is not attached.
3385 // Implements DebugInterface API
3389 *implicitBoundaries = ICorDebugInfo::DEFAULT_BOUNDARIES;
3390 // If there has been an unrecoverable Left Side error, then we
3391 // just pretend that there are no boundaries.
3392 if (CORDBUnrecoverableError(this))
3397 // LCG methods have their own resolution scope that is seperate from a module
3398 // so they shouldn't have their symbols looked up in the module PDB. Right now
3399 // LCG methods have no symbols so we can just early out, but if they ever
3400 // had some symbols attached we would need a different way of getting to them.
3401 // See Dev10 issue 728519
3402 if(md->IsLCGMethod())
3407 // If JIT optimizations are allowed for the module this function
3408 // lives in, then don't grab specific boundaries from the symbol
3409 // store since any boundaries we give the JIT will be pretty much
3411 if (!CORDisableJITOptimizations(md->GetModule()->GetDebuggerInfoBits()))
3413 *implicitBoundaries = ICorDebugInfo::BoundaryTypes(ICorDebugInfo::STACK_EMPTY_BOUNDARIES |
3414 ICorDebugInfo::CALL_SITE_BOUNDARIES);
3419 Module* pModule = md->GetModule();
3420 DWORD dwBits = pModule->GetDebuggerInfoBits();
3421 if ((dwBits & DACF_IGNORE_PDBS) != 0)
3424 // If told to explicitly ignore PDBs for this function, then bail now.
3429 if( !pModule->IsSymbolReadingEnabled() )
3431 // Symbol reading is disabled for this module, so bail out early (for efficiency only)
3435 if (pModule == SystemDomain::SystemModule())
3437 // We don't look up PDBs for mscorlib. This is not quite right, but avoids
3438 // a bootstrapping problem. When an EXE loads, it has the option of setting
3439 // the COM apartment model to STA if we need to. It is important that no
3440 // other Coinitialize happens before this. Since loading the PDB reader uses
3441 // com we can not come first. However managed code IS run before the COM
3442 // apartment model is set, and thus we have a problem since this code is
3443 // called for when JITTing managed code. We avoid the problem by just
3444 // bailing for mscorlib.
3448 // At this point, we're pulling in the debugger.
3451 DebuggerLockHolder lockHolder(this);
3452 LazyInit(); // throws
3455 getBoundariesHelper(md, cILOffsets, pILOffsets);
3459 #endif // #ifndef DACCESS_COMPILE
3463 /******************************************************************************
3465 ******************************************************************************/
3466 void Debugger::getVars(MethodDesc * md, ULONG32 *cVars, ICorDebugInfo::ILVarInfo **vars,
3469 #ifndef DACCESS_COMPILE
3474 GC_TRIGGERS_FROM_GETJITINFO;
3475 PRECONDITION(!ThisIsHelperThreadWorker());
3481 // At worst return no information
3485 // Just tell the JIT to extend everything.
3486 // Note that if optimizations are enabled, the native compilers are
3487 // free to ingore *extendOthers
3488 *extendOthers = true;
3490 DWORD bits = md->GetModule()->GetDebuggerInfoBits();
3492 if (CORDBUnrecoverableError(this))
3495 if (CORDisableJITOptimizations(bits))
3496 // if (!CORDebuggerAllowJITOpts(bits))
3499 // @TODO: Do we really need this code since *extendOthers==true?
3502 // Is this a vararg function?
3503 BOOL fVarArg = false;
3504 GetArgCount(md, &fVarArg);
3508 COR_ILMETHOD *ilMethod = g_pEEInterface->MethodDescGetILHeader(md);
3512 // It is, so we need to tell the JIT to give us the
3514 ICorDebugInfo::ILVarInfo *p = new ICorDebugInfo::ILVarInfo[1];
3515 _ASSERTE(p != NULL); // throws on oom error
3517 COR_ILMETHOD_DECODER header(ilMethod);
3518 unsigned int ilCodeSize = header.GetCodeSize();
3521 p->endOffset = ilCodeSize;
3522 p->varNumber = (DWORD) ICorDebugInfo::VARARGS_HND_ILNUM;
3530 LOG((LF_CORDB, LL_INFO100000, "D::gV: cVars=%d, extendOthers=%d\n",
3531 *cVars, *extendOthers));
3537 #endif // #ifndef DACCESS_COMPILE
3541 #ifndef DACCESS_COMPILE
3543 // If we have a varargs function, we can't set the IP (we don't know how to pack/unpack the arguments), so if we
3544 // call SetIP with fCanSetIPOnly = true, we need to check for that.
3546 // input: nEntries - number of entries in varNativeInfo
3547 // varNativeInfo - array of entries describing the args and locals for the function
3548 // output: true iff the function has varargs
3549 BOOL Debugger::IsVarArgsFunction(unsigned int nEntries, PTR_NativeVarInfo varNativeInfo)
3551 for (unsigned int i = 0; i < nEntries; ++i)
3553 if (varNativeInfo[i].loc.vlType == ICorDebugInfo::VLT_FIXED_VA)
3561 // We want to keep the 'worst' HRESULT - if one has failed (..._E_...) & the
3562 // other hasn't, take the failing one. If they've both/neither failed, then
3563 // it doesn't matter which we take.
3564 // Note that this macro favors retaining the first argument
3565 #define WORST_HR(hr1,hr2) (FAILED(hr1)?hr1:hr2)
3566 /******************************************************************************
3568 ******************************************************************************/
3569 HRESULT Debugger::SetIP( bool fCanSetIPOnly, Thread *thread,Module *module,
3570 mdMethodDef mdMeth, DebuggerJitInfo* dji,
3571 SIZE_T offsetILTo, BOOL fIsIL)
3578 PRECONDITION(CheckPointer(thread));
3579 PRECONDITION(CheckPointer(module));
3580 PRECONDITION(mdMeth != mdMethodDefNil);
3585 static ConfigDWORD breakOnSetIP;
3586 if (breakOnSetIP.val(CLRConfig::INTERNAL_DbgBreakOnSetIP)) _ASSERTE(!"DbgBreakOnSetIP");
3590 HRESULT hrAdvise = S_OK;
3593 CorDebugMappingResult map;
3596 ControllerStackInfo csi;
3601 PCODE pbDest = NULL;
3602 BYTE *pbBase = NULL;
3603 CONTEXT *pCtx = NULL;
3605 SIZE_T *rgVal1 = NULL;
3606 SIZE_T *rgVal2 = NULL;
3609 LOG((LF_CORDB, LL_INFO1000, "D::SIP: In SetIP ==> fCanSetIPOnly:0x%x <==!\n", fCanSetIPOnly));
3611 if (ReJitManager::IsReJITEnabled())
3613 return CORDBG_E_SET_IP_IMPOSSIBLE;
3616 pCtx = GetManagedStoppedCtx(thread);
3618 // If we can't get a context, then we can't possibly be a in a good place
3622 return CORDBG_S_BAD_START_SEQUENCE_POINT;
3625 // Implicit Caveat: We need to be the active frame.
3626 // We can safely take a stack trace because the thread is synchronized.
3627 StackTraceTicket ticket(thread);
3628 csi.GetStackInfo(ticket, thread, LEAF_MOST_FRAME, NULL);
3630 ULONG offsetNatFrom = csi.m_activeFrame.relOffset;
3631 #if defined(WIN64EXCEPTIONS)
3632 if (csi.m_activeFrame.IsFuncletFrame())
3634 offsetNatFrom = (ULONG)((SIZE_T)GetControlPC(&(csi.m_activeFrame.registers)) -
3635 (SIZE_T)(dji->m_addrOfCode));
3637 #endif // WIN64EXCEPTIONS
3639 _ASSERTE(dji != NULL);
3641 // On WIN64 platforms, it's important to use the total size of the
3642 // parent method and the funclets below (i.e. m_sizeOfCode). Don't use
3643 // the size of the individual funclets or the parent method.
3644 pbBase = (BYTE*)CORDB_ADDRESS_TO_PTR(dji->m_addrOfCode);
3645 dwSize = (DWORD)dji->m_sizeOfCode;
3646 #if defined(WIN64EXCEPTIONS)
3647 // Currently, method offsets are not bigger than 4 bytes even on WIN64.
3648 // Assert that it is so here.
3649 _ASSERTE((SIZE_T)dwSize == dji->m_sizeOfCode);
3650 #endif // WIN64EXCEPTIONS
3653 // Create our structure for analyzing this.
3654 // <TODO>@PERF: optimize - hold on to this so we don't rebuild it for both
3655 // CanSetIP & SetIP.</TODO>
3657 const DWORD * rgFunclet = NULL;
3658 #if defined(WIN64EXCEPTIONS)
3659 cFunclet = dji->GetFuncletCount();
3660 rgFunclet = dji->m_rgFunclet;
3661 #endif // WIN64EXCEPTIONS
3663 EHRangeTree* pEHRT = new (nothrow) EHRangeTree(csi.m_activeFrame.pIJM,
3664 csi.m_activeFrame.MethodToken,
3669 // To maintain the current semantics, we will check the following right before SetIPFromSrcToDst() is called
3670 // (instead of checking them now):
3672 // 2) FAILED(pEHRT->m_hrInit)
3676 LOG((LF_CORDB, LL_INFO1000, "D::SIP:Got version info fine\n"));
3678 // Caveat: we need to start from a sequence point
3679 offsetILFrom = dji->MapNativeOffsetToIL(offsetNatFrom,
3680 &map, &whichIgnore);
3681 if ( !(map & MAPPING_EXACT) )
3683 LOG((LF_CORDB, LL_INFO1000, "D::SIP:Starting native offset is bad!\n"));
3684 hrAdvise = WORST_HR(hrAdvise, CORDBG_S_BAD_START_SEQUENCE_POINT);
3687 { // exact IL mapping
3689 if (!(dji->GetSrcTypeFromILOffset(offsetILFrom) & ICorDebugInfo::STACK_EMPTY))
3691 LOG((LF_CORDB, LL_INFO1000, "D::SIP:Starting offset isn't stack empty!\n"));
3692 hrAdvise = WORST_HR(hrAdvise, CORDBG_S_BAD_START_SEQUENCE_POINT);
3696 // Caveat: we need to go to a sequence point
3699 #if defined(WIN64EXCEPTIONS)
3700 int funcletIndexFrom = dji->GetFuncletIndex((CORDB_ADDRESS)offsetNatFrom, DebuggerJitInfo::GFIM_BYOFFSET);
3701 offsetNatTo = dji->MapILOffsetToNativeForSetIP(offsetILTo, funcletIndexFrom, pEHRT, &exact);
3702 #else // WIN64EXCEPTIONS
3703 DebuggerJitInfo::ILToNativeOffsetIterator it;
3704 dji->InitILToNativeOffsetIterator(it, offsetILTo);
3705 offsetNatTo = it.CurrentAssertOnlyOne(&exact);
3706 #endif // WIN64EXCEPTIONS
3710 LOG((LF_CORDB, LL_INFO1000, "D::SIP:Dest (via IL offset) is bad!\n"));
3711 hrAdvise = WORST_HR(hrAdvise, CORDBG_S_BAD_END_SEQUENCE_POINT);
3716 offsetNatTo = offsetILTo;
3717 LOG((LF_CORDB, LL_INFO1000, "D::SIP:Dest of 0x%p (via native "
3718 "offset) is fine!\n", offsetNatTo));
3721 CorDebugMappingResult mapping;
3723 offsetILTo = dji->MapNativeOffsetToIL(offsetNatTo, &mapping, &which);
3725 // We only want to perhaps return CORDBG_S_BAD_END_SEQUENCE_POINT if
3726 // we're not already returning CORDBG_S_BAD_START_SEQUENCE_POINT.
3727 if (hr != CORDBG_S_BAD_START_SEQUENCE_POINT)
3729 if ( !(mapping & MAPPING_EXACT) )
3731 LOG((LF_CORDB, LL_INFO1000, "D::SIP:Ending native offset is bad!\n"));
3732 hrAdvise = WORST_HR(hrAdvise, CORDBG_S_BAD_END_SEQUENCE_POINT);
3737 // All duplicate sequence points (ones with the same IL offset) should have the same SourceTypes.
3739 if (!(dji->GetSrcTypeFromILOffset(offsetILTo) & ICorDebugInfo::STACK_EMPTY))
3741 LOG((LF_CORDB, LL_INFO1000, "D::SIP:Ending offset isn't a sequence"
3742 " point, or not stack empty!\n"));
3743 hrAdvise = WORST_HR(hrAdvise, CORDBG_S_BAD_END_SEQUENCE_POINT);
3748 // Once we finally have a native offset, it had better be in range.
3749 if (offsetNatTo >= dwSize)
3751 LOG((LF_CORDB, LL_INFO1000, "D::SIP:Code out of range! offsetNatTo = 0x%x, dwSize=0x%x\n", offsetNatTo, dwSize));
3752 hrAdvise = E_INVALIDARG;
3756 pbDest = CodeRegionInfo::GetCodeRegionInfo(dji).OffsetToAddress(offsetNatTo);
3757 LOG((LF_CORDB, LL_INFO1000, "D::SIP:Dest is 0x%p\n", pbDest));
3759 // Don't allow SetIP if the source or target is cold (SetIPFromSrcToDst does not
3760 // correctly handle this case).
3761 if (!CodeRegionInfo::GetCodeRegionInfo(dji).IsOffsetHot(offsetNatTo) ||
3762 !CodeRegionInfo::GetCodeRegionInfo(dji).IsOffsetHot(offsetNatFrom))
3764 hrAdvise = WORST_HR(hrAdvise, CORDBG_E_SET_IP_IMPOSSIBLE);
3771 hr = ShuffleVariablesGet(dji,
3777 LOG((LF_CORDB|LF_ENC,
3779 "D::SIP: rgVal1 0x%X, rgVal2 0x%X\n",
3785 // This will only fail fatally, so exit.
3786 hrAdvise = WORST_HR(hrAdvise, hr);
3790 else // fCanSetIPOnly
3792 if (IsVarArgsFunction(dji->GetVarNativeInfoCount(), dji->GetVarNativeInfo()))
3794 hrAdvise = E_INVALIDARG;
3804 else if (FAILED(pEHRT->m_hrInit))
3806 hr = pEHRT->m_hrInit;
3811 // This is a known, ok, violation. END_EXCEPTION_GLUE has a call to GetThrowable in it, but
3812 // we will never hit it because we are passing in NULL below. This is to satisfy the static
3813 // contract analyzer.
3815 CONTRACT_VIOLATION(GCViolation);
3819 hr =g_pEEInterface->SetIPFromSrcToDst(thread,
3824 &(csi.m_activeFrame.registers),
3832 EX_END_CATCH(SwallowAllExceptions);
3836 // Get the return code, if any
3839 hrAdvise = WORST_HR(hrAdvise, hr);
3843 // If we really want to do this, we'll have to put the
3844 // variables into their new locations.
3845 if (!fCanSetIPOnly && !FAILED(hrAdvise))
3847 // TODO: We should zero out any registers which have now become live GC roots,
3848 // but which aren't tracked variables (i.e. they are JIT temporaries). Such registers may
3849 // have garbage left over in them, and we don't want the GC to try and dereference them
3850 // as object references. However, we can't easily tell here which of the callee-saved regs
3851 // are used in this method and therefore safe to clear.
3854 hr = ShuffleVariablesSet(dji,
3864 hrAdvise = WORST_HR(hrAdvise, hr);
3868 _ASSERTE(pbDest != NULL);
3870 ::SetIP(pCtx, pbDest);
3872 LOG((LF_CORDB, LL_INFO1000, "D::SIP:Set IP to be 0x%p\n", GetIP(pCtx)));
3879 DeleteInteropSafe(rgVal1);
3884 DeleteInteropSafe(rgVal2);
3892 LOG((LF_CORDB, LL_INFO1000, "D::SIP:Returning 0x%x\n", hr));
3896 #include "nativevaraccessors.h"
3898 /******************************************************************************
3900 ******************************************************************************/
3902 HRESULT Debugger::ShuffleVariablesGet(DebuggerJitInfo *dji,
3914 PRECONDITION(CheckPointer(dji));
3915 PRECONDITION(CheckPointer(pCtx));
3916 PRECONDITION(CheckPointer(prgVal1));
3917 PRECONDITION(CheckPointer(prgVal2));
3918 PRECONDITION(dji->m_sizeOfCode >= offsetFrom);
3922 LONG cVariables = 0;
3926 // Find the largest variable number
3928 for (i = 0; i < dji->GetVarNativeInfoCount(); i++)
3930 if ((LONG)(dji->GetVarNativeInfo()[i].varNumber) > cVariables)
3932 cVariables = (LONG)(dji->GetVarNativeInfo()[i].varNumber);
3939 // cVariables is a zero-based count of the number of variables. Increment it.
3943 SIZE_T *rgVal1 = new (interopsafe, nothrow) SIZE_T[cVariables + unsigned(-ICorDebugInfo::UNKNOWN_ILNUM)];
3945 SIZE_T *rgVal2 = NULL;
3953 rgVal2 = new (interopsafe, nothrow) SIZE_T[cVariables + unsigned(-ICorDebugInfo::UNKNOWN_ILNUM)];
3961 memset(rgVal1, 0, sizeof(SIZE_T) * (cVariables + unsigned(-ICorDebugInfo::UNKNOWN_ILNUM)));
3962 memset(rgVal2, 0, sizeof(SIZE_T) * (cVariables + unsigned(-ICorDebugInfo::UNKNOWN_ILNUM)));
3964 LOG((LF_CORDB|LF_ENC,
3966 "D::SVG cVariables %d, hiddens %d, rgVal1 0x%X, rgVal2 0x%X\n",
3968 unsigned(-ICorDebugInfo::UNKNOWN_ILNUM),
3972 GetVariablesFromOffset(dji->m_fd,
3973 dji->GetVarNativeInfoCount(),
3974 dji->GetVarNativeInfo(),
3979 cVariables + unsigned(-ICorDebugInfo::UNKNOWN_ILNUM),
3986 (*prgVal1) = rgVal1;
3987 (*prgVal2) = rgVal2;
3991 LOG((LF_CORDB, LL_INFO100, "D::SVG: something went wrong hr=0x%x!", hr));
4006 /******************************************************************************
4008 ******************************************************************************/
4009 HRESULT Debugger::ShuffleVariablesSet(DebuggerJitInfo *dji,
4021 PRECONDITION(CheckPointer(dji));
4022 PRECONDITION(CheckPointer(pCtx));
4023 PRECONDITION(CheckPointer(prgVal1));
4024 PRECONDITION(CheckPointer(prgVal2));
4025 PRECONDITION(dji->m_sizeOfCode >= offsetTo);
4029 LOG((LF_CORDB|LF_ENC,
4031 "D::SVS: rgVal1 0x%X, rgVal2 0x%X\n",
4035 HRESULT hr = SetVariablesAtOffset(dji->m_fd,
4036 dji->GetVarNativeInfoCount(),
4037 dji->GetVarNativeInfo(),
4044 LOG((LF_CORDB|LF_ENC,
4046 "D::SVS deleting rgVal1 0x%X, rgVal2 0x%X\n",
4050 DeleteInteropSafe(*prgVal1);
4052 DeleteInteropSafe(*prgVal2);
4058 // This class is used by Get and SetVariablesFromOffsets to manage a frameHelper
4059 // list for the arguments and locals corresponding to each varNativeInfo. The first
4060 // four are hidden args, but the remainder will all have a corresponding entry
4061 // in the argument or local signature list.
4063 // The structure of the array varNativeInfo contains home information for each variable
4064 // at various points in the function. Thus, you have to search for the proper native offset
4065 // (IP) in the varNativeInfo, and then find the correct varNumber in that native offset to
4066 // find the correct home information.
4068 // Important to note is that the JIT has hidden args that have varNumbers that are negative.
4069 // Thus we cannot use varNumber as a strict index into our holder arrays, and instead shift
4070 // indexes before indexing into our holder arrays.
4072 // The hidden args are a fixed-sized array given by the value of 0-UNKNOWN_ILNUM. These are used
4073 // to pass cookies about the arguments (var args, generics, retarg buffer etc.) to the function.
4074 // The real arguments and locals are as one would expect.
4077 class GetSetFrameHelper
4080 GetSetFrameHelper();
4081 ~GetSetFrameHelper();
4083 HRESULT Init(MethodDesc* pMD);
4085 bool GetValueClassSizeOfVar(int varNum, ICorDebugInfo::VarLocType varType, SIZE_T* pSize);
4086 int ShiftIndexForHiddens(int varNum);
4091 CorElementType* m_rgElemType;
4093 ULONG m_numTotalVars;
4095 SIZE_T GetValueClassSize(MetaSig* pSig);
4097 static SIZE_T GetSizeOfElement(CorElementType cet);
4101 // GetSetFrameHelper::GetSetFrameHelper()
4103 // This is the constructor. It just initailizes all member variables.
4107 // return value: none
4109 GetSetFrameHelper::GetSetFrameHelper() : m_pMD(NULL), m_rgSize(NULL), m_rgElemType(NULL),
4110 m_numArgs(0), m_numTotalVars(0)
4112 LIMITED_METHOD_CONTRACT;
4116 // GetSetFrameHelper::Init()
4118 // This method extracts the element type and the size of the arguments and locals of the method we are doing
4119 // the SetIP on and stores this information in instance variables.
4121 // parameters: pMD - MethodDesc of the method we are doing the SetIP on
4123 // return value: S_OK or E_OUTOFMEMORY
4126 GetSetFrameHelper::Init(MethodDesc *pMD)
4134 PRECONDITION(CheckPointer(pMD));
4139 COR_ILMETHOD* pILHeader = NULL;
4141 MetaSig *pLocSig = NULL;
4142 MetaSig *pArgSig = NULL;
4145 m_rgElemType = NULL;
4147 // Initialize decoderOldIL before checking the method argument signature.
4150 pILHeader = pMD->GetILHeader();
4152 EX_CATCH_HRESULT(hr);
4156 COR_ILMETHOD_DECODER decoderOldIL(pILHeader);
4157 mdSignature mdLocalSig = (decoderOldIL.GetLocalVarSigTok()) ? (decoderOldIL.GetLocalVarSigTok()):
4160 PCCOR_SIGNATURE pCallSig;
4161 DWORD cbCallSigSize;
4163 pMD->GetSig(&pCallSig, &cbCallSigSize);
4165 if (pCallSig != NULL)
4167 // Yes, we do need to pass in the text because this might be generic function!
4168 SigTypeContext tmpContext(pMD);
4170 pArgSig = new (interopsafe, nothrow) MetaSig(pCallSig,
4174 MetaSig::sigMember);
4176 if (pArgSig == NULL)
4178 IfFailGo(E_OUTOFMEMORY);
4181 m_numArgs = pArgSig->NumFixedArgs();
4183 if (pArgSig->HasThis())
4189 // What should we do in this case?
4192 if (argSig.IsVarArg())
4197 // allocation of pArgSig succeeded
4199 PCCOR_SIGNATURE pLocalSig;
4201 if (mdLocalSig != mdSignatureNil)
4203 IfFailGo(pMD->GetModule()->GetMDImport()->GetSigFromToken(mdLocalSig, &cbSig, &pLocalSig));
4205 if (pLocalSig != NULL)
4207 SigTypeContext tmpContext(pMD);
4208 pLocSig = new (interopsafe, nothrow) MetaSig(pLocalSig,
4212 MetaSig::sigLocalVars);
4214 if (pLocSig == NULL)
4216 IfFailGo(E_OUTOFMEMORY);
4220 // allocation of pLocalSig succeeded
4221 m_numTotalVars = m_numArgs + (pLocSig != NULL ? pLocSig->NumFixedArgs() : 0);
4223 if (m_numTotalVars > 0)
4225 m_rgSize = new (interopsafe, nothrow) SIZE_T[m_numTotalVars];
4226 m_rgElemType = new (interopsafe, nothrow) CorElementType[m_numTotalVars];
4228 if ((m_rgSize == NULL) || (m_rgElemType == NULL))
4230 IfFailGo(E_OUTOFMEMORY);
4234 // allocation of m_rgSize and m_rgElemType succeeded
4235 for (ULONG i = 0; i < m_numTotalVars; i++)
4237 // Choose the correct signature to walk.
4238 MetaSig *pCur = NULL;
4248 // The "this" argument isn't stored in the signature, so we have to
4249 // check for it manually.
4250 if (i == 0 && pCur->HasThis())
4252 _ASSERTE(pCur == pArgSig);
4254 m_rgElemType[i] = ELEMENT_TYPE_CLASS;
4255 m_rgSize[i] = sizeof(SIZE_T);
4259 m_rgElemType[i] = pCur->NextArg();
4261 if (m_rgElemType[i] == ELEMENT_TYPE_VALUETYPE)
4263 m_rgSize[i] = GetValueClassSize(pCur);
4267 m_rgSize[i] = GetSetFrameHelper::GetSizeOfElement(m_rgElemType[i]);
4270 LOG((LF_CORDB, LL_INFO10000, "GSFH::I: var 0x%x is of type %x, size:0x%x\n",
4271 i, m_rgElemType[i], m_rgSize[i]));
4274 } // allocation of m_rgSize and m_rgElemType succeeded
4275 } // if there are variables to take care of
4279 if (pArgSig != NULL)
4281 DeleteInteropSafe(pArgSig);
4284 if (pLocSig != NULL)
4286 DeleteInteropSafe(pLocSig);
4291 if (m_rgSize != NULL)
4293 DeleteInteropSafe(m_rgSize);
4296 if (m_rgElemType != NULL)
4298 DeleteInteropSafe((int*)m_rgElemType);
4303 } // GetSetFrameHelper::Init
4306 // GetSetFrameHelper::~GetSetFrameHelper()
4308 // This is the destructor. It checks the two arrays we have allocated and frees the memory accordingly.
4312 // return value: none
4314 GetSetFrameHelper::~GetSetFrameHelper()
4327 DeleteInteropSafe(m_rgSize);
4332 DeleteInteropSafe((int*)m_rgElemType);
4337 // GetSetFrameHelper::GetSizeOfElement()
4339 // Given a CorElementType, this function returns the size of this type.
4340 // Note that this function doesn't handle ELEMENT_TYPE_VALUETYPE. Use GetValueClassSize() instead.
4342 // parameters: cet - the CorElementType of the argument/local we are dealing with
4344 // return value: the size of the argument/local
4347 SIZE_T GetSetFrameHelper::GetSizeOfElement(CorElementType cet)
4355 PRECONDITION(cet != ELEMENT_TYPE_VALUETYPE);
4359 if (!CorIsPrimitiveType(cet))
4361 return sizeof(SIZE_T);
4367 case ELEMENT_TYPE_I8:
4368 case ELEMENT_TYPE_U8:
4370 case ELEMENT_TYPE_I:
4371 case ELEMENT_TYPE_U:
4373 case ELEMENT_TYPE_R8:
4376 case ELEMENT_TYPE_I4:
4377 case ELEMENT_TYPE_U4:
4378 #if !defined(_WIN64)
4379 case ELEMENT_TYPE_I:
4380 case ELEMENT_TYPE_U:
4382 case ELEMENT_TYPE_R4:
4385 case ELEMENT_TYPE_I2:
4386 case ELEMENT_TYPE_U2:
4387 case ELEMENT_TYPE_CHAR:
4390 case ELEMENT_TYPE_I1:
4391 case ELEMENT_TYPE_U1:
4392 case ELEMENT_TYPE_BOOLEAN:
4395 case ELEMENT_TYPE_VOID:
4396 case ELEMENT_TYPE_END:
4397 _ASSERTE(!"debugger.cpp - Check this code path\n");
4400 case ELEMENT_TYPE_STRING:
4401 return sizeof(SIZE_T);
4404 _ASSERTE(!"debugger.cpp - Check this code path\n");
4405 return sizeof(SIZE_T);
4411 // GetSetFrameHelper::GetValueClassSize()
4413 // Given a MetaSig pointer to the signature of a value type, this function returns its size.
4415 // parameters: pSig - MetaSig pointer to the signature of a value type
4417 // return value: the size of this value type
4419 SIZE_T GetSetFrameHelper::GetValueClassSize(MetaSig* pSig)
4426 PRECONDITION(CheckPointer(pSig));
4430 // We need to determine the number of bytes for this value-type.
4431 SigPointer sp = pSig->GetArgProps();
4433 TypeHandle vcType = TypeHandle();
4435 // Lookup operations run the class loader in non-load mode.
4436 ENABLE_FORBID_GC_LOADER_USE_IN_THIS_SCOPE();
4438 // This will return Null if type is not restored
4439 // @todo : is this what we want?
4440 SigTypeContext typeContext(m_pMD);
4441 vcType = sp.GetTypeHandleThrowing(m_pMD->GetModule(),
4443 // == FailIfNotLoaded
4444 ClassLoader::DontLoadTypes);
4446 // We need to know the size of the class in bytes. This means:
4447 // - we need a specific instantiation (since that affects size)
4448 // - but we don't care if it's shared (since it will be the same size either way)
4449 _ASSERTE(!vcType.IsNull() && vcType.IsValueType());
4451 return (vcType.GetMethodTable()->GetAlignedNumInstanceFieldBytes());
4455 // GetSetFrameHelper::GetValueClassSizeOfVar()
4457 // This method retrieves the size of the variable saved in the array m_rgSize. Also, it returns true
4458 // if the variable is a value type.
4460 // parameters: varNum - the variable number (arguments come before locals)
4461 // varType - the type of variable home
4462 // pSize - [out] the size
4464 // return value: whether this variable is a value type
4466 bool GetSetFrameHelper::GetValueClassSizeOfVar(int varNum, ICorDebugInfo::VarLocType varType, SIZE_T* pSize)
4474 PRECONDITION(varType != ICorDebugInfo::VLT_FIXED_VA);
4475 PRECONDITION(pSize != NULL);
4479 // preliminary checking
4482 // Make sure this is one of the secret parameters (e.g. VASigCookie, generics context, etc.).
4483 _ASSERTE(varNum > (int)ICorDebugInfo::MAX_ILNUM);
4485 *pSize = sizeof(LPVOID);
4489 // This check is only safe after we make sure that varNum is not negative.
4490 if ((UINT)varNum >= m_numTotalVars)
4492 _ASSERTE(!"invalid variable index encountered during setip");
4497 CorElementType cet = m_rgElemType[varNum];
4498 *pSize = m_rgSize[varNum];
4500 if ((cet != ELEMENT_TYPE_VALUETYPE) ||
4501 (varType == ICorDebugInfo::VLT_REG) ||
4502 (varType == ICorDebugInfo::VLT_REG_REG) ||
4503 (varType == ICorDebugInfo::VLT_REG_STK) ||
4504 (varType == ICorDebugInfo::VLT_STK_REG))
4514 int GetSetFrameHelper::ShiftIndexForHiddens(int varNum)
4516 LIMITED_METHOD_CONTRACT;
4519 // Need to shift them up so are appropriate index for rgVal arrays
4521 return varNum - ICorDebugInfo::UNKNOWN_ILNUM;
4524 // Helper method pair to grab all, then set all, variables at a given
4525 // point in a routine.
4526 // NOTE: GetVariablesFromOffset and SetVariablesAtOffset are
4527 // very similar - modifying one will probably need to be reflected in the other...
4528 // rgVal1 and rgVal2 are preallocated by callers with estimated size.
4529 // We pass in the size of the allocation in rRgValeSize. The safe index will be rgVal1[0..uRgValSize - 1]
4531 HRESULT Debugger::GetVariablesFromOffset(MethodDesc *pMD,
4532 UINT varNativeInfoCount,
4533 ICorDebugInfo::NativeVarInfo *varNativeInfo,
4538 UINT uRgValSize, // number of elements of the preallocated rgVal1 and rgVal2
4541 // @todo - convert this to throwing w/ holders. It will be cleaner.
4547 PRECONDITION(CheckPointer(rgpVCs));
4548 PRECONDITION(CheckPointer(pCtx));
4549 PRECONDITION(varNativeInfoCount == 0 || CheckPointer(varNativeInfo));
4550 PRECONDITION(varNativeInfoCount == 0 || CheckPointer(rgVal1));
4551 PRECONDITION(varNativeInfoCount == 0 || CheckPointer(rgVal2));
4552 // This may or may not be called on the helper thread.
4557 // if there are no locals, well, we are done!
4559 if (varNativeInfoCount == 0)
4564 memset( rgVal1, 0, sizeof(SIZE_T)*uRgValSize);
4565 memset( rgVal2, 0, sizeof(SIZE_T)*uRgValSize);
4567 LOG((LF_CORDB|LF_ENC, LL_INFO10000, "D::GVFO: %s::%s, infoCount:0x%x, from:0x%p\n",
4568 pMD->m_pszDebugClassName,
4569 pMD->m_pszDebugMethodName,
4573 GetSetFrameHelper frameHelper;
4574 HRESULT hr = frameHelper.Init(pMD);
4579 // preallocate enough to hold all possible valueclass args & locals
4580 // sure this is more than we need, but not a big deal and better
4581 // than having to crawl through the frameHelper and count
4582 ULONG cValueClasses = 0;
4583 BYTE **rgpValueClasses = new (interopsafe, nothrow) BYTE *[varNativeInfoCount];
4584 if (rgpValueClasses == NULL)
4586 return E_OUTOFMEMORY;
4588 memset(rgpValueClasses, 0, sizeof(BYTE *)*varNativeInfoCount);
4592 LOG((LF_CORDB|LF_ENC,
4594 "D::GVFO rgVal1 0x%X, rgVal2 0x%X\n",
4598 // Now go through the full array and save off each arg and local
4599 for (UINT i = 0; i< varNativeInfoCount;i++)
4601 // Ignore variables not live at offsetFrom
4605 // The condition below is a little strange. If a var is alive when this is true:
4607 // startOffset <= offsetFrom < endOffset
4609 // Then you'd expect the negated expression below to be:
4611 // startOffset > offsetFrom || endOffset <= offsetFrom
4613 // instead of what we're doing ("<" instead of "<="):
4615 // startOffset > offsetFrom || endOffset < offsetFrom
4617 // I'm not sure if the condition below is a mistake, or if it's intentionally
4618 // mirroring a workaround from FindNativeInfoInILVariableArray() (Debug\DI\module.cpp)
4619 // to deal with optimized code. So I'm leaving it alone for now. See
4620 // code:FindNativeInfoInILVariableArray for more info on this workaround.
4621 if ((varNativeInfo[i].startOffset > offsetFrom) ||
4622 (varNativeInfo[i].endOffset < offsetFrom) ||
4623 (varNativeInfo[i].loc.vlType == ICorDebugInfo::VLT_INVALID))
4625 LOG((LF_CORDB|LF_ENC,LL_INFO10000, "D::GVFO [%2d] invalid\n", i));
4630 bool isVC = frameHelper.GetValueClassSizeOfVar(varNativeInfo[i].varNumber,
4631 varNativeInfo[i].loc.vlType,
4636 int rgValIndex = frameHelper.ShiftIndexForHiddens(varNativeInfo[i].varNumber);
4638 _ASSERTE(rgValIndex >= 0 && rgValIndex < (int)uRgValSize);
4640 BOOL res = GetNativeVarVal(varNativeInfo[i].loc,
4642 rgVal1 + rgValIndex,
4644 WIN64_ARG(cbClass));
4646 LOG((LF_CORDB|LF_ENC,LL_INFO10000,
4647 "D::GVFO [%2d] varnum %d, nonVC type %x, addr %8.8x: %8.8x;%8.8x\n",
4649 varNativeInfo[i].varNumber,
4650 varNativeInfo[i].loc.vlType,
4651 NativeVarStackAddr(varNativeInfo[i].loc, pCtx),
4653 rgVal2[rgValIndex]));
4660 _ASSERTE(res == TRUE);
4665 // it's definately a value class
4666 // Make space for it - note that it uses the VC index, NOT the variable index
4667 _ASSERTE(cbClass != 0);
4668 rgpValueClasses[cValueClasses] = new (interopsafe, nothrow) BYTE[cbClass];
4669 if (rgpValueClasses[cValueClasses] == NULL)
4674 memcpy(rgpValueClasses[cValueClasses],
4675 NativeVarStackAddr(varNativeInfo[i].loc, pCtx),
4681 LOG((LF_CORDB|LF_ENC,LL_INFO10000,
4682 "D::GVFO [%2d] varnum %d, VC len %d, addr %8.8x, sample: %8.8x%8.8x\n",
4684 varNativeInfo[i].varNumber,
4686 NativeVarStackAddr(varNativeInfo[i].loc, pCtx),
4687 (rgpValueClasses[cValueClasses-1])[0], (rgpValueClasses[cValueClasses-1])[1]));
4691 LOG((LF_CORDB|LF_ENC, LL_INFO10000, "D::GVFO: returning %8.8x\n", hr));
4694 (*rgpVCs) = rgpValueClasses;
4698 // We failed for some reason
4699 if (rgpValueClasses != NULL)
4700 { // free any memory we allocated for VCs here
4701 while(cValueClasses > 0)
4704 DeleteInteropSafe(rgpValueClasses[cValueClasses]); // OK to delete NULL
4706 DeleteInteropSafe(rgpValueClasses);
4707 rgpValueClasses = NULL;
4712 // NOTE: GetVariablesFromOffset and SetVariablesAtOffset are
4713 // very similar - modifying one will probably need to be reflected in the other...
4714 HRESULT Debugger::SetVariablesAtOffset(MethodDesc *pMD,
4715 UINT varNativeInfoCount,
4716 ICorDebugInfo::NativeVarInfo *varNativeInfo,
4728 PRECONDITION(CheckPointer(pCtx));
4729 PRECONDITION(varNativeInfoCount == 0 || CheckPointer(rgpVCs));
4730 PRECONDITION(varNativeInfoCount == 0 || CheckPointer(varNativeInfo));
4731 PRECONDITION(varNativeInfoCount == 0 || CheckPointer(rgVal1));
4732 PRECONDITION(varNativeInfoCount == 0 || CheckPointer(rgVal2));
4733 // This may or may not be called on the helper thread.
4737 LOG((LF_CORDB|LF_ENC, LL_INFO10000, "D::SVAO: %s::%s, infoCount:0x%x, to:0x%p\n",
4738 pMD->m_pszDebugClassName,
4739 pMD->m_pszDebugMethodName,
4743 if (varNativeInfoCount == 0)
4748 GetSetFrameHelper frameHelper;
4749 HRESULT hr = frameHelper.Init(pMD);
4758 // Note that since we obtain all the variables in the first loop, we
4759 // can now splatter those variables into their new locations
4760 // willy-nilly, without the fear that variable locations that have
4761 // been swapped might accidentally overwrite a variable value.
4762 for (UINT i = 0;i< varNativeInfoCount;i++)
4764 // Ignore variables not live at offsetTo
4766 // If this IF condition looks wrong to you, see
4767 // code:Debugger::GetVariablesFromOffset#VarLife for more info
4768 if ((varNativeInfo[i].startOffset > offsetTo) ||
4769 (varNativeInfo[i].endOffset < offsetTo) ||
4770 (varNativeInfo[i].loc.vlType == ICorDebugInfo::VLT_INVALID))
4772 LOG((LF_CORDB|LF_ENC,LL_INFO10000, "D::SVAO [%2d] invalid\n", i));
4777 bool isVC = frameHelper.GetValueClassSizeOfVar(varNativeInfo[i].varNumber,
4778 varNativeInfo[i].loc.vlType,
4783 int rgValIndex = frameHelper.ShiftIndexForHiddens(varNativeInfo[i].varNumber);
4785 _ASSERTE(rgValIndex >= 0);
4787 BOOL res = SetNativeVarVal(varNativeInfo[i].loc,
4791 WIN64_ARG(cbClass));
4793 LOG((LF_CORDB|LF_ENC,LL_INFO10000,
4794 "D::SVAO [%2d] varnum %d, nonVC type %x, addr %8.8x: %8.8x;%8.8x\n",
4796 varNativeInfo[i].varNumber,
4797 varNativeInfo[i].loc.vlType,
4798 NativeVarStackAddr(varNativeInfo[i].loc, pCtx),
4800 rgVal2[rgValIndex]));
4806 _ASSERTE(res == TRUE);
4811 // It's definately a value class.
4812 _ASSERTE(cbClass != 0);
4813 if (rgpVCs[iVC] == NULL)
4815 // it's new in scope, so just clear it
4816 memset(NativeVarStackAddr(varNativeInfo[i].loc, pCtx), 0, cbClass);
4817 LOG((LF_CORDB|LF_ENC,LL_INFO10000, "D::SVAO [%2d] varnum %d, new VC len %d, addr %8.8x\n",
4819 varNativeInfo[i].varNumber,
4821 NativeVarStackAddr(varNativeInfo[i].loc, pCtx)));
4824 // it's a pre-existing VC, so copy it
4825 memmove(NativeVarStackAddr(varNativeInfo[i].loc, pCtx), rgpVCs[iVC], cbClass);
4827 LOG((LF_CORDB|LF_ENC,LL_INFO10000,
4828 "D::SVAO [%2d] varnum %d, VC len %d, addr: %8.8x sample: %8.8x%8.8x\n",
4830 varNativeInfo[i].varNumber,
4832 NativeVarStackAddr(varNativeInfo[i].loc, pCtx),
4836 // Now get rid of the memory
4837 DeleteInteropSafe(rgpVCs[iVC]);
4842 LOG((LF_CORDB|LF_ENC, LL_INFO10000, "D::SVAO: returning %8.8x\n", hr));
4846 DeleteInteropSafe(rgpVCs);
4852 BOOL IsDuplicatePatch(SIZE_T *rgEntries,
4856 LIMITED_METHOD_CONTRACT;
4858 for( ULONG i = 0; i < cEntries;i++)
4860 if (rgEntries[i] == Entry)
4867 /******************************************************************************
4868 // HRESULT Debugger::MapAndBindFunctionBreakpoints(): For each breakpoint
4869 // that we've set in any version of the existing function,
4870 // set a correponding breakpoint in the new function if we haven't moved
4871 // the patch to the new version already.
4873 // This must be done _AFTER_ the MethodDesc has been udpated
4874 // with the new address (ie, when GetFunctionAddress pFD returns
4875 // the address of the new EnC code)
4878 // djiNew - this is the DJI created in D::JitComplete.
4879 // If djiNew == NULL iff we aren't tracking debug-info.
4880 // fd - the method desc that we're binding too.
4881 // addrOfCode - address of the native blob of code we just jitted
4883 // <TODO>@todo Replace array with hashtable for improved efficiency</TODO>
4884 // <TODO>@todo Need to factor code,so that we can selectively map forward DFK(ilOFfset) BPs</TODO>
4885 ******************************************************************************/
4886 HRESULT Debugger::MapAndBindFunctionPatches(DebuggerJitInfo *djiNew,
4888 CORDB_ADDRESS_TYPE *addrOfCode)
4891 // Internal helper API. Can be called from Debugger or Controller.
4898 CALLED_IN_DEBUGGERDATALOCK_HOLDER_SCOPE_MAY_GC_TRIGGERS_CONTRACT;
4899 PRECONDITION(!djiNew || djiNew->m_fd == fd);
4905 SIZE_T *pidTableEntry = NULL;
4906 SIZE_T pidInCaseTableMoves;
4907 Module *pModule = g_pEEInterface->MethodDescGetModule(fd);
4908 mdMethodDef md = fd->GetMemberDef();
4910 LOG((LF_CORDB,LL_INFO10000,"D::MABFP: All BPs will be mapped to "
4911 "Ver:0x%04x (DJI:0x%08x)\n", djiNew?djiNew->m_methodInfo->GetCurrentEnCVersion():0, djiNew));
4913 // We need to traverse the patch list while under the controller lock (small lock).
4914 // But we can only send BreakpointSetErros while under the debugger lock (big lock).
4915 // So to avoid a lock violation, we queue any errors we find under the small lock,
4916 // and then send the whole list when under the big lock.
4917 PATCH_UNORDERED_ARRAY listUnbindablePatches;
4920 // First lock the patch table so it doesn't move while we're
4922 LOG((LF_CORDB,LL_INFO10000, "D::MABFP: About to lock patch table\n"));
4924 DebuggerController::ControllerLockHolder ch;
4926 // Manipulate tables AFTER lock's been acquired.
4927 DebuggerPatchTable *pPatchTable = DebuggerController::GetPatchTable();
4928 GetBPMappingDuplicates()->Clear(); //dups are tracked per-version
4930 for (DebuggerControllerPatch *dcp = pPatchTable->GetFirstPatch(&hf);
4932 dcp = pPatchTable->GetNextPatch( &hf ))
4935 LOG((LF_CORDB, LL_INFO10000, "D::MABFP: got patch 0x%p\n", dcp));
4937 // Only copy over breakpoints that are in this method
4938 // Ideally we'd have a per-method index since there can be a lot of patches
4939 // when the EnCBreakpoint patches are included.
4940 if (dcp->key.module != pModule || dcp->key.md != md)
4942 LOG((LF_CORDB, LL_INFO10000, "Patch not in this method\n"));
4946 // If the patch only applies in certain generic instances, don't bind it
4948 if(dcp->pMethodDescFilter != NULL && dcp->pMethodDescFilter != djiNew->m_fd)
4950 LOG((LF_CORDB, LL_INFO10000, "Patch not in this generic instance\n"));
4955 // Do not copy over slave breakpoint patches. Instead place a new slave
4956 // based off the master.
4957 if (dcp->IsILSlavePatch())
4959 LOG((LF_CORDB, LL_INFO10000, "Not copying over slave breakpoint patch\n"));
4963 // If the patch is already bound, then we don't want to try to rebind it.
4964 // Eg. It may be bound to a different generic method instantiation.
4967 LOG((LF_CORDB, LL_INFO10000, "Skipping already bound patch\n"));
4971 // Only apply breakpoint patches that are for this version.
4972 // If the patch doesn't have a particular EnCVersion available from its data then
4973 // we're (probably) not tracking JIT info.
4974 if (dcp->IsBreakpointPatch() && dcp->HasEnCVersion() && djiNew && dcp->GetEnCVersion() != djiNew->m_encVersion)
4976 LOG((LF_CORDB, LL_INFO10000, "Not applying breakpoint patch to new version\n"));
4980 // Only apply breakpoint and stepper patches
4982 // The DJI gets deleted as part of the Unbind/Rebind process in MovedCode.
4983 // This is to signal that we should not skip here.
4984 // <NICE> under exactly what scenarios (EnC, code pitching etc.) will this apply?... </NICE>
4985 // <NICE> can't we be a little clearer about why we don't want to bind the patch in this arcane situation?</NICE>
4986 if (dcp->HasDJI() && !dcp->IsBreakpointPatch() && !dcp->IsStepperPatch())
4988 LOG((LF_CORDB, LL_INFO10000, "Neither stepper nor BP but we have valid a DJI (i.e. the DJI hasn't been deleted as part of the Unbind/MovedCode/Rebind mess)! - getting next patch!\n"));
4992 // Now check if we're tracking JIT info or not
4995 // This means we put a patch in a method w/ no debug info.
4996 _ASSERTE(dcp->IsBreakpointPatch() ||
4997 dcp->IsStepperPatch() ||
4998 dcp->controller->GetDCType() == DEBUGGER_CONTROLLER_THREAD_STARTER);
5000 // W/o Debug-info, We can only patch native offsets, and only at the start of the method (native offset 0).
5001 // <TODO> Why can't we patch other native offsets??
5002 // Maybe b/c we don't know if we're patching
5003 // in the middle of an instruction. Though that's not a
5004 // strict requirement.</TODO>
5005 // We can't even do a IL-offset 0 because that's after the prolog and w/o the debug-info,
5006 // we don't know where the prolog ends.
5007 // Failing this assert is arguably an API misusage - the debugger should have enabled
5008 // jit-tracking if they wanted to put bps at offsets other than native:0.
5009 if (dcp->IsNativePatch() && (dcp->offset == 0))
5011 DebuggerController::g_patches->BindPatch(dcp, addrOfCode);
5012 DebuggerController::ActivatePatch(dcp);
5016 // IF a debugger calls EnableJitDebugging(true, ...) in the module-load callback,
5017 // we should never get here.
5018 *(listUnbindablePatches.AppendThrowing()) = dcp;
5024 pidInCaseTableMoves = dcp->pid;
5026 // If we've already mapped this one to the current version,
5027 // don't map it again.
5028 LOG((LF_CORDB,LL_INFO10000,"D::MABFP: Checking if 0x%x is a dup...",
5029 pidInCaseTableMoves));
5031 if ( IsDuplicatePatch(GetBPMappingDuplicates()->Table(),
5032 GetBPMappingDuplicates()->Count(),
5033 pidInCaseTableMoves) )
5035 LOG((LF_CORDB,LL_INFO10000,"it is!\n"));
5038 LOG((LF_CORDB,LL_INFO10000,"nope!\n"));
5040 // Attempt mapping from patch to new version of code, and
5041 // we don't care if it turns out that there isn't a mapping.
5042 // <TODO>@todo-postponed: EnC: Make sure that this doesn't cause
5043 // the patch-table to shift.</TODO>
5044 hr = MapPatchToDJI( dcp, djiNew );
5045 if (CORDBG_E_CODE_NOT_AVAILABLE == hr )
5047 *(listUnbindablePatches.AppendThrowing()) = dcp;
5054 //Remember the patch id to prevent duplication later
5055 pidTableEntry = GetBPMappingDuplicates()->Append();
5056 if (NULL == pidTableEntry)
5062 *pidTableEntry = pidInCaseTableMoves;
5063 LOG((LF_CORDB,LL_INFO10000,"D::MABFP Adding 0x%x to list of "
5064 "already mapped patches\n", pidInCaseTableMoves));
5068 // unlock controller lock before sending events.
5070 LOG((LF_CORDB,LL_INFO10000, "D::MABFP: Unlocked patch table\n"));
5073 // Now send any Breakpoint bind error events.
5074 if (listUnbindablePatches.Count() > 0)
5076 LockAndSendBreakpointSetError(&listUnbindablePatches);
5082 /******************************************************************************
5083 // HRESULT Debugger::MapPatchToDJI(): Maps the given
5084 // patch to the corresponding location at the new address.
5085 // We assume that the new code has been JITTed.
5086 // Returns: CORDBG_E_CODE_NOT_AVAILABLE - Indicates that a mapping wasn't
5087 // available, and thus no patch was placed. The caller may or may
5089 ******************************************************************************/
5090 HRESULT Debugger::MapPatchToDJI( DebuggerControllerPatch *dcp,DebuggerJitInfo *djiTo)
5096 CALLED_IN_DEBUGGERDATALOCK_HOLDER_SCOPE_MAY_GC_TRIGGERS_CONTRACT;
5097 PRECONDITION(djiTo != NULL);
5098 PRECONDITION(djiTo->m_jitComplete == true);
5102 _ASSERTE(DebuggerController::HasLock());
5104 static BOOL shouldBreak = -1;
5105 if (shouldBreak == -1)
5106 shouldBreak = UnsafeGetConfigDWORD(CLRConfig::INTERNAL_DbgBreakOnMapPatchToDJI);
5108 if (shouldBreak > 0) {
5109 _ASSERTE(!"DbgBreakOnMatchPatchToDJI");
5113 LOG((LF_CORDB, LL_EVERYTHING, "Calling MapPatchToDJI\n"));
5115 // We shouldn't have been asked to map an already bound patch
5116 _ASSERTE( !dcp->IsBound() );
5117 if ( dcp->IsBound() )
5122 // If the patch has no DJI then we're doing a UnbindFunctionPatches/RebindFunctionPatches. Either
5123 // way, we simply want the most recent version. In the absence of EnC we should have djiCur == djiTo.
5124 DebuggerJitInfo *djiCur = dcp->HasDJI() ? dcp->GetDJI() : djiTo;
5125 PREFIX_ASSUME(djiCur != NULL);
5127 // If the source and destination are the same version, then this method
5128 // decays into BindFunctionPatch's BindPatch function
5129 if (djiCur->m_encVersion == djiTo->m_encVersion)
5131 // If the patch is a "master" then make a new "slave" patch instead of
5132 // binding the old one. This is to stop us mucking with the master breakpoint patch
5133 // which we may need to bind several times for generic code.
5134 if (dcp->IsILMasterPatch())
5136 LOG((LF_CORDB, LL_EVERYTHING, "Add, Bind, Activate new patch from master patch\n"));
5137 if (dcp->controller->AddBindAndActivateILSlavePatch(dcp, djiTo))
5139 LOG((LF_CORDB, LL_INFO1000, "Add, Bind Activate went fine!\n" ));
5144 LOG((LF_CORDB, LL_INFO1000, "Didn't work for some reason!\n"));
5146 // Caller can track this HR and send error.
5147 return CORDBG_E_CODE_NOT_AVAILABLE;
5153 // We could actually have a native managed patch here. This patch is probably added
5154 // as a result of tracing a patch. See if we can eliminate the need for this code path
5156 _ASSERTE( dcp->GetKind() == PATCH_KIND_NATIVE_MANAGED );
5158 // We have an unbound native patch (eg. for PatchTrace), lets try to bind and activate it
5160 LOG((LF_CORDB, LL_EVERYTHING, "trying to bind patch... could be problem\n"));
5161 if (DebuggerController::BindPatch(dcp, djiTo->m_fd, NULL))
5163 DebuggerController::ActivatePatch(dcp);
5164 LOG((LF_CORDB, LL_INFO1000, "Application went fine!\n" ));
5169 LOG((LF_CORDB, LL_INFO1000, "Didn't apply for some reason!\n"));
5171 // Caller can track this HR and send error.
5172 return CORDBG_E_CODE_NOT_AVAILABLE;
5177 // Breakpoint patches never get mapped over
5178 _ASSERTE(!dcp->IsBreakpointPatch());
5184 /* ------------------------------------------------------------------------ *
5185 * EE Interface routines
5186 * ------------------------------------------------------------------------ */
5189 // SendSyncCompleteIPCEvent sends a Sync Complete event to the Right Side.
5191 void Debugger::SendSyncCompleteIPCEvent()
5198 PRECONDITION(ThreadHoldsLock());
5200 // Anyone sending the synccomplete must hold the TSL.
5201 PRECONDITION(ThreadStore::HoldingThreadStore() || g_fProcessDetach);
5203 // The sync complete is now only sent on a helper thread.
5204 PRECONDITION(ThisIsHelperThreadWorker());
5207 // We had better be trapping Runtime threads and not stopped yet.
5208 PRECONDITION(m_stopped && m_trappingRuntimeThreads);
5213 // Internal helper API.
5214 // This is to send Sync Complete event to RightSide.
5215 // We should have hold the debugger lock
5218 STRESS_LOG0(LF_CORDB, LL_INFO10000, "D::SSCIPCE: sync complete.\n");
5220 // Synchronizing while in in rude shutdown should be extremely rare b/c we don't
5221 // TART in rude shutdown. Shutdown must have started after we started to sync.
5222 // We know we're not on the shutdown thread here.
5223 // And we also know we can't block the shutdown thread (b/c it has the TSL and will
5224 // get a free pass through the GC toggles that normally block threads for debugging).
5225 if (g_fProcessDetach)
5227 STRESS_LOG0(LF_CORDB, LL_INFO10000, "D::SSCIPCE: Skipping for shutdown.\n");
5231 // If we're not marked as attached yet, then do that now.
5232 // This can be safely called multiple times.
5233 // This can happen in the normal attach case. The Right-side sends an async-break,
5234 // but we don't want to be considered attach until we've actually gotten our first synchronization.
5235 // Else threads may slip forward during attach and send debug events while we're tyring to attach.
5236 MarkDebuggerAttachedInternal();
5238 DebuggerIPCControlBlock * pDCB;
5239 pDCB = m_pRCThread->GetDCB();
5240 (void)pDCB; //prevent "unused variable" error from GCC
5242 PREFIX_ASSUME(pDCB != NULL); // must have DCB by the time we're sending IPC events.
5243 #ifdef FEATURE_INTEROP_DEBUGGING
5244 // The synccomplete can't be the first IPC event over. That's b/c the LS needs to know
5245 // if we're interop-debugging and the RS needs to know special addresses for interop-debugging
5246 // (like flares). All of this info is in the DCB.
5247 if (pDCB->m_rightSideIsWin32Debugger)
5250 // If the Right Side is the win32 debugger of this process, then we need to throw a special breakpoint exception
5251 // here instead of sending the sync complete event. The Right Side treats this the same as a sync complete
5252 // event, but its also able to suspend unmanaged threads quickly.
5253 // This also prevents races between sending the sync-complete and getting a native debug event
5254 // (since the sync-complete becomes a native debug event, and all native debug events are serialized).
5256 // Note: we reset the syncThreadIsLockFree event before sending the sync complete flare. This thread will set
5257 // this event once its released the debugger lock. This will prevent the Right Side from suspending this thread
5258 // until it has released the debugger lock.
5259 Debugger::NotifyRightSideOfSyncComplete();
5262 #endif // FEATURE_INTEROP_DEBUGGING
5264 STRESS_LOG0(LF_CORDB, LL_EVERYTHING, "GetIPCEventSendBuffer called in SendSyncCompleteIPCEvent\n");
5265 // Send the Sync Complete event to the Right Side
5266 DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer();
5267 InitIPCEvent(ipce, DB_IPCE_SYNC_COMPLETE);
5269 m_pRCThread->SendIPCEvent();
5274 // Lookup or create a DebuggerModule for the given pDomainFile.
5277 // pDomainFile - non-null domain file.
5280 // DebuggerModule instance for the given domain file. May be lazily created.
5283 // @dbgtodo JMC - this should go away when we get rid of DebuggerModule.
5286 DebuggerModule * Debugger::LookupOrCreateModule(DomainFile * pDomainFile)
5288 _ASSERTE(pDomainFile != NULL);
5289 LOG((LF_CORDB, LL_INFO1000, "D::LOCM df=0x%x\n", pDomainFile));
5290 DebuggerModule * pDModule = LookupOrCreateModule(pDomainFile->GetModule(), pDomainFile->GetAppDomain());
5291 LOG((LF_CORDB, LL_INFO1000, "D::LOCM m=0x%x ad=0x%x -> dm=0x%x\n", pDomainFile->GetModule(), pDomainFile->GetAppDomain(), pDModule));
5292 _ASSERTE(pDModule != NULL);
5293 _ASSERTE(pDModule->GetDomainFile() == pDomainFile);
5298 // Overloaded Wrapper around for VMPTR_DomainFile-->DomainFile*
5301 // vmDomainFile - VMPTR cookie for a domain file. This can be NullPtr().
5304 // Debugger Module instance for the given domain file. May be lazily created.
5307 // VMPTR comes from IPC events
5308 DebuggerModule * Debugger::LookupOrCreateModule(VMPTR_DomainFile vmDomainFile)
5310 DomainFile * pDomainFile = vmDomainFile.GetRawPtr();
5311 if (pDomainFile == NULL)
5315 return LookupOrCreateModule(pDomainFile);
5318 // Lookup or create a DebuggerModule for the given (Module, AppDomain) pair.
5321 // pModule - required runtime module. May be domain netural.
5322 // pAppDomain - required appdomain that the module is in.
5325 // Debugger Module isntance for the given domain file. May be lazily created.
5327 DebuggerModule* Debugger::LookupOrCreateModule(Module* pModule, AppDomain *pAppDomain)
5337 LOG((LF_CORDB, LL_INFO1000, "D::LOCM m=0x%x ad=0x%x\n", pModule, pAppDomain));
5339 // DebuggerModules are relative to a specific AppDomain so we should always be looking up a module /
5341 _ASSERTE( pModule != NULL );
5342 _ASSERTE( pAppDomain != NULL );
5344 // This is called from all over. We just need to lock in order to lookup. We don't need
5345 // the lock when actually using the DebuggerModule (since it won't be unloaded as long as there is a thread
5346 // in that appdomain). Many of our callers already have this lock, many don't.
5347 // We can take the lock anyways because it's reentrant.
5348 DebuggerDataLockHolder ch(g_pDebugger); // need to traverse module list
5350 // if this is a module belonging to the system assembly, then scan
5351 // the complete list of DebuggerModules looking for the one
5352 // with a matching appdomain id
5355 _ASSERTE( SystemDomain::SystemAssembly()->IsDomainNeutral() );
5357 DebuggerModule* dmod = NULL;
5359 if (m_pModules != NULL)
5361 if (pModule->GetAssembly()->IsDomainNeutral())
5363 // We have to make sure to lookup the module with the app domain parameter if the module lives in a shared assembly
5364 dmod = m_pModules->GetModule(pModule, pAppDomain);
5368 dmod = m_pModules->GetModule(pModule);
5372 // If it doesn't exist, create it.
5378 DomainFile * pDomainFile = pModule->FindDomainFile(pAppDomain);
5379 SIMPLIFYING_ASSUMPTION(pDomainFile != NULL);
5380 dmod = AddDebuggerModule(pDomainFile); // throws
5382 EX_CATCH_HRESULT(hr);
5383 SIMPLIFYING_ASSUMPTION(dmod != NULL); // may not be true in OOM cases; but LS doesn't handle OOM.
5386 // The module must be in the AppDomain that was requested
5387 _ASSERTE( (dmod == NULL) || (dmod->GetAppDomain() == pAppDomain) );
5389 LOG((LF_CORDB, LL_INFO1000, "D::LOCM m=0x%x ad=0x%x -> dm=0x%x\n", pModule, pAppDomain, dmod));
5393 // Create a new DebuggerModule object
5396 // pDomainFile- runtime domain file to create debugger module object around
5399 // New instnace of a DebuggerModule. Throws on failure.
5401 DebuggerModule* Debugger::AddDebuggerModule(DomainFile * pDomainFile)
5410 LOG((LF_CORDB, LL_INFO1000, "D::ADM df=0x%x\n", pDomainFile));
5411 DebuggerDataLockHolder chInfo(this);
5413 Module * pRuntimeModule = pDomainFile->GetCurrentModule();
5414 AppDomain * pAppDomain = pDomainFile->GetAppDomain();
5416 HRESULT hr = CheckInitModuleTable();
5419 DebuggerModule* pModule = new (interopsafe) DebuggerModule(pRuntimeModule, pDomainFile, pAppDomain);
5420 _ASSERTE(pModule != NULL); // throws on oom
5422 TRACE_ALLOC(pModule);
5424 m_pModules->AddModule(pModule); // throws
5425 // @dbgtodo inspection/exceptions - this may leak module in OOM case. LS is not OOM resilient; and we
5426 // expect to get rid of DebuggerModule anyways.
5428 LOG((LF_CORDB, LL_INFO1000, "D::ADM df=0x%x -> dm=0x%x\n", pDomainFile, pModule));
5433 // TrapAllRuntimeThreads causes every Runtime thread that is executing
5434 // in the EE to trap and send the at safe point event to the RC thread as
5435 // soon as possible. It also sets the EE up so that Runtime threads that
5436 // are outside of the EE will trap when they try to re-enter.
5439 // Neither pDbgLockHolder nor pAppDomain are used.
5440 void Debugger::TrapAllRuntimeThreads()
5445 MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
5446 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
5448 // We acquired the lock b/c we're in a scope between LFES & UFES.
5449 PRECONDITION(ThreadHoldsLock());
5451 // This should never be called on a Temporary Helper thread.
5452 PRECONDITION(IsDbgHelperSpecialThread() ||
5453 (g_pEEInterface->GetThread() == NULL) ||
5454 !g_pEEInterface->IsPreemptiveGCDisabled());
5458 #if !defined(FEATURE_DBGIPC_TRANSPORT_VM)
5459 // Only sync if RS requested it.
5460 if (!m_RSRequestedSync)
5464 m_RSRequestedSync = FALSE;
5467 // If we're doing shutdown, then don't bother trying to communicate w/ the RS.
5468 // If we're not the thread doing shutdown, then we may be asynchronously killed by the OS.
5469 // If we are the thread in shutdown, don't TART b/c that may block and do complicated stuff.
5470 if (g_fProcessDetach)
5472 STRESS_LOG0(LF_CORDB, LL_INFO10000, "D::TART: Skipping for shutdown.\n");
5477 // Only try to start trapping if we're not already trapping.
5478 if (m_trappingRuntimeThreads == FALSE)
5482 STRESS_LOG0(LF_CORDB, LL_INFO10000, "D::TART: Trapping all Runtime threads.\n");
5484 // There's no way that we should be stopped and still trying to call this function.
5485 _ASSERTE(!m_stopped);
5487 // Mark that we're trapping now.
5488 m_trappingRuntimeThreads = TRUE;
5490 // Take the thread store lock.
5491 STRESS_LOG0(LF_CORDB,LL_INFO1000, "About to lock thread Store\n");
5492 ThreadSuspend::LockThreadStore(ThreadSuspend::SUSPEND_FOR_DEBUGGER);
5493 STRESS_LOG0(LF_CORDB,LL_INFO1000, "Locked thread store\n");
5495 // We start the suspension here, and let the helper thread finish it.
5496 // If there's no helper thread, then we need to do helper duty.
5498 SUPPRESS_ALLOCATION_ASSERTS_IN_THIS_SCOPE;
5499 fSuspended = g_pEEInterface->StartSuspendForDebug(NULL, TRUE);
5502 // We tell the RC Thread to check for other threads now and then and help them get synchronized. (This
5503 // is similar to what is done when suspending threads for GC with the HandledJITCase() function.)
5505 // This does not block.
5506 // Pinging this will waken the helper thread (or temp H. thread) and tell it to sweep & send
5507 // the sync complete.
5508 m_pRCThread->WatchForStragglers();
5510 // It's possible we may not have a real helper thread.
5511 // - on startup in dllmain, helper is blocked on DllMain loader lock.
5512 // - on shutdown, helper has been removed on us.
5513 // In those cases, we need somebody to send the sync-complete, and handle
5514 // managed events, and wait for the continue. So we pretend to be the helper thread.
5515 STRESS_LOG0(LF_CORDB, LL_EVERYTHING, "D::SSCIPCE: Calling IsRCThreadReady()\n");
5517 // We must check the helper thread status while under the lock.
5518 _ASSERTE(ThreadHoldsLock());
5519 // If we failed to suspend, then that means we must have multiple managed threads.
5520 // That means that our helper is not blocked on starting up, thus we can wait infinite on it.
5521 // Thus we don't need to do helper duty if the suspend fails.
5522 bool fShouldDoHelperDuty = !m_pRCThread->IsRCThreadReady() && fSuspended;
5523 if (fShouldDoHelperDuty && !g_fProcessDetach)
5525 // In V1.0, we had the assumption that if the helper thread isn't ready yet, then we're in
5526 // a state that SuspendForDebug will succeed on the first try, and thus we'll
5527 // never call Sweep when doing helper thread duty.
5528 _ASSERTE(fSuspended);
5530 // This call will do a ton of work, it will toggle the lock,
5531 // and it will block until we receive a continue!
5532 DoHelperThreadDuty();
5534 // We will have released the TSL after the call to continue.
5538 // We have a live and active helper thread which will handle events
5539 // from the RS now that we're stopped.
5540 // We need to release the TSL which we acquired above. (The helper will
5541 // likely take this lock while doing stuff).
5542 STRESS_LOG0(LF_CORDB,LL_INFO1000, "About to unlock thread store!\n");
5543 ThreadSuspend::UnlockThreadStore(FALSE, ThreadSuspend::SUSPEND_FOR_DEBUGGER);
5544 STRESS_LOG0(LF_CORDB,LL_INFO1000, "TART: Unlocked thread store!\n");
5546 _ASSERTE(ThreadHoldsLock()); // still hold the lock. (though it may have been toggled)
5552 // ReleaseAllRuntimeThreads releases all Runtime threads that may be
5553 // stopped after trapping and sending the at safe point event.
5555 void Debugger::ReleaseAllRuntimeThreads(AppDomain *pAppDomain)
5563 // We acquired the lock b/c we're in a scope between LFES & UFES.
5564 PRECONDITION(ThreadHoldsLock());
5566 // Currently, this is only done on a helper thread.
5567 PRECONDITION(ThisIsHelperThreadWorker());
5569 // Make sure that we were stopped...
5570 PRECONDITION(m_trappingRuntimeThreads && m_stopped);
5574 //<TODO>@todo APPD if we want true isolation, remove this & finish the work</TODO>
5577 STRESS_LOG1(LF_CORDB, LL_INFO10000, "D::RART: Releasing all Runtime threads"
5578 "for AppD 0x%x.\n", pAppDomain);
5580 // Mark that we're on our way now...
5581 m_trappingRuntimeThreads = FALSE;
5584 // Go ahead and resume the Runtime threads.
5585 g_pEEInterface->ResumeFromDebug(pAppDomain);
5588 // Given a method, get's its EnC version number. 1 if the method is not EnCed.
5589 // Note that MethodDescs are reused between versions so this will give us
5590 // the most recent EnC number.
5591 int Debugger::GetMethodEncNumber(MethodDesc * pMethod)
5601 DebuggerJitInfo * dji = GetLatestJitInfoFromMethodDesc(pMethod);
5604 // If there's no DJI, couldn't have been EnCed.
5607 return (int) dji->m_encVersion;
5611 bool Debugger::IsJMCMethod(Module* pModule, mdMethodDef tkMethod)
5619 PRECONDITION(CORDebuggerAttached());
5624 Crst crstDbg(CrstIsJMCMethod, CRST_UNSAFE_ANYMODE);
5625 PRECONDITION(crstDbg.IsSafeToTake());
5628 DebuggerMethodInfo *pInfo = GetOrCreateMethodInfo(pModule, tkMethod);
5633 return pInfo->IsJMCFunction();
5636 /******************************************************************************
5637 * Called by Runtime when on a 1st chance Native Exception.
5638 * This is likely when we hit a breakpoint / single-step.
5639 * This is called for all native exceptions (except COM+) on managed threads,
5640 * regardless of whether the debugger is attached.
5641 ******************************************************************************/
5642 bool Debugger::FirstChanceNativeException(EXCEPTION_RECORD *exception,
5649 // Implement DebugInterface
5650 // Can be called from EE exception code. Or from our M2UHandoffHijackFilter
5651 // must be on managed thread.
5658 // No clear GC_triggers semantics here. See DispatchNativeException.
5659 WRAPPER(GC_TRIGGERS);
5662 PRECONDITION(CheckPointer(exception));
5663 PRECONDITION(CheckPointer(context));
5664 PRECONDITION(CheckPointer(thread));
5669 // Ignore any notification exceptions sent from code:Debugger.SendRawEvent.
5670 // This is not a common case, but could happen in some cases described
5671 // in SendRawEvent. Either way, Left-Side and VM should just ignore these.
5672 if (IsEventDebuggerNotification(exception, PTR_TO_CORDB_ADDRESS(g_pMSCorEE)))
5679 // Don't stop for native debugging anywhere inside our inproc-Filters.
5680 CantStopHolder hHolder;
5682 if (!CORDBUnrecoverableError(this))
5684 retVal = DebuggerController::DispatchNativeException(exception, context,
5695 /******************************************************************************
5697 ******************************************************************************/
5698 PRD_TYPE Debugger::GetPatchedOpcode(CORDB_ADDRESS_TYPE *ip)
5700 WRAPPER_NO_CONTRACT;
5702 if (!CORDBUnrecoverableError(this))
5704 return DebuggerController::GetPatchedOpcode(ip);
5714 /******************************************************************************
5716 ******************************************************************************/
5717 BOOL Debugger::CheckGetPatchedOpcode(CORDB_ADDRESS_TYPE *address, /*OUT*/ PRD_TYPE *pOpcode)
5719 WRAPPER_NO_CONTRACT;
5720 CONSISTENCY_CHECK(CheckPointer(address));
5721 CONSISTENCY_CHECK(CheckPointer(pOpcode));
5723 if (CORDebuggerAttached() && !CORDBUnrecoverableError(this))
5725 return DebuggerController::CheckGetPatchedOpcode(address, pOpcode);
5729 InitializePRD(pOpcode);
5734 /******************************************************************************
5736 ******************************************************************************/
5737 void Debugger::TraceCall(const BYTE *code)
5741 // We're being called right before we call managed code. Can't trigger
5742 // because there may be unprotected args on the stack.
5751 Thread * pCurThread = g_pEEInterface->GetThread();
5752 // Ensure we never even think about running managed code on the helper thread.
5753 _ASSERTE(!ThisIsHelperThreadWorker() || !"You're running managed code on the helper thread");
5755 // One threat is that our helper thread may be forced to execute a managed DLL main.
5756 // In that case, it's before the helper thread proc is even executed, so our conventional
5757 // IsHelperThread() checks are inadequate.
5758 _ASSERTE((GetCurrentThreadId() != g_pRCThread->m_DbgHelperThreadOSTid) || !"You're running managed code on the helper thread");
5760 _ASSERTE((g_pEEInterface->GetThreadFilterContext(pCurThread) == NULL) || !"Shouldn't run managed code w/ Filter-Context set");
5762 if (!CORDBUnrecoverableError(this))
5764 // There are situations where our callers can't tolerate us throwing.
5767 // Since we have a try catch and the debugger code can deal properly with
5768 // faults occuring inside DebuggerController::DispatchTraceCall, we can safely
5769 // establish a FAULT_NOT_FATAL region. This is required since some callers can't
5773 DebuggerController::DispatchTraceCall(pCurThread, code);
5777 // We're being called for our benefit, not our callers. So if we fail,
5779 // Failure for us means that some steppers may miss their notification
5780 // for entering managed code.
5781 LOG((LF_CORDB, LL_INFO10000, "Debugger::TraceCall - inside catch, %p\n", code));
5783 EX_END_CATCH(SwallowAllExceptions);
5787 /******************************************************************************
5788 * For Just-My-Code (aka Just-User-Code).
5789 * Invoked from a probe in managed code when we enter a user method and
5790 * the flag (set by GetJMCFlagAddr) for that method is != 0.
5791 * pIP - the ip within the method, right after the prolog.
5792 * sp - stack pointer (frame pointer on x86) for the managed method we're entering.
5793 * bsp - backing store pointer for the managed method we're entering
5794 ******************************************************************************/
5795 void Debugger::OnMethodEnter(void * pIP)
5805 LOG((LF_CORDB, LL_INFO1000000, "D::OnMethodEnter(ip=%p)\n", pIP));
5807 if (!CORDebuggerAttached())
5809 LOG((LF_CORDB, LL_INFO1000000, "D::OnMethodEnter returning since debugger attached.\n"));
5812 FramePointer fp = LEAF_MOST_FRAME;
5813 DebuggerController::DispatchMethodEnter(pIP, fp);
5815 /******************************************************************************
5817 * Provide an address of the flag that the JMC probes use to decide whether
5818 * or not to call TriggerMethodEnter.
5819 * Called for each method that we jit.
5820 * md - method desc for the JMC probe
5821 * returns an address of a flag that the probe can use.
5822 ******************************************************************************/
5823 DWORD* Debugger::GetJMCFlagAddr(Module * pModule)
5830 PRECONDITION(CheckPointer(pModule));
5834 // This callback will be invoked whenever we jit debuggable code.
5835 // A debugger may not be attached yet, but we still need someplace
5836 // to store this dword.
5837 // Use the EE's module, because it's always around, even if a debugger
5838 // is attached or not.
5839 return &(pModule->m_dwDebuggerJMCProbeCount);
5842 /******************************************************************************
5843 * Updates the JMC flag on all the EE modules.
5844 * We can do this as often as we'd like - though it's a perf hit.
5845 ******************************************************************************/
5846 void Debugger::UpdateAllModuleJMCFlag(bool fStatus)
5855 LOG((LF_CORDB, LL_INFO1000000, "D::UpdateModuleJMCFlag to %d\n", fStatus));
5857 _ASSERTE(HasDebuggerDataLock());
5859 // Loop through each module.
5860 // The module table is lazily allocated. As soon as we set JMC status on any module, that will cause an
5861 // allocation of the module table. So if the table isn't allocated no module has JMC set,
5862 // and so there is nothing to update.
5863 if (m_pModules != NULL)
5866 for (DebuggerModule * m = m_pModules->GetFirstModule(&f);
5868 m = m_pModules->GetNextModule(&f))
5870 // the primary module may get called multiple times, but that's ok.
5871 UpdateModuleJMCFlag(m->GetRuntimeModule(), fStatus);
5872 } // end for all modules.
5876 /******************************************************************************
5877 * Updates the JMC flag on the given Primary module
5878 * We can do this as often as we'd like - though it's a perf hit.
5879 * If we've only changed methods in a single module, then we can just call this.
5880 * If we do a more global thing (Such as enable MethodEnter), then that could
5881 * affect all modules, so we use the UpdateAllModuleJMCFlag helper.
5882 ******************************************************************************/
5883 void Debugger::UpdateModuleJMCFlag(Module * pRuntimeModule, bool fStatus)
5892 _ASSERTE(HasDebuggerDataLock());
5895 DWORD * pFlag = &(pRuntimeModule->m_dwDebuggerJMCProbeCount);
5896 _ASSERTE(pFlag != NULL);
5898 if (pRuntimeModule->HasAnyJMCFunctions())
5900 // If this is a user-code module, then update the JMC flag
5901 // the probes look at so that we get MethodEnter callbacks.
5904 LOG((LF_CORDB, LL_EVERYTHING, "D::UpdateModuleJMCFlag, module %p is user code\n", pRuntimeModule));
5906 LOG((LF_CORDB, LL_EVERYTHING, "D::UpdateModuleJMCFlag, module %p is not-user code\n", pRuntimeModule));
5908 // if non-user code, flag should be 0 so that we don't waste
5909 // cycles in the callbacks.
5910 _ASSERTE(*pFlag == 0);
5914 // This sets the JMC status for the entire module.
5915 // fStatus - default status for whole module
5916 void Debugger::SetModuleDefaultJMCStatus(Module * pRuntimeModule, bool fStatus)
5923 PRECONDITION(ThisIsHelperThreadWorker());
5927 LOG((LF_CORDB, LL_INFO100000, "DM::SetJMCStatus, status=%d, this=%p\n", fStatus, this));
5929 // Ensure that all active DMIs have our status.
5930 // All new DMIs can lookup their status from us.
5931 // This should also update the module count of active JMC DMI's.
5932 DebuggerMethodInfoTable * pTable = g_pDebugger->GetMethodInfoTable();
5936 Debugger::DebuggerDataLockHolder debuggerDataLockHolder(g_pDebugger);
5939 for (DebuggerMethodInfo *dmi = pTable->GetFirstMethodInfo(&info);
5941 dmi = pTable->GetNextMethodInfo(&info))
5943 if (dmi->GetRuntimeModule() == pRuntimeModule)
5945 // This DMI is in this module, so update its status
5946 dmi->SetJMCStatus(fStatus);
5951 pRuntimeModule->SetJMCStatus(fStatus);
5954 // If we're disabling JMC in this module, then we shouldn't
5955 // have any active JMC functions.
5958 _ASSERTE(!pRuntimeModule->HasAnyJMCFunctions());
5963 /******************************************************************************
5964 * Called by GC to determine if it's safe to do a GC.
5965 ******************************************************************************/
5966 bool Debugger::ThreadsAtUnsafePlaces(void)
5968 LIMITED_METHOD_CONTRACT;
5970 // If we're in shutdown mode, then all other threads are parked.
5971 // Even if they claim to be at unsafe regions, they're still safe to do a GC. They won't touch
5973 if (m_fShutdownMode)
5975 if (m_threadsAtUnsafePlaces > 0)
5977 STRESS_LOG1(LF_CORDB, LL_INFO10000, "D::TAUP: Claiming safety in shutdown mode.%d\n", m_threadsAtUnsafePlaces);
5983 return (m_threadsAtUnsafePlaces != 0);
5987 // SendBreakpoint is called by Runtime threads to send that they've
5988 // hit a breakpoint to the Right Side.
5990 void Debugger::SendBreakpoint(Thread *thread, CONTEXT *context,
5991 DebuggerBreakpoint *breakpoint)
6000 if (CORDBUnrecoverableError(this))
6004 static BOOL shouldBreak = -1;
6005 if (shouldBreak == -1)
6006 shouldBreak = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DbgBreakOnSendBreakpoint);
6008 if (shouldBreak > 0) {
6009 _ASSERTE(!"DbgBreakOnSendBreakpoint");
6013 LOG((LF_CORDB, LL_INFO10000, "D::SB: breakpoint BP:0x%x\n", breakpoint));
6015 _ASSERTE((g_pEEInterface->GetThread() &&
6016 !g_pEEInterface->GetThread()->m_fPreemptiveGCDisabled) ||
6019 _ASSERTE(ThreadHoldsLock());
6021 // Send a breakpoint event to the Right Side
6022 DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer();
6026 thread->GetDomain());
6027 ipce->BreakpointData.breakpointToken.Set(breakpoint);
6028 _ASSERTE( breakpoint->m_pAppDomain == ipce->vmAppDomain.GetRawPtr());
6030 m_pRCThread->SendIPCEvent();
6034 //---------------------------------------------------------------------------------------
6035 // Send a user breakpoint event for this thread and sycnhronize the process.
6038 // pThread - non-null thread to send user breakpoint event for.
6041 // Can't assume that a debugger is attached (since it may detach before we get the lock).
6042 void Debugger::SendUserBreakpointAndSynchronize(Thread * pThread)
6044 AtSafePlaceHolder unsafePlaceHolder(pThread);
6046 SENDIPCEVENT_BEGIN(this, pThread);
6048 // Actually send the event
6049 if (CORDebuggerAttached())
6051 SendRawUserBreakpoint(pThread);
6052 TrapAllRuntimeThreads();
6058 //---------------------------------------------------------------------------------------
6060 // SendRawUserBreakpoint is called by Runtime threads to send that
6061 // they've hit a user breakpoint to the Right Side. This is the event
6062 // send only part, since it can be called from a few different places.
6065 // pThread - [in] managed thread where user break point takes place.
6066 // mus be curernt thread.
6068 void Debugger::SendRawUserBreakpoint(Thread * pThread)
6076 PRECONDITION(pThread == GetThread());
6078 PRECONDITION(ThreadHoldsLock());
6080 // Debugger must have been attached to get us to this point.
6081 // We hold the Debugger-lock, so debugger could not have detached from
6082 // underneath us either.
6083 PRECONDITION(CORDebuggerAttached());
6087 if (CORDBUnrecoverableError(this))
6090 LOG((LF_CORDB, LL_INFO10000, "D::SRUB: user breakpoint\n"));
6094 // Send a breakpoint event to the Right Side
6095 DebuggerIPCEvent* pEvent = m_pRCThread->GetIPCEventSendBuffer();
6096 InitIPCEvent(pEvent,
6097 DB_IPCE_USER_BREAKPOINT,
6099 pThread->GetDomain());
6101 m_pRCThread->SendIPCEvent();
6105 // SendInterceptExceptionComplete is called by Runtime threads to send that
6106 // they've completed intercepting an exception to the Right Side. This is the event
6107 // send only part, since it can be called from a few different places.
6109 void Debugger::SendInterceptExceptionComplete(Thread *thread)
6118 if (CORDBUnrecoverableError(this))
6121 LOG((LF_CORDB, LL_INFO10000, "D::SIEC: breakpoint\n"));
6123 _ASSERTE(!g_pEEInterface->IsPreemptiveGCDisabled());
6124 _ASSERTE(ThreadHoldsLock());
6126 // Send a breakpoint event to the Right Side
6127 DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer();
6129 DB_IPCE_INTERCEPT_EXCEPTION_COMPLETE,
6131 thread->GetDomain());
6133 m_pRCThread->SendIPCEvent();
6139 // SendStep is called by Runtime threads to send that they've
6140 // completed a step to the Right Side.
6142 void Debugger::SendStep(Thread *thread, CONTEXT *context,
6143 DebuggerStepper *stepper,
6144 CorDebugStepReason reason)
6153 if (CORDBUnrecoverableError(this))
6156 LOG((LF_CORDB, LL_INFO10000, "D::SS: step:token:0x%p reason:0x%x\n",
6159 _ASSERTE((g_pEEInterface->GetThread() &&
6160 !g_pEEInterface->GetThread()->m_fPreemptiveGCDisabled) ||
6163 _ASSERTE(ThreadHoldsLock());
6165 // Send a step event to the Right Side
6166 DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer();
6168 DB_IPCE_STEP_COMPLETE,
6170 thread->GetDomain());
6171 ipce->StepData.stepperToken.Set(stepper);
6172 ipce->StepData.reason = reason;
6173 m_pRCThread->SendIPCEvent();
6176 //-------------------------------------------------------------------------------------------------
6177 // Send an EnC remap opportunity and block until it is continued.
6179 // dji - current method information
6180 // currentIP - IL offset within that method
6181 // resumeIP - address of a SIZE_T that the RS will write to cross-process if they take the
6182 // remap opportunity. *resumeIP is untouched if the RS does not remap.
6183 //-------------------------------------------------------------------------------------------------
6184 void Debugger::LockAndSendEnCRemapEvent(DebuggerJitInfo * dji, SIZE_T currentIP, SIZE_T *resumeIP)
6189 GC_TRIGGERS; // From SendIPCEvent
6190 PRECONDITION(dji != NULL);
6195 LOG((LF_CORDB, LL_INFO10000, "D::LASEnCRE:\n"));
6197 if (CORDBUnrecoverableError(this))
6200 MethodDesc * pFD = dji->m_fd;
6202 // Note that the debugger lock is reentrant, so we may or may not hold it already.
6203 Thread *thread = g_pEEInterface->GetThread();
6204 SENDIPCEVENT_BEGIN(this, thread);
6206 // Send an EnC remap event to the Right Side.
6207 DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer();
6211 thread->GetDomain());
6213 ipce->EnCRemap.currentVersionNumber = dji->m_encVersion;
6214 ipce->EnCRemap.resumeVersionNumber = dji->m_methodInfo->GetCurrentEnCVersion();;
6215 ipce->EnCRemap.currentILOffset = currentIP;
6216 ipce->EnCRemap.resumeILOffset = resumeIP;
6217 ipce->EnCRemap.funcMetadataToken = pFD->GetMemberDef();
6219 LOG((LF_CORDB, LL_INFO10000, "D::LASEnCRE: token 0x%x, from version %d to %d\n",
6220 ipce->EnCRemap.funcMetadataToken, ipce->EnCRemap.currentVersionNumber, ipce->EnCRemap.resumeVersionNumber));
6222 Module *pRuntimeModule = pFD->GetModule();
6224 DebuggerModule * pDModule = LookupOrCreateModule(pRuntimeModule, thread->GetDomain());
6225 ipce->EnCRemap.vmDomainFile.SetRawPtr((pDModule ? pDModule->GetDomainFile() : NULL));
6227 LOG((LF_CORDB, LL_INFO10000, "D::LASEnCRE: %s::%s "
6228 "dmod:0x%x, methodDef:0x%x \n",
6229 pFD->m_pszDebugClassName, pFD->m_pszDebugMethodName,
6231 ipce->EnCRemap.funcMetadataToken));
6233 // IPC event is now initialized, so we can send it over.
6234 SendSimpleIPCEventAndBlock();
6236 // This will block on the continue
6239 LOG((LF_CORDB, LL_INFO10000, "D::LASEnCRE: done\n"));
6243 // Send the RemapComplete event and block until the debugger Continues
6244 // pFD - specifies the method in which we've remapped into
6245 void Debugger::LockAndSendEnCRemapCompleteEvent(MethodDesc *pFD)
6254 LOG((LF_CORDB, LL_INFO10000, "D::LASEnCRE:\n"));
6256 if (CORDBUnrecoverableError(this))
6259 Thread *thread = g_pEEInterface->GetThread();
6260 // Note that the debugger lock is reentrant, so we may or may not hold it already.
6261 SENDIPCEVENT_BEGIN(this, thread);
6265 // Ensure the DJI for the latest version of this method has been pre-created.
6266 // It's not clear whether this is necessary or not, but it shouldn't hurt since
6267 // we're going to need to create it anyway since we'll be debugging inside it.
6268 DebuggerJitInfo *dji = g_pDebugger->GetLatestJitInfoFromMethodDesc(pFD);
6269 (void)dji; //prevent "unused variable" error from GCC
6270 _ASSERTE( dji != NULL );
6274 // GetLatestJitInfo could throw on OOM, but the debugger isn't resiliant to OOM.
6275 // I'm not aware of any other legitimate reason why it may throw, so we'll ASSERT
6277 _ASSERTE(!"Unexpected exception from Debugger::GetLatestJitInfoFromMethodDesc on EnC remap complete");
6279 EX_END_CATCH(RethrowTerminalExceptions);
6281 // Send an EnC remap complete event to the Right Side.
6282 DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer();
6284 DB_IPCE_ENC_REMAP_COMPLETE,
6286 thread->GetDomain());
6289 ipce->EnCRemapComplete.funcMetadataToken = pFD->GetMemberDef();
6291 Module *pRuntimeModule = pFD->GetModule();
6293 DebuggerModule * pDModule = LookupOrCreateModule(pRuntimeModule, thread->GetDomain());
6294 ipce->EnCRemapComplete.vmDomainFile.SetRawPtr((pDModule ? pDModule->GetDomainFile() : NULL));
6297 LOG((LF_CORDB, LL_INFO10000, "D::LASEnCRC: %s::%s "
6298 "dmod:0x%x, methodDef:0x%x \n",
6299 pFD->m_pszDebugClassName, pFD->m_pszDebugMethodName,
6301 ipce->EnCRemap.funcMetadataToken));
6303 // IPC event is now initialized, so we can send it over.
6304 SendSimpleIPCEventAndBlock();
6306 // This will block on the continue
6309 LOG((LF_CORDB, LL_INFO10000, "D::LASEnCRC: done\n"));
6313 // This function sends a notification to the RS about a specific update that has occurred as part of
6314 // applying an Edit and Continue. We send notification only for function add/update and field add.
6315 // At this point, the EE is already stopped for handling an EnC ApplyChanges operation, so no need
6316 // to take locks etc.
6318 void Debugger::SendEnCUpdateEvent(DebuggerIPCEventType eventType,
6320 mdToken memberToken,
6321 mdTypeDef classToken,
6331 LOG((LF_CORDB, LL_INFO10000, "D::LASEnCUFE:\n"));
6333 _ASSERTE(eventType == DB_IPCE_ENC_UPDATE_FUNCTION ||
6334 eventType == DB_IPCE_ENC_ADD_FUNCTION ||
6335 eventType== DB_IPCE_ENC_ADD_FIELD);
6337 if (CORDBUnrecoverableError(this))
6340 // Send an EnC UpdateFunction event to the Right Side.
6341 DebuggerIPCEvent* event = m_pRCThread->GetIPCEventSendBuffer();
6347 event->EnCUpdate.newVersionNumber = enCVersion;
6348 event->EnCUpdate.memberMetadataToken = memberToken;
6349 // we have to pass the class token across to the RS because we cannot look it up over
6350 // there based on the added field/method because the metadata on the RS will not yet
6351 // have the changes applied, so the token will not exist in its metadata and we have
6352 // no way to find it.
6353 event->EnCUpdate.classMetadataToken = classToken;
6356 // we don't support shared assemblies, so must have an appdomain
6357 _ASSERTE(pModule->GetDomain()->IsAppDomain());
6359 DebuggerModule * pDModule = LookupOrCreateModule(pModule, pModule->GetDomain()->AsAppDomain());
6360 event->EnCUpdate.vmDomainFile.SetRawPtr((pDModule ? pDModule->GetDomainFile() : NULL));
6362 m_pRCThread->SendIPCEvent();
6364 LOG((LF_CORDB, LL_INFO10000, "D::LASEnCUE: done\n"));
6370 // Send a BreakpointSetError event to the Right Side if the given patch is for a breakpoint. Note: we don't care if this
6371 // fails, there is nothing we can do about it anyway, and the breakpoint just wont hit.
6373 void Debugger::LockAndSendBreakpointSetError(PATCH_UNORDERED_ARRAY * listUnbindablePatches)
6377 MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
6382 _ASSERTE(listUnbindablePatches != NULL);
6384 if (CORDBUnrecoverableError(this))
6388 ULONG count = listUnbindablePatches->Count();
6389 _ASSERTE(count > 0); // must send at least 1 event.
6392 Thread *thread = g_pEEInterface->GetThread();
6393 // Note that the debugger lock is reentrant, so we may or may not hold it already.
6394 SENDIPCEVENT_BEGIN(this, thread);
6396 DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer();
6398 for(ULONG i = 0; i < count; i++)
6400 DebuggerControllerPatch *patch = listUnbindablePatches->Table()[i];
6401 _ASSERTE(patch != NULL);
6403 // Only do this for breakpoint controllers
6404 DebuggerController *controller = patch->controller;
6406 if (controller->GetDCType() != DEBUGGER_CONTROLLER_BREAKPOINT)
6411 LOG((LF_CORDB, LL_INFO10000, "D::LASBSE:\n"));
6413 // Send a breakpoint set error event to the Right Side.
6414 InitIPCEvent(ipce, DB_IPCE_BREAKPOINT_SET_ERROR, thread, thread->GetDomain());
6416 ipce->BreakpointSetErrorData.breakpointToken.Set(static_cast<DebuggerBreakpoint*> (controller));
6418 // IPC event is now initialized, so we can send it over.
6419 m_pRCThread->SendIPCEvent();
6422 // Stop all Runtime threads
6423 TrapAllRuntimeThreads();
6425 // This will block on the continue
6431 // Called from the controller to lock the debugger for event
6432 // sending. This is called before controller events are sent, like
6433 // breakpoint, step complete, and thread started.
6435 // Note that it's possible that the debugger detached (and destroyed our IPC
6436 // events) while we're waiting for our turn.
6437 // So Callers should check for that case.
6438 void Debugger::LockForEventSending(DebuggerLockHolder *dbgLockHolder)
6448 // @todo - Force our parents to bump up the stop-count. That way they can
6449 // guarantee it's balanced.
6451 _ASSERTE(IsInCantStopRegion());
6453 // What we need is for caller to get the debugger lock
6454 if (dbgLockHolder != NULL)
6456 dbgLockHolder->Acquire();
6460 // Track our TID. We're not re-entrant.
6461 //_ASSERTE(m_tidLockedForEventSending == 0);
6462 m_tidLockedForEventSending = GetCurrentThreadId();
6468 // Called from the controller to unlock the debugger from event
6469 // sending. This is called after controller events are sent, like
6470 // breakpoint, step complete, and thread started.
6472 void Debugger::UnlockFromEventSending(DebuggerLockHolder *dbgLockHolder)
6483 //_ASSERTE(m_tidLockedForEventSending == GetCurrentThreadId());
6484 m_tidLockedForEventSending = 0;
6486 if (dbgLockHolder != NULL)
6488 dbgLockHolder->Release();
6490 // @todo - Force our parents to bump up the stop-count. That way they can
6491 // guarantee it's balanced.
6492 _ASSERTE(IsInCantStopRegion());
6498 // Called from the controller after all events have been sent for a
6499 // thread to sync the process.
6501 void Debugger::SyncAllThreads(DebuggerLockHolder *dbgLockHolder)
6505 MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
6506 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
6510 if (CORDBUnrecoverableError(this))
6513 STRESS_LOG0(LF_CORDB, LL_INFO10000, "D::SAT: sync all threads.\n");
6515 Thread *pThread = g_pEEInterface->GetThread();
6516 (void)pThread; //prevent "unused variable" error from GCC
6517 _ASSERTE((pThread &&
6518 !pThread->m_fPreemptiveGCDisabled) ||
6521 _ASSERTE(ThreadHoldsLock());
6523 // Stop all Runtime threads
6524 TrapAllRuntimeThreads();
6527 //---------------------------------------------------------------------------------------
6528 // Launch a debugger and then trigger a breakpoint (either managed or native)
6531 // useManagedBPForManagedAttach - TRUE if we should stop with a managed breakpoint
6532 // when managed attached, FALSE if we should always
6533 // stop with a native breakpoint
6534 // pThread - the managed thread that attempts to launch the registered debugger
6535 // pExceptionInfo - the unhandled exception info
6536 // explicitUserRequest - TRUE if this attach is caused by a call to the Debugger.Launch() API.
6539 // S_OK on success. Else failure.
6542 // This function doesn't try to stop the launched native debugger by calling DebugBreak().
6543 // It sends a breakpoint event only for managed debuggers.
6545 HRESULT Debugger::LaunchDebuggerForUser(Thread * pThread, EXCEPTION_POINTERS * pExceptionInfo,
6546 BOOL useManagedBPForManagedAttach, BOOL explicitUserRequest)
6548 WRAPPER_NO_CONTRACT;
6550 LOG((LF_CORDB, LL_INFO10000, "D::LDFU: Attaching Debugger.\n"));
6553 // Initiate a jit attach
6555 JitAttach(pThread, pExceptionInfo, useManagedBPForManagedAttach, explicitUserRequest);
6557 if (useManagedBPForManagedAttach)
6559 if(CORDebuggerAttached() && (g_pEEInterface->GetThread() != NULL))
6562 // Send a managed-breakpoint.
6564 SendUserBreakpointAndSynchronize(g_pEEInterface->GetThread());
6566 else if (!CORDebuggerAttached() && IsDebuggerPresent())
6569 // If the registered debugger is not a managed debugger, send a native breakpoint
6574 else if(!useManagedBPForManagedAttach)
6577 // Send a native breakpoint
6582 if (!IsDebuggerPresent())
6584 LOG((LF_CORDB, LL_ERROR, "D::LDFU: Failed to launch the debugger.\n"));
6591 // The following JDI structures will be passed to a debugger on Vista. Because we do not know when the debugger
6592 // will be done looking at them, and there is at most one debugger attaching to the process, we always set them
6593 // once and leave them set without the risk of clobbering something we care about.
6594 JIT_DEBUG_INFO Debugger::s_DebuggerLaunchJitInfo = {0};
6595 EXCEPTION_RECORD Debugger::s_DebuggerLaunchJitInfoExceptionRecord = {0};
6596 CONTEXT Debugger::s_DebuggerLaunchJitInfoContext = {0};
6598 //----------------------------------------------------------------------------
6600 // InitDebuggerLaunchJitInfo - initialize JDI structure on Vista
6603 // pThread - the managed thread with the unhandled excpetion
6604 // pExceptionInfo - unhandled exception info
6609 //----------------------------------------------------------------------------
6610 void Debugger::InitDebuggerLaunchJitInfo(Thread * pThread, EXCEPTION_POINTERS * pExceptionInfo)
6612 LIMITED_METHOD_CONTRACT;
6614 _ASSERTE((pExceptionInfo != NULL) &&
6615 (pExceptionInfo->ContextRecord != NULL) &&
6616 (pExceptionInfo->ExceptionRecord != NULL));
6618 if ((pExceptionInfo == NULL) || (pExceptionInfo->ContextRecord == NULL) || (pExceptionInfo->ExceptionRecord == NULL))
6623 s_DebuggerLaunchJitInfoExceptionRecord = *pExceptionInfo->ExceptionRecord;
6624 s_DebuggerLaunchJitInfoContext = *pExceptionInfo->ContextRecord;
6626 s_DebuggerLaunchJitInfo.dwSize = sizeof(s_DebuggerLaunchJitInfo);
6627 s_DebuggerLaunchJitInfo.dwThreadID = pThread == NULL ? GetCurrentThreadId() : pThread->GetOSThreadId();
6628 s_DebuggerLaunchJitInfo.lpExceptionRecord = reinterpret_cast<ULONG64>(&s_DebuggerLaunchJitInfoExceptionRecord);
6629 s_DebuggerLaunchJitInfo.lpContextRecord = reinterpret_cast<ULONG64>(&s_DebuggerLaunchJitInfoContext);
6630 s_DebuggerLaunchJitInfo.lpExceptionAddress = s_DebuggerLaunchJitInfoExceptionRecord.ExceptionAddress != NULL ?
6631 reinterpret_cast<ULONG64>(s_DebuggerLaunchJitInfoExceptionRecord.ExceptionAddress) :
6632 reinterpret_cast<ULONG64>(reinterpret_cast<PVOID>(GetIP(pExceptionInfo->ContextRecord)));
6634 #if defined(_TARGET_X86_)
6635 s_DebuggerLaunchJitInfo.dwProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;
6636 #elif defined(_TARGET_AMD64_)
6637 s_DebuggerLaunchJitInfo.dwProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64;
6638 #elif defined(_TARGET_ARM_)
6639 s_DebuggerLaunchJitInfo.dwProcessorArchitecture = PROCESSOR_ARCHITECTURE_ARM;
6640 #elif defined(_TARGET_ARM64_)
6641 s_DebuggerLaunchJitInfo.dwProcessorArchitecture = PROCESSOR_ARCHITECTURE_ARM64;
6643 #error Unknown processor.
6648 //----------------------------------------------------------------------------
6650 // GetDebuggerLaunchJitInfo - retrieve the initialized JDI structure on Vista
6656 // JIT_DEBUG_INFO * - pointer to JDI structure
6658 //----------------------------------------------------------------------------
6659 JIT_DEBUG_INFO * Debugger::GetDebuggerLaunchJitInfo(void)
6661 LIMITED_METHOD_CONTRACT;
6663 _ASSERTE((s_DebuggerLaunchJitInfo.lpExceptionAddress != NULL) &&
6664 (s_DebuggerLaunchJitInfo.lpExceptionRecord != NULL) &&
6665 (s_DebuggerLaunchJitInfo.lpContextRecord != NULL) &&
6666 (((EXCEPTION_RECORD *)(s_DebuggerLaunchJitInfo.lpExceptionRecord))->ExceptionAddress != NULL));
6668 return &s_DebuggerLaunchJitInfo;
6670 #endif // !DACCESS_COMPILE
6673 // This function checks the registry for the debug launch setting upon encountering an exception or breakpoint.
6674 DebuggerLaunchSetting Debugger::GetDbgJITDebugLaunchSetting()
6684 DebuggerLaunchSetting setting = DLS_ATTACH_DEBUGGER;
6688 DebuggerLaunchSetting setting = DLS_ASK_USER;
6690 DWORD cchDbgFormat = MAX_LONGPATH;
6691 INDEBUG(DWORD cchOldDbgFormat = cchDbgFormat);
6693 #if defined(DACCESS_COMPILE)
6694 WCHAR * wszDbgFormat = new (nothrow) WCHAR[cchDbgFormat];
6696 WCHAR * wszDbgFormat = new (interopsafe, nothrow) WCHAR[cchDbgFormat];
6697 #endif // DACCESS_COMPILE
6699 if (wszDbgFormat == NULL)
6704 HRESULT hr = GetDebuggerSettingInfoWorker(wszDbgFormat, &cchDbgFormat, &bAuto);
6705 while (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
6707 _ASSERTE(cchDbgFormat > cchOldDbgFormat);
6708 INDEBUG(cchOldDbgFormat = cchDbgFormat);
6710 #if defined(DACCESS_COMPILE)
6711 delete [] wszDbgFormat;
6712 wszDbgFormat = new (nothrow) WCHAR[cchDbgFormat];
6714 DeleteInteropSafe(wszDbgFormat);
6715 wszDbgFormat = new (interopsafe, nothrow) WCHAR[cchDbgFormat];
6716 #endif // DACCESS_COMPILE
6718 if (wszDbgFormat == NULL)
6723 hr = GetDebuggerSettingInfoWorker(wszDbgFormat, &cchDbgFormat, &bAuto);
6726 #if defined(DACCESS_COMPILE)
6727 delete [] wszDbgFormat;
6729 DeleteInteropSafe(wszDbgFormat);
6730 #endif // DACCESS_COMPILE
6732 if (SUCCEEDED(hr) && bAuto)
6734 setting = DLS_ATTACH_DEBUGGER;
6736 #endif // FEATURE_PAL
6741 // Returns a bitfield reflecting the managed debugging state at the time of
6743 CLR_DEBUGGING_PROCESS_FLAGS Debugger::GetAttachStateFlags()
6745 LIMITED_METHOD_DAC_CONTRACT;
6746 ULONG flags = CLRJitAttachState;
6747 return (CLR_DEBUGGING_PROCESS_FLAGS)flags;
6750 #ifndef DACCESS_COMPILE
6751 //-----------------------------------------------------------------------------
6752 // Get the full launch string for a jit debugger.
6754 // If a jit-debugger is registed, then writes string into pStrArgsBuf and
6757 // If no jit-debugger is registered, then return false.
6759 // Throws on error (like OOM).
6760 //-----------------------------------------------------------------------------
6761 bool Debugger::GetCompleteDebuggerLaunchString(SString * pStrArgsBuf)
6771 DWORD pid = GetCurrentProcessId();
6773 SString ssDebuggerString;
6774 GetDebuggerSettingInfo(ssDebuggerString, NULL);
6776 if (ssDebuggerString.IsEmpty())
6778 // No jit-debugger available. Don't make one up.
6782 // There is no security concern to expect that the debug string we retrieve from HKLM follows a certain
6783 // format because changing HKLM keys requires admin priviledge. Padding with zeros is not a security mitigation,
6784 // but rather a forward looking compability measure. If future verions of Windows introduces more parameters for
6785 // JIT debugger launch, it is preferrable to pass zeros than other random values for those unsupported parameters.
6786 pStrArgsBuf->Printf(ssDebuggerString, pid, GetUnmanagedAttachEvent(), GetDebuggerLaunchJitInfo(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
6789 #else // !FEATURE_PAL
6791 #endif // !FEATURE_PAL
6794 // Proxy code for EDA
6795 struct EnsureDebuggerAttachedParams
6799 PROCESS_INFORMATION * m_pProcessInfo;
6800 EnsureDebuggerAttachedParams() :
6801 m_pThis(NULL), m_retval(E_FAIL), m_pProcessInfo(NULL) {LIMITED_METHOD_CONTRACT; }
6804 // This is called by the helper thread
6805 void EDAHelperStub(EnsureDebuggerAttachedParams * p)
6807 WRAPPER_NO_CONTRACT;
6809 p->m_retval = p->m_pThis->EDAHelper(p->m_pProcessInfo);
6812 // This gets called just like the normal version, but it sends the call over to the helper thread
6813 HRESULT Debugger::EDAHelperProxy(PROCESS_INFORMATION * pProcessInfo)
6822 _ASSERTE(!ThisIsHelperThreadWorker());
6823 _ASSERTE(ThreadHoldsLock());
6825 HRESULT hr = LazyInitWrapper();
6828 // We already stress logged this case.
6833 if (!IsGuardPageGone())
6835 return EDAHelper(pProcessInfo);
6838 EnsureDebuggerAttachedParams p;
6840 p.m_pProcessInfo = pProcessInfo;
6842 LOG((LF_CORDB, LL_INFO1000000, "D::EDAHelperProxy\n"));
6843 m_pRCThread->DoFavor((FAVORCALLBACK) EDAHelperStub, &p);
6844 LOG((LF_CORDB, LL_INFO1000000, "D::EDAHelperProxy return\n"));
6849 // E_ABORT - if the attach was declined
6850 // S_OK - Jit-attach successfully started
6851 HRESULT Debugger::EDAHelper(PROCESS_INFORMATION *pProcessInfo)
6856 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
6858 PRECONDITION(ThisMaybeHelperThread()); // on helper if stackoverflow.
6863 LOG((LF_CORDB, LL_INFO10000, "D::EDA: thread 0x%x is launching the debugger.\n", GetCurrentThreadId()));
6865 _ASSERTE(HasLazyData());
6867 // Another potential hang. This may get run on the helper if we have a stack overflow.
6868 // Hopefully the odds of 1 thread hitting a stack overflow while another is stuck holding the heap
6869 // lock is very small.
6870 SUPPRESS_ALLOCATION_ASSERTS_IN_THIS_SCOPE;
6872 BOOL fCreateSucceeded = FALSE;
6874 StackSString strDbgCommand;
6875 const WCHAR * wszDbgCommand = NULL;
6876 SString strCurrentDir;
6877 const WCHAR * wszCurrentDir = NULL;
6882 // Get the debugger to launch. The returned string is via the strDbgCommand out param. Throws on error.
6883 bool fHasDebugger = GetCompleteDebuggerLaunchString(&strDbgCommand);
6886 wszDbgCommand = strDbgCommand.GetUnicode();
6887 _ASSERTE(wszDbgCommand != NULL); // would have thrown on oom.
6889 LOG((LF_CORDB, LL_INFO10000, "D::EDA: launching with command [%S]\n", wszDbgCommand));
6891 ClrGetCurrentDirectory(strCurrentDir);
6892 wszCurrentDir = strCurrentDir.GetUnicode();
6898 EX_END_CATCH(SwallowAllExceptions);
6900 STARTUPINFOW startupInfo = {0};
6901 startupInfo.cb = sizeof(STARTUPINFOW);
6903 DWORD errCreate = 0;
6905 if (wszDbgCommand != NULL)
6907 // Create the debugger process
6908 // When we are launching an debugger, we need to let the child process inherit our handles.
6909 // This is necessary for the debugger to signal us that the attach is complete.
6910 fCreateSucceeded = WszCreateProcess(NULL, const_cast<WCHAR*> (wszDbgCommand),
6914 NULL, wszCurrentDir,
6917 errCreate = GetLastError();
6920 if (!fCreateSucceeded)
6922 LOG((LF_CORDB, LL_INFO10000, "D::EDA: debugger did not launch successfully.\n"));
6926 LOG((LF_CORDB, LL_INFO10000, "D::EDA: debugger launched successfully.\n"));
6928 #else // !FEATURE_PAL
6930 #endif // !FEATURE_PAL
6933 // ---------------------------------------------------------------------------------------------------------------------
6934 // This function decides who wins the race for any jit attach and marks the appropriate state that a jit
6935 // attach is in progress.
6938 // willSendManagedEvent - indicates whether or not we plan to send a managed debug event after the jit attach
6939 // explicitUserRequest - TRUE if this attach is caused by a call to the Debugger.Launch() API.
6942 // TRUE - if some other thread already has jit attach in progress -> this thread should block until that is complete
6943 // FALSE - this is the first thread to jit attach -> this thread should launch the debugger
6946 BOOL Debugger::PreJitAttach(BOOL willSendManagedEvent, BOOL willLaunchDebugger, BOOL explicitUserRequest)
6953 PRECONDITION(!ThisIsHelperThreadWorker());
6957 LOG( (LF_CORDB, LL_INFO10000, "D::PreJA: Entering\n") );
6959 // Multiple threads may be calling this, so need to take the lock.
6960 if(!m_jitAttachInProgress)
6962 // TODO: This is a known deadlock! Debugger::PreJitAttach is called during WatsonLastChance.
6963 // If the event (exception/crash) happens while this thread is holding the ThreadStore
6964 // lock, we may deadlock if another thread holds the DebuggerMutex and is waiting on
6965 // the ThreadStore lock. The DebuggerMutex has to be broken into two smaller locks
6966 // so that you can take that lock here when holding the ThreadStore lock.
6967 DebuggerLockHolder dbgLockHolder(this);
6969 if (!m_jitAttachInProgress)
6971 m_jitAttachInProgress = TRUE;
6972 m_launchingDebugger = willLaunchDebugger;
6973 CLRJitAttachState = (willSendManagedEvent ? CLR_DEBUGGING_MANAGED_EVENT_PENDING : 0) | (explicitUserRequest ? CLR_DEBUGGING_MANAGED_EVENT_DEBUGGER_LAUNCH : 0);
6974 ResetEvent(GetUnmanagedAttachEvent());
6975 ResetEvent(GetAttachEvent());
6976 LOG( (LF_CORDB, LL_INFO10000, "D::PreJA: Leaving - first thread\n") );
6981 LOG( (LF_CORDB, LL_INFO10000, "D::PreJA: Leaving - following thread\n") );
6985 //---------------------------------------------------------------------------------------------------------------------
6986 // This function gets the jit debugger launched and waits for the native attach to complete
6987 // Make sure you called PreJitAttach and it returned TRUE before you call this
6990 // pThread - the managed thread with the unhandled excpetion
6991 // pExceptionInfo - the unhandled exception info
6994 // S_OK if the debugger was launched successfully and a failing HRESULT otherwise
6996 HRESULT Debugger::LaunchJitDebuggerAndNativeAttach(Thread * pThread, EXCEPTION_POINTERS * pExceptionInfo)
7003 PRECONDITION(!ThisIsHelperThreadWorker());
7007 // You need to have called PreJitAttach first to determine which thread gets to launch the debugger
7008 _ASSERTE(m_jitAttachInProgress);
7010 LOG( (LF_CORDB, LL_INFO10000, "D::LJDANA: Entering\n") );
7011 PROCESS_INFORMATION processInfo = {0};
7012 DebuggerLockHolder dbgLockHolder(this);
7015 // If the JIT debugger failed to launch or if there is no JIT debugger, EDAHelperProxy will
7016 // switch to preemptive GC mode to display a dialog to the user indicating the JIT debugger
7017 // was unavailable. There are some rare cases where this could cause a deadlock with the
7018 // debugger lock; however these are rare enough that fixing this doesn't meet the bar for
7019 // Whidbey at this point. We might want to revisit this later however.
7021 CONTRACT_VIOLATION(GCViolation);
7024 LOG((LF_CORDB, LL_INFO1000, "D::EDA: Initialize JDI.\n"));
7026 EXCEPTION_POINTERS exceptionPointer;
7027 EXCEPTION_RECORD exceptionRecord;
7030 if (pExceptionInfo == NULL)
7032 ZeroMemory(&exceptionPointer, sizeof(exceptionPointer));
7033 ZeroMemory(&exceptionRecord, sizeof(exceptionRecord));
7034 ZeroMemory(&context, sizeof(context));
7036 context.ContextFlags = CONTEXT_CONTROL;
7037 ClrCaptureContext(&context);
7039 exceptionRecord.ExceptionAddress = reinterpret_cast<PVOID>(GetIP(&context));
7040 exceptionPointer.ContextRecord = &context;
7041 exceptionPointer.ExceptionRecord = &exceptionRecord;
7043 pExceptionInfo = &exceptionPointer;
7046 InitDebuggerLaunchJitInfo(pThread, pExceptionInfo);
7049 // This will make the CreateProcess call to create the debugger process.
7050 // We then expect that the debugger process will turn around and attach to us.
7051 HRESULT hr = EDAHelperProxy(&processInfo);
7057 LOG((LF_CORDB, LL_INFO10000, "D::LJDANA: waiting on m_exUnmanagedAttachEvent and debugger's process handle\n"));
7058 DWORD dwHandles = 2;
7059 HANDLE arrHandles[2];
7060 arrHandles[0] = GetUnmanagedAttachEvent();
7061 arrHandles[1] = processInfo.hProcess;
7063 // Let the helper thread do the attach logic for us and wait for the
7064 // attach event. Must release the lock before blocking on a wait.
7065 dbgLockHolder.Release();
7067 // Wait for one or the other to be set. Multiple threads could be waiting here.
7068 // The events are manual events, so when they go high, all threads will be released.
7069 DWORD res = WaitForMultipleObjectsEx(dwHandles, arrHandles, FALSE, INFINITE, FALSE);
7071 // We no long need to keep handles to the debugger process.
7072 CloseHandle(processInfo.hProcess);
7073 CloseHandle(processInfo.hThread);
7075 // Indicate to the caller that the attach was aborted
7076 if (res == WAIT_OBJECT_0 + 1)
7078 LOG((LF_CORDB, LL_INFO10000, "D::LJDANA: Debugger process is unexpectedly terminated!\n"));
7082 // Otherwise, attach was successful (Note, only native attach is done so far)
7083 _ASSERTE((res == WAIT_OBJECT_0) && "WaitForMultipleObjectsEx failed!");
7084 LOG( (LF_CORDB, LL_INFO10000, "D::LJDANA: Leaving\n") );
7089 // Blocks until the debugger completes jit attach
7090 void Debugger::WaitForDebuggerAttach()
7092 LIMITED_METHOD_CONTRACT;
7094 LOG( (LF_CORDB, LL_INFO10000, "D::WFDA:Entering\n") );
7096 // if this thread previously called LaunchDebuggerAndNativeAttach then this wait is spurious,
7097 // the event is still set and it continues immediately. If this is an auxilliary thread however
7098 // then the wait is necessary
7099 // If we are not launching the debugger (e.g. unhandled exception on Win7), then we should not
7100 // wait on the unmanaged attach event. If the debugger is launched by the OS, then the unmanaged
7101 // attach event passed to the debugger is created by the OS, not by us, so our event will never
7103 if (m_launchingDebugger)
7105 WaitForSingleObject(GetUnmanagedAttachEvent(), INFINITE);
7108 // Wait until the pending managed debugger attach is completed
7109 if (CORDebuggerPendingAttach() && !CORDebuggerAttached())
7111 LOG( (LF_CORDB, LL_INFO10000, "D::WFDA: Waiting for managed attach too\n") );
7112 WaitForSingleObject(GetAttachEvent(), INFINITE);
7115 // We can't reset the event here because some threads may
7116 // be just about to wait on it. If we reset it before the
7117 // other threads hit the wait, they'll block.
7119 // We have an innate race here that can't easily fix. The best
7120 // we can do is have a super small window (by moving the reset as
7121 // far out this making it very unlikely that a thread will
7124 LOG( (LF_CORDB, LL_INFO10000, "D::WFDA: Leaving\n") );
7127 // Cleans up after jit attach is complete
7128 void Debugger::PostJitAttach()
7135 PRECONDITION(!ThisIsHelperThreadWorker());
7139 LOG( (LF_CORDB, LL_INFO10000, "D::PostJA: Entering\n") );
7140 // Multiple threads may be calling this, so need to take the lock.
7141 DebuggerLockHolder dbgLockHolder(this);
7143 // clear the attaching flags which allows other threads to initiate jit attach if needed
7144 m_jitAttachInProgress = FALSE;
7145 m_launchingDebugger = FALSE;
7146 CLRJitAttachState = 0;
7148 // set the attaching events to unblock other threads waiting on this attach
7149 // regardless of whether or not it completed
7150 SetEvent(GetUnmanagedAttachEvent());
7151 SetEvent(GetAttachEvent());
7152 LOG( (LF_CORDB, LL_INFO10000, "D::PostJA: Leaving\n") );
7155 //---------------------------------------------------------------------------------------
7156 // Launches a debugger and blocks waiting for it to either attach or abort the attach.
7159 // pThread - the managed thread with the unhandled excpetion
7160 // pExceptionInfo - the unhandled exception info
7161 // willSendManagedEvent - TRUE if after getting attached we will send a managed debug event
7162 // explicitUserRequest - TRUE if this attach is caused by a call to the Debugger.Launch() API.
7165 // None. Callers can requery if a debugger is attached.
7168 // This may be called by multiple threads, each firing their own debug events. This function will handle locking.
7169 // Thus this could block for an arbitrary length of time:
7170 // - may need to prompt the user to decide if an attach occurs.
7171 // - may block waiting for a debugger to attach.
7174 // The launch string is retrieved from code:GetDebuggerSettingInfo.
7175 // This will not do a sync-complete. Instead, the caller can send a debug event (the jit-attach
7176 // event, such as a User-breakpoint or unhandled exception) and that can send a sync-complete,
7177 // just as if the debugger was always attached. This ensures that the jit-attach event is in the
7178 // same callback queue as any faked-up events that the Right-side Shim creates.
7180 void Debugger::JitAttach(Thread * pThread, EXCEPTION_POINTERS * pExceptionInfo, BOOL willSendManagedEvent, BOOL explicitUserRequest)
7188 PRECONDITION(!ThisIsHelperThreadWorker()); // Must be a managed thread
7192 // Don't do anything if there is a native debugger already attached or the debugging support has been disabled.
7193 if (IsDebuggerPresent() || m_pRCThread == NULL)
7196 GCX_PREEMP_EEINTERFACE_TOGGLE_IFTHREAD();
7198 EnsureDebuggerAttached(pThread, pExceptionInfo, willSendManagedEvent, explicitUserRequest);
7201 //-----------------------------------------------------------------------------
7202 // Ensure that a debugger is attached. Will jit-attach if needed.
7205 // pThread - the managed thread with the unhandled excpetion
7206 // pExceptionInfo - the unhandled exception info
7207 // willSendManagedEvent - true if after getting (or staying) attached we will send
7208 // a managed debug event
7209 // explicitUserRequest - true if this attach is caused by a call to the
7210 // Debugger.Launch() API.
7213 // None. Either a debugger is attached or it is not.
7216 // There are several intermediate possible outcomes:
7217 // - Debugger already attached before this was called.
7218 // - JIT-atttach debugger spawned, and attached successfully.
7219 // - JIT-attach debugger spawned, but declined to attach.
7220 // - Failed to spawn jit-attach debugger.
7222 // Ultimately, the only thing that matters at the end is whether a debugger
7223 // is now attached, which is retreived via CORDebuggerAttached().
7224 //-----------------------------------------------------------------------------
7225 void Debugger::EnsureDebuggerAttached(Thread * pThread, EXCEPTION_POINTERS * pExceptionInfo, BOOL willSendManagedEvent, BOOL explicitUserRequest)
7232 PRECONDITION(!ThisIsHelperThreadWorker());
7236 LOG( (LF_CORDB,LL_INFO10000,"D::EDA\n") );
7240 // We could be in three states:
7241 // 1) no debugger attached
7242 // 2) native attached but not managed (yet?)
7243 // 3) native attached and managed
7246 // There is a race condition here that can be hit if multiple threads
7247 // were to trigger jit attach at the right time
7248 // Thread 1 starts jit attach
7249 // Thread 2 also starts jit attach and gets to waiting for the attach complete
7250 // Thread 1 rapidly completes the jit attach then starts it again
7251 // Thread 2 may still be waiting from the first jit attach at this point
7253 // Note that this isn't all that bad because if the debugger hasn't actually detached
7254 // in the middle then the second jit attach will complete almost instantly and thread 2
7255 // is unblocked. If the debugger did detach in the middle then it seems reasonable for
7256 // thread 2 to continue to wait until until the debugger is attached once again for the
7257 // second attach. Basically if one jit attach completes and restarts fast enough it might
7258 // just go unnoticed by some threads and it will be as if it never happened. Doesn't seem
7259 // that bad as long as we know another jit attach is again in progress.
7261 BOOL startedJitAttach = FALSE;
7263 // First check to see if we need to launch the debugger ourselves
7264 if(PreJitAttach(willSendManagedEvent, TRUE, explicitUserRequest))
7266 // if the debugger is already attached then we can't launch one
7267 // and whatever attach state we are in is just what we get
7268 if(IsDebuggerPresent())
7270 // unblock other threads waiting on our attach and clean up
7276 hr = LaunchJitDebuggerAndNativeAttach(pThread, pExceptionInfo);
7279 // unblock other threads waiting on our attach and clean up
7284 startedJitAttach = TRUE;
7287 // at this point someone should have launched the native debugger and
7288 // it is somewhere between not attached and attach complete
7289 // (it might have even been completely attached before this function even started)
7290 // step 2 - wait for the attach to complete
7291 WaitForDebuggerAttach();
7293 // step 3 - if we initiated then we also cleanup
7294 if(startedJitAttach)
7296 LOG( (LF_CORDB, LL_INFO10000, "D::EDA:Leaving\n") );
7300 // Proxy code for AttachDebuggerForBreakpoint
7301 // Structure used in the proxy function callback
7302 struct SendExceptionOnHelperThreadParams
7307 OBJECTHANDLE m_exceptionHandle;
7309 FramePointer m_framePointer;
7311 CorDebugExceptionCallbackType m_eventType;
7315 SendExceptionOnHelperThreadParams() :
7319 {LIMITED_METHOD_CONTRACT; }
7322 //**************************************************************************
7323 // This function sends Exception and ExceptionCallback2 event.
7326 // pThread : managed thread which exception takes place
7327 // exceptionHandle : handle to the managed exception object (usually
7328 // something derived from System.Exception)
7329 // fContinuable : true iff continuable
7330 // framePointer : frame pointer associated with callback.
7331 // nOffset : il offset associated with callback.
7332 // eventType : type of callback
7333 // dwFlags : additional flags (see CorDebugExceptionFlags).
7336 // S_OK on sucess. Else some error. May also throw.
7339 // This is a helper for code:Debugger.SendExceptionEventsWorker.
7340 // See code:Debugger.SendException for more details about parameters.
7341 // This is always called on a managed thread (never the helper thread)
7342 // This will synchronize and block.
7343 //**************************************************************************
7344 HRESULT Debugger::SendExceptionHelperAndBlock(
7346 OBJECTHANDLE exceptionHandle,
7348 FramePointer framePointer,
7350 CorDebugExceptionCallbackType eventType,
7360 PRECONDITION(CheckPointer(pThread));
7366 // This is a normal event to send from LS to RS
7367 SENDIPCEVENT_BEGIN(this, pThread);
7369 // This function can be called on helper thread or managed thread.
7370 // However, we should be holding locks upon entry
7372 DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer();
7375 // Send pre-Whidbey EXCEPTION IPC event.
7377 InitIPCEvent(ipce, DB_IPCE_EXCEPTION, pThread, pThread->GetDomain());
7379 ipce->Exception.vmExceptionHandle.SetRawPtr(exceptionHandle);
7380 ipce->Exception.firstChance = (eventType == DEBUG_EXCEPTION_FIRST_CHANCE);
7381 ipce->Exception.continuable = fContinuable;
7382 hr = m_pRCThread->SendIPCEvent();
7384 _ASSERTE(SUCCEEDED(hr) && "D::SE: Send ExceptionCallback event failed.");
7387 // Send Whidbey EXCEPTION IPC event.
7389 InitIPCEvent(ipce, DB_IPCE_EXCEPTION_CALLBACK2, pThread, pThread->GetDomain());
7391 ipce->ExceptionCallback2.framePointer = framePointer;
7392 ipce->ExceptionCallback2.eventType = eventType;
7393 ipce->ExceptionCallback2.nOffset = nOffset;
7394 ipce->ExceptionCallback2.dwFlags = dwFlags;
7395 ipce->ExceptionCallback2.vmExceptionHandle.SetRawPtr(exceptionHandle);
7397 LOG((LF_CORDB, LL_INFO10000, "D::SE: sending ExceptionCallback2 event"));
7398 hr = m_pRCThread->SendIPCEvent();
7400 if (eventType == DEBUG_EXCEPTION_FIRST_CHANCE)
7402 pThread->GetExceptionState()->GetFlags()->SetSentDebugFirstChance();
7406 _ASSERTE(eventType == DEBUG_EXCEPTION_UNHANDLED);
7409 _ASSERTE(SUCCEEDED(hr) && "D::SE: Send ExceptionCallback2 event failed.");
7413 // Stop all Runtime threads
7414 TrapAllRuntimeThreads();
7417 // Let other Runtime threads handle their events.
7424 // Send various first-chance / unhandled exception events.
7427 // Caller has already determined that we want to send exception events.
7430 // This is a helper function for code:Debugger.SendException
7431 void Debugger::SendExceptionEventsWorker(
7434 bool fIsInterceptable,
7437 FramePointer framePointer,
7442 ThreadExceptionState* pExState = pThread->GetExceptionState();
7444 // Figure out parameters to the IPC events.
7448 SIZE_T nOffset = (SIZE_T)ICorDebugInfo::NO_MAPPING;
7449 DebuggerMethodInfo *pDebugMethodInfo = NULL;
7451 // If we're passed a zero IP or SP, then go to the ThreadExceptionState on the thread to get the data. Note:
7452 // we can only do this if there is a context in the pExState. There are cases (most notably the
7453 // EEPolicy::HandleFatalError case) where we don't have that. So we just leave the IP/SP 0.
7454 if ((currentIP == 0) && (pExState->GetContextRecord() != NULL))
7456 ip = (BYTE *)GetIP(pExState->GetContextRecord());
7460 ip = (BYTE *)currentIP;
7463 if (g_pEEInterface->IsManagedNativeCode(ip))
7466 MethodDesc *pMethodDesc = g_pEEInterface->GetNativeCodeMethodDesc(PCODE(ip));
7467 _ASSERTE(pMethodDesc != NULL);
7469 if (pMethodDesc != NULL)
7471 DebuggerJitInfo *pDebugJitInfo = GetJitInfo(pMethodDesc, ip, &pDebugMethodInfo);
7473 if (pDebugJitInfo != NULL)
7475 SIZE_T nativeOffset = CodeRegionInfo::GetCodeRegionInfo(pDebugJitInfo, pMethodDesc).AddressToOffset(ip);
7476 CorDebugMappingResult mapResult;
7479 nOffset = pDebugJitInfo->MapNativeOffsetToIL(nativeOffset, &mapResult, &which);
7484 DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer();
7488 // We can call into this method when there is no exception in progress to alert
7489 // the debugger to a stack overflow, however that case should never specify first
7490 // chance. An exception must be in progress to check the flags on the exception state
7491 _ASSERTE(pThread->IsExceptionInProgress());
7494 // Send the first chance exception if we have not already and if it is not suppressed
7496 if (m_sendExceptionsOutsideOfJMC && !pExState->GetFlags()->SentDebugFirstChance())
7498 // Blocking here is especially important so that the debugger can mark any code as JMC.
7499 hr = SendExceptionHelperAndBlock(
7501 g_pEEInterface->GetThreadException(pThread),
7505 DEBUG_EXCEPTION_FIRST_CHANCE,
7506 fIsInterceptable ? DEBUG_EXCEPTION_CAN_BE_INTERCEPTED : 0);
7509 // Toggle GC into COOP to block this thread.
7510 GCX_COOP_EEINTERFACE();
7513 // If we weren't at a safe place when we enabled PGC, then go ahead and unmark that fact now that we've successfully
7518 g_pDebugger->DecThreadsAtUnsafePlaces();
7521 ProcessAnyPendingEvals(pThread);
7524 // If we weren't at a safe place, increment the unsafe count before we enable preemptive mode.
7528 g_pDebugger->IncThreadsAtUnsafePlaces();
7530 } // end of GCX_CCOP_EEINTERFACE();
7531 } //end if (m_sendExceptionsOutsideOfJMC && !SentDebugFirstChance())
7534 // If this is a JMC function, then we send a USER's first chance as well.
7536 if ((pDebugMethodInfo != NULL) &&
7537 pDebugMethodInfo->IsJMCFunction() &&
7538 !pExState->GetFlags()->SentDebugUserFirstChance())
7540 SENDIPCEVENT_BEGIN(this, pThread);
7542 InitIPCEvent(ipce, DB_IPCE_EXCEPTION_CALLBACK2, pThread, pThread->GetDomain());
7544 ipce->ExceptionCallback2.framePointer = framePointer;
7545 ipce->ExceptionCallback2.eventType = DEBUG_EXCEPTION_USER_FIRST_CHANCE;
7546 ipce->ExceptionCallback2.nOffset = nOffset;
7547 ipce->ExceptionCallback2.dwFlags = fIsInterceptable ? DEBUG_EXCEPTION_CAN_BE_INTERCEPTED : 0;
7548 ipce->ExceptionCallback2.vmExceptionHandle.SetRawPtr(g_pEEInterface->GetThreadException(pThread));
7550 LOG((LF_CORDB, LL_INFO10000, "D::SE: sending ExceptionCallback2 (USER FIRST CHANCE)"));
7551 hr = m_pRCThread->SendIPCEvent();
7553 _ASSERTE(SUCCEEDED(hr) && "D::SE: Send ExceptionCallback2 (User) event failed.");
7557 // Stop all Runtime threads
7558 TrapAllRuntimeThreads();
7561 pExState->GetFlags()->SetSentDebugUserFirstChance();
7563 // Let other Runtime threads handle their events.
7566 } // end if (!SentDebugUserFirstChance)
7568 } // end if (firstChance)
7571 // unhandled exception case
7572 // if there is no exception in progress then we are sending a fake exception object
7573 // as an indication of a fatal error (stack overflow). In this case it is illegal
7574 // to read GetFlags() from the exception state.
7575 // else if there is an exception in progress we only want to send the notification if
7576 // we did not already send a CHF, previous unhandled, or unwind begin notification
7577 BOOL sendNotification = TRUE;
7578 if(pThread->IsExceptionInProgress())
7580 sendNotification = !pExState->GetFlags()->DebugCatchHandlerFound() &&
7581 !pExState->GetFlags()->SentDebugUnhandled() &&
7582 !pExState->GetFlags()->SentDebugUnwindBegin();
7585 if(sendNotification)
7587 hr = SendExceptionHelperAndBlock(
7589 g_pEEInterface->GetThreadException(pThread),
7592 (SIZE_T)ICorDebugInfo::NO_MAPPING,
7593 DEBUG_EXCEPTION_UNHANDLED,
7594 fIsInterceptable ? DEBUG_EXCEPTION_CAN_BE_INTERCEPTED : 0);
7596 if(pThread->IsExceptionInProgress())
7598 pExState->GetFlags()->SetSentDebugUnhandled();
7602 } // end if (!firstChance)
7606 // SendException is called by Runtime threads to send that they've hit an Managed exception to the Right Side.
7607 // This may block this thread and suspend the debuggee, and let the debugger inspect us.
7609 // The thread's throwable should be set so that the debugger can inspect the current exception.
7610 // It does not report native exceptions in native code (which is consistent because those don't have a
7611 // managed exception object).
7613 // This may kick off a jit-attach (in which case fAttaching==true), and so may be called even when no debugger
7617 // pThread - the thread throwing the exception.
7618 // fFirstChance - true if this is a first chance exception. False if this is an unhandled exception.
7619 // currentIP - absolute native address of the exception if it is from managed code. If this is 0, we try to find it
7620 // based off the thread's current exception state.
7621 // currentSP - stack pointer of the exception. This will get converted into a FramePointer and then used by the debugger
7622 // to identify which stack frame threw the exception.
7623 // currentBSP - additional information for IA64 only to identify the stack frame.
7624 // fContinuable - not used.
7625 // fAttaching - true iff this exception may initiate a jit-attach. In the common case, if this is true, then
7626 // CorDebuggerAttached() is false. However, since a debugger can attach at any time, it's possible
7627 // for another debugger to race against the jit-attach and win. Thus this may err on the side of being true.
7628 // fForceNonInterceptable - This is used to determine if the exception is continuable (ie "Interceptible",
7629 // we can handle a DB_IPCE_INTERCEPT_EXCEPTION event for it). If true, then the exception can not be continued.
7630 // If false, we get continuation status from the exception properties of the current thread.
7633 // S_OK on success (common case by far).
7634 // propogates other errors.
7636 HRESULT Debugger::SendException(Thread *pThread,
7640 bool fContinuable, // not used by RS.
7642 bool fForceNonInterceptable,
7643 EXCEPTION_POINTERS * pExceptionInfo)
7652 PRECONDITION(HasLazyData());
7653 PRECONDITION(CheckPointer(pThread));
7654 PRECONDITION((pThread->GetFilterContext() == NULL) || !fFirstChance);
7658 LOG((LF_CORDB, LL_INFO10000, "D::SendException\n"));
7660 if (CORDBUnrecoverableError(this))
7665 // Mark if we're at an unsafe place.
7666 AtSafePlaceHolder unsafePlaceHolder(pThread);
7668 // Grab the exception name from the current exception object to pass to the JIT attach.
7669 bool fIsInterceptable;
7671 if (fForceNonInterceptable)
7673 fIsInterceptable = false;
7674 m_forceNonInterceptable = true;
7678 fIsInterceptable = IsInterceptableException(pThread);
7679 m_forceNonInterceptable = false;
7682 ThreadExceptionState* pExState = pThread->GetExceptionState();
7683 BOOL managedEventNeeded = ((!fFirstChance) ||
7684 (fFirstChance && (!pExState->GetFlags()->SentDebugFirstChance() || !pExState->GetFlags()->SentDebugUserFirstChance())));
7686 // There must be a managed exception object to send a managed exception event
7687 if (g_pEEInterface->IsThreadExceptionNull(pThread) && (pThread->LastThrownObjectHandle() == NULL))
7689 managedEventNeeded = FALSE;
7694 JitAttach(pThread, pExceptionInfo, managedEventNeeded, FALSE);
7695 // If the jit-attach occurred, CORDebuggerAttached() may now be true and we can
7696 // just act as if a debugger was always attached.
7699 if(managedEventNeeded)
7702 // We have to send enabled, so enable now.
7703 GCX_PREEMP_EEINTERFACE();
7705 // Send the exception events. Even in jit-attach case, we should now be fully attached.
7706 if (CORDebuggerAttached())
7708 // Initialize frame-pointer associated with exception notification.
7709 LPVOID stackPointer;
7710 if ((currentSP == 0) && (pExState->GetContextRecord() != NULL))
7712 stackPointer = dac_cast<PTR_VOID>(GetSP(pExState->GetContextRecord()));
7716 stackPointer = (LPVOID)currentSP;
7718 FramePointer framePointer = FramePointer::MakeFramePointer(stackPointer);
7721 // Do the real work of sending the events
7722 SendExceptionEventsWorker(
7729 !unsafePlaceHolder.IsAtUnsafePlace());
7733 LOG((LF_CORDB,LL_INFO100, "D:SE: Skipping SendIPCEvent because not supposed to send anything, or RS detached.\n"));
7737 // If we weren't at a safe place when we switched to PREEMPTIVE, then go ahead and unmark that fact now
7738 // that we're successfully back in COOPERATIVE mode.
7739 unsafePlaceHolder.Clear();
7742 GCX_COOP_EEINTERFACE();
7743 ProcessAnyPendingEvals(pThread);
7747 if (CORDebuggerAttached())
7759 * ProcessAnyPendingEvals
7761 * This function checks for, and then processes, any pending func-evals.
7764 * pThread - The thread to process.
7770 void Debugger::ProcessAnyPendingEvals(Thread *pThread)
7780 #ifndef DACCESS_COMPILE
7782 // If no debugger is attached, then no evals to process.
7783 // We may get here in oom situations during jit-attach, so we'll check now and be safe.
7784 if (!CORDebuggerAttached())
7790 // Note: if there is a filter context installed, we may need remove it, do the eval, then put it back. I'm not 100%
7791 // sure which yet... it kinda depends on whether or not we really need the filter context updated due to a
7792 // collection during the func eval...
7794 // If we need to do a func eval on this thread, then there will be a pending eval registered for this thread. We'll
7795 // loop so long as there are pending evals registered. We block in FuncEvalHijackWorker after sending up the
7796 // FuncEvalComplete event, so if the user asks for another func eval then there will be a new pending eval when we
7797 // loop and check again.
7799 DebuggerPendingFuncEval *pfe;
7801 while (GetPendingEvals() != NULL && (pfe = GetPendingEvals()->GetPendingEval(pThread)) != NULL)
7803 DebuggerEval *pDE = pfe->pDE;
7805 _ASSERTE(pDE->m_evalDuringException);
7806 _ASSERTE(pDE->m_thread == GetThread());
7808 // Remove the pending eval from the hash. This ensures that if we take a first chance exception during the eval
7809 // that we can do another nested eval properly.
7810 GetPendingEvals()->RemovePendingEval(pThread);
7812 // Go ahead and do the pending func eval. pDE is invalid after this.
7814 ret = ::FuncEvalHijackWorker(pDE);
7817 // The return value should be NULL when FuncEvalHijackWorker is called as part of an exception.
7818 _ASSERTE(ret == NULL);
7821 // If we need to re-throw a ThreadAbortException, go ahead and do it now.
7822 if (GetThread()->m_StateNC & Thread::TSNC_DebuggerReAbort)
7824 // Now clear the bit else we'll see it again when we process the Exception notification
7825 // from this upcoming UserAbort exception.
7826 pThread->ResetThreadStateNC(Thread::TSNC_DebuggerReAbort);
7827 pThread->UserAbort(Thread::TAR_Thread, EEPolicy::TA_Safe, INFINITE, Thread::UAC_Normal);
7836 * FirstChanceManagedException is called by Runtime threads when crawling the managed stack frame
7837 * for a handler for the exception. It is called for each managed call on the stack.
7840 * pThread - The thread the exception is occurring on.
7841 * currentIP - the IP in the current stack frame.
7842 * currentSP - the SP in the current stack frame.
7848 bool Debugger::FirstChanceManagedException(Thread *pThread, SIZE_T currentIP, SIZE_T currentSP)
7852 // Implement DebugInterface
7853 // Can only be called from EE/exception
7854 // must be on managed thread.
7859 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
7861 PRECONDITION(CORDebuggerAttached());
7865 LOG((LF_CORDB, LL_INFO10000, "D::FCE: First chance exception, TID:0x%x, \n", GetThreadIdHelper(pThread)));
7867 _ASSERTE(GetThread() != NULL);
7870 static ConfigDWORD d_fce;
7871 if (d_fce.val(CLRConfig::INTERNAL_D__FCE))
7872 _ASSERTE(!"Stop in Debugger::FirstChanceManagedException?");
7875 SendException(pThread, TRUE, currentIP, currentSP, FALSE, FALSE, FALSE, NULL);
7882 * FirstChanceManagedExceptionCatcherFound is called by Runtime threads when crawling the
7883 * managed stack frame and a handler for the exception is found.
7886 * pThread - The thread the exception is occurring on.
7887 * pTct - Contains the function information that has the catch clause.
7888 * pEHClause - Contains the native offset information of the catch clause.
7894 void Debugger::FirstChanceManagedExceptionCatcherFound(Thread *pThread,
7895 MethodDesc *pMD, TADDR pMethodAddr,
7897 EE_ILEXCEPTION_CLAUSE *pEHClause)
7903 GC_TRIGGERS_FROM_GETJITINFO;
7909 // Implements DebugInterface
7910 // Call by EE/exception. Must be on managed thread
7911 _ASSERTE(GetThread() != NULL);
7914 if (!CORDebuggerAttached())
7919 // Compute the offset
7921 DWORD nOffset = (DWORD)(SIZE_T)ICorDebugInfo::NO_MAPPING;
7922 DebuggerMethodInfo *pDebugMethodInfo = NULL;
7923 DebuggerJitInfo *pDebugJitInfo = NULL;
7924 bool isInJMCFunction = false;
7928 _ASSERTE(!pMD->IsILStub());
7930 pDebugJitInfo = GetJitInfo(pMD, (const BYTE *) pMethodAddr, &pDebugMethodInfo);
7931 if (pDebugMethodInfo != NULL)
7933 isInJMCFunction = pDebugMethodInfo->IsJMCFunction();
7937 // Here we check if debugger opted-out of receiving exception related events from outside of JMC methods
7938 // or this exception ever crossed JMC frame (in this case we have already sent user first chance event)
7939 if (m_sendExceptionsOutsideOfJMC ||
7941 pThread->GetExceptionState()->GetFlags()->SentDebugUserFirstChance())
7943 if (pDebugJitInfo != NULL)
7945 CorDebugMappingResult mapResult;
7948 // Map the native instruction to the IL instruction.
7949 // Be sure to skip past the prolog on amd64/arm to get the right IL
7950 // instruction (on x86 there will not be a prolog as x86 does not use
7952 nOffset = pDebugJitInfo->MapNativeOffsetToIL(
7953 pEHClause->HandlerStartPC,
7960 bool fIsInterceptable = IsInterceptableException(pThread);
7961 m_forceNonInterceptable = false;
7962 DWORD dwFlags = fIsInterceptable ? DEBUG_EXCEPTION_CAN_BE_INTERCEPTED : 0;
7964 FramePointer fp = FramePointer::MakeFramePointer(currentSP);
7965 SendCatchHandlerFound(pThread, fp, nOffset, dwFlags);
7968 // flag that we catch handler found so that we won't send other mutually exclusive events
7969 // such as unwind begin or unhandled
7970 pThread->GetExceptionState()->GetFlags()->SetDebugCatchHandlerFound();
7973 // Filter to trigger CHF callback
7974 // Notify of a catch-handler found callback.
7975 LONG Debugger::NotifyOfCHFFilter(EXCEPTION_POINTERS* pExceptionPointers, PVOID pData)
7979 if ((GetThread() == NULL) || g_pEEInterface->IsThreadExceptionNull(GetThread()))
7987 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
7993 SCAN_IGNORE_TRIGGER; // Scan can't handle conditional contracts.
7996 // Implements DebugInterface
7997 // Can only be called from EE
7999 // If no debugger is attached, then don't bother sending the events.
8000 // This can't kick off a jit-attach.
8001 if (!CORDebuggerAttached())
8003 return EXCEPTION_CONTINUE_SEARCH;
8007 // If this exception has never bubbled thru to managed code, then there is no
8008 // useful information for the debugger and, in fact, it may be a completely
8009 // internally handled runtime exception, so we should do nothing.
8011 if ((GetThread() == NULL) || g_pEEInterface->IsThreadExceptionNull(GetThread()))
8013 return EXCEPTION_CONTINUE_SEARCH;
8016 // Caller must pass in the stack address. This should match up w/ a Frame.
8017 BYTE * pCatcherStackAddr = (BYTE*) pData;
8019 // If we don't have any catcher frame, then use ebp from the context.
8022 pCatcherStackAddr = (BYTE*) GetFP(pExceptionPointers->ContextRecord);
8027 _ASSERTE(pData != NULL);
8029 // We want the CHF stack addr to match w/ the Internal Frame Cordbg sees
8030 // in the stacktrace.
8031 // The Internal Frame comes from an EE Frame. This means that the CHF stack
8032 // addr must match that EE Frame exactly. Let's check that now.
8034 Frame * pFrame = reinterpret_cast<Frame*>(pData);
8035 // Calling a virtual method will enforce that we have a valid Frame. ;)
8036 // If we got passed in a random catch address, then when we cast to a Frame
8037 // the vtable pointer will be bogus and this call will AV.
8038 Frame::ETransitionType e;
8039 e = pFrame->GetTransitionType();
8044 // @todo - when Stubs-In-Stacktraces is always enabled, remove this.
8047 return EXCEPTION_CONTINUE_SEARCH;
8050 // Stubs don't have an IL offset.
8051 const SIZE_T offset = (SIZE_T)ICorDebugInfo::NO_MAPPING;
8052 Thread *pThread = GetThread();
8053 DWORD dwFlags = IsInterceptableException(pThread) ? DEBUG_EXCEPTION_CAN_BE_INTERCEPTED : 0;
8054 m_forceNonInterceptable = false;
8056 FramePointer fp = FramePointer::MakeFramePointer(pCatcherStackAddr);
8059 // If we have not sent a first-chance notification, do so now.
8061 ThreadExceptionState* pExState = pThread->GetExceptionState();
8063 if (!pExState->GetFlags()->SentDebugFirstChance())
8065 SendException(pThread,
8066 TRUE, // first-chance
8067 (SIZE_T)(GetIP(pExceptionPointers->ContextRecord)), // IP
8068 (SIZE_T)pCatcherStackAddr, // SP
8069 FALSE, // fContinuable
8071 TRUE, // ForceNonInterceptable since we are transition stub, the first and last place
8072 // that will see this exception.
8073 pExceptionPointers);
8076 // Here we check if debugger opted-out of receiving exception related events from outside of JMC methods
8077 // or this exception ever crossed JMC frame (in this case we have already sent user first chance event)
8078 if (m_sendExceptionsOutsideOfJMC || pExState->GetFlags()->SentDebugUserFirstChance())
8080 SendCatchHandlerFound(pThread, fp, offset, dwFlags);
8083 // flag that we catch handler found so that we won't send other mutually exclusive events
8084 // such as unwind begin or unhandled
8085 pExState->GetFlags()->SetDebugCatchHandlerFound();
8087 #ifdef DEBUGGING_SUPPORTED
8088 #ifdef DEBUGGER_EXCEPTION_INTERCEPTION_SUPPORTED
8089 if ( (pThread != NULL) &&
8090 (pThread->IsExceptionInProgress()) &&
8091 (pThread->GetExceptionState()->GetFlags()->DebuggerInterceptInfo()) )
8094 // The debugger wants to intercept this exception. It may return in a failure case,
8095 // in which case we want to continue thru this path.
8097 ClrDebuggerDoUnwindAndIntercept(X86_FIRST_ARG(EXCEPTION_CHAIN_END) pExceptionPointers->ExceptionRecord);
8099 #endif // DEBUGGER_EXCEPTION_INTERCEPTION_SUPPORTED
8100 #endif // DEBUGGING_SUPPORTED
8102 return EXCEPTION_CONTINUE_SEARCH;
8106 // Actually send the catch handler found event.
8107 // This can be used to send CHF for both regular managed catchers as well
8108 // as stubs that catch (Func-eval, COM-Interop, AppDomains)
8109 void Debugger::SendCatchHandlerFound(
8120 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
8125 LOG((LF_CORDB, LL_INFO10000, "D::FirstChanceManagedExceptionCatcherFound\n"));
8127 if (pThread == NULL)
8129 _ASSERTE(!"Bad parameter");
8130 LOG((LF_CORDB, LL_INFO10000, "D::FirstChanceManagedExceptionCatcherFound - Bad parameter.\n"));
8134 if (CORDBUnrecoverableError(this))
8140 // Mark if we're at an unsafe place.
8142 AtSafePlaceHolder unsafePlaceHolder(pThread);
8145 GCX_COOP_EEINTERFACE();
8148 SENDIPCEVENT_BEGIN(this, pThread);
8150 if (CORDebuggerAttached() &&
8151 !pThread->GetExceptionState()->GetFlags()->DebugCatchHandlerFound() &&
8152 !pThread->GetExceptionState()->GetFlags()->SentDebugUnhandled() &&
8153 !pThread->GetExceptionState()->GetFlags()->SentDebugUnwindBegin())
8158 // Figure out parameters to the IPC events.
8160 DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer();
8163 // Send Whidbey EXCEPTION IPC event.
8165 InitIPCEvent(ipce, DB_IPCE_EXCEPTION_CALLBACK2, pThread, pThread->GetDomain());
8167 ipce->ExceptionCallback2.framePointer = fp;
8168 ipce->ExceptionCallback2.eventType = DEBUG_EXCEPTION_CATCH_HANDLER_FOUND;
8169 ipce->ExceptionCallback2.nOffset = nOffset;
8170 ipce->ExceptionCallback2.dwFlags = dwFlags;
8171 ipce->ExceptionCallback2.vmExceptionHandle.SetRawPtr(g_pEEInterface->GetThreadException(pThread));
8173 LOG((LF_CORDB, LL_INFO10000, "D::FCMECF: sending ExceptionCallback2"));
8174 hr = m_pRCThread->SendIPCEvent();
8176 _ASSERTE(SUCCEEDED(hr) && "D::FCMECF: Send ExceptionCallback2 event failed.");
8179 // Stop all Runtime threads
8181 TrapAllRuntimeThreads();
8183 } // end if (!Attached)
8186 LOG((LF_CORDB,LL_INFO1000, "D:FCMECF: Skipping SendIPCEvent because RS detached.\n"));
8190 // Let other Runtime threads handle their events.
8196 // If we weren't at a safe place when we enabled PGC, then go ahead and unmark that fact now that we've successfully
8199 unsafePlaceHolder.Clear();
8201 ProcessAnyPendingEvals(pThread);
8202 } // end of GCX_COOP_EEINTERFACE();
8208 * ManagedExceptionUnwindBegin is called by Runtime threads when crawling the
8209 * managed stack frame and unwinding them.
8212 * pThread - The thread the unwind is occurring on.
8218 void Debugger::ManagedExceptionUnwindBegin(Thread *pThread)
8222 MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
8223 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
8228 // Implements DebugInterface
8229 // Can only be called on managed threads
8232 LOG((LF_CORDB, LL_INFO10000, "D::ManagedExceptionUnwindBegin\n"));
8234 if (pThread == NULL)
8236 _ASSERTE(!"Bad parameter");
8237 LOG((LF_CORDB, LL_INFO10000, "D::ManagedExceptionUnwindBegin - Bad parameter.\n"));
8241 if (CORDBUnrecoverableError(this))
8247 // Mark if we're at an unsafe place.
8249 AtSafePlaceHolder unsafePlaceHolder(pThread);
8251 GCX_COOP_EEINTERFACE();
8254 SENDIPCEVENT_BEGIN(this, pThread);
8256 if (CORDebuggerAttached() &&
8257 !pThread->GetExceptionState()->GetFlags()->SentDebugUnwindBegin() &&
8258 !pThread->GetExceptionState()->GetFlags()->DebugCatchHandlerFound() &&
8259 !pThread->GetExceptionState()->GetFlags()->SentDebugUnhandled())
8263 DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer();
8266 // Send Whidbey EXCEPTION IPC event.
8268 InitIPCEvent(ipce, DB_IPCE_EXCEPTION_UNWIND, pThread, pThread->GetDomain());
8270 ipce->ExceptionUnwind.eventType = DEBUG_EXCEPTION_UNWIND_BEGIN;
8271 ipce->ExceptionUnwind.dwFlags = 0;
8273 LOG((LF_CORDB, LL_INFO10000, "D::MEUB: sending ExceptionUnwind event"));
8274 hr = m_pRCThread->SendIPCEvent();
8276 _ASSERTE(SUCCEEDED(hr) && "D::MEUB: Send ExceptionUnwind event failed.");
8278 pThread->GetExceptionState()->GetFlags()->SetSentDebugUnwindBegin();
8281 // Stop all Runtime threads
8283 TrapAllRuntimeThreads();
8285 } // end if (!Attached)
8288 // Let other Runtime threads handle their events.
8294 // If we weren't at a safe place when we enabled PGC, then go ahead and unmark that fact now that we've successfully
8297 unsafePlaceHolder.Clear();
8304 * DeleteInterceptContext
8306 * This function is called by the VM to release any debugger specific information for an
8307 * exception object. It is called when the VM releases its internal exception stuff, i.e.
8308 * ExInfo on X86 and ExceptionTracker on WIN64.
8312 * pContext - Debugger specific context.
8318 * pContext is just a pointer to a DebuggerContinuableExceptionBreakpoint.
8321 void Debugger::DeleteInterceptContext(void *pContext)
8323 LIMITED_METHOD_CONTRACT;
8325 DebuggerContinuableExceptionBreakpoint *pBp = (DebuggerContinuableExceptionBreakpoint *)pContext;
8329 DeleteInteropSafe(pBp);
8334 // Get the frame point for an exception handler
8335 FramePointer GetHandlerFramePointer(BYTE *pStack)
8337 FramePointer handlerFP;
8339 #if !defined(_TARGET_ARM_) && !defined(_TARGET_ARM64_)
8340 // Refer to the comment in DispatchUnwind() to see why we have to add
8341 // sizeof(LPVOID) to the handler ebp.
8342 handlerFP = FramePointer::MakeFramePointer(LPVOID(pStack + sizeof(void*)));
8344 // ARM is similar to IA64 in that it uses the establisher frame as the
8345 // handler. in this case we don't need to add sizeof(void*) to the FP.
8346 handlerFP = FramePointer::MakeFramePointer((LPVOID)pStack);
8347 #endif // _TARGET_ARM_
8353 // ExceptionFilter is called by the Runtime threads when an exception
8354 // is being processed.
8355 // - fd - MethodDesc of filter function
8356 // - pMethodAddr - any address inside of the method. This lets us resolve exactly which version
8357 // of the method is being executed (for EnC)
8358 // - offset - native offset to handler.
8359 // - pStack, pBStore - stack pointers.
8361 void Debugger::ExceptionFilter(MethodDesc *fd, TADDR pMethodAddr, SIZE_T offset, BYTE *pStack)
8369 PRECONDITION(!IsDbgHelperSpecialThread());
8373 LOG((LF_CORDB,LL_INFO10000, "D::EF: pStack:0x%x MD: %s::%s, offset:0x%x\n",
8374 pStack, fd->m_pszDebugClassName, fd->m_pszDebugMethodName, offset));
8377 // !!! Need to think through logic for when to step through filter code -
8378 // perhaps only during a "step in".
8382 // !!! Eventually there may be some weird mechanics introduced for
8383 // returning from the filter that we have to understand. For now we should
8384 // be able to proceed normally.
8387 FramePointer handlerFP;
8388 handlerFP = GetHandlerFramePointer(pStack);
8390 DebuggerJitInfo * pDJI = NULL;
8393 pDJI = GetJitInfo(fd, (const BYTE *) pMethodAddr);
8398 EX_END_CATCH(SwallowAllExceptions);
8400 if (!fd->IsDynamicMethod() && (pDJI == NULL))
8402 // The only way we shouldn't have a DJI is from a dynamic method or from oom (which the LS doesn't handle).
8403 _ASSERTE(!"Debugger doesn't support OOM scenarios.");
8407 DebuggerController::DispatchUnwind(g_pEEInterface->GetThread(),
8408 fd, pDJI, offset, handlerFP, STEP_EXCEPTION_FILTER);
8413 // ExceptionHandle is called by Runtime threads when an exception is
8415 // - fd - MethodDesc of filter function
8416 // - pMethodAddr - any address inside of the method. This lets us resolve exactly which version
8417 // of the method is being executed (for EnC)
8418 // - offset - native offset to handler.
8419 // - pStack, pBStore - stack pointers.
8421 void Debugger::ExceptionHandle(MethodDesc *fd, TADDR pMethodAddr, SIZE_T offset, BYTE *pStack)
8429 PRECONDITION(!IsDbgHelperSpecialThread());
8434 FramePointer handlerFP;
8435 handlerFP = GetHandlerFramePointer(pStack);
8437 DebuggerJitInfo * pDJI = NULL;
8440 pDJI = GetJitInfo(fd, (const BYTE *) pMethodAddr);
8445 EX_END_CATCH(SwallowAllExceptions);
8447 if (!fd->IsDynamicMethod() && (pDJI == NULL))
8449 // The only way we shouldn't have a DJI is from a dynamic method or from oom (which the LS doesn't handle).
8450 _ASSERTE(!"Debugger doesn't support OOM scenarios.");
8455 DebuggerController::DispatchUnwind(g_pEEInterface->GetThread(),
8456 fd, pDJI, offset, handlerFP, STEP_EXCEPTION_HANDLER);
8459 BOOL Debugger::ShouldAutoAttach()
8468 _ASSERTE(!CORDebuggerAttached());
8470 // We're relying on the caller to determine the
8472 LOG((LF_CORDB, LL_INFO1000000, "D::SAD\n"));
8474 // Check if the user has specified a seting in the registry about what he
8475 // wants done when an unhandled exception occurs.
8476 DebuggerLaunchSetting dls = GetDbgJITDebugLaunchSetting();
8478 return (dls == DLS_ATTACH_DEBUGGER);
8480 // @TODO cache the debugger launch setting.
8484 BOOL Debugger::FallbackJITAttachPrompt()
8486 _ASSERTE(!CORDebuggerAttached());
8487 return (ATTACH_YES == this->ShouldAttachDebuggerProxy(false));
8490 void Debugger::MarkDebuggerAttachedInternal()
8492 LIMITED_METHOD_CONTRACT;
8494 // Attach is complete now.
8495 LOG((LF_CORDB, LL_INFO10000, "D::FEDA: Attach Complete!\n"));
8496 g_pEEInterface->MarkDebuggerAttached();
8498 _ASSERTE(HasLazyData());
8500 void Debugger::MarkDebuggerUnattachedInternal()
8502 LIMITED_METHOD_CONTRACT;
8504 _ASSERTE(HasLazyData());
8506 g_pEEInterface->MarkDebuggerUnattached();
8509 //-----------------------------------------------------------------------------
8510 // Favor to do lazy initialization on helper thread.
8511 // This is needed to allow lazy intialization in Stack Overflow scenarios.
8512 // We may or may not already be initialized.
8513 //-----------------------------------------------------------------------------
8514 void LazyInitFavor(void *)
8522 Debugger::DebuggerLockHolder dbgLockHolder(g_pDebugger);
8524 hr = g_pDebugger->LazyInitWrapper();
8525 (void)hr; //prevent "unused variable" error from GCC
8527 // On checked builds, warn that we're hitting a scenario that debugging doesn't support.
8528 _ASSERTE(SUCCEEDED(hr) || !"Couldn't initialize lazy data for LastChanceManagedException");
8531 /******************************************************************************
8533 ******************************************************************************/
8534 LONG Debugger::LastChanceManagedException(EXCEPTION_POINTERS * pExceptionInfo,
8536 BOOL jitAttachRequested)
8541 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
8547 // Implements DebugInterface.
8548 // Can be run only on managed thread.
8550 LOG((LF_CORDB, LL_INFO10000, "D::LastChanceManagedException\n"));
8552 // Don't stop for native debugging anywhere inside our inproc-Filters.
8553 CantStopHolder hHolder;
8555 EXCEPTION_RECORD * pExceptionRecord = pExceptionInfo->ExceptionRecord;
8556 CONTEXT * pContext = pExceptionInfo->ContextRecord;
8558 // You're allowed to call this function with a NULL exception record and context. If you do, then its assumed
8559 // that we want to head right down to asking the user if they want to attach a debugger. No need to try to
8560 // dispatch the exception to the debugger controllers. You have to pass NULL for both the exception record and
8561 // the context, though. They're a pair. Both have to be NULL, or both have to be valid.
8562 _ASSERTE(((pExceptionRecord != NULL) && (pContext != NULL)) ||
8563 ((pExceptionRecord == NULL) && (pContext == NULL)));
8565 if (CORDBUnrecoverableError(this))
8567 return ExceptionContinueSearch;
8570 // We don't do anything on the second pass
8571 if ((pExceptionRecord != NULL) && ((pExceptionRecord->ExceptionFlags & EXCEPTION_UNWINDING) != 0))
8573 return ExceptionContinueSearch;
8576 // Let the controllers have a chance at it - this may be the only handler which can catch the exception if this
8577 // is a native patch.
8579 if ((pThread != NULL) &&
8580 (pContext != NULL) &&
8581 CORDebuggerAttached() &&
8582 DebuggerController::DispatchNativeException(pExceptionRecord,
8584 pExceptionRecord->ExceptionCode,
8587 return ExceptionContinueExecution;
8590 // Otherwise, run our last chance exception logic
8591 ATTACH_ACTION action;
8594 if (CORDebuggerAttached() || jitAttachRequested)
8596 LOG((LF_CORDB, LL_INFO10000, "D::BEH ... debugger attached.\n"));
8598 Thread *thread = g_pEEInterface->GetThread();
8599 _ASSERTE((thread != NULL) && (thread == pThread));
8601 // ExceptionFlags is 0 for continuable, EXCEPTION_NONCONTINUABLE otherwise. Note that if we don't have an
8602 // exception record, then we assume this is a non-continuable exception.
8603 bool continuable = (pExceptionRecord != NULL) && (pExceptionRecord->ExceptionFlags == 0);
8605 LOG((LF_CORDB, LL_INFO10000, "D::BEH ... sending exception.\n"));
8607 HRESULT hr = E_FAIL;
8609 // In the jit-attach case, lazy-init. We may be in a stack-overflow, so do it via a favor to avoid
8610 // using this thread's stack space.
8611 if (jitAttachRequested)
8613 m_pRCThread->DoFavor((FAVORCALLBACK) LazyInitFavor, NULL);
8616 // The only way we don't have lazy data at this point is in an OOM scenario, which
8617 // the debugger doesn't support.
8620 return ExceptionContinueSearch;
8624 // In Whidbey, we used to set the filter CONTEXT when we hit an unhandled exception while doing
8625 // mixed-mode debugging. This helps the debugger walk the stack since it can skip the leaf
8626 // portion of the stack (including stack frames in the runtime) and start the stackwalk at the
8627 // faulting stack frame. The code to set the filter CONTEXT is in a hijack function which is only
8628 // used during mixed-mode debugging.
8629 if (m_pRCThread->GetDCB()->m_rightSideIsWin32Debugger)
8633 _ASSERTE(thread->GetFilterContext() == NULL);
8634 thread->SetFilterContext(pExceptionInfo->ContextRecord);
8638 // We pass the attaching status to SendException so that it knows
8639 // whether to attach a debugger or not. We should really do the
8640 // attach stuff out here and not bother with the flag.
8641 hr = SendException(thread,
8643 ((pContext != NULL) ? (SIZE_T)GetIP(pContext) : NULL),
8644 ((pContext != NULL) ? (SIZE_T)GetSP(pContext) : NULL),
8646 !!jitAttachRequested, // If we are JIT attaching on an unhandled exceptioin, we force
8647 !!jitAttachRequested, // the exception to be uninterceptable.
8653 EX_END_CATCH(SwallowAllExceptions);
8654 if (m_pRCThread->GetDCB()->m_rightSideIsWin32Debugger)
8658 thread->SetFilterContext(NULL);
8663 // Note: we don't do anything on NO or TERMINATE. We just return to the exception logic, which will abort the
8664 // app or not depending on what the CLR impl decides is appropiate.
8665 _ASSERTE(action == ATTACH_TERMINATE || action == ATTACH_NO);
8668 return ExceptionContinueSearch;
8672 // NotifyUserOfFault notifies the user of a fault (unhandled exception
8673 // or user breakpoint) in the process, giving them the option to
8674 // attach a debugger or terminate the application.
8676 int Debugger::NotifyUserOfFault(bool userBreakpoint, DebuggerLaunchSetting dls)
8678 LOG((LF_CORDB, LL_INFO1000000, "D::NotifyUserOfFault\n"));
8683 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;;
8688 int result = IDCANCEL;
8690 if (!CORDebuggerAttached())
8695 pid = GetCurrentProcessId();
8696 tid = GetCurrentThreadId();
8699 UINT resIDMessage = 0;
8703 resIDMessage = IDS_DEBUG_USER_BREAKPOINT_MSG;
8704 flags |= MB_ABORTRETRYIGNORE | MB_ICONEXCLAMATION;
8708 resIDMessage = IDS_DEBUG_UNHANDLED_EXCEPTION_MSG;
8709 flags |= MB_OKCANCEL | MB_ICONEXCLAMATION;
8713 // Another potential hang. This may get run on the helper if we have a stack overflow.
8714 // Hopefully the odds of 1 thread hitting a stack overflow while another is stuck holding the heap
8715 // lock is very small.
8716 SUPPRESS_ALLOCATION_ASSERTS_IN_THIS_SCOPE;
8718 result = MessageBox(resIDMessage, IDS_DEBUG_SERVICE_CAPTION,
8719 flags, TRUE, TRUE, pid, pid, tid, tid);
8723 LOG((LF_CORDB, LL_INFO1000000, "D::NotifyUserOfFault left\n"));
8728 // Proxy for ShouldAttachDebugger
8729 struct ShouldAttachDebuggerParams {
8731 bool m_fIsUserBreakpoint;
8732 Debugger::ATTACH_ACTION m_retval;
8735 // This is called by the helper thread
8736 void ShouldAttachDebuggerStub(ShouldAttachDebuggerParams * p)
8738 WRAPPER_NO_CONTRACT;
8740 p->m_retval = p->m_pThis->ShouldAttachDebugger(p->m_fIsUserBreakpoint);
8743 // This gets called just like the normal version, but it sends the call over to the helper thread
8744 Debugger::ATTACH_ACTION Debugger::ShouldAttachDebuggerProxy(bool fIsUserBreakpoint)
8755 DebuggerLockHolder lockHolder(this);
8756 HRESULT hr = LazyInitWrapper();
8759 // We already stress logged this case.
8765 if (!IsGuardPageGone())
8766 return ShouldAttachDebugger(fIsUserBreakpoint);
8768 ShouldAttachDebuggerParams p;
8770 p.m_fIsUserBreakpoint = fIsUserBreakpoint;
8772 LOG((LF_CORDB, LL_INFO1000000, "D::SADProxy\n"));
8773 m_pRCThread->DoFavor((FAVORCALLBACK) ShouldAttachDebuggerStub, &p);
8774 LOG((LF_CORDB, LL_INFO1000000, "D::SADProxy return %d\n", p.m_retval));
8779 //---------------------------------------------------------------------------------------
8780 // Do policy to determine if we should attach a debugger.
8783 // fIsUserBreakpoint - true iff this is in response to a user-breakpoint, else false.
8786 // Action to perform based off policy.
8787 // ATTACH_NO if a debugger is already attached.
8788 Debugger::ATTACH_ACTION Debugger::ShouldAttachDebugger(bool fIsUserBreakpoint)
8793 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
8799 LOG((LF_CORDB, LL_INFO1000000, "D::SAD\n"));
8801 // If the debugger is already attached, not necessary to re-attach
8802 if (CORDebuggerAttached())
8807 // Check if the user has specified a seting in the registry about what he wants done when an unhandled exception
8809 DebuggerLaunchSetting dls = GetDbgJITDebugLaunchSetting();
8812 if (dls == DLS_ATTACH_DEBUGGER)
8818 // Only ask the user once if they wish to attach a debugger. This is because LastChanceManagedException can be called
8819 // twice, which causes ShouldAttachDebugger to be called twice, which causes the user to have to answer twice.
8820 static BOOL s_fHasAlreadyAsked = FALSE;
8821 static ATTACH_ACTION s_action;
8824 // This lock is also part of the above workaround.
8825 // Must go to preemptive to take this lock since we'll trigger down the road.
8827 DebuggerLockHolder lockHolder(this);
8829 // We always want to ask about user breakpoints!
8830 if (!s_fHasAlreadyAsked || fIsUserBreakpoint)
8832 if (!fIsUserBreakpoint)
8833 s_fHasAlreadyAsked = TRUE;
8835 // While we could theoretically run into a deadlock if another thread
8836 // which acquires the debugger lock in cooperative GC mode is blocked
8837 // on this thread while it is running arbitrary user code out of the
8838 // MessageBox message pump, given that this codepath will only be used
8839 // on Win9x and that the chances of this happenning are quite slim,
8840 // for Whidbey a GCViolation is acceptable.
8841 CONTRACT_VIOLATION(GCViolation);
8843 // Ask the user if they want to attach
8844 int iRes = NotifyUserOfFault(fIsUserBreakpoint, dls);
8846 // If it's a user-defined breakpoint, they must hit Retry to launch
8847 // the debugger. If it's an unhandled exception, user must press
8848 // Cancel to attach the debugger.
8849 if ((iRes == IDCANCEL) || (iRes == IDRETRY))
8850 s_action = ATTACH_YES;
8852 else if ((iRes == IDABORT) || (iRes == IDOK))
8853 s_action = ATTACH_TERMINATE;
8856 s_action = ATTACH_NO;
8859 // dbgLockHolder goes out of scope - implicit Release
8865 //---------------------------------------------------------------------------------------
8866 // SendUserBreakpoint is called by Runtime threads to send that they've hit
8867 // a user breakpoint to the Right Side.
8870 // thread - managed thread that the breakpoint is on
8873 // A user breakpoint is generally triggered by a call to System.Diagnostics.Debugger.Break.
8874 // This can be very common. VB's 'stop' statement compiles to a Debugger.Break call.
8875 // Some other CLR facilities (MDAs) may call this directly too.
8877 // This may trigger a Jit attach.
8878 // If the debugger is already attached, this will issue a step-out so that the UserBreakpoint
8879 // appears to come from the callsite.
8880 void Debugger::SendUserBreakpoint(Thread * thread)
8888 PRECONDITION(thread != NULL);
8889 PRECONDITION(thread == ::GetThread());
8895 // For testing Watson, we want a consistent way to be able to generate a
8896 // Fatal Execution Error
8897 // So we have a debug-only knob in this particular managed call that can be used
8898 // to artificially inject the error.
8899 // This is only for testing.
8900 static int fDbgInjectFEE = -1;
8902 if (fDbgInjectFEE == -1)
8903 fDbgInjectFEE = UnsafeGetConfigDWORD(CLRConfig::INTERNAL_DbgInjectFEE);
8907 STRESS_LOG0(LF_CORDB, LL_INFO10000, "Debugger posting bogus FEE b/c knob DbgInjectFEE is set.\n");
8908 EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE);
8909 // These never return.
8913 if (CORDBUnrecoverableError(this))
8918 // UserBreakpoint behaves differently if we're under a debugger vs. a jit-attach.
8919 // If we're under the debugger, it does an additional step-out to get us back to the call site.
8921 // If already attached, then do a step-out and send the userbreak event.
8922 if (CORDebuggerAttached())
8924 // A debugger is already attached, so setup a DebuggerUserBreakpoint controller to get us out of the helper
8925 // that got us here. The DebuggerUserBreakpoint will call AttachDebuggerForBreakpoint for us when we're out
8926 // of the helper. The controller will delete itself when its done its work.
8927 DebuggerUserBreakpoint::HandleDebugBreak(thread);
8931 ATTACH_ACTION dbgAction = ShouldAttachDebugger(true);
8933 // No debugger is attached. Consider a JIT attach.
8934 // This will do ShouldAttachDebugger() and wait for the results.
8935 // - It may terminate if the user requested that.
8936 // - It may do a full jit-attach.
8937 if (dbgAction == ATTACH_YES)
8939 JitAttach(thread, NULL, TRUE, FALSE);
8941 else if (dbgAction == ATTACH_TERMINATE)
8943 // ATTACH_TERMINATE indicates the the user wants to terminate the app.
8944 LOG((LF_CORDB, LL_INFO10000, "D::SUB: terminating this process due to user request\n"));
8946 // Should this go through the host?
8947 TerminateProcess(GetCurrentProcess(), 0);
8948 _ASSERTE(!"Should never reach this point.");
8952 _ASSERTE(dbgAction == ATTACH_NO);
8955 if (CORDebuggerAttached())
8957 // On jit-attach, we just send the UserBreak event. Don't do an extra step-out.
8958 SendUserBreakpointAndSynchronize(thread);
8960 else if (IsDebuggerPresent())
8967 // void Debugger::ThreadCreated(): ThreadCreated is called when
8968 // a new Runtime thread has been created, but before its ever seen
8969 // managed code. This is a callback invoked by the EE into the Debugger.
8970 // This will create a DebuggerThreadStarter patch, which will set
8971 // a patch at the first instruction in the managed code. When we hit
8972 // that patch, the DebuggerThreadStarter will invoke ThreadStarted, below.
8974 // Thread* pRuntimeThread: The EE Thread object representing the
8975 // runtime thread that has just been created.
8976 void Debugger::ThreadCreated(Thread* pRuntimeThread)
8986 // This function implements the DebugInterface. But it is also called from Attach
8987 // logic internally.
8990 if (CORDBUnrecoverableError(this))
8993 LOG((LF_CORDB, LL_INFO100, "D::TC: thread created for 0x%x. ******\n",
8994 GetThreadIdHelper(pRuntimeThread)));
8996 // Sanity check the thread.
8997 _ASSERTE(pRuntimeThread != NULL);
8998 _ASSERTE(pRuntimeThread->GetThreadId() != 0);
9001 // Create a thread starter and enable its WillEnterManaged code
9002 // callback. This will cause the starter to trigger once the
9003 // thread has hit managed code, which will cause
9004 // Debugger::ThreadStarted() to be called. NOTE: the starter will
9005 // be deleted automatically when its done its work.
9006 DebuggerThreadStarter *starter = new (interopsafe, nothrow) DebuggerThreadStarter(pRuntimeThread);
9008 if (starter == NULL)
9010 CORDBDebuggerSetUnrecoverableWin32Error(this, 0, false);
9014 starter->EnableTraceCall(LEAF_MOST_FRAME);
9018 // void Debugger::ThreadStarted(): ThreadStarted is called when
9019 // a new Runtime thread has reached its first managed code. This is
9020 // called by the DebuggerThreadStarter patch's SendEvent method.
9022 // Thread* pRuntimeThread: The EE Thread object representing the
9023 // runtime thread that has just hit managed code.
9024 void Debugger::ThreadStarted(Thread* pRuntimeThread)
9034 // This method implemented DebugInterface but it is also called from Controller
9036 if (CORDBUnrecoverableError(this))
9039 LOG((LF_CORDB, LL_INFO100, "D::TS: thread attach : ID=%#x AD:%#x\n",
9040 GetThreadIdHelper(pRuntimeThread), pRuntimeThread->GetDomain()));
9042 // We just need to send a VMPTR_Thread. The RS will get everything else it needs from DAC.
9045 _ASSERTE((g_pEEInterface->GetThread() &&
9046 !g_pEEInterface->GetThread()->m_fPreemptiveGCDisabled) ||
9048 _ASSERTE(ThreadHoldsLock());
9050 DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer();
9052 DB_IPCE_THREAD_ATTACH,
9054 pRuntimeThread->GetDomain());
9057 m_pRCThread->SendIPCEvent();
9060 // Well, if this thread got created _after_ we started sync'ing
9061 // then its Runtime thread flags don't have the fact that there
9062 // is a debug suspend pending. We need to call over to the
9063 // Runtime and set the flag in the thread now...
9065 if (m_trappingRuntimeThreads)
9067 g_pEEInterface->MarkThreadForDebugSuspend(pRuntimeThread);
9072 //---------------------------------------------------------------------------------------
9074 // DetachThread is called by Runtime threads when they are completing
9075 // their execution and about to be destroyed.
9078 // pRuntimeThread - Pointer to the runtime's thread object to detach.
9083 //---------------------------------------------------------------------------------------
9084 void Debugger::DetachThread(Thread *pRuntimeThread)
9088 MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
9089 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
9093 if (CORDBUnrecoverableError(this))
9098 if (m_ignoreThreadDetach)
9103 _ASSERTE (pRuntimeThread != NULL);
9106 LOG((LF_CORDB, LL_INFO100, "D::DT: thread detach : ID=%#x AD:%#x.\n",
9107 GetThreadIdHelper(pRuntimeThread), pRuntimeThread->GetDomain()));
9110 // We may be killing a thread before the Thread-starter fired.
9111 // So check (and cancel) any outstanding thread-starters.
9112 // If we don't, this old thread starter may conflict w/ a new thread-starter
9113 // if AppDomains or EE Thread's get recycled.
9114 DebuggerController::CancelOutstandingThreadStarter(pRuntimeThread);
9116 // Controller lock is bigger than debugger lock.
9117 // Don't take debugger lock before the CancelOutStandingThreadStarter function.
9118 SENDIPCEVENT_BEGIN(this, pRuntimeThread);
9120 if (CORDebuggerAttached())
9122 // Send a detach thread event to the Right Side.
9123 DebuggerIPCEvent * pEvent = m_pRCThread->GetIPCEventSendBuffer();
9125 InitIPCEvent(pEvent,
9126 DB_IPCE_THREAD_DETACH,
9128 pRuntimeThread->GetDomain());
9130 m_pRCThread->SendIPCEvent();
9132 // Stop all Runtime threads
9133 TrapAllRuntimeThreads();
9135 // This prevents a race condition where we blocked on the Lock()
9136 // above while another thread was sending an event and while we
9137 // were blocked the debugger suspended us and so we wouldn't be
9138 // resumed after the suspension about to happen below.
9139 pRuntimeThread->ResetThreadStateNC(Thread::TSNC_DebuggerUserSuspend);
9143 LOG((LF_CORDB,LL_INFO1000, "D::DT: Skipping SendIPCEvent because RS detached."));
9151 // SuspendComplete is called when the last Runtime thread reaches a safe point in response to having its trap flags set.
9152 // This may be called on either the real helper thread or someone doing helper thread duty.
9154 BOOL Debugger::SuspendComplete()
9161 // This will is conceptually mode-cooperative.
9162 // But we haven't marked the runtime as stopped yet (m_stopped), so the contract
9163 // subsystem doesn't realize it yet.
9164 DISABLED(MODE_COOPERATIVE);
9169 // Call from RCThread::MainLoop and TemporaryHelperThreadMainLoop.
9170 // when all threads suspended. Can happen on managed thread or helper thread.
9171 // If happen on managed thread, it must be doing the helper thread duty.
9174 _ASSERTE(ThreadStore::HoldingThreadStore() || g_fProcessDetach);
9176 // We should be holding debugger lock m_mutex.
9177 _ASSERTE(ThreadHoldsLock());
9179 // We can't throw here (we're in the middle of the runtime suspension logic).
9180 // But things below us throw. So we catch the exception, but then what state are we in?
9182 _ASSERTE((!g_pEEInterface->GetThread() || !g_pEEInterface->GetThread()->m_fPreemptiveGCDisabled) || g_fInControlC);
9183 _ASSERTE(ThisIsHelperThreadWorker());
9185 STRESS_LOG0(LF_CORDB, LL_INFO10000, "D::SC: suspension complete\n");
9187 // We have suspended runtime.
9189 // We're stopped now. Marking m_stopped allows us to use MODE_COOPERATIVE contracts.
9190 _ASSERTE(!m_stopped && m_trappingRuntimeThreads);
9194 // Send the sync complete event to the Right Side.
9196 // If we fail to send the SyncComplete, what do we do?
9197 CONTRACT_VIOLATION(ThrowsViolation);
9199 SendSyncCompleteIPCEvent(); // sets m_stopped = true...
9202 // Everything in the next scope is meant to mimic what we do UnlockForEventSending minus EnableEventHandling.
9203 // We do the EEH part when we get the Continue event.
9206 //_ASSERTE(m_tidLockedForEventSending == GetCurrentThreadId());
9207 m_tidLockedForEventSending = 0;
9211 // Event handling is re-enabled by the RCThread in response to a
9212 // continue message from the Right Side.
9216 // @todo - what should we do if this function failed?
9223 //---------------------------------------------------------------------------------------
9225 // Debugger::SendCreateAppDomainEvent - notify the RS of an AppDomain
9228 // pRuntimeAppdomain - pointer to the AppDomain
9234 // This is used to notify the debugger of either a newly created
9235 // AppDomain (when fAttaching is FALSE) or of existing AppDomains
9236 // at attach time (fAttaching is TRUE). In both cases, this should
9237 // be called before any LoadModule/LoadAssembly events are sent for
9238 // this domain. Otherwise the RS will get an event for an AppDomain
9239 // it doesn't recognize and ASSERT.
9241 // For the non-attach case this means there is no need to enumerate
9242 // the assemblies/modules in an AppDomain after sending this event
9243 // because we know there won't be any.
9246 void Debugger::SendCreateAppDomainEvent(AppDomain * pRuntimeAppDomain)
9250 MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
9251 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
9257 if (CORDBUnrecoverableError(this))
9262 STRESS_LOG2(LF_CORDB, LL_INFO10000, "D::SCADE: AppDomain creation:%#08x, %#08x\n",
9263 pRuntimeAppDomain, pRuntimeAppDomain->GetId().m_dwId);
9267 Thread *pThread = g_pEEInterface->GetThread();
9268 SENDIPCEVENT_BEGIN(this, pThread);
9272 // We may have detached while waiting in LockForEventSending,
9273 // in which case we can't send the event.
9274 if (CORDebuggerAttached())
9276 // Send a create appdomain event to the Right Side.
9277 DebuggerIPCEvent * pEvent = m_pRCThread->GetIPCEventSendBuffer();
9279 InitIPCEvent(pEvent,
9280 DB_IPCE_CREATE_APP_DOMAIN,
9284 // Only send a pointer to the AppDomain, the RS will get everything else via DAC.
9285 pEvent->AppDomainData.vmAppDomain.SetRawPtr(pRuntimeAppDomain);
9286 m_pRCThread->SendIPCEvent();
9288 TrapAllRuntimeThreads();
9291 // Let other Runtime threads handle their events.
9300 // SendExitAppDomainEvent is called when an app domain is destroyed.
9302 void Debugger::SendExitAppDomainEvent(AppDomain* pRuntimeAppDomain)
9306 MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
9307 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
9311 if (CORDBUnrecoverableError(this))
9314 LOG((LF_CORDB, LL_INFO100, "D::EAD: Exit AppDomain 0x%08x.\n",
9315 pRuntimeAppDomain));
9317 STRESS_LOG3(LF_CORDB, LL_INFO10000, "D::EAD: AppDomain exit:%#08x, %#08x, %#08x\n",
9318 pRuntimeAppDomain, pRuntimeAppDomain->GetId().m_dwId, CORDebuggerAttached());
9320 Thread *thread = g_pEEInterface->GetThread();
9321 // Prevent other Runtime threads from handling events.
9322 SENDIPCEVENT_BEGIN(this, thread);
9324 if (CORDebuggerAttached())
9326 if (pRuntimeAppDomain->IsDefaultDomain() )
9328 // The Debugger expects to never get an unload event for the default Domain.
9329 // Currently we should never get here because g_fProcessDetach will be true by
9330 // the time this method is called. However, we'd like to know if this ever changes
9331 _ASSERTE(!"Trying to deliver notification of unload for default domain" );
9335 // Send the exit appdomain event to the Right Side.
9336 DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer();
9338 DB_IPCE_EXIT_APP_DOMAIN,
9341 m_pRCThread->SendIPCEvent();
9343 // Delete any left over modules for this appdomain.
9344 // Note that we're doing this under the lock.
9345 if (m_pModules != NULL)
9347 DebuggerDataLockHolder ch(this);
9348 m_pModules->RemoveModules(pRuntimeAppDomain);
9351 // Stop all Runtime threads
9352 TrapAllRuntimeThreads();
9356 LOG((LF_CORDB,LL_INFO1000, "D::EAD: Skipping SendIPCEvent because RS detached."));
9365 // LoadAssembly is called when a new Assembly gets loaded.
9367 void Debugger::LoadAssembly(DomainAssembly * pDomainAssembly)
9371 MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
9372 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
9376 if (CORDBUnrecoverableError(this))
9379 LOG((LF_CORDB, LL_INFO100, "D::LA: Load Assembly Asy:0x%p AD:0x%p which:%ls\n",
9380 pDomainAssembly, pDomainAssembly->GetAppDomain(), pDomainAssembly->GetAssembly()->GetDebugName() ));
9382 if (!CORDebuggerAttached())
9387 Thread *pThread = g_pEEInterface->GetThread();
9388 SENDIPCEVENT_BEGIN(this, pThread)
9391 if (CORDebuggerAttached())
9393 // Send a load assembly event to the Right Side.
9394 DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer();
9396 DB_IPCE_LOAD_ASSEMBLY,
9398 pDomainAssembly->GetAppDomain());
9400 ipce->AssemblyData.vmDomainAssembly.SetRawPtr(pDomainAssembly);
9402 m_pRCThread->SendIPCEvent();
9406 LOG((LF_CORDB,LL_INFO1000, "D::LA: Skipping SendIPCEvent because RS detached."));
9409 // Stop all Runtime threads
9410 if (CORDebuggerAttached())
9412 TrapAllRuntimeThreads();
9421 // UnloadAssembly is called when a Runtime thread unloads an assembly.
9423 void Debugger::UnloadAssembly(DomainAssembly * pDomainAssembly)
9427 MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
9428 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
9432 if (CORDBUnrecoverableError(this))
9435 LOG((LF_CORDB, LL_INFO100, "D::UA: Unload Assembly Asy:0x%p AD:0x%p which:%ls\n",
9436 pDomainAssembly, pDomainAssembly->GetAppDomain(), pDomainAssembly->GetAssembly()->GetDebugName() ));
9438 Thread *thread = g_pEEInterface->GetThread();
9439 // Note that the debugger lock is reentrant, so we may or may not hold it already.
9440 SENDIPCEVENT_BEGIN(this, thread);
9442 // Send the unload assembly event to the Right Side.
9443 DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer();
9446 DB_IPCE_UNLOAD_ASSEMBLY,
9448 pDomainAssembly->GetAppDomain());
9449 ipce->AssemblyData.vmDomainAssembly.SetRawPtr(pDomainAssembly);
9451 SendSimpleIPCEventAndBlock();
9453 // This will block on the continue
9462 // LoadModule is called when a Runtime thread loads a new module and a debugger
9463 // is attached. This also includes when a domain-neutral module is "loaded" into
9466 // TODO: remove pszModuleName and perhaps other args.
9467 void Debugger::LoadModule(Module* pRuntimeModule,
9468 LPCWSTR pszModuleName, // module file name.
9469 DWORD dwModuleName, // length of pszModuleName in chars, not including null.
9470 Assembly *pAssembly,
9471 AppDomain *pAppDomain,
9472 DomainFile * pDomainFile,
9478 NOTHROW; // not protected for Throws.
9479 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
9484 // Implement DebugInterface but can be called internally as well.
9485 // This can be called by EE loading module or when we are attaching called by IteratingAppDomainForAttaching
9487 _ASSERTE(!fAttaching);
9489 if (CORDBUnrecoverableError(this))
9492 // If this is a dynamic module, then it's part of a multi-module assembly. The manifest
9493 // module within the assembly contains metadata for all the module names in the assembly.
9494 // When a new dynamic module is created, the manifest module's metadata is updated to
9495 // include the new module (see code:Assembly.CreateDynamicModule).
9496 // So we need to update the RS's copy of the metadata. One place the manifest module's
9497 // metadata gets used is in code:DacDbiInterfaceImpl.GetModuleSimpleName
9499 // See code:ReflectionModule.CaptureModuleMetaDataToMemory for why we send the metadata-refresh here.
9500 if (pRuntimeModule->IsReflection() && !pRuntimeModule->IsManifest() && !fAttaching)
9505 // The loader lookups may throw or togggle GC mode, so do them inside a TRY/Catch and
9506 // outside any debugger locks.
9507 Module * pManifestModule = pRuntimeModule->GetAssembly()->GetManifestModule();
9509 _ASSERTE(pManifestModule != pRuntimeModule);
9510 _ASSERTE(pManifestModule->IsManifest());
9511 _ASSERTE(pManifestModule->GetAssembly() == pRuntimeModule->GetAssembly());
9513 DomainFile * pManifestDomainFile = pManifestModule->GetDomainFile(pAppDomain);
9515 DebuggerLockHolder dbgLockHolder(this);
9517 // Raise the debug event.
9518 // This still tells the debugger that the manifest module metadata is invalid and needs to
9520 DebuggerIPCEvent eventMetadataUpdate;
9521 InitIPCEvent(&eventMetadataUpdate, DB_IPCE_METADATA_UPDATE, NULL, pAppDomain);
9523 eventMetadataUpdate.MetadataUpdateData.vmDomainFile.SetRawPtr(pManifestDomainFile);
9525 SendRawEvent(&eventMetadataUpdate);
9527 EX_CATCH_HRESULT(hr);
9528 SIMPLIFYING_ASSUMPTION_SUCCEEDED(hr);
9532 DebuggerModule * module = NULL;
9534 Thread *pThread = g_pEEInterface->GetThread();
9535 SENDIPCEVENT_BEGIN(this, pThread);
9539 DebuggerIPCEvent* ipce = NULL;
9541 // Don't create new record if already loaded. We do still want to send the ModuleLoad event, however.
9542 // The RS has logic to ignore duplicate ModuleLoad events. We have to send what could possibly be a dup, though,
9543 // due to some really nasty issues with getting proper assembly and module load events from the loader when dealing
9544 // with shared assemblies.
9545 module = LookupOrCreateModule(pDomainFile);
9546 _ASSERTE(module != NULL);
9549 // During a real LoadModule event, debugger can change jit flags.
9550 // Can't do this during a fake event sent on attach.
9551 // This is cleared after we send the LoadModule event.
9552 module->SetCanChangeJitFlags(true);
9555 // @dbgtodo inspection - Check whether the DomainFile we get is consistent with the Module and AppDomain we get.
9556 // We should simply things when we actually get rid of DebuggerModule, possibly by just passing the
9557 // DomainFile around.
9558 _ASSERTE(module->GetDomainFile() == pDomainFile);
9559 _ASSERTE(module->GetAppDomain() == pDomainFile->GetAppDomain());
9560 _ASSERTE(module->GetRuntimeModule() == pDomainFile->GetModule());
9562 // Send a load module event to the Right Side.
9563 ipce = m_pRCThread->GetIPCEventSendBuffer();
9564 InitIPCEvent(ipce,DB_IPCE_LOAD_MODULE, pThread, pAppDomain);
9566 ipce->LoadModuleData.vmDomainFile.SetRawPtr(pDomainFile);
9568 m_pRCThread->SendIPCEvent();
9571 // Stop all Runtime threads
9575 TrapAllRuntimeThreads();
9577 EX_CATCH_HRESULT(hr); // @dbgtodo synchronization - catch exception and go on to restore state.
9578 // Synchronization feature crew needs to figure out what happens to TrapAllRuntimeThreads().
9583 // need to update pdb stream for SQL passed in pdb stream
9584 // regardless attach or not.
9586 if (pRuntimeModule->IsIStream())
9588 // Just ignore failures. Caller was just sending a debug event and we don't
9589 // want that to interop non-debugging functionality.
9593 SendUpdateModuleSymsEventAndBlock(pRuntimeModule, pAppDomain);
9595 EX_CATCH_HRESULT(hr);
9598 // Now that we're done with the load module event, can no longer change Jit flags.
9599 module->SetCanChangeJitFlags(false);
9603 //---------------------------------------------------------------------------------------
9605 // Special LS-only notification that a module has reached the FILE_LOADED level. For now
9606 // this is only useful to bind breakpoints in generic instantiations from NGENd modules
9607 // that we couldn't bind earlier (at LoadModule notification time) because the method
9608 // iterator refuses to consider modules earlier than the FILE_LOADED level. Normally
9609 // generic instantiations would have their breakpoints bound when they get JITted, but in
9610 // the case of NGEN that may never happen, so we need to bind them here.
9613 // * pRuntimeModule - Module that just loaded
9614 // * pAppDomain - AD into which the Module was loaded
9617 // This is called during the loading process, and blocks that process from
9618 // completing. The module has reached the FILE_LOADED stage, but typically not yet
9619 // the IsReadyForTypeLoad stage.
9622 void Debugger::LoadModuleFinished(Module * pRuntimeModule, AppDomain * pAppDomain)
9631 _ASSERTE(pRuntimeModule != NULL);
9632 _ASSERTE(pAppDomain != NULL);
9634 if (CORDBUnrecoverableError(this))
9637 // Just as an optimization, skip binding breakpoints if there's no debugger attached.
9638 // If a debugger attaches at some point after here, it will be able to bind patches
9639 // by making the request at that time. If a debugger detaches at some point after
9640 // here, there's no harm in having extra patches bound.
9641 if (!CORDebuggerAttached())
9644 // For now, this notification only does interesting work if the module that loaded is
9645 // an NGENd module, because all we care about in this notification is ensuring NGENd
9646 // methods get breakpoints bound on them
9647 if (!pRuntimeModule->HasNativeImage())
9650 // This notification is called just before MODULE_READY_FOR_TYPELOAD gets set. But
9651 // for shared modules (loaded into multiple domains), MODULE_READY_FOR_TYPELOAD has
9652 // already been set if this module was already loaded into an earlier domain. For
9653 // such cases, there's no need to bind breakpoints now because the module has already
9654 // been fully loaded into at least one domain, and breakpoint binding has already
9656 if (pRuntimeModule->IsReadyForTypeLoad())
9661 // This notification is called once the module is loaded
9662 DomainFile * pDomainFile = pRuntimeModule->FindDomainFile(pAppDomain);
9663 _ASSERTE((pDomainFile != NULL) && (pDomainFile->GetLoadLevel() >= FILE_LOADED));
9667 // Find all IL Master patches for this module, and bind & activate their
9668 // corresponding slave patches.
9670 DebuggerController::ControllerLockHolder ch;
9673 DebuggerPatchTable * pTable = DebuggerController::GetPatchTable();
9675 for (DebuggerControllerPatch * pMasterPatchCur = pTable->GetFirstPatch(&info);
9676 pMasterPatchCur != NULL;
9677 pMasterPatchCur = pTable->GetNextPatch(&info))
9679 if (!pMasterPatchCur->IsILMasterPatch())
9682 DebuggerMethodInfo *dmi = GetOrCreateMethodInfo(pMasterPatchCur->key.module, pMasterPatchCur->key.md);
9684 // Found a relevant IL master patch. Now bind all corresponding slave patches
9685 // that belong to this Module
9686 DebuggerMethodInfo::DJIIterator it;
9687 dmi->IterateAllDJIs(pAppDomain, pRuntimeModule, pMasterPatchCur->pMethodDescFilter, &it);
9688 for (; !it.IsAtEnd(); it.Next())
9690 DebuggerJitInfo *dji = it.Current();
9691 _ASSERTE(dji->m_jitComplete);
9693 if (dji->m_encVersion != pMasterPatchCur->GetEnCVersion())
9696 // Do we already have a slave for this DJI & Controller? If so, no need
9697 // to add another one
9698 BOOL fSlaveExists = FALSE;
9700 for (DebuggerControllerPatch * pSlavePatchCur = pTable->GetFirstPatch(&f);
9701 pSlavePatchCur != NULL;
9702 pSlavePatchCur = pTable->GetNextPatch(&f))
9704 if (pSlavePatchCur->IsILSlavePatch() &&
9705 (pSlavePatchCur->GetDJI() == dji) &&
9706 (pSlavePatchCur->controller == pMasterPatchCur->controller))
9708 fSlaveExists = TRUE;
9716 pMasterPatchCur->controller->AddBindAndActivateILSlavePatch(pMasterPatchCur, dji);
9723 // Send the raw event for Updating symbols. Debugger must query for contents from out-of-process
9726 // pRuntimeModule - required, module to send symbols for. May be domain neutral.
9727 // pAppDomain - required, appdomain that module is in.
9730 // This is just a ping event. Debugger must query for actual symbol contents.
9731 // This keeps the launch + attach cases identical.
9732 // This just sends the raw event and does not synchronize the runtime.
9733 // Use code:Debugger.SendUpdateModuleSymsEventAndBlock for that.
9734 void Debugger::SendRawUpdateModuleSymsEvent(Module *pRuntimeModule, AppDomain *pAppDomain)
9742 PRECONDITION(ThreadHoldsLock());
9744 // Debugger must have been attached to get us to this point.
9745 // We hold the Debugger-lock, so debugger could not have detached from
9746 // underneath us either.
9747 PRECONDITION(CORDebuggerAttached());
9751 if (CORDBUnrecoverableError(this))
9754 // This event is used to trigger the ICorDebugManagedCallback::UpdateModuleSymbols
9755 // callback. That callback is defined to pass a PDB stream, and so we still use this
9756 // only for legacy compatibility reasons when we've actually got PDB symbols.
9757 // New clients know they must request a new symbol reader after ClassLoad events.
9758 if (pRuntimeModule->GetInMemorySymbolStreamFormat() != eSymbolFormatPDB)
9759 return; // Non-PDB symbols
9761 DebuggerModule* module = LookupOrCreateModule(pRuntimeModule, pAppDomain);
9762 PREFIX_ASSUME(module != NULL);
9764 DebuggerIPCEvent* ipce = NULL;
9765 ipce = m_pRCThread->GetIPCEventSendBuffer();
9766 InitIPCEvent(ipce, DB_IPCE_UPDATE_MODULE_SYMS,
9767 g_pEEInterface->GetThread(),
9770 ipce->UpdateModuleSymsData.vmDomainFile.SetRawPtr((module ? module->GetDomainFile() : NULL));
9772 m_pRCThread->SendIPCEvent();
9776 // UpdateModuleSyms is called when the symbols for a module need to be
9777 // sent to the Right Side because they've changed.
9780 // pRuntimeModule - required, module to send symbols for. May be domain neutral.
9781 // pAppDomain - required, appdomain that module is in.
9785 // This will send the event (via code:Debugger.SendRawUpdateModuleSymsEvent) and then synchronize
9786 // the runtime waiting for a continue.
9788 // This should only be called in cases where we reasonably expect to send symbols.
9789 // However, this may not send symbols if the symbols aren't available.
9790 void Debugger::SendUpdateModuleSymsEventAndBlock(Module* pRuntimeModule, AppDomain *pAppDomain)
9800 if (CORDBUnrecoverableError(this) || !CORDebuggerAttached())
9805 CGrowableStream * pStream = pRuntimeModule->GetInMemorySymbolStream();
9806 LOG((LF_CORDB, LL_INFO10000, "D::UMS: update module syms RuntimeModule:0x%08x CGrowableStream:0x%08x\n", pRuntimeModule, pStream));
9807 if (pStream == NULL)
9809 // No in-memory Pdb available.
9810 STRESS_LOG1(LF_CORDB, LL_INFO10000, "No syms available %p", pRuntimeModule);
9814 SENDIPCEVENT_BEGIN(this, g_pEEInterface->GetThread()); // toggles to preemptive
9816 // Actually send the event
9817 if (CORDebuggerAttached())
9819 SendRawUpdateModuleSymsEvent(pRuntimeModule, pAppDomain);
9820 TrapAllRuntimeThreads();
9828 // UnloadModule is called by the Runtime for each module (including shared ones)
9829 // in an AppDomain that is being unloaded, when a debugger is attached.
9830 // In the EE, a module may be domain-neutral and therefore shared across all AppDomains.
9831 // We abstract this detail away in the Debugger and consider each such EE module to correspond
9832 // to multiple "Debugger Module" instances (one per AppDomain).
9833 // Therefore, this doesn't necessarily mean the runtime is unloading the module, just
9834 // that the Debugger should consider it's (per-AppDomain) DebuggerModule to be unloaded.
9836 void Debugger::UnloadModule(Module* pRuntimeModule,
9837 AppDomain *pAppDomain)
9841 MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
9842 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
9847 // implements DebugInterface.
9848 // can only called by EE on Module::NotifyDebuggerUnload
9851 if (CORDBUnrecoverableError(this))
9856 LOG((LF_CORDB, LL_INFO100, "D::UM: unload module Mod:%#08x AD:%#08x runtimeMod:%#08x modName:%ls\n",
9857 LookupOrCreateModule(pRuntimeModule, pAppDomain), pAppDomain, pRuntimeModule, pRuntimeModule->GetDebugName()));
9860 Thread *thread = g_pEEInterface->GetThread();
9861 SENDIPCEVENT_BEGIN(this, thread);
9863 if (CORDebuggerAttached())
9866 DebuggerModule* module = LookupOrCreateModule(pRuntimeModule, pAppDomain);
9869 LOG((LF_CORDB, LL_INFO100, "D::UM: module already unloaded AD:%#08x runtimeMod:%#08x modName:%ls\n",
9870 pAppDomain, pRuntimeModule, pRuntimeModule->GetDebugName()));
9873 _ASSERTE(module != NULL);
9875 STRESS_LOG3(LF_CORDB, LL_INFO10000, "D::UM: Unloading Mod:%#08x, %#08x, %#08x\n",
9876 pRuntimeModule, pAppDomain, pRuntimeModule->IsIStream());
9878 // Note: the appdomain the module was loaded in must match the appdomain we're unloading it from. If it doesn't,
9879 // then we've either found the wrong DebuggerModule in LookupModule or we were passed bad data.
9880 _ASSERTE(module->GetAppDomain() == pAppDomain);
9882 // Send the unload module event to the Right Side.
9883 DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer();
9884 InitIPCEvent(ipce, DB_IPCE_UNLOAD_MODULE, thread, pAppDomain);
9885 ipce->UnloadModuleData.vmDomainFile.SetRawPtr((module ? module->GetDomainFile() : NULL));
9886 ipce->UnloadModuleData.debuggerAssemblyToken.Set(pRuntimeModule->GetClassLoader()->GetAssembly());
9887 m_pRCThread->SendIPCEvent();
9890 // Cleanup the module (only for resources consumed when a debugger is attached)
9893 // Remove all patches that apply to this module/AppDomain combination
9894 AppDomain* domainToRemovePatchesIn = NULL; // all domains by default
9895 if( pRuntimeModule->GetAssembly()->IsDomainNeutral() )
9897 // Deactivate all the patches specific to the AppDomain being unloaded
9898 domainToRemovePatchesIn = pAppDomain;
9900 // Note that we'll explicitly NOT delete DebuggerControllers, so that
9901 // the Right Side can delete them later.
9902 DebuggerController::RemovePatchesFromModule(pRuntimeModule, domainToRemovePatchesIn);
9904 // Deactive all JMC functions in this module. We don't do this for shared assemblies
9905 // because JMC status is not maintained on a per-AppDomain basis and we don't
9906 // want to change the JMC behavior of the module in other domains.
9907 if( !pRuntimeModule->GetAssembly()->IsDomainNeutral() )
9909 LOG((LF_CORDB, LL_EVERYTHING, "Setting all JMC methods to false:\n"));
9910 DebuggerDataLockHolder debuggerDataLockHolder(this);
9911 DebuggerMethodInfoTable * pTable = GetMethodInfoTable();
9916 for (DebuggerMethodInfo *dmi = pTable->GetFirstMethodInfo(&info);
9918 dmi = pTable->GetNextMethodInfo(&info))
9920 if (dmi->m_module == pRuntimeModule)
9922 dmi->SetJMCStatus(false);
9926 LOG((LF_CORDB, LL_EVERYTHING, "Done clearing JMC methods!\n"));
9929 // Delete the Left Side representation of the module.
9930 if (m_pModules != NULL)
9932 DebuggerDataLockHolder chInfo(this);
9933 m_pModules->RemoveModule(pRuntimeModule, pAppDomain);
9936 // Stop all Runtime threads
9937 TrapAllRuntimeThreads();
9941 LOG((LF_CORDB,LL_INFO1000, "D::UM: Skipping SendIPCEvent because RS detached."));
9948 // Called when this module is completely gone from ALL AppDomains, regardless of
9949 // whether a debugger is attached.
9950 // Note that this doesn't get called until after the ADUnload is complete, which happens
9951 // asyncronously in Whidbey (and won't happen at all if the process shuts down first).
9952 // This is normally not called only domain-neutral assemblies because they can't be unloaded.
9953 // However, it may be called if the loader fails to completely load a domain-neutral assembly.
9954 void Debugger::DestructModule(Module *pModule)
9963 LOG((LF_CORDB, LL_INFO100, "D::DM: destruct module runtimeMod:%#08x modName:%ls\n",
9964 pModule, pModule->GetDebugName()));
9967 // Implements DebugInterface.
9968 // It is called for Module::Destruct. We do not need to send any IPC event.
9970 DebuggerLockHolder dbgLockHolder(this);
9972 // We should have removed all patches at AD unload time (or detach time if the
9973 // debugger detached).
9974 _ASSERTE( !DebuggerController::ModuleHasPatches(pModule) );
9976 // Do module clean-up that applies even when no debugger is attached.
9977 // Ideally, we might like to do this cleanup more eagerly and detministically,
9978 // but we don't currently get any early AD unload callback from the loader
9979 // when no debugger is attached. Perhaps we should make the loader
9980 // call this callback earlier.
9981 RemoveModuleReferences(pModule);
9985 // Internal helper to remove all the DJIs / DMIs and other references for a given Module.
9986 // If we don't remove the DJIs / DMIs, then we're subject to recycling bugs because the underlying
9987 // MethodDescs will get removed. Thus we'll look up a new MD and it will pull up an old DMI that matched
9988 // the old MD. Now the DMI and MD are out of sync and it's downhill from there.
9989 // Note that DMIs may be used (and need cleanup) even when no debugger is attached.
9990 void Debugger::RemoveModuleReferences( Module* pModule )
9992 _ASSERTE( ThreadHoldsLock() );
9994 // We want to remove all references to the module from the various
9995 // tables. It's not just possible, but probable, that the module
9996 // will be re-loaded at the exact same address, and in that case,
9997 // we'll have piles of entries in our DJI table that mistakenly
9998 // match this new module.
9999 // Note that this doesn't apply to domain neutral assemblies, that only
10000 // get unloaded when the process dies. We won't be reclaiming their
10001 // DJIs/patches b/c the process is going to die, so we'll reclaim
10002 // the memory when the various hashtables are unloaded.
10004 if (m_pMethodInfos != NULL)
10007 if (!HasLazyData())
10009 hr = LazyInitWrapper();
10014 DebuggerDataLockHolder debuggerDataLockHolder(this);
10016 m_pMethodInfos->ClearMethodsOfModule(pModule);
10018 // DebuggerDataLockHolder out of scope - release implied
10023 //---------------------------------------------------------------------------------------
10025 // SendClassLoadUnloadEvent - notify the RS of a class either loading or unloading.
10029 // fAttaching - true if a debugger is in the process of attaching
10034 //---------------------------------------------------------------------------------------
10035 void Debugger::SendClassLoadUnloadEvent (mdTypeDef classMetadataToken,
10036 DebuggerModule * pClassDebuggerModule,
10037 Assembly *pAssembly,
10038 AppDomain *pAppDomain,
10043 MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
10044 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
10049 LOG((LF_CORDB,LL_INFO10000, "D::SCLUE: Tok:0x%x isLoad:0x%x Mod:%#08x AD:%#08x\n",
10050 classMetadataToken, fIsLoadEvent, pClassDebuggerModule, pAppDomain));
10052 DebuggerIPCEvent * pEvent = m_pRCThread->GetIPCEventSendBuffer();
10054 BOOL fIsReflection = pClassDebuggerModule->GetRuntimeModule()->IsReflection();
10056 if (fIsLoadEvent == TRUE)
10058 // We need to update Metadata before Symbols (since symbols depend on metadata)
10059 // It's debatable which needs to come first: Class Load or Sym update.
10060 // V1.1 sent Sym Update first so that binding at the class load has the latest symbols.
10061 // However, The Class Load may need to be in sync with updating new metadata,
10062 // and that has to come before the Sym update.
10063 InitIPCEvent(pEvent, DB_IPCE_LOAD_CLASS, g_pEEInterface->GetThread(), pAppDomain);
10065 pEvent->LoadClass.classMetadataToken = classMetadataToken;
10066 pEvent->LoadClass.vmDomainFile.SetRawPtr((pClassDebuggerModule ? pClassDebuggerModule->GetDomainFile() : NULL));
10067 pEvent->LoadClass.classDebuggerAssemblyToken.Set(pAssembly);
10070 // For class loads in dynamic modules, RS knows that the metadata has now grown and is invalid.
10071 // RS will re-fetch new metadata from out-of-process.
10075 InitIPCEvent(pEvent, DB_IPCE_UNLOAD_CLASS, g_pEEInterface->GetThread(), pAppDomain);
10077 pEvent->UnloadClass.classMetadataToken = classMetadataToken;
10078 pEvent->UnloadClass.vmDomainFile.SetRawPtr((pClassDebuggerModule ? pClassDebuggerModule->GetDomainFile() : NULL));
10079 pEvent->UnloadClass.classDebuggerAssemblyToken.Set(pAssembly);
10082 m_pRCThread->SendIPCEvent();
10084 if (fIsLoadEvent && fIsReflection)
10086 // Send the raw event, but don't actually sync and block the runtime.
10087 SendRawUpdateModuleSymsEvent(pClassDebuggerModule->GetRuntimeModule(), pAppDomain);
10094 /******************************************************************************
10096 ******************************************************************************/
10097 BOOL Debugger::SendSystemClassLoadUnloadEvent(mdTypeDef classMetadataToken,
10098 Module *classModule,
10103 MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
10104 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
10108 if (!m_dClassLoadCallbackCount)
10113 BOOL fRetVal = FALSE;
10115 Assembly *pAssembly = classModule->GetAssembly();
10117 if (!m_pAppDomainCB->Lock())
10120 AppDomainInfo *pADInfo = m_pAppDomainCB->FindFirst();
10122 while (pADInfo != NULL)
10124 AppDomain *pAppDomain = pADInfo->m_pAppDomain;
10125 _ASSERTE(pAppDomain != NULL);
10127 // Only notify for app domains where the module has been fully loaded already
10128 // We used to make a different check here domain->ContainsAssembly() but that
10129 // triggers too early in the loading process. FindDomainFile will not become
10130 // non-NULL until the module is fully loaded into the domain which is what we
10132 if ((classModule->FindDomainFile(pAppDomain) != NULL ) &&
10133 !(fIsLoadEvent && pAppDomain->IsUnloading()) )
10135 // Find the Left Side module that this class belongs in.
10136 DebuggerModule* pModule = LookupOrCreateModule(classModule, pAppDomain);
10137 _ASSERTE(pModule != NULL);
10139 // Only send a class load event if they're enabled for this module.
10140 if (pModule && pModule->ClassLoadCallbacksEnabled())
10142 SendClassLoadUnloadEvent(classMetadataToken,
10151 pADInfo = m_pAppDomainCB->FindNext(pADInfo);
10154 m_pAppDomainCB->Unlock();
10161 // LoadClass is called when a Runtime thread loads a new Class.
10162 // Returns TRUE if an event is sent, FALSE otherwise
10163 BOOL Debugger::LoadClass(TypeHandle th,
10164 mdTypeDef classMetadataToken,
10165 Module *classModule,
10166 AppDomain *pAppDomain)
10170 MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
10171 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
10176 // Implements DebugInterface
10177 // This can be called by EE/Loader when class is loaded.
10180 BOOL fRetVal = FALSE;
10182 if (CORDBUnrecoverableError(this))
10185 // Note that pAppDomain may be null. The AppDomain isn't used here, and doesn't make a lot of sense since
10186 // we may be delivering the notification for a class in an assembly which is loaded into multiple AppDomains. We
10187 // handle this in SendSystemClassLoadUnloadEvent below by looping through all AppDomains and dispatching
10188 // events for each that contain this assembly.
10190 LOG((LF_CORDB, LL_INFO10000, "D::LC: load class Tok:%#08x Mod:%#08x AD:%#08x classMod:%#08x modName:%ls\n",
10191 classMetadataToken, (pAppDomain == NULL) ? NULL : LookupOrCreateModule(classModule, pAppDomain),
10192 pAppDomain, classModule, classModule->GetDebugName()));
10195 // If we're attaching, then we only need to send the event. We
10196 // don't need to disable event handling or lock the debugger
10199 SENDIPCEVENT_BEGIN(this, g_pEEInterface->GetThread());
10201 if (CORDebuggerAttached())
10203 fRetVal = SendSystemClassLoadUnloadEvent(classMetadataToken, classModule, TRUE);
10205 if (fRetVal == TRUE)
10207 // Stop all Runtime threads
10208 TrapAllRuntimeThreads();
10213 LOG((LF_CORDB,LL_INFO1000, "D::LC: Skipping SendIPCEvent because RS detached."));
10223 // UnloadClass is called when a Runtime thread unloads a Class.
10225 void Debugger::UnloadClass(mdTypeDef classMetadataToken,
10226 Module *classModule,
10227 AppDomain *pAppDomain)
10231 MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
10232 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
10237 // Implements DebugInterface
10238 // Can only be called from EE
10240 if (CORDBUnrecoverableError(this))
10245 LOG((LF_CORDB, LL_INFO10000, "D::UC: unload class Tok:0x%08x Mod:%#08x AD:%#08x runtimeMod:%#08x modName:%ls\n",
10246 classMetadataToken, LookupOrCreateModule(classModule, pAppDomain), pAppDomain, classModule, classModule->GetDebugName()));
10248 Assembly *pAssembly = classModule->GetClassLoader()->GetAssembly();
10249 DebuggerModule *pModule = LookupOrCreateModule(classModule, pAppDomain);
10251 if ((pModule == NULL) || !pModule->ClassLoadCallbacksEnabled())
10256 SENDIPCEVENT_BEGIN(this, g_pEEInterface->GetThread());
10258 if (CORDebuggerAttached())
10260 _ASSERTE((pAppDomain != NULL) && (pAssembly != NULL) && (pModule != NULL));
10262 SendClassLoadUnloadEvent(classMetadataToken, pModule, pAssembly, pAppDomain, FALSE);
10264 // Stop all Runtime threads
10265 TrapAllRuntimeThreads();
10269 LOG((LF_CORDB,LL_INFO1000, "D::UC: Skipping SendIPCEvent because RS detached."));
10272 // Let other Runtime threads handle their events.
10277 /******************************************************************************
10279 ******************************************************************************/
10280 void Debugger::FuncEvalComplete(Thread* pThread, DebuggerEval *pDE)
10289 #ifndef DACCESS_COMPILE
10291 if (CORDBUnrecoverableError(this))
10294 LOG((LF_CORDB, LL_INFO1000, "D::FEC: func eval complete pDE:%p evalType:%d %s %s\n",
10295 pDE, pDE->m_evalType, pDE->m_successful ? "Success" : "Fail", pDE->m_aborted ? "Abort" : "Completed"));
10298 _ASSERTE(pDE->m_completed);
10299 _ASSERTE((g_pEEInterface->GetThread() && !g_pEEInterface->GetThread()->m_fPreemptiveGCDisabled) || g_fInControlC);
10300 _ASSERTE(ThreadHoldsLock());
10302 // If we need to rethrow a ThreadAbortException then set the thread's state so we remember that.
10303 if (pDE->m_rethrowAbortException)
10305 pThread->SetThreadStateNC(Thread::TSNC_DebuggerReAbort);
10310 // Get the domain that the result is valid in. The RS will cache this in the ICorDebugValue
10311 // Note: it's possible that the AppDomain has (or is about to be) unloaded, which could lead to a
10312 // crash when we use the DebuggerModule. Ideally we'd only be using AppDomain IDs here.
10313 // We can't easily convert our ADID to an AppDomain* (SystemDomain::GetAppDomainFromId)
10314 // because we can't proove that that the AppDomain* would be valid (not unloaded).
10316 AppDomain *pDomain = pThread->GetDomain();
10317 AppDomain *pResultDomain = ((pDE->m_debuggerModule == NULL) ? pDomain : pDE->m_debuggerModule->GetAppDomain());
10318 _ASSERTE( pResultDomain->GetId() == pDE->m_appDomainId );
10320 // Send a func eval complete event to the Right Side.
10321 DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer();
10322 InitIPCEvent(ipce, DB_IPCE_FUNC_EVAL_COMPLETE, pThread, pDomain);
10324 ipce->FuncEvalComplete.funcEvalKey = pDE->m_funcEvalKey;
10325 ipce->FuncEvalComplete.successful = pDE->m_successful;
10326 ipce->FuncEvalComplete.aborted = pDE->m_aborted;
10327 ipce->FuncEvalComplete.resultAddr = pDE->m_result;
10328 ipce->FuncEvalComplete.vmAppDomain.SetRawPtr(pResultDomain);
10329 ipce->FuncEvalComplete.vmObjectHandle = pDE->m_vmObjectHandle;
10331 LOG((LF_CORDB, LL_INFO1000, "D::FEC: TypeHandle is %p\n", pDE->m_resultType.AsPtr()));
10333 Debugger::TypeHandleToExpandedTypeInfo(pDE->m_retValueBoxing, // whether return values get boxed or not depends on the particular FuncEval we're doing...
10336 &ipce->FuncEvalComplete.resultType);
10338 _ASSERTE(ipce->FuncEvalComplete.resultType.elementType != ELEMENT_TYPE_VALUETYPE);
10340 // We must adjust the result address to point to the right place
10341 ipce->FuncEvalComplete.resultAddr = ArgSlotEndianessFixup((ARG_SLOT*)ipce->FuncEvalComplete.resultAddr,
10342 GetSizeForCorElementType(ipce->FuncEvalComplete.resultType.elementType));
10344 LOG((LF_CORDB, LL_INFO1000, "D::FEC: returned el %04x resultAddr %p\n",
10345 ipce->FuncEvalComplete.resultType.elementType, ipce->FuncEvalComplete.resultAddr));
10347 m_pRCThread->SendIPCEvent();
10352 /******************************************************************************
10354 ******************************************************************************/
10355 bool Debugger::ResumeThreads(AppDomain* pAppDomain)
10361 PRECONDITION(ThisIsHelperThreadWorker());
10365 // Okay, mark that we're not stopped anymore and let the
10366 // Runtime threads go...
10367 ReleaseAllRuntimeThreads(pAppDomain);
10369 // Return that we've continued the process.
10378 BYTE *getCodeBuffer(DebuggerJitInfo *dji)
10387 CodeRegionInfo codeRegionInfo = CodeRegionInfo::GetCodeRegionInfo(dji);
10389 if (codeRegionInfo.getAddrOfColdCode())
10391 _ASSERTE(codeRegionInfo.getSizeOfHotCode() != 0);
10392 _ASSERTE(codeRegionInfo.getSizeOfColdCode() != 0);
10393 S_SIZE_T totalSize = S_SIZE_T( codeRegionInfo.getSizeOfHotCode() ) +
10394 S_SIZE_T( codeRegionInfo.getSizeOfColdCode() );
10395 if ( totalSize.IsOverflow() )
10397 _ASSERTE(0 && "Buffer overflow error in getCodeBuffer");
10401 BYTE *code = (BYTE *) buffer.AllocNoThrow( totalSize.Value() );
10405 (void *) codeRegionInfo.getAddrOfHotCode(),
10406 codeRegionInfo.getSizeOfHotCode());
10408 memcpy(code + codeRegionInfo.getSizeOfHotCode(),
10409 (void *) codeRegionInfo.getAddrOfColdCode(),
10410 codeRegionInfo.getSizeOfColdCode());
10412 // Now patch the control transfer instructions
10419 return dac_cast<PTR_BYTE>(codeRegionInfo.getAddrOfHotCode());
10424 CQuickBytes buffer;
10428 //---------------------------------------------------------------------------------------
10430 // Called on the helper thread to serialize metadata so it can be read out-of-process.
10433 // pModule - module that needs metadata serialization
10434 // countBytes - out value, holds the number of bytes which were allocated in the
10435 // serialized buffer
10438 // A pointer to a serialized buffer of metadata. The caller should free this bufer using
10439 // DeleteInteropSafe
10442 // This is called on the helper-thread, or a thread pretending to be the helper-thread.
10443 // For any synchronous message, the debuggee should be synchronized. The only async
10444 // messages are Attach and Async-Break.
10447 //---------------------------------------------------------------------------------------
10448 BYTE* Debugger::SerializeModuleMetaData(Module * pModule, DWORD * countBytes)
10457 LOG((LF_CORDB, LL_INFO10000, "Debugger::SMMD called\n"));
10459 // Do not release the emitter. This is a weak reference.
10460 IMetaDataEmit *pEmitter = pModule->GetEmitter();
10461 _ASSERTE(pEmitter != NULL);
10464 BYTE* metadataBuffer = NULL;
10465 ReleaseHolder<IMDInternalEmit> pInternalEmitter;
10466 ULONG originalUpdateMode;
10467 hr = pEmitter->QueryInterface(IID_IMDInternalEmit, (void **)&pInternalEmitter);
10470 LOG((LF_CORDB, LL_INFO10, "Debugger::SMMD pEmitter doesn't support IID_IMDInternalEmit hr=0x%x\n", hr));
10473 _ASSERTE(pInternalEmitter != NULL);
10475 hr = pInternalEmitter->SetMDUpdateMode(MDUpdateExtension, &originalUpdateMode);
10478 LOG((LF_CORDB, LL_INFO10, "Debugger::SMMD SetMDUpdateMode failed hr=0x%x\n", hr));
10481 _ASSERTE(originalUpdateMode == MDUpdateFull);
10483 hr = pEmitter->GetSaveSize(cssQuick, countBytes);
10486 LOG((LF_CORDB, LL_INFO10, "Debugger::SMMD GetSaveSize failed hr=0x%x\n", hr));
10487 pInternalEmitter->SetMDUpdateMode(originalUpdateMode, NULL);
10493 metadataBuffer = new (interopsafe) BYTE[*countBytes];
10497 LOG((LF_CORDB, LL_INFO10, "Debugger::SMMD Allocation failed\n"));
10498 pInternalEmitter->SetMDUpdateMode(originalUpdateMode, NULL);
10501 EX_END_CATCH(SwallowAllExceptions);
10502 _ASSERTE(metadataBuffer != NULL); // allocation would throw first
10504 // Caller ensures serialization that guarantees that the metadata doesn't grow underneath us.
10505 hr = pEmitter->SaveToMemory(metadataBuffer, *countBytes);
10508 LOG((LF_CORDB, LL_INFO10, "Debugger::SMMD SaveToMemory failed hr=0x%x\n", hr));
10509 DeleteInteropSafe(metadataBuffer);
10510 pInternalEmitter->SetMDUpdateMode(originalUpdateMode, NULL);
10514 pInternalEmitter->SetMDUpdateMode(originalUpdateMode, NULL);
10515 LOG((LF_CORDB, LL_INFO10000, "Debugger::SMMD exiting\n"));
10516 return metadataBuffer;
10519 //---------------------------------------------------------------------------------------
10521 // Handle an IPC event from the Debugger.
10524 // event - IPC event to handle.
10527 // True if the event was a continue. Else false.
10530 // This is called on the helper-thread, or a thread pretending to be the helper-thread.
10531 // For any synchronous message, the debuggee should be synchronized. The only async
10532 // messages are Attach and Async-Break.
10535 // HandleIPCEvent is called by the RC thread in response to an event
10536 // from the Debugger Interface. No other IPC events, nor any Runtime
10537 // events will come in until this method returns. Returns true if this
10538 // was a Continue event.
10540 // If this function is called on native debugger helper thread, we will
10541 // handle everything. However if this is called on managed thread doing
10542 // helper thread duty, we will fail on operation since we are mainly
10543 // waiting for CONTINUE message from the RS.
10546 //---------------------------------------------------------------------------------------
10549 #pragma warning(push)
10550 #pragma warning(disable:21000) // Suppress PREFast warning about overly large function
10552 bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent)
10557 if (g_pEEInterface->GetThread() != NULL) { GC_TRIGGERS; } else { GC_NOTRIGGER; }
10559 PRECONDITION(ThisIsHelperThreadWorker());
10572 // If we're the temporary helper thread, then we may reject certain operations.
10573 bool temporaryHelp = ThisIsTempHelperThread();
10577 // This reg key allows us to test our unhandled event filter installed in HandleIPCEventWrapper
10578 // to make sure it works properly.
10579 static int s_fDbgFaultInHandleIPCEvent = -1;
10580 if (s_fDbgFaultInHandleIPCEvent == -1)
10582 s_fDbgFaultInHandleIPCEvent = UnsafeGetConfigDWORD(CLRConfig::INTERNAL_DbgFaultInHandleIPCEvent);
10585 // If we need to fault, let's generate an access violation.
10586 if (s_fDbgFaultInHandleIPCEvent)
10588 *((volatile BYTE *)0) = 0;
10593 bool fContinue = false;
10596 LOG((LF_CORDB, LL_INFO10000, "D::HIPCE: got %s\n", IPCENames::GetName(pEvent->type)));
10597 DbgLog((DebuggerIPCEventType)(pEvent->type & DB_IPCE_TYPE_MASK));
10599 // As for runtime is considered stopped, it means that managed threads will not
10600 // execute anymore managed code. However, these threads may be still running for
10601 // unmanaged code. So it is not true that we do not need to hold the lock while processing
10602 // synchrnoized event.
10604 // The worst of all, it is the special case where user break point and exception can
10605 // be sent as part of attach if debugger was launched by managed app.
10607 DebuggerLockHolder dbgLockHolder(this, FALSE);
10609 if ((pEvent->type & DB_IPCE_TYPE_MASK) == DB_IPCE_ASYNC_BREAK ||
10610 (pEvent->type & DB_IPCE_TYPE_MASK) == DB_IPCE_ATTACHING)
10612 dbgLockHolder.Acquire();
10616 _ASSERTE(m_stopped);
10617 _ASSERTE(ThreadHoldsLock());
10621 switch (pEvent->type & DB_IPCE_TYPE_MASK)
10624 case DB_IPCE_ATTACHING:
10625 // In V3, Attach is atomic, meaning that there isn't a complex handshake back and forth between LS + RS.
10626 // the RS sends a single-attaching event and attaches at the first response from the Left-side.
10627 StartCanaryThread();
10629 // In V3 after attaching event was handled we iterate throughout all ADs and made shadow copies of PDBs in the BIN directories.
10630 // After all AppDomain, DomainAssembly and modules iteration was available in out-of-proccess model in V4 the code that enables
10631 // PDBs to be copied was not called at attach time.
10632 // Eliminating PDBs copying side effect is an issue: Dev10 #927143
10635 IterateAppDomainsForPdbs();
10637 EX_CATCH_HRESULT(hr); // ignore failures
10639 if (m_jitAttachInProgress)
10641 // For jit-attach, mark that we're attached now.
10642 // This lets callers to code:Debugger.JitAttach check the flag and
10643 // send the jit-attach event just like a normal event.
10644 MarkDebuggerAttachedInternal();
10646 // set the managed attach event so that waiting threads can continue
10647 VERIFY(SetEvent(GetAttachEvent()));
10651 VERIFY(SetEvent(GetAttachEvent()));
10654 // For regular (non-jit) attach, fall through to do an async break.
10657 case DB_IPCE_ASYNC_BREAK:
10661 // Don't support async break on temporary helper thread.
10662 // Well, this function does not return HR. So this means that
10663 // ASYNC_BREAK event will be catching silently while we are
10664 // doing helper thread duty!
10666 hr = CORDBG_E_NOTREADY;
10670 // not synchornized. We get debugger lock upon the function entry
10671 _ASSERTE(ThreadHoldsLock());
10673 // Simply trap all Runtime threads if we're not already trying to.
10674 if (!m_trappingRuntimeThreads)
10676 // If the RS sent an Async-break, then that's an explicit request.
10677 m_RSRequestedSync = TRUE;
10678 TrapAllRuntimeThreads(); // Non-blocking...
10684 case DB_IPCE_CONTINUE:
10686 GetCanary()->ClearCache();
10688 fContinue = ResumeThreads(pEvent->vmAppDomain.GetRawPtr());
10691 // Go ahead and release the TSL now that we're continuing. This ensures that we've held
10692 // the thread store lock the entire time the Runtime was just stopped.
10694 ThreadSuspend::UnlockThreadStore(FALSE, ThreadSuspend::SUSPEND_FOR_DEBUGGER);
10699 case DB_IPCE_BREAKPOINT_ADD:
10703 // Currently, we can't create a breakpoint before a
10704 // function desc is available.
10705 // Also, we can't know if a breakpoint is ok
10706 // prior to the method being JITted.
10709 _ASSERTE(hr == S_OK);
10710 DebuggerBreakpoint * pDebuggerBP = NULL;
10712 DebuggerModule * pDebuggerModule = LookupOrCreateModule(pEvent->BreakpointData.vmDomainFile);
10713 Module * pModule = pDebuggerModule->GetRuntimeModule();
10714 DebuggerMethodInfo * pDMI = GetOrCreateMethodInfo(pModule, pEvent->BreakpointData.funcMetadataToken);
10715 MethodDesc * pMethodDesc = pEvent->BreakpointData.nativeCodeMethodDescToken.UnWrap();
10717 DebuggerJitInfo * pDJI = NULL;
10718 if ((pMethodDesc != NULL) && (pDMI != NULL))
10720 pDJI = pDMI->FindOrCreateInitAndAddJitInfo(pMethodDesc, NULL /* startAddr */);
10724 // If we haven't been either JITted or EnC'd yet, then
10725 // we'll put a patch in by offset, implicitly relative
10726 // to the first version of the code.
10728 pDebuggerBP = new (interopsafe, nothrow) DebuggerBreakpoint(pModule,
10729 pEvent->BreakpointData.funcMetadataToken,
10730 pEvent->vmAppDomain.GetRawPtr(),
10731 pEvent->BreakpointData.offset,
10732 !pEvent->BreakpointData.isIL,
10733 pEvent->BreakpointData.encVersion,
10736 pEvent->BreakpointData.nativeCodeMethodDescToken == NULL,
10739 TRACE_ALLOC(pDebuggerBP);
10741 if ((pDebuggerBP != NULL) && !fSuccess)
10743 DeleteInteropSafe(pDebuggerBP);
10744 pDebuggerBP = NULL;
10745 hr = CORDBG_E_UNABLE_TO_SET_BREAKPOINT;
10749 if ((pDebuggerBP == NULL) && !FAILED(hr))
10751 hr = E_OUTOFMEMORY;
10754 LOG((LF_CORDB,LL_INFO10000,"\tBP Add: BPTOK:"
10755 "0x%x, tok=0x%08x, offset=0x%x, isIL=%d dm=0x%x m=0x%x\n",
10757 pEvent->BreakpointData.funcMetadataToken,
10758 pEvent->BreakpointData.offset,
10759 pEvent->BreakpointData.isIL,
10764 // We're using a two-way event here, so we place the
10765 // result event into the _receive_ buffer, not the send
10769 DebuggerIPCEvent * pIPCResult = m_pRCThread->GetIPCEventReceiveBuffer();
10771 InitIPCEvent(pIPCResult,
10772 DB_IPCE_BREAKPOINT_ADD_RESULT,
10773 g_pEEInterface->GetThread(),
10774 pEvent->vmAppDomain);
10776 pIPCResult->BreakpointData.breakpointToken.Set(pDebuggerBP);
10777 pIPCResult->hr = hr;
10779 m_pRCThread->SendIPCReply();
10785 LOG((LF_CORDB,LL_INFO10000, "D::HIPCE: stepIn:0x%x frmTok:0x%x"
10786 "StepIn:0x%x RangeIL:0x%x RangeCount:0x%x MapStop:0x%x "
10787 "InterceptStop:0x%x AppD:0x%x\n",
10788 pEvent->StepData.stepIn,
10789 pEvent->StepData.frameToken.GetSPValue(),
10790 pEvent->StepData.stepIn,
10791 pEvent->StepData.rangeIL,
10792 pEvent->StepData.rangeCount,
10793 pEvent->StepData.rgfMappingStop,
10794 pEvent->StepData.rgfInterceptStop,
10795 pEvent->vmAppDomain.GetRawPtr()));
10797 // <TODO>@todo memory allocation - bad if we're synced</TODO>
10798 Thread * pThread = pEvent->StepData.vmThreadToken.GetRawPtr();
10799 AppDomain * pAppDomain = pEvent->vmAppDomain.GetRawPtr();
10801 DebuggerIPCEvent * pIPCResult = m_pRCThread->GetIPCEventReceiveBuffer();
10803 InitIPCEvent(pIPCResult,
10804 DB_IPCE_STEP_RESULT,
10806 pEvent->vmAppDomain);
10810 // Can't step on the temporary helper thread.
10811 pIPCResult->hr = CORDBG_E_NOTREADY;
10815 DebuggerStepper * pStepper;
10817 if (pEvent->StepData.IsJMCStop)
10819 pStepper = new (interopsafe, nothrow) DebuggerJMCStepper(pThread,
10820 pEvent->StepData.rgfMappingStop,
10821 pEvent->StepData.rgfInterceptStop,
10826 pStepper = new (interopsafe, nothrow) DebuggerStepper(pThread,
10827 pEvent->StepData.rgfMappingStop,
10828 pEvent->StepData.rgfInterceptStop,
10832 if (pStepper == NULL)
10834 pIPCResult->hr = E_OUTOFMEMORY;
10836 m_pRCThread->SendIPCReply();
10840 TRACE_ALLOC(pStepper);
10842 unsigned int cRanges = pEvent->StepData.totalRangeCount;
10844 _ASSERTE(cRanges == 0 || ((cRanges > 0) && (cRanges == pEvent->StepData.rangeCount)));
10846 if (!pStepper->Step(pEvent->StepData.frameToken,
10847 pEvent->StepData.stepIn,
10848 &(pEvent->StepData.range),
10850 ((cRanges > 0) ? pEvent->StepData.rangeIL : false)))
10852 pIPCResult->hr = E_OUTOFMEMORY;
10854 m_pRCThread->SendIPCReply();
10856 DeleteInteropSafe(pStepper);
10860 pIPCResult->StepData.stepperToken.Set(pStepper);
10863 } // end normal step case.
10866 m_pRCThread->SendIPCReply();
10870 case DB_IPCE_STEP_OUT:
10872 // <TODO>@todo memory allocation - bad if we're synced</TODO>
10873 Thread * pThread = pEvent->StepData.vmThreadToken.GetRawPtr();
10874 AppDomain * pAppDomain = pEvent->vmAppDomain.GetRawPtr();
10876 DebuggerIPCEvent * pIPCResult = m_pRCThread->GetIPCEventReceiveBuffer();
10878 InitIPCEvent(pIPCResult,
10879 DB_IPCE_STEP_RESULT,
10885 // Can't step on the temporary helper thread.
10886 pIPCResult->hr = CORDBG_E_NOTREADY;
10890 DebuggerStepper * pStepper;
10892 if (pEvent->StepData.IsJMCStop)
10894 pStepper = new (interopsafe, nothrow) DebuggerJMCStepper(pThread,
10895 pEvent->StepData.rgfMappingStop,
10896 pEvent->StepData.rgfInterceptStop,
10901 pStepper = new (interopsafe, nothrow) DebuggerStepper(pThread,
10902 pEvent->StepData.rgfMappingStop,
10903 pEvent->StepData.rgfInterceptStop,
10908 if (pStepper == NULL)
10910 pIPCResult->hr = E_OUTOFMEMORY;
10911 m_pRCThread->SendIPCReply();
10916 TRACE_ALLOC(pStepper);
10918 // Safe to stack trace b/c we're stopped.
10919 StackTraceTicket ticket(pThread);
10921 pStepper->StepOut(pEvent->StepData.frameToken, ticket);
10923 pIPCResult->StepData.stepperToken.Set(pStepper);
10926 m_pRCThread->SendIPCReply();
10930 case DB_IPCE_BREAKPOINT_REMOVE:
10932 // <TODO>@todo memory allocation - bad if we're synced</TODO>
10934 DebuggerBreakpoint * pDebuggerBP = pEvent->BreakpointData.breakpointToken.UnWrap();
10936 pDebuggerBP->Delete();
10940 case DB_IPCE_STEP_CANCEL:
10942 // <TODO>@todo memory allocation - bad if we're synced</TODO>
10943 LOG((LF_CORDB,LL_INFO10000, "D:HIPCE:Got STEP_CANCEL for stepper 0x%p\n",
10944 pEvent->StepData.stepperToken.UnWrap()));
10946 DebuggerStepper * pStepper = pEvent->StepData.stepperToken.UnWrap();
10948 pStepper->Delete();
10952 case DB_IPCE_SET_ALL_DEBUG_STATE:
10954 Thread * pThread = pEvent->SetAllDebugState.vmThreadToken.GetRawPtr();
10955 CorDebugThreadState debugState = pEvent->SetAllDebugState.debugState;
10957 LOG((LF_CORDB,LL_INFO10000,"HandleIPCE: SetAllDebugState: except thread 0x%08x (ID:0x%x) to state 0x%x\n",
10959 (pThread != NULL) ? GetThreadIdHelper(pThread) : 0,
10962 if (!g_fProcessDetach)
10964 g_pEEInterface->SetAllDebugState(pThread, debugState);
10967 STRESS_LOG1(LF_CORDB,LL_INFO10000,"HandleIPC: Got 0x%x back from SetAllDebugState\n", hr);
10969 // Just send back an HR.
10970 DebuggerIPCEvent * pIPCResult = m_pRCThread->GetIPCEventReceiveBuffer();
10972 PREFIX_ASSUME(pIPCResult != NULL);
10974 InitIPCEvent(pIPCResult, DB_IPCE_SET_DEBUG_STATE_RESULT, NULL, NULL);
10976 pIPCResult->hr = S_OK;
10978 m_pRCThread->SendIPCReply();
10982 case DB_IPCE_GET_GCHANDLE_INFO:
10983 // Given an unvalidated GC-handle, find out all the info about it to view the object
10984 // at the other end
10986 OBJECTHANDLE objectHandle = pEvent->GetGCHandleInfo.GCHandle.GetRawPtr();
10988 DebuggerIPCEvent * pIPCResult = m_pRCThread->GetIPCEventReceiveBuffer();
10990 PREFIX_ASSUME(pIPCResult != NULL);
10992 InitIPCEvent(pIPCResult, DB_IPCE_GET_GCHANDLE_INFO_RESULT, NULL, NULL);
10994 bool fValid = SUCCEEDED(ValidateGCHandle(objectHandle));
10996 AppDomain * pAppDomain = NULL;
11000 // Get the appdomain
11001 IGCHandleManager *mgr = GCHandleUtilities::GetGCHandleManager();
11002 ADIndex appDomainIndex = ADIndex(reinterpret_cast<DWORD>(mgr->GetHandleContext(objectHandle)));
11003 pAppDomain = SystemDomain::GetAppDomainAtIndex(appDomainIndex);
11005 _ASSERTE(pAppDomain != NULL);
11008 pIPCResult->hr = S_OK;
11009 pIPCResult->GetGCHandleInfoResult.vmAppDomain.SetRawPtr(pAppDomain);
11010 pIPCResult->GetGCHandleInfoResult.fValid = fValid;
11012 m_pRCThread->SendIPCReply();
11017 case DB_IPCE_GET_BUFFER:
11019 GetAndSendBuffer(m_pRCThread, pEvent->GetBuffer.bufSize);
11023 case DB_IPCE_RELEASE_BUFFER:
11025 SendReleaseBuffer(m_pRCThread, pEvent->ReleaseBuffer.pBuffer);
11028 #ifdef EnC_SUPPORTED
11029 case DB_IPCE_APPLY_CHANGES:
11031 LOG((LF_ENC, LL_INFO100, "D::HIPCE: DB_IPCE_APPLY_CHANGES 1\n"));
11033 DebuggerModule * pDebuggerModule = LookupOrCreateModule(pEvent->ApplyChanges.vmDomainFile);
11035 // @todo handle error.
11037 hr = ApplyChangesAndSendResult(pDebuggerModule,
11038 pEvent->ApplyChanges.cbDeltaMetadata,
11039 (BYTE*) CORDB_ADDRESS_TO_PTR(pEvent->ApplyChanges.pDeltaMetadata),
11040 pEvent->ApplyChanges.cbDeltaIL,
11041 (BYTE*) CORDB_ADDRESS_TO_PTR(pEvent->ApplyChanges.pDeltaIL));
11043 LOG((LF_ENC, LL_INFO100, "D::HIPCE: DB_IPCE_APPLY_CHANGES 2\n"));
11046 #endif // EnC_SUPPORTED
11048 case DB_IPCE_SET_CLASS_LOAD_FLAG:
11050 DebuggerModule *pDebuggerModule = LookupOrCreateModule(pEvent->SetClassLoad.vmDomainFile);
11052 _ASSERTE(pDebuggerModule != NULL);
11054 LOG((LF_CORDB, LL_INFO10000,
11055 "D::HIPCE: class load flag is %d for module 0x%p\n",
11056 pEvent->SetClassLoad.flag,
11059 pDebuggerModule->EnableClassLoadCallbacks((BOOL)pEvent->SetClassLoad.flag);
11063 case DB_IPCE_IS_TRANSITION_STUB:
11064 GetAndSendTransitionStubInfo((CORDB_ADDRESS_TYPE*)pEvent->IsTransitionStub.address);
11067 case DB_IPCE_MODIFY_LOGSWITCH:
11068 g_pEEInterface->DebuggerModifyingLogSwitch (pEvent->LogSwitchSettingMessage.iLevel,
11069 pEvent->LogSwitchSettingMessage.szSwitchName.GetString());
11073 case DB_IPCE_ENABLE_LOG_MESSAGES:
11075 bool fOnOff = pEvent->LogSwitchSettingMessage.iLevel ? true : false;
11076 EnableLogMessages (fOnOff);
11080 case DB_IPCE_SET_IP:
11083 // This is a synchronous event (reply required)
11084 DebuggerIPCEvent * pIPCResult = m_pRCThread->GetIPCEventReceiveBuffer();
11086 // Don't have an explicit reply msg
11087 InitIPCReply(pIPCResult, DB_IPCE_SET_IP);
11091 pIPCResult->hr = CORDBG_E_NOTREADY;
11093 else if (!g_fProcessDetach)
11096 // Since this pointer is coming from the RS, it may be NULL or something
11097 // unexpected in an OOM situation. Quickly just sanity check them.
11099 Thread * pThread = pEvent->SetIP.vmThreadToken.GetRawPtr();
11100 Module * pModule = pEvent->SetIP.vmDomainFile.GetRawPtr()->GetModule();
11102 // Get the DJI for this function
11103 DebuggerMethodInfo * pDMI = GetOrCreateMethodInfo(pModule, pEvent->SetIP.mdMethod);
11104 DebuggerJitInfo * pDJI = NULL;
11107 // In the EnC case, if we look for an older version, we need to find the DJI by starting
11108 // address, rather than just by MethodDesc. In the case of generics, we may need to create a DJI, so we
11109 pDJI = pDMI->FindOrCreateInitAndAddJitInfo(pEvent->SetIP.vmMethodDesc.GetRawPtr(),
11110 PINSTRToPCODE((TADDR)pEvent->SetIP.startAddress));
11113 if ((pDJI != NULL) && (pThread != NULL) && (pModule != NULL))
11115 CHECK_IF_CAN_TAKE_HELPER_LOCKS_IN_THIS_SCOPE(&(pIPCResult->hr), GetCanary());
11117 if (SUCCEEDED(pIPCResult->hr))
11119 pIPCResult->hr = SetIP(pEvent->SetIP.fCanSetIPOnly,
11122 pEvent->SetIP.mdMethod,
11124 pEvent->SetIP.offset,
11125 pEvent->SetIP.fIsIL
11131 pIPCResult->hr = E_INVALIDARG;
11136 pIPCResult->hr = S_OK;
11140 m_pRCThread->SendIPCReply();
11144 case DB_IPCE_DETACH_FROM_PROCESS:
11145 LOG((LF_CORDB, LL_INFO10000, "Detaching from process!\n"));
11147 // Delete all controllers (remove patches etc.)
11148 DebuggerController::DeleteAllControllers();
11149 // Note that we'd like to be able to do this assert here
11150 // _ASSERTE(DebuggerController::GetNumberOfPatches() == 0);
11151 // However controllers may get queued for deletion if there is outstanding
11152 // work and so we can't gaurentee the deletion will complete now.
11153 // @dbgtodo inspection: This shouldn't be an issue in the complete V3 architecture
11155 MarkDebuggerUnattachedInternal();
11157 m_pRCThread->RightSideDetach();
11160 // Clear JMC status
11162 LOG((LF_CORDB, LL_EVERYTHING, "Setting all JMC methods to false:\n"));
11163 // On detach, set all DMI's JMC status to false.
11164 // We have to do this b/c we clear the DebuggerModules and allocated
11165 // new ones on re-attach; and the DMI & DM need to be in sync
11166 // (in this case, agreeing that JMC-status = false).
11167 // This also syncs the EE modules and disables all JMC probes.
11168 DebuggerMethodInfoTable * pMethodInfoTable = g_pDebugger->GetMethodInfoTable();
11170 if (pMethodInfoTable != NULL)
11173 DebuggerDataLockHolder debuggerDataLockHolder(this);
11175 for (DebuggerMethodInfo * pMethodInfo = pMethodInfoTable->GetFirstMethodInfo(&hashFind);
11176 pMethodInfo != NULL;
11177 pMethodInfo = pMethodInfoTable->GetNextMethodInfo(&hashFind))
11179 pMethodInfo->SetJMCStatus(false);
11182 LOG((LF_CORDB, LL_EVERYTHING, "Done clearing JMC methods!\n"));
11185 // Clean up the hash of DebuggerModules
11186 // This method is overridden to also free all DebuggerModule objects
11187 if (m_pModules != NULL)
11190 // Removes all DebuggerModules
11191 DebuggerDataLockHolder ch(this);
11192 m_pModules->Clear();
11196 // Reply to the detach message before we release any Runtime threads. This ensures that the debugger will get
11197 // the detach reply before the process exits if the main thread is near exiting.
11198 m_pRCThread->SendIPCReply();
11200 // Let the process run free now... there is no debugger to bother it anymore.
11201 fContinue = ResumeThreads(NULL);
11204 // Go ahead and release the TSL now that we're continuing. This ensures that we've held
11205 // the thread store lock the entire time the Runtime was just stopped.
11207 ThreadSuspend::UnlockThreadStore(FALSE, ThreadSuspend::SUSPEND_FOR_DEBUGGER);
11210 #ifndef DACCESS_COMPILE
11212 case DB_IPCE_FUNC_EVAL:
11214 // This is a synchronous event (reply required)
11215 pEvent = m_pRCThread->GetIPCEventReceiveBuffer();
11217 Thread * pThread = pEvent->FuncEval.vmThreadToken.GetRawPtr();
11219 InitIPCEvent(pEvent, DB_IPCE_FUNC_EVAL_SETUP_RESULT, pThread, pThread->GetDomain());
11221 BYTE * pbArgDataArea = NULL;
11222 DebuggerEval * pDebuggerEvalKey = NULL;
11224 pEvent->hr = FuncEvalSetup(&(pEvent->FuncEval), &pbArgDataArea, &pDebuggerEvalKey);
11226 // Send the result of how the func eval setup went.
11227 pEvent->FuncEvalSetupComplete.argDataArea = PTR_TO_CORDB_ADDRESS(pbArgDataArea);
11228 pEvent->FuncEvalSetupComplete.debuggerEvalKey.Set(pDebuggerEvalKey);
11230 m_pRCThread->SendIPCReply();
11237 case DB_IPCE_SET_REFERENCE:
11239 // This is a synchronous event (reply required)
11240 pEvent = m_pRCThread->GetIPCEventReceiveBuffer();
11242 InitIPCReply(pEvent, DB_IPCE_SET_REFERENCE_RESULT);
11244 pEvent->hr = SetReference(pEvent->SetReference.objectRefAddress,
11245 pEvent->SetReference.vmObjectHandle,
11246 pEvent->SetReference.newReference);
11248 // Send the result of how the set reference went.
11249 m_pRCThread->SendIPCReply();
11253 case DB_IPCE_SET_VALUE_CLASS:
11255 // This is a synchronous event (reply required)
11256 pEvent = m_pRCThread->GetIPCEventReceiveBuffer();
11258 InitIPCReply(pEvent, DB_IPCE_SET_VALUE_CLASS_RESULT);
11260 pEvent->hr = SetValueClass(pEvent->SetValueClass.oldData,
11261 pEvent->SetValueClass.newData,
11262 &pEvent->SetValueClass.type);
11264 // Send the result of how the set reference went.
11265 m_pRCThread->SendIPCReply();
11269 case DB_IPCE_GET_THREAD_FOR_TASKID:
11271 TASKID taskid = pEvent->GetThreadForTaskId.taskid;
11272 Thread *pThread = ThreadStore::GetThreadList(NULL);
11273 Thread *pThreadRet = NULL;
11275 while (pThread != NULL)
11277 if (pThread->GetTaskId() == taskid)
11279 pThreadRet = pThread;
11282 pThread = ThreadStore::GetThreadList(pThread);
11285 // This is a synchronous event (reply required)
11286 pEvent = m_pRCThread->GetIPCEventReceiveBuffer();
11288 InitIPCReply(pEvent, DB_IPCE_GET_THREAD_FOR_TASKID_RESULT);
11290 pEvent->GetThreadForTaskIdResult.vmThreadToken.SetRawPtr(pThreadRet);
11293 m_pRCThread->SendIPCReply();
11297 case DB_IPCE_CREATE_HANDLE:
11299 Object * pObject = (Object*)pEvent->CreateHandle.objectToken;
11300 OBJECTREF objref = ObjectToOBJECTREF(pObject);
11301 AppDomain * pAppDomain = pEvent->vmAppDomain.GetRawPtr();
11302 BOOL fStrong = pEvent->CreateHandle.fStrong;
11303 OBJECTHANDLE objectHandle;
11305 // This is a synchronous event (reply required)
11306 pEvent = m_pRCThread->GetIPCEventReceiveBuffer();
11308 InitIPCReply(pEvent, DB_IPCE_CREATE_HANDLE_RESULT);
11311 // Handle creation may need to allocate memory.
11312 // The API specifically limits the number of handls Cordbg can create,
11313 // so we could preallocate and fail allocating anything beyond that.
11314 CHECK_IF_CAN_TAKE_HELPER_LOCKS_IN_THIS_SCOPE(&(pEvent->hr), GetCanary());
11316 if (SUCCEEDED(pEvent->hr))
11318 if (fStrong == TRUE)
11320 // create strong handle
11321 objectHandle = pAppDomain->CreateStrongHandle(objref);
11325 // create the weak long handle
11326 objectHandle = pAppDomain->CreateLongWeakHandle(objref);
11328 pEvent->CreateHandleResult.vmObjectHandle.SetRawPtr(objectHandle);
11332 m_pRCThread->SendIPCReply();
11336 case DB_IPCE_DISPOSE_HANDLE:
11338 // DISPOSE an object handle
11339 OBJECTHANDLE objectHandle = pEvent->DisposeHandle.vmObjectHandle.GetRawPtr();
11341 if (pEvent->DisposeHandle.fStrong == TRUE)
11343 DestroyStrongHandle(objectHandle);
11347 DestroyLongWeakHandle(objectHandle);
11352 #ifndef DACCESS_COMPILE
11354 case DB_IPCE_FUNC_EVAL_ABORT:
11356 LOG((LF_CORDB, LL_INFO1000, "D::HIPCE: Got FuncEvalAbort for pDE:%08x\n",
11357 pEvent->FuncEvalAbort.debuggerEvalKey.UnWrap()));
11359 // This is a synchronous event (reply required)
11361 pEvent = m_pRCThread->GetIPCEventReceiveBuffer();
11362 InitIPCReply(pEvent,DB_IPCE_FUNC_EVAL_ABORT_RESULT);
11364 pEvent->hr = FuncEvalAbort(pEvent->FuncEvalAbort.debuggerEvalKey.UnWrap());
11366 m_pRCThread->SendIPCReply();
11370 case DB_IPCE_FUNC_EVAL_RUDE_ABORT:
11372 LOG((LF_CORDB, LL_INFO1000, "D::HIPCE: Got FuncEvalRudeAbort for pDE:%08x\n",
11373 pEvent->FuncEvalRudeAbort.debuggerEvalKey.UnWrap()));
11375 // This is a synchronous event (reply required)
11377 pEvent = m_pRCThread->GetIPCEventReceiveBuffer();
11379 InitIPCReply(pEvent, DB_IPCE_FUNC_EVAL_RUDE_ABORT_RESULT);
11381 pEvent->hr = FuncEvalRudeAbort(pEvent->FuncEvalRudeAbort.debuggerEvalKey.UnWrap());
11383 m_pRCThread->SendIPCReply();
11387 case DB_IPCE_FUNC_EVAL_CLEANUP:
11389 // This is a synchronous event (reply required)
11391 pEvent = m_pRCThread->GetIPCEventReceiveBuffer();
11393 InitIPCReply(pEvent,DB_IPCE_FUNC_EVAL_CLEANUP_RESULT);
11395 pEvent->hr = FuncEvalCleanup(pEvent->FuncEvalCleanup.debuggerEvalKey.UnWrap());
11397 m_pRCThread->SendIPCReply();
11403 case DB_IPCE_CONTROL_C_EVENT_RESULT:
11405 // store the result of whether the event has been handled by the debugger and
11406 // wake up the thread waiting for the result
11407 SetDebuggerHandlingCtrlC(pEvent->hr == S_OK);
11408 VERIFY(SetEvent(GetCtrlCMutex()));
11412 // Set the JMC status on invididual methods
11413 case DB_IPCE_SET_METHOD_JMC_STATUS:
11415 // Get the info out of the event
11416 DebuggerModule * pDebuggerModule = LookupOrCreateModule(pEvent->SetJMCFunctionStatus.vmDomainFile);
11417 Module * pModule = pDebuggerModule->GetRuntimeModule();
11419 bool fStatus = (pEvent->SetJMCFunctionStatus.dwStatus != 0);
11421 mdMethodDef token = pEvent->SetJMCFunctionStatus.funcMetadataToken;
11424 pEvent = m_pRCThread->GetIPCEventReceiveBuffer();
11426 InitIPCEvent(pEvent, DB_IPCE_SET_METHOD_JMC_STATUS_RESULT, NULL, NULL);
11430 if (pDebuggerModule->HasAnyOptimizedCode() && fStatus)
11432 // If there's optimized code, then we can't be set JMC status to true.
11433 // That's because JMC probes are not injected in optimized code, and we
11434 // need a JMC probe to have a JMC function.
11435 pEvent->hr = CORDBG_E_CANT_SET_TO_JMC;
11439 DebuggerDataLockHolder debuggerDataLockHolder(this);
11440 // This may be called on an unjitted method, so we may
11441 // have to create the MethodInfo.
11442 DebuggerMethodInfo * pMethodInfo = GetOrCreateMethodInfo(pModule, token);
11444 if (pMethodInfo == NULL)
11446 pEvent->hr = E_OUTOFMEMORY;
11450 // Update the storage on the LS
11451 pMethodInfo->SetJMCStatus(fStatus);
11456 m_pRCThread->SendIPCReply();
11460 // Get the JMC status on a given function
11461 case DB_IPCE_GET_METHOD_JMC_STATUS:
11464 DebuggerModule * pDebuggerModule = LookupOrCreateModule(pEvent->SetJMCFunctionStatus.vmDomainFile);
11466 Module * pModule = pDebuggerModule->GetRuntimeModule();
11468 mdMethodDef token = pEvent->SetJMCFunctionStatus.funcMetadataToken;
11471 pEvent = m_pRCThread->GetIPCEventReceiveBuffer();
11472 InitIPCEvent(pEvent, DB_IPCE_GET_METHOD_JMC_STATUS_RESULT, NULL, NULL);
11475 // This may be called on an unjitted method, so we may
11476 // have to create the MethodInfo.
11478 DebuggerMethodInfo * pMethodInfo = GetOrCreateMethodInfo(pModule, token);
11480 if (pMethodInfo == NULL)
11482 pEvent->hr = E_OUTOFMEMORY;
11486 bool fStatus = pMethodInfo->IsJMCFunction();
11487 pEvent->SetJMCFunctionStatus.dwStatus = fStatus;
11491 m_pRCThread->SendIPCReply();
11495 case DB_IPCE_SET_MODULE_JMC_STATUS:
11497 // Get data out of event
11498 DebuggerModule * pDebuggerModule = LookupOrCreateModule(pEvent->SetJMCFunctionStatus.vmDomainFile);
11500 bool fStatus = (pEvent->SetJMCFunctionStatus.dwStatus != 0);
11503 pEvent = m_pRCThread->GetIPCEventReceiveBuffer();
11505 InitIPCReply(pEvent, DB_IPCE_SET_MODULE_JMC_STATUS_RESULT);
11509 if (pDebuggerModule->HasAnyOptimizedCode() && fStatus)
11511 // If there's optimized code, then we can't be set JMC status to true.
11512 // That's because JMC probes are not injected in optimized code, and we
11513 // need a JMC probe to have a JMC function.
11514 pEvent->hr = CORDBG_E_CANT_SET_TO_JMC;
11518 g_pDebugger->SetModuleDefaultJMCStatus(pDebuggerModule->GetRuntimeModule(), fStatus);
11524 m_pRCThread->SendIPCReply();
11529 case DB_IPCE_INTERCEPT_EXCEPTION:
11530 GetAndSendInterceptCommand(pEvent);
11533 case DB_IPCE_RESOLVE_UPDATE_METADATA_1:
11536 LOG((LF_CORDB, LL_INFO10000, "D::HIPCE Handling DB_IPCE_RESOLVE_UPDATE_METADATA_1\n"));
11537 // This isn't ideal - Making SerializeModuleMetaData not call new is hard,
11538 // but the odds of trying to load a module after a thread is stopped w/
11539 // the heap lock should be pretty low.
11540 // All of the metadata calls can violate this and call new.
11541 SUPPRESS_ALLOCATION_ASSERTS_IN_THIS_SCOPE;
11543 Module * pModule = pEvent->MetadataUpdateRequest.vmModule.GetRawPtr();
11544 LOG((LF_CORDB, LL_INFO100000, "D::HIPCE Got module 0x%x\n", pModule));
11546 DWORD countBytes = 0;
11548 // This will allocate memory. Debugger will then copy from here and send a
11549 // DB_IPCE_RESOLVE_UPDATE_METADATA_2 to free this memory.
11550 BYTE* pData = NULL;
11553 LOG((LF_CORDB, LL_INFO100000, "D::HIPCE Calling SerializeModuleMetaData\n"));
11554 pData = SerializeModuleMetaData(pModule, &countBytes);
11557 EX_CATCH_HRESULT(hr);
11559 LOG((LF_CORDB, LL_INFO100000, "D::HIPCE hr is 0x%x\n", hr));
11561 DebuggerIPCEvent * pResult = m_pRCThread->GetIPCEventReceiveBuffer();
11562 InitIPCEvent(pResult, DB_IPCE_RESOLVE_UPDATE_METADATA_1_RESULT, NULL, NULL);
11564 pResult->MetadataUpdateRequest.pMetadataStart = pData;
11565 pResult->MetadataUpdateRequest.nMetadataSize = countBytes;
11567 LOG((LF_CORDB, LL_INFO1000000, "D::HIPCE metadataStart=0x%x, nMetadataSize=0x%x\n", pData, countBytes));
11569 m_pRCThread->SendIPCReply();
11570 LOG((LF_CORDB, LL_INFO1000000, "D::HIPCE reply sent\n"));
11574 case DB_IPCE_RESOLVE_UPDATE_METADATA_2:
11576 // Delete memory allocated with DB_IPCE_RESOLVE_UPDATE_METADATA_1.
11577 BYTE * pData = (BYTE *) pEvent->MetadataUpdateRequest.pMetadataStart;
11578 DeleteInteropSafe(pData);
11580 DebuggerIPCEvent * pResult = m_pRCThread->GetIPCEventReceiveBuffer();
11581 InitIPCEvent(pResult, DB_IPCE_RESOLVE_UPDATE_METADATA_2_RESULT, NULL, NULL);
11582 pResult->hr = S_OK;
11583 m_pRCThread->SendIPCReply();
11589 // We should never get an event that we don't know about.
11590 CONSISTENCY_CHECK_MSGF(false, ("Unknown Debug-Event on LS:id=0x%08x.", pEvent->type));
11591 LOG((LF_CORDB, LL_INFO10000, "Unknown event type: 0x%08x\n",
11595 STRESS_LOG0(LF_CORDB, LL_INFO10000, "D::HIPCE: finished handling event\n");
11597 // dbgLockHolder goes out of scope - implicit Release
11601 #pragma warning(pop)
11605 * GetAndSendInterceptCommand
11607 * This function processes an INTERCEPT_EXCEPTION IPC event, sending the appropriate response.
11610 * event - the event to process.
11616 HRESULT Debugger::GetAndSendInterceptCommand(DebuggerIPCEvent *event)
11621 GC_TRIGGERS_FROM_GETJITINFO;
11627 _ASSERTE((event->type & DB_IPCE_TYPE_MASK) == DB_IPCE_INTERCEPT_EXCEPTION);
11630 // Simple state validation first.
11632 Thread *pThread = event->InterceptException.vmThreadToken.GetRawPtr();
11634 if ((pThread != NULL) &&
11635 !m_forceNonInterceptable &&
11636 IsInterceptableException(pThread))
11638 ThreadExceptionState* pExState = pThread->GetExceptionState();
11640 // We can only have one interception going on at any given time.
11641 if (!pExState->GetFlags()->DebuggerInterceptInfo())
11644 // Now start processing the parameters from the event.
11646 FramePointer targetFramePointer = event->InterceptException.frameToken;
11648 ControllerStackInfo csi;
11650 // Safe because we're stopped.
11651 StackTraceTicket ticket(pThread);
11652 csi.GetStackInfo(ticket, pThread, targetFramePointer, NULL);
11654 if (csi.m_targetFrameFound)
11657 // If the target frame is below the point where the current exception was
11658 // thrown from, then we should reject this interception command. This
11659 // can happen in a func-eval during an exception callback, or during a
11660 // breakpoint in a filter function. Or it can just be a user error.
11662 CONTEXT* pContext = pExState->GetContextRecord();
11664 // This is an approximation on IA64, where we should use the caller SP instead of
11665 // the current SP. However, if the targetFramePointer is valid, the comparison should
11666 // still work. targetFramePointer should be valid because it ultimately comes from a
11668 FramePointer excepFramePointer = FramePointer::MakeFramePointer(GetSP(pContext));
11670 if (IsCloserToRoot(excepFramePointer, targetFramePointer))
11672 hr = CORDBG_E_CURRENT_EXCEPTION_IS_OUTSIDE_CURRENT_EXECUTION_SCOPE;
11673 goto LSendResponse;
11678 // If the instruction that faulted is not in this managed code, at the leaf
11679 // frame, then the IP is actually the return address from the managed or
11680 // unmanaged function that really did fault. Thus, we actually want the
11681 // IP of the call instruction. I fake this by simply subtracting 1 from
11682 // the IP, which is close enough approximation for the search below.
11684 if (pExState->GetContextRecord() != NULL)
11686 // If the faulting instruction is not in managed code, then the interception frame
11687 // must be non-leaf.
11688 if (!g_pEEInterface->IsManagedNativeCode((BYTE *)(GetIP(pExState->GetContextRecord()))))
11690 csi.m_activeFrame.relOffset--;
11694 MethodDesc *pMethodDesc = g_pEEInterface->GetNativeCodeMethodDesc(dac_cast<PCODE>(GetIP(pExState->GetContextRecord())));
11696 // check if the interception frame is the leaf frame
11697 if ((pMethodDesc == NULL) ||
11698 (pMethodDesc != csi.m_activeFrame.md) ||
11699 (GetSP(pExState->GetContextRecord()) != GetRegdisplaySP(&(csi.m_activeFrame.registers))))
11701 csi.m_activeFrame.relOffset--;
11707 // Now adjust the IP to be the previous zero-stack depth sequence point.
11709 SIZE_T foundOffset = 0;
11710 DebuggerJitInfo *pJitInfo = csi.m_activeFrame.GetJitInfoFromFrame();
11712 if (pJitInfo != NULL)
11714 ICorDebugInfo::SourceTypes src;
11716 ULONG relOffset = csi.m_activeFrame.relOffset;
11718 #if defined(WIN64EXCEPTIONS)
11719 int funcletIndex = PARENT_METHOD_INDEX;
11721 // For funclets, we need to make sure that the stack empty sequence point we use is
11722 // in the same funclet as the current offset.
11723 if (csi.m_activeFrame.IsFuncletFrame())
11725 funcletIndex = pJitInfo->GetFuncletIndex(relOffset, DebuggerJitInfo::GFIM_BYOFFSET);
11728 // Refer to the loop using pMap below.
11729 DebuggerILToNativeMap* pMap = NULL;
11730 #endif // WIN64EXCEPTIONS
11732 for (unsigned int i = 0; i < pJitInfo->GetSequenceMapCount(); i++)
11734 SIZE_T startOffset = pJitInfo->GetSequenceMap()[i].nativeStartOffset;
11736 if (DbgIsSpecialILOffset(pJitInfo->GetSequenceMap()[i].ilOffset))
11738 LOG((LF_CORDB, LL_INFO10000,
11739 "D::HIPCE: not placing breakpoint at special offset 0x%x\n", startOffset));
11743 if ((i >= 1) && (startOffset == pJitInfo->GetSequenceMap()[i-1].nativeStartOffset))
11745 LOG((LF_CORDB, LL_INFO10000,
11746 "D::HIPCE: not placing redundant breakpoint at duplicate offset 0x%x\n", startOffset));
11750 if (startOffset > relOffset)
11752 LOG((LF_CORDB, LL_INFO10000,
11753 "D::HIPCE: Stopping scan for breakpoint at offset 0x%x\n", startOffset));
11757 src = pJitInfo->GetSequenceMap()[i].source;
11759 if (!(src & ICorDebugInfo::STACK_EMPTY))
11761 LOG((LF_CORDB, LL_INFO10000, "D::HIPCE: not placing E&C breakpoint at offset "
11762 "0x%x b/c not STACK_EMPTY:it's 0x%x\n", startOffset, src));
11766 if ((foundOffset < startOffset) && (startOffset <= relOffset)
11767 #if defined(WIN64EXCEPTIONS)
11768 // Check if we are still in the same funclet.
11769 && (funcletIndex == pJitInfo->GetFuncletIndex(startOffset, DebuggerJitInfo::GFIM_BYOFFSET))
11770 #endif // WIN64EXCEPTIONS
11773 LOG((LF_CORDB, LL_INFO10000, "D::HIPCE: updating breakpoint at native offset 0x%x\n",
11775 foundOffset = startOffset;
11776 #if defined(WIN64EXCEPTIONS)
11777 // Save the map entry for modification later.
11778 pMap = &(pJitInfo->GetSequenceMap()[i]);
11779 #endif // WIN64EXCEPTIONS
11783 #if defined(WIN64EXCEPTIONS)
11784 // This is nasty. Starting recently we could have multiple sequence points with the same IL offset
11785 // in the SAME funclet/parent method (previously different sequence points with the same IL offset
11786 // imply that they are in different funclet/parent method). Fortunately, we only run into this
11787 // if we have a loop which throws a range check failed exception. The code for throwing the
11788 // exception executes out of line (this is JIT-specific, of course). The following loop makes sure
11789 // that when we interecept the exception, we intercept it at the smallest native offset instead
11790 // of intercepting it right before we throw the exception.
11791 for (/* no initialization */; pMap > pJitInfo->GetSequenceMap() ; pMap--)
11793 if (pMap->ilOffset == (pMap-1)->ilOffset)
11795 foundOffset = (pMap-1)->nativeStartOffset;
11802 _ASSERTE(foundOffset < relOffset);
11803 #endif // WIN64EXCEPTIONS
11806 // Set up a breakpoint on the intercept IP
11808 DebuggerContinuableExceptionBreakpoint *pBreakpoint;
11810 pBreakpoint = new (interopsafe, nothrow) DebuggerContinuableExceptionBreakpoint(pThread,
11813 csi.m_activeFrame.currentAppDomain
11816 if (pBreakpoint != NULL)
11819 // Set up the VM side of intercepting.
11821 if (pExState->GetDebuggerState()->SetDebuggerInterceptInfo(csi.m_activeFrame.pIJM,
11823 csi.m_activeFrame.MethodToken,
11824 csi.m_activeFrame.md,
11826 #if defined (_TARGET_ARM_ )|| defined (_TARGET_ARM64_ )
11827 // ARM requires the caller stack pointer, not the current stack pointer
11828 CallerStackFrame::FromRegDisplay(&(csi.m_activeFrame.registers)),
11830 StackFrame::FromRegDisplay(&(csi.m_activeFrame.registers)),
11832 pExState->GetFlags()
11836 // Make sure no more exception callbacks come thru.
11838 pExState->GetFlags()->SetSentDebugFirstChance();
11839 pExState->GetFlags()->SetSentDebugUserFirstChance();
11840 pExState->GetFlags()->SetSentDebugUnwindBegin();
11843 // Save off this breakpoint, so that if the exception gets unwound before we hit
11844 // the breakpoint - the exception info can call back to remove it.
11846 pExState->GetDebuggerState()->SetDebuggerInterceptContext((void *)pBreakpoint);
11850 else // VM could not set up for intercept
11852 DeleteInteropSafe(pBreakpoint);
11857 else // could not allocate for breakpoint
11859 hr = E_OUTOFMEMORY;
11863 else // could not get JitInfo
11869 else // target frame not found.
11875 else // already set up for an intercept.
11877 hr = CORDBG_E_INTERCEPT_FRAME_ALREADY_SET;
11881 else if (pThread == NULL)
11883 hr = E_INVALIDARG; // pThread is NULL.
11887 hr = CORDBG_E_NONINTERCEPTABLE_EXCEPTION;
11895 event = m_pRCThread->GetIPCEventReceiveBuffer();
11896 InitIPCReply(event, DB_IPCE_INTERCEPT_EXCEPTION_RESULT);
11902 m_pRCThread->SendIPCReply();
11907 // Poll & wait for the real helper thread to come up.
11908 // It's possible that the helper thread is blocked by DllMain, and so we can't
11909 // Wait infinite. If this poll does timeout, then it just means we're likely
11910 // go do helper duty instead of have the real helper do it.
11911 void Debugger::PollWaitingForHelper()
11914 LOG((LF_CORDB, LL_INFO10000, "PollWaitingForHelper() start\n"));
11916 DebuggerIPCControlBlock * pDCB = g_pRCThread->GetDCB();
11918 PREFIX_ASSUME(pDCB != NULL);
11920 int nTotalMSToWait = 8 * 1000;
11922 // Spin waiting for either the real helper thread or a temp. to be ready.
11923 // This should never timeout unless the helper is blocked on the loader lock.
11924 while (!pDCB->m_helperThreadId && !pDCB->m_temporaryHelperThreadId)
11926 STRESS_LOG1(LF_CORDB,LL_INFO1000, "PollWaitForHelper. %d\n", nTotalMSToWait);
11928 // If we hold the lock, we'll block the helper thread and this poll is not useful
11929 _ASSERTE(!ThreadHoldsLock());
11931 const DWORD dwTime = 50;
11932 ClrSleepEx(dwTime, FALSE);
11933 nTotalMSToWait -= dwTime;
11935 if (nTotalMSToWait <= 0)
11937 LOG((LF_CORDB, LL_INFO10000, "PollWaitingForHelper() timeout\n"));
11942 LOG((LF_CORDB, LL_INFO10000, "PollWaitingForHelper() succeed\n"));
11949 void Debugger::TypeHandleToBasicTypeInfo(AppDomain *pAppDomain, TypeHandle th, DebuggerIPCE_BasicTypeData *res)
11958 LOG((LF_CORDB, LL_INFO10000, "D::THTBTI: converting left-side type handle to basic right-side type info, ELEMENT_TYPE: %d.\n", th.GetSignatureCorElementType()));
11959 // GetSignatureCorElementType returns E_T_CLASS for E_T_STRING... :-(
11962 res->elementType = ELEMENT_TYPE_VOID;
11964 else if (th.GetMethodTable() == g_pObjectClass)
11966 res->elementType = ELEMENT_TYPE_OBJECT;
11968 else if (th.GetMethodTable() == g_pStringClass)
11970 res->elementType = ELEMENT_TYPE_STRING;
11974 res->elementType = th.GetSignatureCorElementType();
11977 switch (res->elementType)
11979 case ELEMENT_TYPE_ARRAY:
11980 case ELEMENT_TYPE_SZARRAY:
11981 case ELEMENT_TYPE_PTR:
11982 case ELEMENT_TYPE_FNPTR:
11983 case ELEMENT_TYPE_BYREF:
11984 res->vmTypeHandle = WrapTypeHandle(th);
11985 res->metadataToken = mdTokenNil;
11986 res->vmDomainFile.SetRawPtr(NULL);
11989 case ELEMENT_TYPE_CLASS:
11990 case ELEMENT_TYPE_VALUETYPE:
11992 res->vmTypeHandle = th.HasInstantiation() ? WrapTypeHandle(th) : VMPTR_TypeHandle::NullPtr();
11993 // only set if instantiated
11994 res->metadataToken = th.GetCl();
11995 DebuggerModule * pDModule = LookupOrCreateModule(th.GetModule(), pAppDomain);
11996 res->vmDomainFile.SetRawPtr((pDModule ? pDModule->GetDomainFile() : NULL));
12001 res->vmTypeHandle = VMPTR_TypeHandle::NullPtr();
12002 res->metadataToken = mdTokenNil;
12003 res->vmDomainFile.SetRawPtr(NULL);
12009 void Debugger::TypeHandleToExpandedTypeInfo(AreValueTypesBoxed boxed,
12010 AppDomain *pAppDomain,
12012 DebuggerIPCE_ExpandedTypeData *res)
12023 res->elementType = ELEMENT_TYPE_VOID;
12025 else if (th.GetMethodTable() == g_pObjectClass)
12027 res->elementType = ELEMENT_TYPE_OBJECT;
12029 else if (th.GetMethodTable() == g_pStringClass)
12031 res->elementType = ELEMENT_TYPE_STRING;
12035 LOG((LF_CORDB, LL_INFO10000, "D::THTETI: converting left-side type handle to expanded right-side type info, ELEMENT_TYPE: %d.\n", th.GetSignatureCorElementType()));
12036 // GetSignatureCorElementType returns E_T_CLASS for E_T_STRING... :-(
12037 res->elementType = th.GetSignatureCorElementType();
12040 switch (res->elementType)
12042 case ELEMENT_TYPE_ARRAY:
12043 case ELEMENT_TYPE_SZARRAY:
12044 _ASSERTE(th.IsArray());
12045 res->ArrayTypeData.arrayRank = th.AsArray()->GetRank();
12046 TypeHandleToBasicTypeInfo(pAppDomain,
12047 th.AsArray()->GetArrayElementTypeHandle(),
12048 &(res->ArrayTypeData.arrayTypeArg));
12051 case ELEMENT_TYPE_PTR:
12052 case ELEMENT_TYPE_BYREF:
12053 if (boxed == AllBoxed)
12055 res->elementType = ELEMENT_TYPE_CLASS;
12056 goto treatAllValuesAsBoxed;
12058 _ASSERTE(th.IsTypeDesc());
12059 TypeHandleToBasicTypeInfo(pAppDomain,
12060 th.AsTypeDesc()->GetTypeParam(),
12061 &(res->UnaryTypeData.unaryTypeArg));
12064 case ELEMENT_TYPE_VALUETYPE:
12065 if (boxed == OnlyPrimitivesUnboxed || boxed == AllBoxed)
12066 res->elementType = ELEMENT_TYPE_CLASS;
12069 case ELEMENT_TYPE_CLASS:
12071 treatAllValuesAsBoxed:
12072 res->ClassTypeData.typeHandle = th.HasInstantiation() ? WrapTypeHandle(th) : VMPTR_TypeHandle::NullPtr(); // only set if instantiated
12073 res->ClassTypeData.metadataToken = th.GetCl();
12074 DebuggerModule * pModule = LookupOrCreateModule(th.GetModule(), pAppDomain);
12075 res->ClassTypeData.vmDomainFile.SetRawPtr((pModule ? pModule->GetDomainFile() : NULL));
12076 _ASSERTE(!res->ClassTypeData.vmDomainFile.IsNull());
12080 case ELEMENT_TYPE_FNPTR:
12082 if (boxed == AllBoxed)
12084 res->elementType = ELEMENT_TYPE_CLASS;
12085 goto treatAllValuesAsBoxed;
12087 res->NaryTypeData.typeHandle = WrapTypeHandle(th);
12091 // The element type is sufficient, unless the type is effectively a "boxed"
12092 // primitive value type...
12093 if (boxed == AllBoxed)
12095 res->elementType = ELEMENT_TYPE_CLASS;
12096 goto treatAllValuesAsBoxed;
12100 LOG((LF_CORDB, LL_INFO10000, "D::THTETI: converted left-side type handle to expanded right-side type info, res->ClassTypeData.typeHandle = 0x%08x.\n", res->ClassTypeData.typeHandle.GetRawPtr()));
12105 HRESULT Debugger::BasicTypeInfoToTypeHandle(DebuggerIPCE_BasicTypeData *data, TypeHandle *pRes)
12114 LOG((LF_CORDB, LL_INFO10000, "D::BTITTH: expanding basic right-side type to left-side type, ELEMENT_TYPE: %d.\n", data->elementType));
12115 *pRes = TypeHandle();
12117 switch (data->elementType)
12119 case ELEMENT_TYPE_ARRAY:
12120 case ELEMENT_TYPE_SZARRAY:
12121 case ELEMENT_TYPE_PTR:
12122 case ELEMENT_TYPE_BYREF:
12123 _ASSERTE(!data->vmTypeHandle.IsNull());
12124 th = GetTypeHandle(data->vmTypeHandle);
12127 case ELEMENT_TYPE_CLASS:
12128 case ELEMENT_TYPE_VALUETYPE:
12130 if (!data->vmTypeHandle.IsNull())
12132 th = GetTypeHandle(data->vmTypeHandle);
12136 DebuggerModule *pDebuggerModule = g_pDebugger->LookupOrCreateModule(data->vmDomainFile);
12138 th = g_pEEInterface->FindLoadedClass(pDebuggerModule->GetRuntimeModule(), data->metadataToken);
12141 LOG((LF_CORDB, LL_INFO10000, "D::ETITTH: class isn't loaded.\n"));
12142 return CORDBG_E_CLASS_NOT_LOADED;
12145 _ASSERTE(th.GetNumGenericArgs() == 0);
12150 case ELEMENT_TYPE_FNPTR:
12152 _ASSERTE(!data->vmTypeHandle.IsNull());
12153 th = GetTypeHandle(data->vmTypeHandle);
12158 th = g_pEEInterface->FindLoadedElementType(data->elementType);
12162 return CORDBG_E_CLASS_NOT_LOADED;
12167 // Iterate through the type argument data, creating type handles as we go.
12168 void Debugger::TypeDataWalk::ReadTypeHandles(unsigned int nTypeArgs, TypeHandle *ppResults)
12170 WRAPPER_NO_CONTRACT;
12172 for (unsigned int i = 0; i < nTypeArgs; i++)
12173 ppResults[i] = ReadTypeHandle();
12176 TypeHandle Debugger::TypeDataWalk::ReadInstantiation(Module *pModule, mdTypeDef tok, unsigned int nTypeArgs)
12178 WRAPPER_NO_CONTRACT;
12181 if (!ClrSafeInt<DWORD>::multiply(nTypeArgs, sizeof(TypeHandle), dwAllocSize))
12183 ThrowHR(COR_E_OVERFLOW);
12185 TypeHandle * inst = (TypeHandle *) _alloca(dwAllocSize);
12186 ReadTypeHandles(nTypeArgs, inst) ;
12187 TypeHandle th = g_pEEInterface->LoadInstantiation(pModule, tok, nTypeArgs, inst);
12189 COMPlusThrow(kArgumentException, W("Argument_InvalidGenericArg"));
12193 TypeHandle Debugger::TypeDataWalk::ReadTypeHandle()
12202 DebuggerIPCE_TypeArgData * data = ReadOne();
12204 COMPlusThrow(kArgumentException, W("Argument_InvalidGenericArg"));
12206 LOG((LF_CORDB, LL_INFO10000, "D::ETITTH: expanding right-side type to left-side type, ELEMENT_TYPE: %d.\n", data->data.elementType));
12209 CorElementType et = data->data.elementType;
12212 case ELEMENT_TYPE_ARRAY:
12213 case ELEMENT_TYPE_SZARRAY:
12214 case ELEMENT_TYPE_PTR:
12215 case ELEMENT_TYPE_BYREF:
12216 if(data->numTypeArgs == 1)
12218 TypeHandle typar = ReadTypeHandle();
12221 case ELEMENT_TYPE_ARRAY:
12222 case ELEMENT_TYPE_SZARRAY:
12223 th = g_pEEInterface->LoadArrayType(data->data.elementType, typar, data->data.ArrayTypeData.arrayRank);
12225 case ELEMENT_TYPE_PTR:
12226 case ELEMENT_TYPE_BYREF:
12227 th = g_pEEInterface->LoadPointerOrByrefType(data->data.elementType, typar);
12235 case ELEMENT_TYPE_CLASS:
12236 case ELEMENT_TYPE_VALUETYPE:
12238 DebuggerModule *pDebuggerModule = g_pDebugger->LookupOrCreateModule(data->data.ClassTypeData.vmDomainFile);
12239 th = ReadInstantiation(pDebuggerModule->GetRuntimeModule(), data->data.ClassTypeData.metadataToken, data->numTypeArgs);
12243 case ELEMENT_TYPE_FNPTR:
12245 SIZE_T cbAllocSize;
12246 if ((!ClrSafeInt<SIZE_T>::multiply(data->numTypeArgs, sizeof(TypeHandle), cbAllocSize)) ||
12247 (cbAllocSize != (size_t)(cbAllocSize)))
12249 _ASSERTE(COR_E_OVERFLOW);
12250 cbAllocSize = UINT_MAX;
12252 TypeHandle * inst = (TypeHandle *) _alloca(cbAllocSize);
12253 ReadTypeHandles(data->numTypeArgs, inst) ;
12254 th = g_pEEInterface->LoadFnptrType(inst, data->numTypeArgs);
12259 th = g_pEEInterface->LoadElementType(data->data.elementType);
12263 COMPlusThrow(kArgumentNullException, W("ArgumentNull_Type"));
12269 // GetAndSendTransitionStubInfo figures out if an address is a stub
12270 // address and sends the result back to the right side.
12272 void Debugger::GetAndSendTransitionStubInfo(CORDB_ADDRESS_TYPE *stubAddress)
12281 LOG((LF_CORDB, LL_INFO10000, "D::GASTSI: IsTransitionStub. Addr=0x%08x\n", stubAddress));
12283 bool result = false;
12285 result = g_pEEInterface->IsStub((const BYTE *)stubAddress);
12288 // If its not a stub, then maybe its an address in mscoree?
12289 if (result == false)
12291 result = (IsIPInModule(g_pMSCorEE, (PCODE)stubAddress) == TRUE);
12294 // This is a synchronous event (reply required)
12295 DebuggerIPCEvent *event = m_pRCThread->GetIPCEventReceiveBuffer();
12296 InitIPCEvent(event, DB_IPCE_IS_TRANSITION_STUB_RESULT, NULL, NULL);
12297 event->IsTransitionStubResult.isStub = result;
12300 m_pRCThread->SendIPCReply();
12304 * A generic request for a buffer in the left-side for use by the right-side
12306 * This is a synchronous event (reply required).
12308 HRESULT Debugger::GetAndSendBuffer(DebuggerRCThread* rcThread, ULONG bufSize)
12317 // This is a synchronous event (reply required)
12318 DebuggerIPCEvent* event = rcThread->GetIPCEventReceiveBuffer();
12319 PREFIX_ASSUME(event != NULL);
12320 InitIPCEvent(event, DB_IPCE_GET_BUFFER_RESULT, NULL, NULL);
12322 // Allocate the buffer
12323 event->GetBufferResult.hr = AllocateRemoteBuffer( bufSize, &event->GetBufferResult.pBuffer );
12326 return rcThread->SendIPCReply();
12330 * Allocate a buffer in the left-side for use by the right-side
12332 HRESULT Debugger::AllocateRemoteBuffer( ULONG bufSize, void **ppBuffer )
12341 // The call to Append below will call CUnorderedArray, which will call unsafe New.
12343 CHECK_IF_CAN_TAKE_HELPER_LOCKS_IN_THIS_SCOPE(&hr, GetCanary());
12349 // Actually allocate the buffer
12350 BYTE* pBuffer = new (interopsafe, nothrow) BYTE[bufSize];
12352 LOG((LF_CORDB, LL_EVERYTHING, "D::ARB: new'd 0x%x\n", *ppBuffer));
12354 // Check for out of memory error
12355 if (pBuffer == NULL)
12357 return E_OUTOFMEMORY;
12360 // Track the allocation so we can free it later
12361 void **ppNextBlob = GetMemBlobs()->Append();
12362 if( ppNextBlob == NULL )
12364 DeleteInteropSafe( pBuffer );
12365 return E_OUTOFMEMORY;
12367 *ppNextBlob = pBuffer;
12369 // Return the allocated memory
12370 *ppBuffer = pBuffer;
12375 * Used to release a previously-requested buffer
12377 * This is a synchronous event (reply required).
12379 HRESULT Debugger::SendReleaseBuffer(DebuggerRCThread* rcThread, void *pBuffer)
12388 LOG((LF_CORDB,LL_INFO10000, "D::SRB for buffer 0x%x\n", pBuffer));
12390 // This is a synchronous event (reply required)
12391 DebuggerIPCEvent* event = rcThread->GetIPCEventReceiveBuffer();
12392 PREFIX_ASSUME(event != NULL);
12393 InitIPCEvent(event, DB_IPCE_RELEASE_BUFFER_RESULT, NULL, NULL);
12395 _ASSERTE(pBuffer != NULL);
12398 ReleaseRemoteBuffer(pBuffer, true);
12400 // Indicate success in reply
12401 event->ReleaseBufferResult.hr = S_OK;
12404 return rcThread->SendIPCReply();
12409 // Used to delete the buffer previously-requested by the right side.
12410 // We've factored the code since both the ~Debugger and SendReleaseBuffer
12411 // methods do this.
12413 HRESULT Debugger::ReleaseRemoteBuffer(void *pBuffer, bool removeFromBlobList)
12422 LOG((LF_CORDB, LL_EVERYTHING, "D::RRB: Releasing RS-alloc'd buffer 0x%x\n", pBuffer));
12424 // Remove the buffer from the blob list if necessary.
12425 if (removeFromBlobList)
12427 USHORT cBlobs = GetMemBlobs()->Count();
12428 void **rgpBlobs = GetMemBlobs()->Table();
12431 for (i = 0; i < cBlobs; i++)
12433 if (rgpBlobs[i] == pBuffer)
12435 GetMemBlobs()->DeleteByIndex(i);
12440 // We should have found a match. All buffers passed to ReleaseRemoteBuffer
12441 // should have been allocated with AllocateRemoteBuffer and not yet freed.
12442 _ASSERTE( i < cBlobs );
12445 // Delete the buffer. (Need cast for GCC template support)
12446 DeleteInteropSafe( (BYTE*)pBuffer );
12452 // UnrecoverableError causes the Left Side to enter a state where no more
12453 // debugging can occur and we leave around enough information for the
12454 // Right Side to tell what happened.
12456 void Debugger::UnrecoverableError(HRESULT errorHR,
12457 unsigned int errorCode,
12458 const char *errorFile,
12459 unsigned int errorLine,
12469 LOG((LF_CORDB, LL_INFO10,
12470 "Unrecoverable error: hr=0x%08x, code=%d, file=%s, line=%d\n",
12471 errorHR, errorCode, errorFile, errorLine));
12474 // Setting this will ensure that not much else happens...
12476 m_unrecoverableError = TRUE;
12479 // Fill out the control block with the error.
12480 // in-proc will find out when the function fails
12482 DebuggerIPCControlBlock *pDCB = m_pRCThread->GetDCB();
12484 PREFIX_ASSUME(pDCB != NULL);
12486 pDCB->m_errorHR = errorHR;
12487 pDCB->m_errorCode = errorCode;
12490 // If we're told to, exit the thread.
12494 LOG((LF_CORDB, LL_INFO10,
12495 "Thread exiting due to unrecoverable error.\n"));
12496 ExitThread(errorHR);
12501 // Callback for IsThreadAtSafePlace's stack walk.
12503 StackWalkAction Debugger::AtSafePlaceStackWalkCallback(CrawlFrame *pCF,
12511 PRECONDITION(CheckPointer(pCF));
12512 PRECONDITION(CheckPointer(data));
12516 bool *atSafePlace = (bool*)data;
12517 LOG((LF_CORDB, LL_INFO100000, "D:AtSafePlaceStackWalkCallback\n"));
12519 if (pCF->IsFrameless() && pCF->IsActiveFunc())
12521 LOG((LF_CORDB, LL_INFO1000000, "D:AtSafePlaceStackWalkCallback, IsFrameLess() and IsActiveFunc()\n"));
12522 if (g_pEEInterface->CrawlFrameIsGcSafe(pCF))
12524 LOG((LF_CORDB, LL_INFO1000000, "D:AtSafePlaceStackWalkCallback - TRUE: CrawlFrameIsGcSafe()\n"));
12525 *atSafePlace = true;
12532 // Determine, via a quick one frame stack walk, if a given thread is
12533 // in a gc safe place.
12535 bool Debugger::IsThreadAtSafePlaceWorker(Thread *thread)
12542 PRECONDITION(CheckPointer(thread));
12546 bool atSafePlace = false;
12548 // Setup our register display.
12550 CONTEXT *context = g_pEEInterface->GetThreadFilterContext(thread);
12552 _ASSERTE(!(g_pEEInterface->GetThreadFilterContext(thread) && ISREDIRECTEDTHREAD(thread)));
12553 if (context != NULL)
12555 g_pEEInterface->InitRegDisplay(thread, &rd, context, TRUE);
12560 ZeroMemory(&rd, sizeof(rd));
12561 ZeroMemory(&ctx, sizeof(ctx));
12562 #if defined(_TARGET_X86_) && !defined(WIN64EXCEPTIONS)
12563 rd.ControlPC = ctx.Eip;
12564 rd.PCTAddr = (TADDR)&(ctx.Eip);
12566 FillRegDisplay(&rd, &ctx);
12569 if (ISREDIRECTEDTHREAD(thread))
12571 thread->GetFrame()->UpdateRegDisplay(&rd);
12575 // Do the walk. If it fails, we don't care, because we default
12576 // atSafePlace to false.
12577 g_pEEInterface->StackWalkFramesEx(
12580 Debugger::AtSafePlaceStackWalkCallback,
12581 (VOID*)(&atSafePlace),
12582 QUICKUNWIND | HANDLESKIPPEDFRAMES |
12583 DISABLE_MISSING_FRAME_DETECTION | SKIP_GSCOOKIE_CHECK);
12587 LOG((LF_CORDB | LF_GC, LL_INFO1000,
12588 "Thread 0x%x is not at a safe place.\n",
12589 GetThreadIdHelper(thread)));
12592 return atSafePlace;
12595 bool Debugger::IsThreadAtSafePlace(Thread *thread)
12602 PRECONDITION(CheckPointer(thread));
12607 if (m_fShutdownMode)
12614 // Make sure this fix is evaluated when doing real work for debugging SO handling.
12616 // On the Stack Overflow code path calling IsThreadAtSafePlaceWorker as it is
12617 // currently implemented is way too stack intensive. For now we cheat and just
12618 // say that if a thread is in the middle of handling a SO it is NOT at a safe
12619 // place. This is a reasonably safe assumption to make and hopefully shouldn't
12620 // result in deadlocking the debugger.
12621 if ( (thread->IsExceptionInProgress()) &&
12622 (g_pEEInterface->GetThreadException(thread) == CLRException::GetPreallocatedStackOverflowExceptionHandle()) )
12629 return IsThreadAtSafePlaceWorker(thread);
12633 //-----------------------------------------------------------------------------
12634 // Get the complete user state flags.
12635 // This will collect flags both from the EE and from the LS.
12636 // This is the real implementation of the RS's ICorDebugThread::GetUserState().
12639 // pThread - non-null thread to get state for.
12641 // Returns: a CorDebugUserState flags enum describing state.
12642 //-----------------------------------------------------------------------------
12643 CorDebugUserState Debugger::GetFullUserState(Thread *pThread)
12649 PRECONDITION(CheckPointer(pThread));
12653 CorDebugUserState state = g_pEEInterface->GetPartialUserState(pThread);
12655 bool fSafe = IsThreadAtSafePlace(pThread);
12658 state = (CorDebugUserState) (state | USER_UNSAFE_POINT);
12664 /******************************************************************************
12666 * Helper for debugger to get an unique thread id
12668 ******************************************************************************/
12669 DWORD Debugger::GetThreadIdHelper(Thread *pThread)
12671 WRAPPER_NO_CONTRACT;
12673 return pThread->GetOSThreadId();
12676 //-----------------------------------------------------------------------------
12677 // Called by EnC during remapping to get information about the local vars.
12678 // EnC will then use this to set values in the new version to their corresponding
12679 // values from the old version.
12681 // Returns a pointer to the debugger's copies of the maps. Caller
12682 // does not own the memory provided via vars outparameter.
12683 //-----------------------------------------------------------------------------
12684 void Debugger::GetVarInfo(MethodDesc * fd, // [IN] method of interest
12685 void *DebuggerVersionToken, // [IN] which edit version
12686 SIZE_T * cVars, // [OUT] size of 'vars'
12687 const ICorDebugInfo::NativeVarInfo **vars // [OUT] map telling where local vars are stored
12693 GC_TRIGGERS_FROM_GETJITINFO;
12697 DebuggerJitInfo * ji = (DebuggerJitInfo *)DebuggerVersionToken;
12699 // If we didn't supply a DJI, then we're asking for the most recent version.
12702 ji = GetLatestJitInfoFromMethodDesc(fd);
12704 _ASSERTE(fd == ji->m_fd);
12706 PREFIX_ASSUME(ji != NULL);
12708 *vars = ji->GetVarNativeInfo();
12709 *cVars = ji->GetVarNativeInfoCount();
12712 #include "openum.h"
12714 #ifdef EnC_SUPPORTED
12716 //---------------------------------------------------------------------------------------
12718 // Apply an EnC edit to the CLR datastructures and send the result event to the
12719 // debugger right-side.
12722 // pDebuggerModule - the module in which the edit should occur
12723 // cbMetadata - the number of bytes in pMetadata
12724 // pMetadata - pointer to the delta metadata
12725 // cbIL - the number of bytes in pIL
12726 // pIL - pointer to the delta IL
12734 // This is just the first half of processing an EnC request (hot swapping). This updates
12735 // the metadata and other CLR data structures to reflect the edit, but does not directly
12736 // affect code which is currently running. In order to achieve on-stack replacement
12737 // (remap of running code), we mine all old methods with "EnC remap breakpoints"
12738 // (instances of DebuggerEnCBreakpoint) at many sequence points. When one of those
12739 // breakpoints is hit, we give the debugger a RemapOpportunity event and give it a
12740 // chance to remap the execution to the new version of the method.
12743 HRESULT Debugger::ApplyChangesAndSendResult(DebuggerModule * pDebuggerModule,
12756 // @todo - if EnC never works w/ interop, caller New on the helper thread may be ok.
12757 SUPPRESS_ALLOCATION_ASSERTS_IN_THIS_SCOPE;
12761 LOG((LF_ENC, LL_INFO100, "Debugger::ApplyChangesAndSendResult\n"));
12763 Module *pModule = pDebuggerModule->GetRuntimeModule();
12764 if (! pModule->IsEditAndContinueEnabled())
12766 hr = CORDBG_E_ENC_MODULE_NOT_ENC_ENABLED;
12770 // Violation with the following call stack:
12771 // CONTRACT in MethodTableBuilder::InitMethodDesc
12772 // CONTRACT in EEClass::AddMethod
12773 // CONTRACT in EditAndContinueModule::AddMethod
12774 // CONTRACT in EditAndContinueModule::ApplyEditAndContinue
12775 // CONTRACT in EEDbgInterfaceImpl::EnCApplyChanges
12776 // VIOLATED--> CONTRACT in Debugger::ApplyChangesAndSendResult
12777 CONTRACT_VIOLATION(GCViolation);
12779 // Tell the VM to apply the edit
12780 hr = g_pEEInterface->EnCApplyChanges(
12781 (EditAndContinueModule*)pModule, cbMetadata, pMetadata, cbIL, pIL);
12784 LOG((LF_ENC, LL_INFO100, "Debugger::ApplyChangesAndSendResult 2\n"));
12786 DebuggerIPCEvent* event = m_pRCThread->GetIPCEventSendBuffer();
12787 InitIPCEvent(event,
12788 DB_IPCE_APPLY_CHANGES_RESULT,
12792 event->ApplyChangesResult.hr = hr;
12795 return m_pRCThread->SendIPCEvent();
12799 // This structure is used to hold a list of the sequence points in a function and
12800 // determine which should have remap breakpoints applied to them for EnC
12802 class EnCSequencePointHelper
12805 // Calculates remap info given the supplied JitInfo
12806 EnCSequencePointHelper(DebuggerJitInfo *pJitInfo);
12807 ~EnCSequencePointHelper();
12809 // Returns true if the specified sequence point (given by it's index in the
12810 // sequence point table in the JitInfo) should get an EnC remap breakpoint.
12811 BOOL ShouldSetRemapBreakpoint(unsigned int offsetIndex);
12814 DebuggerJitInfo *m_pJitInfo;
12816 DebugOffsetToHandlerInfo *m_pOffsetToHandlerInfo;
12820 // Goes through the list of sequence points for a function and determines whether or not each
12821 // is a valid Remap Breakpoint location (not in a special offset, must be empty stack, and not in a handler.
12823 EnCSequencePointHelper::EnCSequencePointHelper(DebuggerJitInfo *pJitInfo)
12824 : m_pOffsetToHandlerInfo(NULL),
12825 m_pJitInfo(pJitInfo)
12834 if (m_pJitInfo->GetSequenceMapCount() == 0)
12839 // Construct a list of native offsets we may want to place EnC breakpoints at
12840 m_pOffsetToHandlerInfo = new DebugOffsetToHandlerInfo[m_pJitInfo->GetSequenceMapCount()];
12841 for (unsigned int i = 0; i < m_pJitInfo->GetSequenceMapCount(); i++)
12843 // By default this slot is unused. We want the indexes in m_pOffsetToHandlerInfo
12844 // to correspond to the indexes of m_pJitInfo->GetSequenceMapCount, so we rely
12845 // on a -1 offset to indicate that a DebuggerOffsetToHandlerInfo is unused.
12846 // However, it would be cleaner and permit a simpler API to the EE if we just
12847 // had an array mapping the offsets instead.
12848 m_pOffsetToHandlerInfo[i].offset = (SIZE_T) -1;
12849 m_pOffsetToHandlerInfo[i].isInFilterOrHandler = FALSE;
12851 SIZE_T offset = m_pJitInfo->GetSequenceMap()[i].nativeStartOffset;
12853 // Check if this is a "special" IL offset, such as representing the prolog or eppilog,
12854 // or other region not directly mapped to native code.
12855 if (DbgIsSpecialILOffset(pJitInfo->GetSequenceMap()[i].ilOffset))
12857 LOG((LF_ENC, LL_INFO10000,
12858 "D::UF: not placing E&C breakpoint at special offset 0x%x (IL: 0x%x)\n",
12859 offset, m_pJitInfo->GetSequenceMap()[i].ilOffset));
12863 // Skip duplicate sequence points
12864 if (i >=1 && offset == pJitInfo->GetSequenceMap()[i-1].nativeStartOffset)
12866 LOG((LF_ENC, LL_INFO10000,
12867 "D::UF: not placing redundant E&C "
12868 "breakpoint at duplicate offset 0x%x (IL: 0x%x)\n",
12869 offset, m_pJitInfo->GetSequenceMap()[i].ilOffset));
12873 // Skip sequence points that aren't due to the evaluation stack being empty
12874 // We can only remap at stack-empty points (since we don't have a mapping for
12875 // contents of the evaluation stack).
12876 if (!(pJitInfo->GetSequenceMap()[i].source & ICorDebugInfo::STACK_EMPTY))
12878 LOG((LF_ENC, LL_INFO10000,
12879 "D::UF: not placing E&C breakpoint at offset "
12880 "0x%x (IL: 0x%x) b/c not STACK_EMPTY:it's 0x%x\n", offset,
12881 m_pJitInfo->GetSequenceMap()[i].ilOffset, pJitInfo->GetSequenceMap()[i].source));
12885 // So far this sequence point looks good, so store it's native offset so we can get
12886 // EH information about it from the EE.
12887 LOG((LF_ENC, LL_INFO10000,
12888 "D::UF: possibly placing E&C breakpoint at offset "
12889 "0x%x (IL: 0x%x)\n", offset, m_pJitInfo->GetSequenceMap()[i].ilOffset));
12890 m_pOffsetToHandlerInfo[i].offset = m_pJitInfo->GetSequenceMap()[i].nativeStartOffset;
12894 // Ask the EE to fill in the isInFilterOrHandler bit for the native offsets we're interested in
12895 g_pEEInterface->DetermineIfOffsetsInFilterOrHandler(
12896 (BYTE *)pJitInfo->m_addrOfCode, m_pOffsetToHandlerInfo, m_pJitInfo->GetSequenceMapCount());
12899 EnCSequencePointHelper::~EnCSequencePointHelper()
12908 if (m_pOffsetToHandlerInfo)
12910 delete m_pOffsetToHandlerInfo;
12915 // Returns if we should set a remap breakpoint at a given offset. We only set them at 0-depth stack
12916 // and not when inside a handler, either finally, filter, or catch
12918 BOOL EnCSequencePointHelper::ShouldSetRemapBreakpoint(unsigned int offsetIndex)
12930 // GetSequenceMapCount calls LazyInitBounds() which can eventually
12931 // call ExecutionManager::IncrementReader
12932 CONTRACT_VIOLATION(TakesLockViolation);
12933 _ASSERTE(offsetIndex <= m_pJitInfo->GetSequenceMapCount());
12936 // If this slot is unused (offset -1), we excluded it early
12937 if (m_pOffsetToHandlerInfo[offsetIndex].offset == (SIZE_T) -1)
12942 // Otherwise, check the isInFilterOrHandler bit
12943 if (m_pOffsetToHandlerInfo[offsetIndex].isInFilterOrHandler)
12945 LOG((LF_ENC, LL_INFO10000,
12946 "D::UF: not placing E&C breakpoint in filter/handler at offset 0x%x\n",
12947 m_pOffsetToHandlerInfo[offsetIndex].offset));
12955 //-----------------------------------------------------------------------------
12956 // For each function that's EnC-ed, the EE will call either UpdateFunction
12957 // (if the function already is loaded + jitted) or AddFunction
12959 // This is called before the EE updates the MethodDesc, so pMD does not yet
12960 // point to the version we'll be remapping to.
12961 //-----------------------------------------------------------------------------
12962 HRESULT Debugger::UpdateFunction(MethodDesc* pMD, SIZE_T encVersion)
12967 GC_TRIGGERS_FROM_GETJITINFO;
12968 PRECONDITION(ThisIsHelperThread()); // guarantees we're serialized.
12969 PRECONDITION(IsStopped());
12973 LOG((LF_CORDB, LL_INFO10000, "D::UF: updating "
12974 "%s::%s to version %d\n", pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName, encVersion));
12976 // tell the RS that this function has been updated so that it can create new CorDBFunction
12977 Module *pModule = g_pEEInterface->MethodDescGetModule(pMD);
12978 _ASSERTE(pModule != NULL);
12979 mdToken methodDef = pMD->GetMemberDef();
12980 SendEnCUpdateEvent(DB_IPCE_ENC_UPDATE_FUNCTION,
12983 pMD->GetMethodTable()->GetCl(),
12986 DebuggerMethodInfo *dmi = GetOrCreateMethodInfo(pModule, methodDef);
12989 return E_OUTOFMEMORY;
12992 // The DMI always holds the most current EnC version number. We always JIT the most
12993 // current version of the function, so when we do see a JitBegin we will create a new
12994 // dji for it and stash the current version there. We don't want to change the current
12995 // jit info because it has to maintain the version for the code it corresponds to.
12996 dmi->SetCurrentEnCVersion(encVersion);
12998 // This is called before the MethodDesc is updated to point to the new function.
12999 // So this call will get the most recent old function.
13000 DebuggerJitInfo *pJitInfo = GetLatestJitInfoFromMethodDesc(pMD);
13002 if (pJitInfo == NULL )
13004 LOG((LF_CORDB,LL_INFO10000,"Unable to get DJI by recently "
13005 "D::UF: JITted version number (it hasn't been jitted yet),"
13006 "which is fine\n"));
13011 // Mine the old version of the method with patches so that we can provide
13012 // remap opportunities whenever the old version of the method is executed.
13015 if (pJitInfo->m_encBreakpointsApplied)
13017 LOG((LF_CORDB,LL_INFO10000,"D::UF: Breakpoints already applied\n"));
13021 LOG((LF_CORDB,LL_INFO10000,"D::UF: Applying breakpoints\n"));
13023 // We only place the patches if we have jit info for this
13024 // function, i.e., its already been jitted. Otherwise, the EE will
13025 // pickup the new method on the next JIT anyway.
13027 EnCSequencePointHelper sequencePointHelper(pJitInfo);
13029 // For each offset in the IL->Native map, set a new EnC breakpoint on the
13030 // ones that we know could be remap points.
13031 for (unsigned int i = 0; i < pJitInfo->GetSequenceMapCount(); i++)
13033 // Skip if this isn't a valid remap point (eg. is in an exception handler)
13034 if (! sequencePointHelper.ShouldSetRemapBreakpoint(i))
13039 SIZE_T offset = pJitInfo->GetSequenceMap()[i].nativeStartOffset;
13041 LOG((LF_CORDB, LL_INFO10000,
13042 "D::UF: placing E&C breakpoint at native offset 0x%x\n",
13045 DebuggerEnCBreakpoint *bp;
13047 // Create and activate a new EnC remap breakpoint here in the old version of the method
13048 bp = new (interopsafe) DebuggerEnCBreakpoint( offset,
13050 DebuggerEnCBreakpoint::REMAP_PENDING,
13051 (AppDomain *)pModule->GetDomain());
13053 _ASSERTE(bp != NULL);
13056 pJitInfo->m_encBreakpointsApplied = true;
13061 // Called to update a function that hasn't yet been loaded (and so we don't have a MethodDesc).
13062 // This may be updating an existing function on a type that hasn't been loaded
13063 // or adding a new function to a type that hasn't been loaded.
13064 // We need to notify the debugger so that it can properly track version info.
13065 HRESULT Debugger::UpdateNotYetLoadedFunction(mdMethodDef token, Module * pModule, SIZE_T encVersion)
13072 PRECONDITION(ThisIsHelperThread());
13073 PRECONDITION(ThreadHoldsLock()); // must have lock since we're on helper and stopped.
13077 DebuggerMethodInfo *dmi = GetOrCreateMethodInfo(pModule, token);
13080 return E_OUTOFMEMORY;
13082 dmi->SetCurrentEnCVersion(encVersion);
13085 // Must tell the RS that this function has been added so that it can create new CorDBFunction.
13086 mdTypeDef classToken = 0;
13088 HRESULT hr = pModule->GetMDImport()->GetParentToken(token, &classToken);
13091 // We never expect this to actually fail, but just in case it does for some other crazy reason,
13092 // we'll return before we AV.
13093 CONSISTENCY_CHECK_MSGF(false, ("Class lookup failed:mdToken:0x%08x, pModule=%p. hr=0x%08x\n", token, pModule, hr));
13097 SendEnCUpdateEvent(DB_IPCE_ENC_ADD_FUNCTION, pModule, token, classToken, encVersion);
13103 // Called to add a new function when the type has been loaded already.
13104 // This is effectively the same as above, except that we're given a
13105 // MethodDesc instead of a module and token.
13106 // This should probably be merged into a single method since the caller
13107 // should always have a module and token available in both cases.
13108 HRESULT Debugger::AddFunction(MethodDesc* pMD, SIZE_T encVersion)
13115 PRECONDITION(ThisIsHelperThread());
13116 PRECONDITION(ThreadHoldsLock()); // must have lock since we're on helper and stopped.
13120 DebuggerDataLockHolder debuggerDataLockHolder(this);
13122 LOG((LF_CORDB, LL_INFO10000, "D::AF: adding "
13123 "%s::%s to version %d\n", pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName, encVersion));
13125 _ASSERTE(pMD != NULL);
13126 Module *pModule = g_pEEInterface->MethodDescGetModule(pMD);
13127 _ASSERTE(pModule != NULL);
13128 mdToken methodDef = pMD->GetMemberDef();
13130 // tell the RS that this function has been added so that it can create new CorDBFunction
13131 SendEnCUpdateEvent( DB_IPCE_ENC_ADD_FUNCTION,
13134 pMD->GetMethodTable()->GetCl(),
13137 DebuggerMethodInfo *dmi = CreateMethodInfo(pModule, methodDef);
13140 return E_OUTOFMEMORY;
13142 dmi->SetCurrentEnCVersion(encVersion);
13147 // Invoke when a field is added to a class using EnC
13148 HRESULT Debugger::AddField(FieldDesc* pFD, SIZE_T encVersion)
13157 LOG((LF_CORDB, LL_INFO10000, "D::AFld: adding "
13158 "%8.8d::%8.8d to version %d\n", pFD->GetApproxEnclosingMethodTable()->GetCl(), pFD->GetMemberDef(), encVersion));
13160 // tell the RS that this field has been added so that it can update it's structures
13161 SendEnCUpdateEvent( DB_IPCE_ENC_ADD_FIELD,
13163 pFD->GetMemberDef(),
13164 pFD->GetApproxEnclosingMethodTable()->GetCl(),
13171 // RemapComplete is called when we are just about to resume into
13172 // the function so that we can setup our breakpoint to trigger
13173 // a call to the RemapComplete callback once the function is actually
13174 // on the stack. We need to wait until the function is jitted before
13175 // we can add the trigger, which doesn't happen until we call
13176 // ResumeInUpdatedFunction in the VM
13178 // addr is address within the given function, which we use to determine
13179 // exact EnC version.
13181 HRESULT Debugger::RemapComplete(MethodDesc* pMD, TADDR addr, SIZE_T nativeOffset)
13186 GC_TRIGGERS_FROM_GETJITINFO;
13190 _ASSERTE(pMD != NULL);
13191 _ASSERTE(addr != NULL);
13193 LOG((LF_CORDB, LL_INFO10000, "D::RC: installed remap complete patch for "
13194 "%s::%s to version %d\n", pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName));
13196 DebuggerMethodInfo *dmi = GetOrCreateMethodInfo(pMD->GetModule(), pMD->GetMemberDef());
13200 return E_OUTOFMEMORY;
13203 DebuggerJitInfo *pJitInfo = GetJitInfo(pMD, (const BYTE *) addr);
13205 if (pJitInfo == NULL)
13207 _ASSERTE(!"Debugger doesn't handle OOM");
13208 return E_OUTOFMEMORY;
13210 _ASSERTE(pJitInfo->m_addrOfCode + nativeOffset == addr);
13212 DebuggerEnCBreakpoint *bp;
13214 // Create and activate a new REMAP_COMPLETE EnC breakpoint to let us know when
13215 // the EE has completed the remap process.
13216 // This will be deleted when the patch is hit.
13217 bp = new (interopsafe, nothrow) DebuggerEnCBreakpoint( nativeOffset,
13219 DebuggerEnCBreakpoint::REMAP_COMPLETE,
13220 (AppDomain *)pMD->GetModule()->GetDomain());
13223 return E_OUTOFMEMORY;
13229 //-----------------------------------------------------------------------------
13230 // Called by EnC stuff to map an IL offset to a native offset for the given
13231 // method described by (pMD, nativeFnxStart).
13233 // pMD - methoddesc for method being remapped
13234 // ilOffset - incoming offset in old method to remap.
13235 // nativeFnxStart - address of new function. This can be used to find the DJI
13236 // for the new method.
13237 // nativeOffset - outparameter for native linear offset relative to start address.
13238 //-----------------------------------------------------------------------------
13240 HRESULT Debugger::MapILInfoToCurrentNative(MethodDesc *pMD,
13242 TADDR nativeFnxStart,
13243 SIZE_T *nativeOffset)
13248 GC_TRIGGERS_FROM_GETJITINFO;
13249 PRECONDITION(nativeOffset != NULL);
13250 PRECONDITION(CheckPointer(pMD));
13251 PRECONDITION(nativeFnxStart != NULL);
13255 _ASSERTE(HasLazyData()); // only used for EnC, should have already inited.
13258 LOG((LF_CORDB, LL_INFO1000000, "D::MILITCN: %s::%s ilOff:0x%x, "
13259 ", natFnx:0x%x dji:0x%x\n", pMD->m_pszDebugClassName,
13260 pMD->m_pszDebugMethodName, ilOffset, nativeFnxStart));
13263 DebuggerJitInfo *djiTo = GetJitInfo( pMD, (const BYTE *)nativeFnxStart);
13266 _ASSERTE(!"No DJI in EnC case: should only happen on oom. Debugger doesn't support OOM.");
13270 DebuggerJitInfo::ILToNativeOffsetIterator it;
13271 djiTo->InitILToNativeOffsetIterator(it, ilOffset);
13272 *nativeOffset = it.CurrentAssertOnlyOne(NULL);
13276 #endif // EnC_SUPPORTED
13278 //---------------------------------------------------------------------------------------
13279 // Hijack worker stub called from asm stub. This can then delegate to other hijacks.
13282 // pContext - context from which we were hijacked. Always non-null.
13283 // pRecord - exception record if hijacked from an exception event.
13284 // Else null (if hijacked from a managed IP).
13285 // reason - hijack reason. Use this to delegate to the proper hijack stub.
13286 // pData - arbitrary data for the hijack to use. (eg, such as a DebuggerEval object)
13289 // This does not return. Instead it restores this threads context to pContext.
13292 // If hijacked at an exception event, the debugger must have cleared the exception.
13295 // The debugger hijacked the thread to get us here via the DacDbi Hijack primitive.
13296 // This is called from a hand coded asm stub.
13298 void STDCALL ExceptionHijackWorker(
13299 CONTEXT * pContext,
13300 EXCEPTION_RECORD * pRecord,
13301 EHijackReason::EHijackReason reason,
13304 STRESS_LOG0(LF_CORDB,LL_INFO100, "D::EHW: Enter ExceptionHijackWorker\n");
13306 // We could have many different reasons for hijacking. Switch and invoke the proper hijacker.
13309 case EHijackReason::kUnhandledException:
13310 STRESS_LOG0(LF_CORDB,LL_INFO10, "D::EHW: Calling g_pDebugger->UnhandledHijackWorker()\n");
13311 _ASSERTE(pData == NULL);
13312 g_pDebugger->UnhandledHijackWorker(pContext, pRecord);
13314 #ifdef FEATURE_INTEROP_DEBUGGING
13315 case EHijackReason::kM2UHandoff:
13316 _ASSERTE(pData == NULL);
13317 g_pDebugger->M2UHandoffHijackWorker(pContext, pRecord);
13319 case EHijackReason::kFirstChanceSuspend:
13320 _ASSERTE(pData == NULL);
13321 g_pDebugger->FirstChanceSuspendHijackWorker(pContext, pRecord);
13323 case EHijackReason::kGenericHijack:
13324 _ASSERTE(pData == NULL);
13325 g_pDebugger->GenericHijackFunc();
13329 CONSISTENCY_CHECK_MSGF(false, ("Unrecognized Hijack code: %d", reason));
13332 // Currently, no Hijack actually returns yet.
13335 // If we return to this point, then we'll restore ourselves.
13336 // We've got the context that we were hijacked from, so we should be able to just
13337 // call SetThreadContext on ourself to fix us.
13340 #if defined(WIN64EXCEPTIONS) && !defined(FEATURE_PAL)
13342 #if defined(_TARGET_AMD64_)
13343 // ----------------------------------------------------------------------------
13344 // EmptyPersonalityRoutine
13347 // This personality routine is used to work around a limitation of the OS unwinder when we return
13348 // ExceptionCollidedUnwind.
13349 // See code:ExceptionHijackPersonalityRoutine for more information.
13352 // * pExceptionRecord - not used
13353 // * MemoryStackFp - not used
13354 // * BackingStoreFp - not used
13355 // * pContextRecord - not used
13356 // * pDispatcherContext - not used
13357 // * GlobalPointer - not used
13360 // Always return ExceptionContinueSearch.
13363 EXCEPTION_DISPOSITION EmptyPersonalityRoutine(IN PEXCEPTION_RECORD pExceptionRecord,
13364 IN ULONG64 MemoryStackFp,
13365 IN OUT PCONTEXT pContextRecord,
13366 IN OUT PDISPATCHER_CONTEXT pDispatcherContext)
13368 LIMITED_METHOD_CONTRACT;
13369 return ExceptionContinueSearch;
13371 #endif // _TARGET_AMD64_
13373 //---------------------------------------------------------------------------------------
13374 // Personality routine for unwinder the assembly hijack stub on 64-bit.
13377 // standard Personality routine signature.
13380 // This is caleld by the OS exception logic during exception handling.
13383 // We just need 1 personality routine for the tiny assembly hijack stub.
13384 // All the C++ code invoked by the stub is ok.
13386 // This needs to fetch the original context that this thread was hijacked from
13387 // (which the hijack pushed onto the stack) and pass that back to the OS. This lets
13388 // ths OS unwind out of the hijack.
13390 // This function should only be executed if an unhandled exception is intercepted by a managed debugger.
13391 // Otherwise there should never be a 2nd pass exception dispatch crossing the hijack stub.
13393 // The basic idea here is straightforward. The OS does an exception dispatch and hit our hijack stub.
13394 // Since the hijack stub is not unwindable, we need a personality routine to restore the CONTEXT and
13395 // tell the OS to continue the dispatch with that CONTEXT by returning ExceptionCollidedUnwind.
13397 // However, empricially, the OS expects that when we return ExceptionCollidedUnwind, the function
13398 // represented by the CONTEXT has a personality routine. The OS will actually AV if we return a NULL
13399 // personality routine.
13401 // On AMD64, we work around this by using an empty personality routine.
13403 EXTERN_C EXCEPTION_DISPOSITION
13404 ExceptionHijackPersonalityRoutine(IN PEXCEPTION_RECORD pExceptionRecord
13405 WIN64_ARG(IN ULONG64 MemoryStackFp)
13406 NOT_WIN64_ARG(IN ULONG32 MemoryStackFp),
13407 IN OUT PCONTEXT pContextRecord,
13408 IN OUT PDISPATCHER_CONTEXT pDispatcherContext
13411 #if defined(_TARGET_AMD64_)
13412 CONTEXT * pHijackContext = NULL;
13414 // Get the 1st parameter (the Context) from hijack worker.
13415 // EstablisherFrame points to the stack slot 8 bytes above the
13416 // return address to the ExceptionHijack. This would contain the
13417 // parameters passed to ExceptionHijackWorker, which is marked
13418 // STDCALL, but the x64 calling convention lets the
13419 // ExceptionHijackWorker use that stack space, resulting in the
13420 // context being overwritten. Instead, we get the context from the
13421 // previous stack frame, which contains the arguments to
13422 // ExceptionHijack, placed there by the debugger in
13423 // DacDbiInterfaceImpl::Hijack. This works because ExceptionHijack
13424 // allocates exactly 4 stack slots.
13425 pHijackContext = *reinterpret_cast<CONTEXT **>(pDispatcherContext->EstablisherFrame + 0x20);
13427 // This copies pHijackContext into pDispatcherContext, which the OS can then
13428 // use to walk the stack.
13429 FixupDispatcherContext(pDispatcherContext, pHijackContext, pContextRecord, (PEXCEPTION_ROUTINE)EmptyPersonalityRoutine);
13431 _ASSERTE(!"NYI - ExceptionHijackPersonalityRoutine()");
13434 // Returning ExceptionCollidedUnwind will cause the OS to take our new context record and
13435 // dispatcher context and restart the exception dispatching on this call frame, which is
13436 // exactly the behavior we want.
13437 return ExceptionCollidedUnwind;
13439 #endif // WIN64EXCEPTIONS && !FEATURE_PAL
13442 // UEF Prototype from excep.cpp
13443 LONG InternalUnhandledExceptionFilter_Worker(EXCEPTION_POINTERS *pExceptionInfo);
13445 //---------------------------------------------------------------------------------------
13446 // Hijack for a 2nd-chance exception. Will invoke the CLR's UEF.
13449 // pContext - context that this thread was hijacked from.
13450 // pRecord - exception record of the exception that this was hijacked at.
13451 // pData - random data.
13453 // When under a native-debugger, the OS does not invoking the Unhandled Exception Filter (UEF).
13454 // It dispatches a 2nd-chance Exception event instead.
13455 // However, the CLR's UEF does lots of useful work (like dispatching the 2nd-chance managed exception,
13456 // allowing func-eval on 2nd-chance, and allowing intercepting unhandled exceptions).
13457 // So we'll emulate the OS behavior here by invoking the CLR's UEF directly.
13459 void Debugger::UnhandledHijackWorker(CONTEXT * pContext, EXCEPTION_RECORD * pRecord)
13463 // The ultimate protection shield is that this hijack can be executed under the same circumstances
13464 // as a top-level UEF that pinvokes into managed code
13465 // - That means we're GC-triggers safe
13466 // - that means that we can crawl the stack. (1st-pass EH logic ensures this).
13467 // We need to be GC-triggers because this may invoke a func-eval.
13470 // Don't throw out of a hijack! There's nobody left to catch this.
13473 // We expect to always be in preemptive here by the time we get this unhandled notification.
13474 // We know this is true because a native UEF is preemptive.
13476 // 1) If we got here from a software exception (eg, Throw from C#), then the jit helper
13477 // toggled us to preemptive before calling RaiseException().
13478 // 2) If we got here from a hardware exception in managed code, then the 1st-pass already did
13479 // some magic to get us into preemptive. On x86, this is magic. On 64-bit, it did some magic
13480 // to push a Faulting-Exception-Frame and rethrow the exception as a software exception.
13484 PRECONDITION(CheckPointer(pContext));
13485 PRECONDITION(CheckPointer(pRecord));
13489 EXCEPTION_POINTERS exceptionInfo;
13490 exceptionInfo.ContextRecord = pContext;
13491 exceptionInfo.ExceptionRecord = pRecord;
13493 // Snag the Runtime thread. Since we're hijacking a managed exception, we should always have one.
13494 Thread * pThread = g_pEEInterface->GetThread();
13495 (void)pThread; //prevent "unused variable" error from GCC
13496 _ASSERTE(pThread != NULL);
13498 BOOL fSOException = FALSE;
13500 if ((pRecord != NULL) &&
13501 (pRecord->ExceptionCode == STATUS_STACK_OVERFLOW))
13503 fSOException = TRUE;
13506 // because we hijack here during jit attach invoked by the OS we need to make sure that the debugger is completely
13507 // attached before continuing. If we ever hijacked here when an attach was not in progress this function returns
13508 // immediately so no problems there.
13509 WaitForDebuggerAttach();
13512 // On Win7 WatsonLastChance returns CONTINUE_SEARCH for unhandled exceptions execpt stack overflow, and
13513 // lets OS launch debuggers for us. Before the unhandled exception reaches the OS, CLR UEF has already
13514 // processed this unhandled exception. Thus, we should not call into CLR UEF again if it is the case.
13516 (pThread->HasThreadStateNC(Thread::TSNC_ProcessedUnhandledException) ||
13517 pThread->HasThreadStateNC(Thread::TSNC_AppDomainContainUnhandled) ||
13521 FrameWithCookie<FaultingExceptionFrame> fef;
13522 #if defined(WIN64EXCEPTIONS)
13523 *((&fef)->GetGSCookiePtr()) = GetProcessGSCookie();
13524 #endif // WIN64EXCEPTIONS
13525 if ((pContext != NULL) && fSOException)
13527 GCX_COOP(); // Must be cooperative to modify frame chain.
13529 // EEPolicy::HandleFatalStackOverflow pushes a FaultingExceptionFrame on the stack after SO
13530 // exception. Our hijack code runs in the exception context, and overwrites the stack space
13531 // after SO excpetion, so this frame was popped out before invoking RaiseFailFast. We need to
13532 // put it back here for running func-eval code.
13533 // This cumbersome code should be removed once SO synchronization is moved to be completely
13535 fef.InitAndLink(pContext);
13538 STRESS_LOG0(LF_CORDB, LL_INFO10, "D::EHW: Calling NotifyDebuggerLastChance\n");
13539 NotifyDebuggerLastChance(pThread, &exceptionInfo, TRUE);
13541 // Continuing from a second chance managed exception causes the process to exit.
13542 TerminateProcess(GetCurrentProcess(), 0);
13545 // Since this is a unhandled managed exception:
13546 // - we always have a Thread* object.
13547 // - we always have a throwable
13548 // - we executed through the 1st-pass of the EH logic. This means the 1st-pass could do work
13549 // to enforce certain invariants (like the ones listed here, or ensuring the thread can be crawled)
13551 // Need to call the CLR's UEF. This will do all the key work including:
13552 // - send the managed 2nd-chance exception event.
13553 // - deal with synchronization.
13554 // - allow func-evals.
13555 // - deal with interception.
13557 // If intercepted, then this never returns. It will manually invoke the unwinders and fix the context.
13559 // InternalUnhandledExceptionFilter_Worker has a throws contract, but should not be throwing in any
13560 // conditions we care about. This hijack should never throw, so catch everything.
13564 InternalUnhandledExceptionFilter_Worker(&exceptionInfo);
13566 EX_CATCH_HRESULT(hrIgnore);
13568 // Continuing from a second chance managed exception causes the process to exit.
13569 TerminateProcess(GetCurrentProcess(), 0);
13572 #ifdef FEATURE_INTEROP_DEBUGGING
13574 // This is the handler function that is put in place of a thread's top-most SEH handler function when it is hijacked by
13575 // the Right Side during an unmanaged first chance exception.
13577 typedef EXCEPTION_DISPOSITION (__cdecl *SEHHandler)(EXCEPTION_RECORD *pExceptionRecord,
13578 EXCEPTION_REGISTRATION_RECORD *pEstablisherFrame,
13580 void *DispatcherContext);
13592 //-----------------------------------------------------------------------------
13593 // Hijack when we have a M2U handoff.
13594 // This happens when we do a step-out from Managed-->Unmanaged, and so we hit a managed patch in Native code.
13595 // This also happens when a managed stepper does a step-in to unmanaged code.
13596 // Since we're in native code, there's no CPFH, and so we have to hijack.
13597 // @todo- could this be removed? Step-out to native is illegal in v2.0, and do existing
13598 // CLR filters catch the step-in patch?
13599 // @dbgtodo controller/stepping - this will be completely unneeded in V3 when all stepping is oop
13600 //-----------------------------------------------------------------------------
13601 VOID Debugger::M2UHandoffHijackWorker(CONTEXT *pContext,
13602 EXCEPTION_RECORD *pExceptionRecord)
13604 // We must use a static contract here because the function does not return normally
13605 STATIC_CONTRACT_NOTHROW;
13606 STATIC_CONTRACT_GC_TRIGGERS; // from sending managed event
13607 STATIC_CONTRACT_MODE_PREEMPTIVE; // we're in umanaged code.
13608 SO_NOT_MAINLINE_FUNCTION;
13611 LOG((LF_CORDB, LL_INFO1000, "D::M2UHHW: Context=0x%p exception record=0x%p\n",
13612 pContext, pExceptionRecord));
13614 // We should only be here for a BP
13615 _ASSERTE(pExceptionRecord->ExceptionCode == STATUS_BREAKPOINT);
13617 // Get the current runtime thread. This is only an optimized TLS access.
13618 // Since we're coming off a managed-step, we should always have a thread.
13619 Thread *pEEThread = g_pEEInterface->GetThread();
13620 _ASSERTE(pEEThread != NULL);
13622 _ASSERTE(!pEEThread->GetInteropDebuggingHijacked());
13623 pEEThread->SetInteropDebuggingHijacked(TRUE);
13625 //win32 has a weird property where EIP points after the BP in the debug event
13626 //so we are adjusting it to point at the BP
13627 CORDbgAdjustPCForBreakInstruction((DT_CONTEXT*)pContext);
13628 LOG((LF_CORDB, LL_INFO1000, "D::M2UHHW: Context ip set to 0x%p\n", GetIP(pContext)));
13630 _ASSERTE(!ISREDIRECTEDTHREAD(pEEThread));
13632 // Don't bother setting FilterContext here because we already pass it to FirstChanceNativeException.
13633 // Shortcut right to our dispatch native exception logic, there may be no COMPlusFrameHandler in place!
13636 LOG((LF_CORDB, LL_INFO1000, "D::M2UHHW: Calling FirstChanceNativeException\n"));
13638 okay = g_pDebugger->FirstChanceNativeException(pExceptionRecord,
13640 pExceptionRecord->ExceptionCode,
13642 _ASSERTE(okay == true);
13643 LOG((LF_CORDB, LL_INFO1000, "D::M2UHHW: FirstChanceNativeException returned\n"));
13647 // It would be really bad if somebody threw here. We're actually outside of managed code,
13648 // so there's not a lot we can do besides just swallow the exception and hope for the best.
13649 LOG((LF_CORDB, LL_INFO1000, "D::M2UHHW: ERROR! FirstChanceNativeException threw an exception\n"));
13651 EX_END_CATCH(SwallowAllExceptions);
13653 _ASSERTE(!ISREDIRECTEDTHREAD(pEEThread));
13654 _ASSERTE(pEEThread->GetInteropDebuggingHijacked());
13655 pEEThread->SetInteropDebuggingHijacked(FALSE);
13657 // This signal will be received by the RS and it will use SetThreadContext
13658 // to clear away the entire hijack frame. This function does not return.
13659 LOG((LF_CORDB, LL_INFO1000, "D::M2UHHW: Flaring hijack complete\n"));
13660 SignalHijackComplete();
13662 _ASSERTE(!"UNREACHABLE");
13665 //-----------------------------------------------------------------------------
13666 // This hijack is run after receiving an IB event that we don't know how the
13667 // debugger will want to continue. Under the covers we clear the event and divert
13668 // execution here where we block until the debugger decides whether or not to clear
13669 // the event. At that point we exit this hijack and the LS diverts execution back
13670 // to the offending instruction.
13672 // - whether we have an EE-thread?
13673 // - how we're going to continue this (handled / not-handled).
13675 // But we do know that:
13676 // - this exception does not belong to the CLR.
13677 // - this thread is not in cooperative mode.
13678 //-----------------------------------------------------------------------------
13679 LONG Debugger::FirstChanceSuspendHijackWorker(CONTEXT *pContext,
13680 EXCEPTION_RECORD *pExceptionRecord)
13682 // if we aren't set up to do interop debugging this function should just bail out
13683 if(m_pRCThread == NULL)
13684 return EXCEPTION_CONTINUE_SEARCH;
13686 DebuggerIPCControlBlock *pDCB = m_pRCThread->GetDCB();
13688 return EXCEPTION_CONTINUE_SEARCH;
13690 if (!pDCB->m_rightSideIsWin32Debugger)
13691 return EXCEPTION_CONTINUE_SEARCH;
13693 // at this point we know that there is an interop debugger attached. This makes it safe to send
13696 DWORD tid = GetCurrentThreadId();
13699 SPEW(fprintf(stderr, "0x%x D::FCHF: in first chance hijack filter.\n", tid));
13700 SPEW(fprintf(stderr, "0x%x D::FCHF: pExceptionRecord=0x%p (%d), pContext=0x%p (%d)\n", tid, pExceptionRecord, sizeof(EXCEPTION_RECORD),
13701 pContext, sizeof(CONTEXT)));
13702 #if defined(_TARGET_AMD64_)
13703 SPEW(fprintf(stderr, "0x%x D::FCHF: code=0x%08x, addr=0x%p, Rip=0x%p, Rsp=0x%p, EFlags=0x%08x\n",
13704 tid, pExceptionRecord->ExceptionCode, pExceptionRecord->ExceptionAddress, pContext->Rip, pContext->Rsp,
13705 pContext->EFlags));
13706 #elif defined(_TARGET_X86_)
13707 SPEW(fprintf(stderr, "0x%x D::FCHF: code=0x%08x, addr=0x%08x, Eip=0x%08x, Esp=0x%08x, EFlags=0x%08x\n",
13708 tid, pExceptionRecord->ExceptionCode, pExceptionRecord->ExceptionAddress, pContext->Eip, pContext->Esp,
13709 pContext->EFlags));
13710 #elif defined(_TARGET_ARM64_)
13711 SPEW(fprintf(stderr, "0x%x D::FCHF: code=0x%08x, addr=0x%08x, Pc=0x%p, Sp=0x%p, EFlags=0x%08x\n",
13712 tid, pExceptionRecord->ExceptionCode, pExceptionRecord->ExceptionAddress, pContext->Pc, pContext->Sp,
13713 pContext->EFlags));
13716 // This memory is used as IPC during the hijack. We will place a pointer to this in
13717 // the EE debugger word (a TLS slot that works even on the debugger break-in thread)
13718 // and then the RS can write info into the memory.
13719 DebuggerIPCFirstChanceData fcd;
13721 // Accessing through the volatile pointer to fend off some potential compiler optimizations.
13722 // If the debugger changes that data from OOP we need to see those updates
13723 volatile DebuggerIPCFirstChanceData* pFcd = &fcd;
13725 // The Windows native break in thread does not have TLS storage allocated.
13726 bool debuggerBreakInThread = (NtCurrentTeb()->ThreadLocalStoragePointer == NULL);
13728 // Hijack filters are always in the can't stop range.
13729 // The RS knows this b/c it knows which threads it hijacked.
13730 // Bump up the CS counter so that any further calls in the LS can see this too.
13731 // (This makes places where we assert that we're in a CS region happy).
13732 CantStopHolder hCantStop(!debuggerBreakInThread);
13734 // Get the current runtime thread. This is only an optimized TLS access.
13735 Thread *pEEThread = debuggerBreakInThread ? NULL : g_pEEInterface->GetThread();
13737 // Hook up the memory so RS can get to it
13738 fcd.pLeftSideContext.Set((DT_CONTEXT*)pContext);
13739 fcd.action = HIJACK_ACTION_EXIT_UNHANDLED;
13740 fcd.debugCounter = 0;
13742 SPEW(fprintf(stderr, "0x%x D::FCHF: Set debugger word to 0x%p.\n", tid, pFcd));
13743 g_pEEInterface->SetThreadDebuggerWord((VOID*)pFcd);
13745 // Signal the RS to tell us what to do
13746 SPEW(fprintf(stderr, "0x%x D::FCHF: Signaling hijack started.\n", tid));
13747 SignalHijackStarted();
13748 SPEW(fprintf(stderr, "0x%x D::FCHF: Signaling hijack started complete. DebugCounter=0x%x\n", tid, pFcd->debugCounter));
13750 if (pFcd->action == HIJACK_ACTION_WAIT)
13752 // This exception does NOT belong to the CLR.
13753 // If we belong to the CLR, then we either:
13754 // - were a M2U transition, in which case we should be in a different Hijack
13755 // - were a CLR exception in CLR code, in which case we should have continued and let the inproc handlers get it.
13756 SPEW(fprintf(stderr, "0x%x D::FCHF: exception does not belong to the Runtime, pEEThread=0x%p, pContext=0x%p\n",
13757 tid, pEEThread, pContext));
13759 if (pEEThread != NULL)
13761 _ASSERTE(!pEEThread->GetInteropDebuggingHijacked()); // hijack is not re-entrant.
13762 pEEThread->SetInteropDebuggingHijacked(TRUE);
13764 // Setting the FilterContext must be done in cooperative mode (since it's like pushing a Frame onto the Frame chain).
13765 // Thus we have a violation. We don't really need the filter context specifically here, we're just using
13766 // it for legacy purposes as a way to stash the context of the original exception (that this thread was hijacked from).
13767 // @todo - use another way to store the context indepedent of the Filter context.
13768 CONTRACT_VIOLATION(ModeViolation);
13769 _ASSERTE(g_pEEInterface->GetThreadFilterContext(pEEThread) == NULL);
13770 g_pEEInterface->SetThreadFilterContext(pEEThread, pContext);
13773 // Wait for the continue. We may / may not have an EE Thread for this, (and we're definitely
13774 // not doing fiber-mode debugging), so just use a raw win32 API, and not some fancy fiber-safe call.
13775 SPEW(fprintf(stderr, "0x%x D::FCHF: waiting for continue.\n", tid));
13776 DWORD ret = WaitForSingleObject(g_pDebugger->m_pRCThread->GetDCB()->m_leftSideUnmanagedWaitEvent, INFINITE);
13777 SPEW(fprintf(stderr, "0x%x D::FCHF: waiting for continue complete.\n", tid));
13779 if (ret != WAIT_OBJECT_0)
13781 SPEW(fprintf(stderr, "0x%x D::FCHF: wait failed!\n", tid));
13784 if (pEEThread != NULL)
13786 _ASSERTE(pEEThread->GetInteropDebuggingHijacked());
13787 pEEThread->SetInteropDebuggingHijacked(FALSE);
13788 _ASSERTE(!ISREDIRECTEDTHREAD(pEEThread));
13790 // See violation above.
13791 CONTRACT_VIOLATION(ModeViolation);
13792 g_pEEInterface->SetThreadFilterContext(pEEThread, NULL);
13793 _ASSERTE(g_pEEInterface->GetThreadFilterContext(pEEThread) == NULL);
13797 SPEW(fprintf(stderr, "0x%x D::FCHF: signaling HijackComplete.\n", tid));
13798 SignalHijackComplete();
13799 SPEW(fprintf(stderr, "0x%x D::FCHF: done signaling HijackComplete. DebugCounter=0x%x\n", tid, pFcd->debugCounter));
13801 // we should know what we are about to do now
13802 _ASSERTE(pFcd->action != HIJACK_ACTION_WAIT);
13804 // cleanup from above
13805 SPEW(fprintf(stderr, "0x%x D::FCHF: set debugger word = NULL.\n", tid));
13806 g_pEEInterface->SetThreadDebuggerWord(NULL);
13808 } // end can't stop region
13810 if (pFcd->action == HIJACK_ACTION_EXIT_HANDLED)
13812 SPEW(fprintf(stderr, "0x%x D::FCHF: exiting with CONTINUE_EXECUTION\n", tid));
13813 return EXCEPTION_CONTINUE_EXECUTION;
13817 SPEW(fprintf(stderr, "0x%x D::FCHF: exiting with CONTINUE_SEARCH\n", tid));
13818 _ASSERTE(pFcd->action == HIJACK_ACTION_EXIT_UNHANDLED);
13819 return EXCEPTION_CONTINUE_SEARCH;
13823 #if defined(_TARGET_X86_) || defined(_TARGET_AMD64_) || defined(_TARGET_ARM64_)
13824 void GenericHijackFuncHelper()
13827 DWORD tid = GetCurrentThreadId();
13830 // The Windows native break in thread does not have TLS storage allocated.
13831 bool debuggerBreakInThread = (NtCurrentTeb()->ThreadLocalStoragePointer == NULL);
13833 // Hijack filters are always in the can't stop range.
13834 // The RS knows this b/c it knows which threads it hijacked.
13835 // Bump up the CS counter so that any further calls in the LS can see this too.
13836 // (This makes places where we assert that we're in a CS region happy).
13837 CantStopHolder hCantStop(!debuggerBreakInThread);
13839 SPEW(fprintf(stderr, "0x%x D::GHF: in generic hijack.\n", tid));
13841 // There is no need to setup any context pointer or interact with the Right Side in anyway. We simply wait for
13842 // the continue event to be set.
13843 SPEW(fprintf(stderr, "0x%x D::GHF: waiting for continue.\n", tid));
13845 // If this thread has an EE thread and that EE thread has preemptive gc disabled, then mark that there is a
13846 // thread at an unsafe place and enable pgc. This will allow us to sync even with this thread hijacked.
13847 bool disabled = false;
13849 Thread *pEEThread = debuggerBreakInThread ? NULL : g_pEEInterface->GetThread();
13851 if (pEEThread != NULL)
13853 disabled = g_pEEInterface->IsPreemptiveGCDisabled();
13854 _ASSERTE(!disabled);
13856 _ASSERTE(!pEEThread->GetInteropDebuggingHijacked());
13857 pEEThread->SetInteropDebuggingHijacked(TRUE);
13860 DWORD ret = WaitForSingleObject(g_pRCThread->GetDCB()->m_leftSideUnmanagedWaitEvent,
13863 if (ret != WAIT_OBJECT_0)
13865 SPEW(fprintf(stderr, "0x%x D::GHF: wait failed!\n", tid));
13868 // Get the continue type. Non-zero means that the exception was not cleared by the Right Side and therefore has
13869 // not been handled. Zero means that the exception has been cleared. (Presumably, the debugger altered the
13870 // thread's context before clearing the exception, so continuing will give a different result.)
13871 DWORD continueType = 0;
13873 void* threadDebuggerWord = g_pEEInterface->GetThreadDebuggerWord();
13875 if (pEEThread != NULL)
13877 // We've got a Thread ptr, so get the continue type out of the thread's debugger word.
13878 continueType = (DWORD)threadDebuggerWord;
13880 _ASSERTE(pEEThread->GetInteropDebuggingHijacked());
13881 pEEThread->SetInteropDebuggingHijacked(FALSE);
13883 else if (threadDebuggerWord != NULL)
13886 g_pEEInterface->SetThreadDebuggerWord(NULL);
13889 SPEW(fprintf(stderr, "0x%x D::GHF: continued with %d.\n", tid, continueType));
13893 SPEW(fprintf(stderr, "0x%x D::GHF: calling ExitProcess\n", tid));
13895 // Continuing from a second chance exception without clearing the exception causes the process to
13896 // exit. Note: the continue type will only be non-zero if this hijack was setup for a second chance
13897 // exception. If the hijack was setup for another type of debug event, then we'll never get here.
13899 // We explicitly terminate the process directly instead of going through any escalation policy because:
13900 // 1) that's what a native-only debugger would do. Interop and Native-only should be the same.
13901 // 2) there's no CLR escalation policy anyways for *native* unhandled exceptions.
13902 // 3) The escalation policy may do lots of extra confusing work (like fire MDAs) that can only cause
13904 TerminateProcess(GetCurrentProcess(), 0);
13907 SPEW(fprintf(stderr, "0x%x D::GHF: signaling continue...\n", tid));
13913 // This is the function that a thread is hijacked to by the Right Side during a variety of debug events. This function
13916 #if defined(_TARGET_X86_)
13918 #endif // defined (_x86_)
13919 void Debugger::GenericHijackFunc(void)
13921 #if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
13923 #if defined(_TARGET_X86_)
13928 sub esp,__LOCAL_SIZE
13931 // We can't have C++ classes w/ dtors in a declspec naked, so just have call into a helper.
13932 GenericHijackFuncHelper();
13934 #if defined(_TARGET_X86_)
13942 // This signals the Right Side that this thread is ready to have its context restored.
13943 ExceptionNotForRuntime();
13946 _ASSERTE(!"@todo - port GenericHijackFunc");
13947 #endif // defined (_x86_)
13949 _ASSERTE(!"Should never get here (Debugger::GenericHijackFunc)");
13955 //#ifdef _TARGET_X86_
13957 // This is the function that is called when we determine that a first chance exception hijack has
13958 // begun and memory is prepared for the RS to tell the LS what to do
13960 void Debugger::SignalHijackStarted(void)
13962 WRAPPER_NO_CONTRACT;
13964 #if defined(FEATURE_INTEROP_DEBUGGING)
13965 SignalHijackStartedFlare();
13967 _ASSERTE(!"@todo - port the flares to the platform your running on.");
13972 // This is the function that is called when we determine that a first chance exception really belongs to the Runtime,
13973 // and that that exception is due to a managed->unmanaged transition. This notifies the Right Side of this and the Right
13974 // Side fixes up the thread's execution state from there, making sure to remember that it needs to continue to hide the
13975 // hijack state of the thread.
13977 void Debugger::ExceptionForRuntimeHandoffStart(void)
13979 WRAPPER_NO_CONTRACT;
13981 #if defined(FEATURE_INTEROP_DEBUGGING)
13982 ExceptionForRuntimeHandoffStartFlare();
13984 _ASSERTE(!"@todo - port the flares to the platform your running on.");
13990 // This is the function that is called when the original handler returns after we've determined that an exception was
13991 // due to a managed->unmanaged transition. This notifies the Right Side of this and the Right Side fixes up the thread's
13992 // execution state from there, making sure to turn off its flag indicating that the thread's hijack state should still
13995 void Debugger::ExceptionForRuntimeHandoffComplete(void)
13997 WRAPPER_NO_CONTRACT;
13999 #if defined(FEATURE_INTEROP_DEBUGGING)
14000 ExceptionForRuntimeHandoffCompleteFlare();
14002 _ASSERTE(!"@todo - port the flares to the platform your running on.");
14008 // This signals the RS that a hijack function is ready to return. This will cause the RS to restore
14009 // the thread context
14011 void Debugger::SignalHijackComplete(void)
14013 WRAPPER_NO_CONTRACT;
14015 #if defined(FEATURE_INTEROP_DEBUGGING)
14016 SignalHijackCompleteFlare();
14018 _ASSERTE(!"@todo - port the flares to the platform your running on.");
14024 // This is the function that is called when we determine that a first chance exception does not belong to the
14025 // Runtime. This notifies the Right Side of this and the Right Side fixes up the thread's execution state from there.
14027 void Debugger::ExceptionNotForRuntime(void)
14029 WRAPPER_NO_CONTRACT;
14031 #if defined(FEATURE_INTEROP_DEBUGGING)
14032 ExceptionNotForRuntimeFlare();
14034 _ASSERTE(!"@todo - port the flares to the platform your running on.");
14039 // This is the function that is called when we want to send a sync complete event to the Right Side when it is the Win32
14040 // debugger of this process. This notifies the Right Side of this and the Right Side fixes up the thread's execution
14041 // state from there.
14043 void Debugger::NotifyRightSideOfSyncComplete(void)
14045 WRAPPER_NO_CONTRACT;
14046 STRESS_LOG0(LF_CORDB, LL_INFO100000, "D::NRSOSC: Sending flare...\n");
14047 #if defined(FEATURE_INTEROP_DEBUGGING)
14048 NotifyRightSideOfSyncCompleteFlare();
14050 _ASSERTE(!"@todo - port the flares to the platform your running on.");
14052 STRESS_LOG0(LF_CORDB, LL_INFO100000, "D::NRSOSC: Flare sent\n");
14055 #endif // FEATURE_INTEROP_DEBUGGING
14057 /******************************************************************************
14059 ******************************************************************************/
14060 bool Debugger::GetILOffsetFromNative (MethodDesc *pFunc, const BYTE *pbAddr,
14061 DWORD nativeOffset, DWORD *ilOffset)
14066 GC_TRIGGERS_FROM_GETJITINFO;
14070 _ASSERTE(pFunc != NULL);
14071 _ASSERTE(pbAddr != NULL);
14073 if (!HasLazyData())
14075 DebuggerLockHolder dbgLockHolder(this);
14076 // This is an entry path into the debugger, so make sure we're inited.
14080 // Sometimes we'll get called w/ an instantiating stub MD.
14081 if (pFunc->IsWrapperStub())
14083 pFunc = pFunc->GetWrappedMethodDesc();
14086 if (pFunc->IsDynamicMethod())
14091 DebuggerMethodInfo *methodInfo = GetOrCreateMethodInfo(pFunc->GetModule(), pFunc->GetMemberDef());
14092 if (methodInfo == NULL)
14097 PCODE methodStartAddress = g_pEEInterface->GetNativeCodeStartAddress((PCODE)pbAddr);
14098 if (methodStartAddress == NULL)
14103 DebuggerJitInfo *jitInfo = methodInfo->FindOrCreateInitAndAddJitInfo(pFunc, methodStartAddress);
14104 if (jitInfo == NULL)
14109 CorDebugMappingResult map;
14110 DWORD whichIDontCare;
14111 *ilOffset = jitInfo->MapNativeOffsetToIL(
14118 /******************************************************************************
14120 ******************************************************************************/
14121 DWORD Debugger::GetHelperThreadID(void )
14123 LIMITED_METHOD_CONTRACT;
14125 return m_pRCThread ? m_pRCThread->GetDCB()->m_temporaryHelperThreadId : 0;
14129 // HRESULT Debugger::InsertToMethodInfoList(): Make sure
14130 // that there's only one head of the the list of DebuggerMethodInfos
14131 // for the (implicitly) given MethodDef/Module pair.
14133 Debugger::InsertToMethodInfoList( DebuggerMethodInfo *dmi )
14142 LOG((LF_CORDB,LL_INFO10000,"D:IAHOL DMI: dmi:0x%08x\n", dmi));
14146 _ASSERTE(dmi != NULL);
14148 _ASSERTE(HasDebuggerDataLock());
14150 // CHECK_DJI_TABLE_DEBUGGER;
14152 hr = CheckInitMethodInfoTable();
14158 DebuggerMethodInfo *dmiPrev = m_pMethodInfos->GetMethodInfo(dmi->m_module, dmi->m_token);
14160 _ASSERTE((dmiPrev == NULL) || ((dmi->m_token == dmiPrev->m_token) && (dmi->m_module == dmiPrev->m_module)));
14162 LOG((LF_CORDB,LL_INFO10000,"D:IAHOL: current head of dmi list:0x%08x\n",dmiPrev));
14164 if (dmiPrev != NULL)
14166 dmi->m_prevMethodInfo = dmiPrev;
14167 dmiPrev->m_nextMethodInfo = dmi;
14169 _ASSERTE(dmi->m_module != NULL);
14170 hr = m_pMethodInfos->OverwriteMethodInfo(dmi->m_module,
14175 LOG((LF_CORDB,LL_INFO10000,"D:IAHOL: DMI version 0x%04x for token 0x%08x\n",
14176 dmi->GetCurrentEnCVersion(),dmi->m_token));
14180 LOG((LF_CORDB, LL_EVERYTHING, "AddMethodInfo being called in D:IAHOL\n"));
14181 hr = m_pMethodInfos->AddMethodInfo(dmi->m_module,
14186 dmiPrev = m_pMethodInfos->GetMethodInfo(dmi->m_module, dmi->m_token);
14187 LOG((LF_CORDB,LL_INFO10000,"D:IAHOL: new head of dmi list:0x%08x\n",
14191 // DebuggerDataLockHolder out of scope - release implied
14195 //-----------------------------------------------------------------------------
14196 // Helper to get an SString through the IPC buffer.
14197 // We do this by putting the SString data into a LS_RS_buffer object,
14198 // and then the RS reads it out as soon as it's queued.
14199 // It's very very important that the SString's buffer is around while we send the event.
14200 // So we pass the SString by reference in case there's an implicit conversion (because
14201 // we don't want to do the conversion on a temporary object and then lose that object).
14202 //-----------------------------------------------------------------------------
14203 void SetLSBufferFromSString(Ls_Rs_StringBuffer * pBuffer, SString & str)
14205 // Copy string contents (+1 for null terminator) into a LS_RS_Buffer.
14206 // Then the RS can pull it out as a null-terminated string.
14207 pBuffer->SetLsData(
14208 (BYTE*) str.GetUnicode(),
14209 (str.GetCount() +1)* sizeof(WCHAR)
14213 //*************************************************************
14214 // structure that we to marshal MDA Notification event data.
14215 //*************************************************************
14216 struct SendMDANotificationParams
14218 Thread * m_pThread; // may be NULL. Lets us send on behalf of other threads.
14220 // Pass SStrings by ptr in case to guarantee that they're shared (in case we internally modify their storage).
14221 SString * m_szName;
14222 SString * m_szDescription;
14224 CorDebugMDAFlags m_flags;
14226 SendMDANotificationParams(
14227 Thread * pThread, // may be NULL. Lets us send on behalf of other threads.
14229 SString * szDescription,
14231 CorDebugMDAFlags flags
14233 m_pThread(pThread),
14235 m_szDescription(szDescription),
14239 LIMITED_METHOD_CONTRACT;
14244 //-----------------------------------------------------------------------------
14245 // Actually send the MDA event. (Could be on any thread)
14247 // params - data to initialize the IPC event.
14248 //-----------------------------------------------------------------------------
14249 void Debugger::SendRawMDANotification(
14250 SendMDANotificationParams * params
14253 // Send the unload assembly event to the Right Side.
14254 DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer();
14256 Thread * pThread = params->m_pThread;
14257 AppDomain *pAppDomain = (pThread != NULL) ? pThread->GetDomain() : NULL;
14260 DB_IPCE_MDA_NOTIFICATION,
14264 SetLSBufferFromSString(&ipce->MDANotification.szName, *(params->m_szName));
14265 SetLSBufferFromSString(&ipce->MDANotification.szDescription, *(params->m_szDescription));
14266 SetLSBufferFromSString(&ipce->MDANotification.szXml, *(params->m_szXML));
14267 ipce->MDANotification.dwOSThreadId = GetCurrentThreadId();
14268 ipce->MDANotification.flags = params->m_flags;
14270 m_pRCThread->SendIPCEvent();
14273 //-----------------------------------------------------------------------------
14274 // Send an MDA notification. This ultimately translates to an ICorDebugMDA object on the Right-Side.
14275 // Called by EE to send a MDA debug event. This will block on the debug event
14276 // until the RS continues us.
14277 // Debugger may or may not be attached. If bAttached, then this
14278 // will trigger a jitattach as well.
14279 // See MDA documentation for what szName, szDescription + szXML should look like.
14280 // The debugger just passes them through.
14283 // pThread - thread for debug event. May be null.
14284 // szName - short name of MDA.
14285 // szDescription - full description of MDA.
14286 // szXML - xml string for MDA.
14287 // bAttach - do a JIT-attach
14288 //-----------------------------------------------------------------------------
14289 void Debugger::SendMDANotification(
14290 Thread * pThread, // may be NULL. Lets us send on behalf of other threads.
14292 SString * szDescription,
14294 CorDebugMDAFlags flags,
14306 PREFIX_ASSUME(szName != NULL);
14307 PREFIX_ASSUME(szDescription != NULL);
14308 PREFIX_ASSUME(szXML != NULL);
14310 // Note: we normally don't send events like this when there is an unrecoverable error. However,
14311 // if a host attempts to setup fiber mode on a thread, then we'll set an unrecoverable error
14312 // and use an MDA to 1) tell the user and 2) get the Right Side to notice the unrecoverable error.
14313 // Therefore, we'll go ahead and send a MDA event if the unrecoverable error is
14314 // CORDBG_E_CANNOT_DEBUG_FIBER_PROCESS.
14315 DebuggerIPCControlBlock *pDCB = m_pRCThread->GetDCB();
14318 // If the MDA is ocuring very early in startup before the DCB is setup, then bail.
14324 if (CORDBUnrecoverableError(this) && (pDCB->m_errorHR != CORDBG_E_CANNOT_DEBUG_FIBER_PROCESS))
14329 // Validate flags. Make sure that folks don't start passing flags that we don't handle.
14330 // If pThread != current thread, caller should either pass in MDA_FLAG_SLIP or guarantee
14331 // that pThread is not slipping.
14332 _ASSERTE((flags & ~(MDA_FLAG_SLIP)) == 0);
14334 // Helper thread should not be triggering MDAs. The helper thread is executing code in a very constrained
14335 // and controlled region and shouldn't be able to do anything dangerous.
14336 // If we revise this in the future, we should probably just post the event to the RS w/ use the MDA_FLAG_SLIP flag,
14337 // and then not bother suspending the runtime. The RS will get it on its next event.
14338 // The jit-attach logic below assumes we're not on the helper. (If we are on the helper, then a debugger should already
14340 if (ThisIsHelperThreadWorker())
14342 CONSISTENCY_CHECK_MSGF(false, ("MDA '%s' fired on *helper* thread.\r\nDesc:%s",
14343 szName->GetUnicode(), szDescription->GetUnicode()
14346 // If for some reason we're wrong about the assert above, we'll just ignore the MDA (rather than potentially deadlock)
14350 // Public entry point into the debugger. May cause a jit-attach, so we may need to be lazily-init.
14351 if (!HasLazyData())
14353 DebuggerLockHolder dbgLockHolder(this);
14354 // This is an entry path into the debugger, so make sure we're inited.
14360 // 1) Debugger already attached, send event normally (ignore severity)
14361 // 2) No debugger attached, Non-severe probe - ignore.
14362 // 3) No debugger attached, Severe-probe - do a jit-attach.
14363 bool fTryJitAttach = bAttach == TRUE;
14365 // Check case #2 - no debugger, and no jit-attach. Early opt out.
14366 if (!CORDebuggerAttached() && !fTryJitAttach)
14371 if (pThread == NULL)
14373 // If there's no thread object, then we're not blocking after the event,
14374 // and thus this probe may slip.
14375 flags = (CorDebugMDAFlags) (flags | MDA_FLAG_SLIP);
14379 GCX_PREEMP_EEINTERFACE_TOGGLE_IFTHREAD();
14381 // For "Severe" probes, we'll do a jit attach dialog
14385 // - S_OK if we do a jit-attach,
14386 // - S_FALSE if a debugger is already attached.
14387 // - Error in other cases..
14389 JitAttach(pThread, NULL, TRUE, FALSE);
14392 // Debugger may be attached now...
14393 if (CORDebuggerAttached())
14395 SendMDANotificationParams params(pThread, szName, szDescription, szXML, flags);
14397 // Non-attach case. Send like normal event.
14398 // This includes if someone launch the debugger during the meantime.
14399 // just send the event
14400 SENDIPCEVENT_BEGIN(this, pThread);
14402 // Send Log message event to the Right Side
14403 SendRawMDANotification(¶ms);
14405 // Stop all Runtime threads
14406 // Even if we don't have a managed thead object, this will catch us at the next good spot.
14407 TrapAllRuntimeThreads();
14409 // Let other Runtime threads handle their events.
14412 } // end of GCX_PREEMP_EEINTERFACE_TOGGLE()
14415 //*************************************************************
14416 // This method sends a log message over to the right side for the debugger to log it.
14418 // The CLR doesn't assign any semantics to the level or cateogory values.
14419 // The BCL has a level convention (LoggingLevels enum), but this isn't exposed publicly,
14420 // so we shouldn't base our behavior on it in any way.
14421 //*************************************************************
14422 void Debugger::SendLogMessage(int iLevel,
14423 SString * pSwitchName,
14424 SString * pMessage)
14433 LOG((LF_CORDB, LL_INFO10000, "D::SLM: Sending log message.\n"));
14435 // Send the message only if the debugger is attached to this appdomain.
14436 // Note the the debugger may detach at any time, so we'll have to check
14437 // this again after we get the lock.
14438 AppDomain *pAppDomain = g_pEEInterface->GetThread()->GetDomain();
14440 if (!CORDebuggerAttached())
14445 Thread *pThread = g_pEEInterface->GetThread();
14446 SENDIPCEVENT_BEGIN(this, pThread);
14448 // Send Log message event to the Right Side
14456 // Stop all Runtime threads
14457 TrapAllRuntimeThreads();
14459 // Let other Runtime threads handle their events.
14464 //*************************************************************
14466 // Helper function to just send LogMessage event. Can be called on either
14467 // helper thread or managed thread.
14469 //*************************************************************
14470 void Debugger::SendRawLogMessage(
14472 AppDomain *pAppDomain,
14474 SString * pCategory,
14478 DebuggerIPCEvent* ipce;
14481 // We should have hold debugger lock
14482 // This can happen on either native helper thread or managed thread
14483 _ASSERTE(ThreadHoldsLock());
14485 // It's possible that the debugger dettached while we were waiting
14486 // for our lock. Check again and abort the event if it did.
14487 if (!CORDebuggerAttached())
14492 ipce = m_pRCThread->GetIPCEventSendBuffer();
14494 // Send a LogMessage event to the Right Side
14496 DB_IPCE_FIRST_LOG_MESSAGE,
14500 ipce->FirstLogMessage.iLevel = iLevel;
14501 ipce->FirstLogMessage.szCategory.SetString(pCategory->GetUnicode());
14502 SetLSBufferFromSString(&ipce->FirstLogMessage.szContent, *pMessage);
14504 m_pRCThread->SendIPCEvent();
14508 // This function sends a message to the right side informing it about
14509 // the creation/modification of a LogSwitch
14510 void Debugger::SendLogSwitchSetting(int iLevel,
14512 __in_z LPCWSTR pLogSwitchName,
14513 __in_z LPCWSTR pParentSwitchName)
14517 MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
14518 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
14522 LOG((LF_CORDB, LL_INFO1000, "D::SLSS: Sending log switch message switch=%S parent=%S.\n",
14523 pLogSwitchName, pParentSwitchName));
14525 // Send the message only if the debugger is attached to this appdomain.
14526 if (!CORDebuggerAttached())
14531 Thread *pThread = g_pEEInterface->GetThread();
14532 SENDIPCEVENT_BEGIN(this, pThread);
14534 if (CORDebuggerAttached())
14536 DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer();
14538 DB_IPCE_LOGSWITCH_SET_MESSAGE,
14540 pThread->GetDomain());
14542 ipce->LogSwitchSettingMessage.iLevel = iLevel;
14543 ipce->LogSwitchSettingMessage.iReason = iReason;
14546 ipce->LogSwitchSettingMessage.szSwitchName.SetString(pLogSwitchName);
14548 if (pParentSwitchName == NULL)
14550 pParentSwitchName = W("");
14553 ipce->LogSwitchSettingMessage.szParentSwitchName.SetString(pParentSwitchName);
14555 m_pRCThread->SendIPCEvent();
14557 // Stop all Runtime threads
14558 TrapAllRuntimeThreads();
14562 LOG((LF_CORDB,LL_INFO1000, "D::SLSS: Skipping SendIPCEvent because RS detached."));
14568 // send a custom debugger notification to the RS
14570 // input: pThread - thread on which the notification occurred
14571 // pDomain - domain file for the domain in which the notification occurred
14572 // classToken - metadata token for the type of the notification object
14573 void Debugger::SendCustomDebuggerNotification(Thread * pThread,
14574 DomainFile * pDomain,
14575 mdTypeDef classToken)
14584 LOG((LF_CORDB, LL_INFO10000, "D::SLM: Sending log message.\n"));
14586 // Send the message only if the debugger is attached to this appdomain.
14587 // Note the the debugger may detach at any time, so we'll have to check
14588 // this again after we get the lock.
14589 if (!CORDebuggerAttached())
14594 Thread *curThread = g_pEEInterface->GetThread();
14595 SENDIPCEVENT_BEGIN(this, curThread);
14597 if (CORDebuggerAttached())
14599 DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer();
14601 DB_IPCE_CUSTOM_NOTIFICATION,
14603 curThread->GetDomain());
14605 VMPTR_DomainFile vmDomainFile = VMPTR_DomainFile::MakePtr(pDomain);
14607 ipce->CustomNotification.classToken = classToken;
14608 ipce->CustomNotification.vmDomainFile = vmDomainFile;
14611 m_pRCThread->SendIPCEvent();
14613 // Stop all Runtime threads
14614 TrapAllRuntimeThreads();
14618 LOG((LF_CORDB,LL_INFO1000, "D::SCDN: Skipping SendIPCEvent because RS detached."));
14625 //-----------------------------------------------------------------------------
14627 // Add the AppDomain to the list stored in the IPC block. It adds the id and
14631 // pAppDomain - The runtime app domain object to add.
14634 // S_OK on success, else detailed error code.
14636 HRESULT Debugger::AddAppDomainToIPC(AppDomain *pAppDomain)
14640 MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
14647 LPCWSTR szName = NULL;
14649 LOG((LF_CORDB, LL_INFO100, "D::AADTIPC: Executing AADTIPC for AppDomain 0x%08x (0x%x).\n",
14651 pAppDomain->GetId().m_dwId));
14653 STRESS_LOG2(LF_CORDB, LL_INFO10000, "D::AADTIPC: AddAppDomainToIPC:%#08x, %#08x\n",
14654 pAppDomain, pAppDomain->GetId().m_dwId);
14658 _ASSERTE(m_pAppDomainCB->m_iTotalSlots > 0);
14659 _ASSERTE(m_pAppDomainCB->m_rgListOfAppDomains != NULL);
14663 // We need to synchronize this routine with the attach logic. The "normal"
14664 // attach case uses the HelperThread and TrapAllRuntimeThreads to synchronize
14665 // the runtime before sending any of the events (including AppDomainCreates)
14666 // to the right-side. Thus, we can synchronize with this case by forcing us
14667 // to go co-operative. If we were already co-op, then the helper thread will
14668 // wait to start the attach until all co-op threads are paused. If we were
14669 // pre-emptive, then going co-op will suspend us until the HelperThread finishes.
14671 // The second case is under the IPC event for ATTACHING, which is where there are
14672 // zero app domains, so it is considered an 'early attach' case. To synchronize
14673 // with this we have to grab and hold the AppDomainDB lock.
14679 if (!m_pAppDomainCB->Lock())
14684 // Get a free entry from the list
14685 AppDomainInfo *pAppDomainInfo = m_pAppDomainCB->GetFreeEntry();
14687 // Function returns NULL if the list is full and a realloc failed.
14688 if (!pAppDomainInfo)
14690 hr = E_OUTOFMEMORY;
14695 pAppDomainInfo->m_id = pAppDomain->GetId().m_dwId;
14697 // Now set the AppDomainName.
14702 * Make sure that returning NULL here does not result in a catastrophic
14705 * GetFriendlyNameNoThrow may call SetFriendlyName, which may call
14706 * UpdateAppDomainEntryInIPC. There is no recursive death, however, because
14707 * the AppDomainInfo object does not contain a pointer to the app domain
14710 szName = pAppDomain->GetFriendlyNameForDebugger();
14711 pAppDomainInfo->SetName(szName);
14713 // Save on to the appdomain pointer
14714 pAppDomainInfo->m_pAppDomain = pAppDomain;
14716 // bump the used slot count
14717 m_pAppDomainCB->m_iNumOfUsedSlots++;
14721 m_pAppDomainCB->Unlock();
14723 // Send event to debugger if one is attached.
14724 if (CORDebuggerAttached())
14726 SendCreateAppDomainEvent(pAppDomain);
14734 /******************************************************************************
14735 * Remove the AppDomain from the list stored in the IPC block and send an ExitAppDomain
14736 * event to the debugger if attached.
14737 ******************************************************************************/
14738 HRESULT Debugger::RemoveAppDomainFromIPC (AppDomain *pAppDomain)
14742 MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
14743 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
14748 HRESULT hr = E_FAIL;
14750 LOG((LF_CORDB, LL_INFO100, "D::RADFIPC: Executing RADFIPC for AppDomain 0x%08x (0x%x).\n",
14752 pAppDomain->GetId().m_dwId));
14754 // if none of the slots are occupied, then simply return.
14755 if (m_pAppDomainCB->m_iNumOfUsedSlots == 0)
14759 if (!m_pAppDomainCB->Lock())
14763 // Look for the entry
14764 AppDomainInfo *pADInfo = m_pAppDomainCB->FindEntry(pAppDomain);
14766 // Shouldn't be trying to remove an appdomain that was never added
14769 // We'd like to assert this, but there is a small window where we may have
14770 // called AppDomain::Init (and so it's fair game to call Stop, and hence come here),
14771 // but not yet published the app domain.
14772 // _ASSERTE(!"D::RADFIPC: trying to remove an AppDomain that was never added");
14777 // Release the entry
14778 m_pAppDomainCB->FreeEntry(pADInfo);
14782 m_pAppDomainCB->Unlock();
14784 // send event to debugger if one is attached
14785 if (CORDebuggerAttached())
14787 SendExitAppDomainEvent(pAppDomain);
14793 /******************************************************************************
14794 * Update the AppDomain in the list stored in the IPC block.
14795 ******************************************************************************/
14796 HRESULT Debugger::UpdateAppDomainEntryInIPC(AppDomain *pAppDomain)
14801 if (GetThread()) { GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
14807 LPCWSTR szName = NULL;
14809 LOG((LF_CORDB, LL_INFO100,
14810 "D::UADEIIPC: Executing UpdateAppDomainEntryInIPC ad:0x%x.\n",
14813 // if none of the slots are occupied, then simply return.
14814 if (m_pAppDomainCB->m_iNumOfUsedSlots == 0)
14818 if (!m_pAppDomainCB->Lock())
14821 // Look up the info entry
14822 AppDomainInfo *pADInfo = m_pAppDomainCB->FindEntry(pAppDomain);
14830 // Update the name only if new name is non-null
14831 szName = pADInfo->m_pAppDomain->GetFriendlyNameForDebugger();
14832 pADInfo->SetName(szName);
14834 LOG((LF_CORDB, LL_INFO100,
14835 "D::UADEIIPC: New name:%ls (AD:0x%x)\n", pADInfo->m_szAppDomainName,
14840 m_pAppDomainCB->Unlock();
14845 HRESULT Debugger::CopyModulePdb(Module* pRuntimeModule)
14850 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
14853 PRECONDITION(ThisIsHelperThread());
14858 if (!pRuntimeModule->IsVisibleToDebugger())
14868 /******************************************************************************
14869 * When attaching to a process, this is called to enumerate all of the
14870 * AppDomains currently in the process and allow modules pdbs to be copied over to the shadow dir maintaining out V2 in-proc behaviour.
14871 ******************************************************************************/
14872 HRESULT Debugger::IterateAppDomainsForPdbs()
14877 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
14880 PRECONDITION(ThisIsHelperThread());
14885 STRESS_LOG0(LF_CORDB, LL_INFO100, "Entered function IterateAppDomainsForPdbs()\n");
14889 if (!m_pAppDomainCB->Lock())
14892 // Iterate through the app domains
14893 AppDomainInfo *pADInfo = m_pAppDomainCB->FindFirst();
14897 STRESS_LOG3(LF_CORDB, LL_INFO100, "Iterating over domain %#08x AD:%#08x %ls\n", pADInfo->m_pAppDomain->GetId().m_dwId, pADInfo->m_pAppDomain, pADInfo->m_szAppDomainName);
14899 AppDomain::AssemblyIterator i;
14900 i = pADInfo->m_pAppDomain->IterateAssembliesEx((AssemblyIterationFlags)(kIncludeLoaded | kIncludeLoading | kIncludeExecution));
14901 CollectibleAssemblyHolder<DomainAssembly *> pDomainAssembly;
14902 while (i.Next(pDomainAssembly.This()))
14904 if (!pDomainAssembly->IsVisibleToDebugger())
14907 DomainAssembly::ModuleIterator j = pDomainAssembly->IterateModules(kModIterIncludeLoading);
14910 DomainFile * pDomainFile = j.GetDomainFile();
14911 if (!pDomainFile->ShouldNotifyDebugger())
14914 Module* pRuntimeModule = pDomainFile->GetModule();
14915 CopyModulePdb(pRuntimeModule);
14917 if (pDomainAssembly->ShouldNotifyDebugger())
14919 CopyModulePdb(pDomainAssembly->GetModule());
14923 // Get the next appdomain in the list
14924 pADInfo = m_pAppDomainCB->FindNext(pADInfo);
14928 m_pAppDomainCB->Unlock();
14930 STRESS_LOG0(LF_CORDB, LL_INFO100, "Exiting function IterateAppDomainsForPdbs\n");
14936 /******************************************************************************
14938 ******************************************************************************/
14939 HRESULT Debugger::InitAppDomainIPC(void)
14947 PRECONDITION(CheckPointer(m_pAppDomainCB));
14951 // Ensure that if we throw here, the Terminate will get called and cleanup all resources.
14952 // This will make Init an atomic operation - it either fully inits or fully fails.
14953 class EnsureCleanup
14955 Debugger * m_pThis;
14958 EnsureCleanup(Debugger * pThis)
14963 void SupressCleanup()
14970 if (m_pThis != NULL)
14972 m_pThis->TerminateAppDomainIPC();
14975 } hEnsureCleanup(this);
14977 DWORD dwStrLen = 0;
14981 // all fields in the object can be zero initialized.
14982 // If we throw, before fully initializing this, then cleanup won't try to free
14983 // uninited values.
14984 ZeroMemory(m_pAppDomainCB, sizeof(*m_pAppDomainCB));
14986 // Create a mutex to allow the Left and Right Sides to properly
14987 // synchronize. The Right Side will spin until m_hMutex is valid,
14988 // then it will acquire it before accessing the data.
14989 HandleHolder hMutex(WszCreateMutex(NULL, TRUE/*hold*/, NULL));
14990 if (hMutex == NULL)
14994 if (!m_pAppDomainCB->m_hMutex.SetLocal(hMutex))
14998 hMutex.SuppressRelease();
15000 m_pAppDomainCB->m_iSizeInBytes = INITIAL_APP_DOMAIN_INFO_LIST_SIZE *
15001 sizeof (AppDomainInfo);
15003 // Number of slots in AppDomainListElement array
15004 m_pAppDomainCB->m_rgListOfAppDomains = new AppDomainInfo[INITIAL_APP_DOMAIN_INFO_LIST_SIZE];
15005 _ASSERTE(m_pAppDomainCB->m_rgListOfAppDomains != NULL); // throws on oom
15008 m_pAppDomainCB->m_iTotalSlots = INITIAL_APP_DOMAIN_INFO_LIST_SIZE;
15010 // Initialize each AppDomainListElement
15011 for (i = 0; i < INITIAL_APP_DOMAIN_INFO_LIST_SIZE; i++)
15013 m_pAppDomainCB->m_rgListOfAppDomains[i].FreeEntry();
15016 // also initialize the process name
15017 dwStrLen = WszGetModuleFileName(NULL,
15021 // If we couldn't get the name, then use a nice default.
15024 szExeName.Set(W("<NoProcessName>"));
15025 dwStrLen = szExeName.GetCount();
15028 // If we got the name, copy it into a buffer. dwStrLen is the
15029 // count of characters in the name, not including the null
15031 m_pAppDomainCB->m_szProcessName = new WCHAR[dwStrLen + 1];
15032 _ASSERTE(m_pAppDomainCB->m_szProcessName != NULL); // throws on oom
15034 wcscpy_s(m_pAppDomainCB->m_szProcessName, dwStrLen + 1, szExeName);
15036 // Add 1 to the string length so the Right Side will copy out the
15037 // null terminator, too.
15038 m_pAppDomainCB->m_iProcessNameLengthInBytes = (dwStrLen + 1) * sizeof(WCHAR);
15040 if (m_pAppDomainCB->m_hMutex != NULL)
15042 m_pAppDomainCB->Unlock();
15045 hEnsureCleanup.SupressCleanup();
15049 /******************************************************************************
15050 * Unitialize the AppDomain IPC block
15052 * S_OK -if fully unitialized
15053 * E_FAIL - if we can't get ownership of the block, and thus no unitialization
15055 ******************************************************************************/
15056 HRESULT Debugger::TerminateAppDomainIPC(void)
15066 // If we have no AppDomain block, then we can consider it's already terminated.
15067 if (m_pAppDomainCB == NULL)
15073 // If there's no mutex, then we're in a partially created state.
15074 // This means InitAppDomainIPC failed halfway through. But we're still thread safe
15075 // since other threads can't access us if we don't have the mutex.
15076 if ((m_pAppDomainCB->m_hMutex != NULL) && !m_pAppDomainCB->Lock())
15078 // The callers don't check our return value, we may want to know when we can't gracefully clean up
15079 LOG((LF_CORDB, LL_INFO10, "Debugger::TerminateAppDomainIPC: Failed to get AppDomain IPC lock, not cleaning up.\n"));
15081 // If the lock is valid, but we can't get it, then we can't really
15082 // uninitialize since someone else is using the block.
15086 // The shared IPC segment could still be around after the debugger
15087 // object has been destroyed during process shutdown. So, reset
15088 // the UsedSlots count to 0 so that any out of process clients
15089 // enumeratingthe app domains in this process see 0 AppDomains.
15090 m_pAppDomainCB->m_iNumOfUsedSlots = 0;
15091 m_pAppDomainCB->m_iTotalSlots = 0;
15093 // Now delete the memory allocated for AppDomainInfo array
15094 delete [] m_pAppDomainCB->m_rgListOfAppDomains;
15095 m_pAppDomainCB->m_rgListOfAppDomains = NULL;
15097 delete [] m_pAppDomainCB->m_szProcessName;
15098 m_pAppDomainCB->m_szProcessName = NULL;
15099 m_pAppDomainCB->m_iProcessNameLengthInBytes = 0;
15101 // Set the mutex handle to NULL.
15102 // If the Right Side acquires the mutex, it will verify
15103 // that the handle is still not NULL. If it is, then it knows it
15105 RemoteHANDLE m = m_pAppDomainCB->m_hMutex;
15106 m_pAppDomainCB->m_hMutex.m_hLocal = NULL;
15108 // And bring us back to a fully unintialized state.
15109 ZeroMemory(m_pAppDomainCB, sizeof(*m_pAppDomainCB));
15111 // We're done. release and close the mutex. Note that this must be done
15112 // after we clear it out above to ensure there is no race condition.
15115 VERIFY(ReleaseMutex(m));
15123 #ifndef DACCESS_COMPILE
15126 // FuncEvalSetup sets up a function evaluation for the given method on the given thread.
15128 HRESULT Debugger::FuncEvalSetup(DebuggerIPCE_FuncEvalInfo *pEvalInfo,
15129 BYTE **argDataArea,
15130 DebuggerEval **debuggerEvalKey)
15140 Thread *pThread = pEvalInfo->vmThreadToken.GetRawPtr();
15144 // If TS_AbortRequested (which may have been set by a pending FuncEvalAbort),
15145 // we will not be able to do a new func-eval
15147 // <TODO>@TODO: Remember the current value of m_State, reset m_State as appropriate,
15148 // do the new func-eval, and then set m_State to the original value</TODO>
15149 if (pThread->m_State & Thread::TS_AbortRequested)
15150 return CORDBG_E_FUNC_EVAL_BAD_START_POINT;
15152 if (g_fProcessDetach)
15153 return CORDBG_E_FUNC_EVAL_BAD_START_POINT;
15155 // If there is no guard page on this thread, then we've taken a stack overflow exception and can't run managed
15156 // code on this thread. Therefore, we can't do a func eval on this thread.
15157 if (!pThread->DetermineIfGuardPagePresent())
15159 return CORDBG_E_ILLEGAL_IN_STACK_OVERFLOW;
15162 bool fInException = pEvalInfo->evalDuringException;
15164 // The thread has to be at a GC safe place for now, just in case the func eval causes a collection. Processing an
15165 // exception also counts as a "safe place." Eventually, we'd like to have to avoid this check and eval anyway, but
15166 // that's a way's off...
15167 if (!fInException && !g_pDebugger->IsThreadAtSafePlace(pThread))
15168 return CORDBG_E_ILLEGAL_AT_GC_UNSAFE_POINT;
15170 // For now, we assume that the target thread must be stopped in managed code due to a single step or a
15171 // breakpoint. Being stopped while sending a first or second chance exception is also valid, and there may or may
15172 // not be a filter context when we do a func eval from such places. This will loosen over time, eventually allowing
15173 // threads that are stopped anywhere in managed code to perform func evals.
15174 CONTEXT *filterContext = GetManagedStoppedCtx(pThread);
15176 if (filterContext == NULL && !fInException)
15178 return CORDBG_E_ILLEGAL_AT_GC_UNSAFE_POINT;
15181 // Create a DebuggerEval to hold info about this eval while its in progress. Constructor copies the thread's
15183 DebuggerEval *pDE = new (interopsafe, nothrow) DebuggerEval(filterContext, pEvalInfo, fInException);
15187 return E_OUTOFMEMORY;
15189 else if (!pDE->Init())
15191 // We fail to change the m_breakpointInstruction field to PAGE_EXECUTE_READWRITE permission.
15195 SIZE_T argDataAreaSize = 0;
15197 argDataAreaSize += pEvalInfo->genericArgsNodeCount * sizeof(DebuggerIPCE_TypeArgData);
15199 if ((pEvalInfo->funcEvalType == DB_IPCE_FET_NORMAL) ||
15200 (pEvalInfo->funcEvalType == DB_IPCE_FET_NEW_OBJECT) ||
15201 (pEvalInfo->funcEvalType == DB_IPCE_FET_NEW_OBJECT_NC))
15202 argDataAreaSize += pEvalInfo->argCount * sizeof(DebuggerIPCE_FuncEvalArgData);
15203 else if (pEvalInfo->funcEvalType == DB_IPCE_FET_NEW_STRING)
15204 argDataAreaSize += pEvalInfo->stringSize;
15205 else if (pEvalInfo->funcEvalType == DB_IPCE_FET_NEW_ARRAY)
15206 argDataAreaSize += pEvalInfo->arrayRank * sizeof(SIZE_T);
15208 if (argDataAreaSize > 0)
15210 pDE->m_argData = new (interopsafe, nothrow) BYTE[argDataAreaSize];
15212 if (pDE->m_argData == NULL)
15214 DeleteInteropSafeExecutable(pDE);
15215 return E_OUTOFMEMORY;
15218 // Pass back the address of the argument data area so the right side can write to it for us.
15219 *argDataArea = pDE->m_argData;
15222 // Set the thread's IP (in the filter context) to our hijack function if we're stopped due to a breakpoint or single
15226 _ASSERTE(filterContext != NULL);
15228 ::SetIP(filterContext, (UINT_PTR)GetEEFuncEntryPoint(::FuncEvalHijack));
15230 // Don't be fooled into thinking you can push things onto the thread's stack now. If the thread is stopped at a
15231 // breakpoint or from a single step, then its really suspended in the SEH filter. ESP in the thread's CONTEXT,
15232 // therefore, points into the middle of the thread's current stack. So we pass things we need in the hijack in
15233 // the thread's registers.
15235 // Set the first argument to point to the DebuggerEval.
15236 #if defined(_TARGET_X86_)
15237 filterContext->Eax = (DWORD)pDE;
15238 #elif defined(_TARGET_AMD64_)
15239 #ifdef UNIX_AMD64_ABI
15240 filterContext->Rdi = (SIZE_T)pDE;
15241 #else // UNIX_AMD64_ABI
15242 filterContext->Rcx = (SIZE_T)pDE;
15243 #endif // !UNIX_AMD64_ABI
15244 #elif defined(_TARGET_ARM_)
15245 filterContext->R0 = (DWORD)pDE;
15246 #elif defined(_TARGET_ARM64_)
15247 filterContext->X0 = (SIZE_T)pDE;
15249 PORTABILITY_ASSERT("Debugger::FuncEvalSetup is not implemented on this platform.");
15253 // To prevent GCs until the func-eval gets a chance to run, we increment the counter here.
15254 // We only need to do this if we have changed the filter CONTEXT, since the stack will be unwalkable
15257 g_pDebugger->IncThreadsAtUnsafePlaces();
15261 HRESULT hr = CheckInitPendingFuncEvalTable();
15265 DeleteInteropSafeExecutable(pDE); // Note this runs the destructor for DebuggerEval, which releases its internal buffers
15268 // If we're in an exception, then add a pending eval for this thread. This will cause us to perform the func
15269 // eval when the user continues the process after the current exception event.
15270 GetPendingEvals()->AddPendingEval(pDE->m_thread, pDE);
15274 // Return that all went well. Tracing the stack at this point should not show that the func eval is setup, but it
15275 // will show a wrong IP, so it shouldn't be done.
15276 *debuggerEvalKey = pDE;
15278 LOG((LF_CORDB, LL_INFO100000, "D:FES for pDE:%08x evalType:%d on thread %#x, id=0x%x\n",
15279 pDE, pDE->m_evalType, pThread, GetThreadIdHelper(pThread)));
15285 // FuncEvalSetupReAbort sets up a function evaluation specifically to rethrow a ThreadAbortException on the given
15288 HRESULT Debugger::FuncEvalSetupReAbort(Thread *pThread, Thread::ThreadAbortRequester requester)
15298 LOG((LF_CORDB, LL_INFO1000,
15299 "D::FESRA: performing reabort on thread %#x, id=0x%x\n",
15300 pThread, GetThreadIdHelper(pThread)));
15302 // The thread has to be at a GC safe place. It should be, since this is only done in response to a previous eval
15303 // completing with a ThreadAbortException.
15304 if (!g_pDebugger->IsThreadAtSafePlace(pThread))
15305 return CORDBG_E_ILLEGAL_AT_GC_UNSAFE_POINT;
15307 // Grab the filter context.
15308 CONTEXT *filterContext = GetManagedStoppedCtx(pThread);
15310 if (filterContext == NULL)
15312 return CORDBG_E_ILLEGAL_AT_GC_UNSAFE_POINT;
15315 // Create a DebuggerEval to hold info about this eval while its in progress. Constructor copies the thread's
15317 DebuggerEval *pDE = new (interopsafe, nothrow) DebuggerEval(filterContext, pThread, requester);
15321 return E_OUTOFMEMORY;
15323 else if (!pDE->Init())
15325 // We fail to change the m_breakpointInstruction field to PAGE_EXECUTE_READWRITE permission.
15329 // Set the thread's IP (in the filter context) to our hijack function.
15330 _ASSERTE(filterContext != NULL);
15332 ::SetIP(filterContext, (UINT_PTR)GetEEFuncEntryPoint(::FuncEvalHijack));
15334 #ifdef _TARGET_X86_ // reliance on filterContext->Eip & Eax
15335 // Set EAX to point to the DebuggerEval.
15336 filterContext->Eax = (DWORD)pDE;
15337 #elif defined(_TARGET_AMD64_)
15338 // Set RCX to point to the DebuggerEval.
15339 filterContext->Rcx = (SIZE_T)pDE;
15340 #elif defined(_TARGET_ARM_)
15341 filterContext->R0 = (DWORD)pDE;
15342 #elif defined(_TARGET_ARM64_)
15343 filterContext->X0 = (SIZE_T)pDE;
15345 PORTABILITY_ASSERT("FuncEvalSetupReAbort (Debugger.cpp) is not implemented on this platform.");
15348 // Now clear the bit requesting a re-abort
15349 pThread->ResetThreadStateNC(Thread::TSNC_DebuggerReAbort);
15351 g_pDebugger->IncThreadsAtUnsafePlaces();
15353 // Return that all went well. Tracing the stack at this point should not show that the func eval is setup, but it
15354 // will show a wrong IP, so it shouldn't be done.
15360 // FuncEvalAbort: Does a gentle abort of a func-eval already in progress.
15361 // Because this type of abort waits for the thread to get to a good state,
15362 // it may never return, or may time out.
15366 // Wait at most 0.5 seconds.
15368 #define FUNC_EVAL_DEFAULT_TIMEOUT_VALUE 500
15371 Debugger::FuncEvalAbort(
15372 DebuggerEval *debuggerEvalKey
15382 DebuggerEval *pDE = (DebuggerEval*) debuggerEvalKey;
15384 CHECK_IF_CAN_TAKE_HELPER_LOCKS_IN_THIS_SCOPE(&hr, GetCanary());
15391 if (pDE->m_aborting == DebuggerEval::FE_ABORT_NONE)
15393 // Remember that we're aborting this func eval.
15394 pDE->m_aborting = DebuggerEval::FE_ABORT_NORMAL;
15396 LOG((LF_CORDB, LL_INFO1000,
15397 "D::FEA: performing UserAbort on thread %#x, id=0x%x\n",
15398 pDE->m_thread, GetThreadIdHelper(pDE->m_thread)));
15400 if (!g_fProcessDetach && !pDE->m_completed)
15403 // Perform a stop on the thread that the eval is running on.
15404 // This will cause a ThreadAbortException to be thrown on the thread.
15408 hr = pDE->m_thread->UserAbort(Thread::TAR_FuncEval, EEPolicy::TA_Safe, (DWORD)FUNC_EVAL_DEFAULT_TIMEOUT_VALUE, Thread::UAC_Normal);
15409 if (hr == HRESULT_FROM_WIN32(ERROR_TIMEOUT))
15416 _ASSERTE(!"Unknown exception from UserAbort(), not expected");
15418 EX_END_CATCH(EX_RETHROW);
15422 LOG((LF_CORDB, LL_INFO1000, "D::FEA: UserAbort complete.\n"));
15429 // FuncEvalRudeAbort: Does a rude abort of a func-eval in progress. This
15430 // leaves the thread in an undetermined state.
15433 Debugger::FuncEvalRudeAbort(
15434 DebuggerEval *debuggerEvalKey
15446 CHECK_IF_CAN_TAKE_HELPER_LOCKS_IN_THIS_SCOPE(&hr, GetCanary());
15453 DebuggerEval *pDE = debuggerEvalKey;
15456 if (!(pDE->m_aborting & DebuggerEval::FE_ABORT_RUDE))
15459 // Remember that we're aborting this func eval.
15461 pDE->m_aborting = (DebuggerEval::FUNC_EVAL_ABORT_TYPE)(pDE->m_aborting | DebuggerEval::FE_ABORT_RUDE);
15463 LOG((LF_CORDB, LL_INFO1000,
15464 "D::FEA: performing RudeAbort on thread %#x, id=0x%x\n",
15465 pDE->m_thread, Debugger::GetThreadIdHelper(pDE->m_thread)));
15467 if (!g_fProcessDetach && !pDE->m_completed)
15470 // Perform a stop on the thread that the eval is running on.
15471 // This will cause a ThreadAbortException to be thrown on the thread.
15475 hr = pDE->m_thread->UserAbort(Thread::TAR_FuncEval, EEPolicy::TA_Rude, (DWORD)FUNC_EVAL_DEFAULT_TIMEOUT_VALUE, Thread::UAC_Normal);
15476 if (hr == HRESULT_FROM_WIN32(ERROR_TIMEOUT))
15483 _ASSERTE(!"Unknown exception from UserAbort(), not expected");
15486 EX_END_CATCH(RethrowTerminalExceptions);
15489 LOG((LF_CORDB, LL_INFO1000, "D::FEA: RudeAbort complete.\n"));
15496 // FuncEvalCleanup cleans up after a function evaluation is released.
15498 HRESULT Debugger::FuncEvalCleanup(DebuggerEval *debuggerEvalKey)
15500 LIMITED_METHOD_CONTRACT;
15502 DebuggerEval *pDE = debuggerEvalKey;
15504 _ASSERTE(pDE->m_completed);
15506 LOG((LF_CORDB, LL_INFO1000, "D::FEC: pDE:%08x 0x%08x, id=0x%x\n",
15507 pDE, pDE->m_thread, GetThreadIdHelper(pDE->m_thread)));
15509 DeleteInteropSafeExecutable(pDE->m_bpInfoSegment);
15510 DeleteInteropSafe(pDE);
15515 #endif // ifndef DACCESS_COMPILE
15518 // SetReference sets an object reference for the Right Side,
15519 // respecting the write barrier for references that are in the heap.
15521 HRESULT Debugger::SetReference(void *objectRefAddress,
15522 VMPTR_OBJECTHANDLE vmObjectHandle,
15523 void *newReference)
15534 hr = ValidateObject((Object *)newReference);
15541 // If the object ref isn't in a handle, then go ahead and use
15542 // SetObjectReference.
15543 if (vmObjectHandle.IsNull())
15545 OBJECTREF *dst = (OBJECTREF*)objectRefAddress;
15546 OBJECTREF src = *((OBJECTREF*)&newReference);
15548 SetObjectReferenceUnchecked(dst, src);
15553 // If the object reference to set is inside of a handle, then
15554 // fixup the handle.
15555 OBJECTHANDLE h = vmObjectHandle.GetRawPtr();
15556 OBJECTREF src = *((OBJECTREF*)&newReference);
15558 IGCHandleManager* mgr = GCHandleUtilities::GetGCHandleManager();
15559 mgr->StoreObjectInHandle(h, OBJECTREFToObject(src));
15566 // SetValueClass sets a value class for the Right Side, respecting the write barrier for references that are embedded
15567 // within in the value class.
15569 HRESULT Debugger::SetValueClass(void *oldData, void *newData, DebuggerIPCE_BasicTypeData * type)
15581 hr = BasicTypeInfoToTypeHandle(type, &th);
15584 return CORDBG_E_CLASS_NOT_LOADED;
15586 // Update the value class.
15587 CopyValueClassUnchecked(oldData, newData, th.GetMethodTable());
15589 // Free the buffer that is holding the new data. This is a buffer that was created in response to a GET_BUFFER
15590 // message, so we release it with ReleaseRemoteBuffer.
15591 ReleaseRemoteBuffer((BYTE*)newData, true);
15596 /******************************************************************************
15598 ******************************************************************************/
15599 HRESULT Debugger::SetILInstrumentedCodeMap(MethodDesc *fd,
15601 ULONG32 cILMapEntries,
15602 COR_IL_MAP rgILMapEntries[])
15607 GC_TRIGGERS_FROM_GETJITINFO;
15611 if (!HasLazyData())
15613 DebuggerLockHolder dbgLockHolder(this);
15614 // This is an entry path into the debugger, so make sure we're inited.
15618 DebuggerMethodInfo * dmi = GetOrCreateMethodInfo(fd->GetModule(), fd->GetMemberDef());
15621 return E_OUTOFMEMORY;
15624 dmi->SetInstrumentedILMap(rgILMapEntries, cILMapEntries);
15630 // EarlyHelperThreadDeath handles the case where the helper
15631 // thread has been ripped out from underneath of us by
15632 // ExitProcess or TerminateProcess. These calls are bad, whacking
15633 // all threads except the caller in the process. This can happen, for
15634 // instance, when an app calls ExitProcess. All threads are wacked,
15635 // the main thread calls all DLL main's, and the EE starts shutting
15636 // down in its DLL main with the helper thread terminated.
15638 void Debugger::EarlyHelperThreadDeath(void)
15640 WRAPPER_NO_CONTRACT;
15643 m_pRCThread->EarlyHelperThreadDeath();
15647 // This tells the debugger that shutdown of the in-proc debugging services has begun. We need to know this during
15648 // managed/unmanaged debugging so we can stop doing certian things to the process (like hijacking threads.)
15650 void Debugger::ShutdownBegun(void)
15661 // Shouldn't be Debugger-stopped if we're shutting down.
15662 // However, shutdown can occur in preemptive mode. Thus if the RS does an AsyncBreak late
15663 // enough, then the LS will appear to be stopped but may still shutdown.
15664 // Since the debuggee can exit asynchronously at any time (eg, suppose somebody forcefully
15665 // kills it with taskman), this doesn't introduce a new case.
15666 // That aside, it would be great to be able to assert this:
15667 //_ASSERTE(!IsStopped());
15669 if (m_pRCThread != NULL)
15671 DebuggerIPCControlBlock *dcb = m_pRCThread->GetDCB();
15673 if ((dcb != NULL) && (dcb->m_rightSideIsWin32Debugger))
15674 dcb->m_shutdownBegun = true;
15679 * LockDebuggerForShutdown
15681 * This routine is used during shutdown to tell the in-process portion of the
15682 * debugger to synchronize with any threads that are currently using the
15683 * debugging facilities such that no more threads will run debugging services.
15685 * This is accomplished by transitioning the debugger lock in to a state where
15686 * it will block all threads, except for the finalizer, shutdown, and helper thread.
15688 void Debugger::LockDebuggerForShutdown(void)
15690 #ifndef DACCESS_COMPILE
15701 DebuggerLockHolder dbgLockHolder(this);
15703 // Shouldn't be Debugger-stopped if we're shutting down.
15704 // However, shutdown can occur in preemptive mode. Thus if the RS does an AsyncBreak late
15705 // enough, then the LS will appear to be stopped but may still shutdown.
15706 // Since the debuggee can exit asynchronously at any time (eg, suppose somebody forcefully
15707 // kills it with taskman), this doesn't introduce a new case.
15708 // That aside, it would be great to be able to assert this:
15709 //_ASSERTE(!IsStopped());
15711 // After setting this flag, nonspecial threads will not be able to
15712 // take the debugger lock.
15713 m_fShutdownMode = true;
15715 m_ignoreThreadDetach = TRUE;
15725 * This routine is used by the EE to inform the debugger that it should block all
15726 * threads from executing as soon as it can. Any thread entering the debugger can
15727 * block infinitely, as well.
15729 * This is accomplished by transitioning the debugger lock into a mode where it will
15730 * block all threads infinitely rather than taking the lock.
15733 void Debugger::DisableDebugger(void)
15735 #ifndef DACCESS_COMPILE
15742 PRECONDITION(ThisMaybeHelperThread());
15746 m_fDisabled = true;
15748 CORDBDebuggerSetUnrecoverableError(this, CORDBG_E_DEBUGGING_DISABLED, false);
15756 /****************************************************************************
15757 * This will perform the duties of the helper thread if none already exists.
15758 * This is called in the case that the loader lock is held and so no new
15759 * threads can be spun up to be the helper thread, so the existing thread
15760 * must be the helper thread until a new one can spin up.
15761 * This is also called in the shutdown case (g_fProcessDetach==true) and our
15762 * helper may have already been blown away.
15763 ***************************************************************************/
15764 void Debugger::DoHelperThreadDuty()
15770 WRAPPER(GC_TRIGGERS);
15774 // This should not be a real helper thread.
15775 _ASSERTE(!IsDbgHelperSpecialThread());
15776 _ASSERTE(ThreadHoldsLock());
15778 // We may be here in the shutdown case (only if the shutdown started after we got here).
15779 // We'll get killed randomly anyways, so not much we can do.
15781 // These assumptions are based off us being called from TART.
15782 _ASSERTE(ThreadStore::HoldingThreadStore() || g_fProcessDetach); // got this from TART
15783 _ASSERTE(m_trappingRuntimeThreads); // We're only called from TART.
15784 _ASSERTE(!m_stopped); // we haven't sent the sync-complete yet.
15786 // Can't have 2 threads doing helper duty.
15787 _ASSERTE(m_pRCThread->GetDCB()->m_temporaryHelperThreadId == 0);
15789 LOG((LF_CORDB, LL_INFO1000,
15790 "D::SSCIPCE: helper thread is not ready, doing helper "
15791 "thread duty...\n"));
15793 // We're the temporary helper thread now.
15794 DWORD dwMyTID = GetCurrentThreadId();
15795 m_pRCThread->GetDCB()->m_temporaryHelperThreadId = dwMyTID;
15797 // Make sure the helper thread has something to wait on while
15798 // we're trying to be the helper thread.
15799 VERIFY(ResetEvent(m_pRCThread->GetHelperThreadCanGoEvent()));
15801 // We have not sent the sync-complete flare yet.
15803 // Now that we've synchronized, we'll eventually send the sync-complete. But we're currently within the
15804 // scope of sombody already sending an event. So unlock from that event so that we can send the sync-complete.
15805 // Don't release the debugger lock
15807 UnlockFromEventSending(NULL);
15809 // We are the temporary helper thread. We will not deal with everything! But just pump for
15812 m_pRCThread->TemporaryHelperThreadMainLoop();
15814 // We do not need to relock it since we never release it.
15815 LockForEventSending(NULL);
15816 _ASSERTE(ThreadHoldsLock());
15819 STRESS_LOG1(LF_CORDB, LL_INFO1000,
15820 "D::SSCIPCE: done doing helper thread duty. "
15821 "Current helper thread id=0x%x\n",
15822 m_pRCThread->GetDCB()->m_helperThreadId);
15824 // We're not the temporary helper thread anymore.
15825 _ASSERTE(m_pRCThread->GetDCB()->m_temporaryHelperThreadId == dwMyTID);
15826 m_pRCThread->GetDCB()->m_temporaryHelperThreadId = 0;
15828 // Let the helper thread go if its waiting on us.
15829 VERIFY(SetEvent(m_pRCThread->GetHelperThreadCanGoEvent()));
15834 // This function is called from the EE to notify the right side
15835 // whenever the name of a thread or AppDomain changes
15838 // This just sends a ping event to notify that the name has been changed.
15839 // It does not send the actual updated name. Instead, the debugger can query for the name.
15841 // For an AppDomain name change:
15842 // - pAppDoamin != NULL
15843 // - name retrieved via ICorDebugAppDomain::GetName
15845 // For a Thread name change:
15846 // - pAppDomain == NULL, pThread != NULL
15847 // - name retrieved via a func-eval of Thread::get_Name
15848 HRESULT Debugger::NameChangeEvent(AppDomain *pAppDomain, Thread *pThread)
15853 MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
15854 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
15858 // Don't try to send one of these if the thread really isn't setup
15859 // yet. This can happen when initially setting up an app domain,
15860 // before the appdomain create event has been sent. Since the app
15861 // domain create event hasn't been sent yet in this case, its okay
15863 if (g_pEEInterface->GetThread() == NULL)
15866 // Skip if thread doesn't yet have native ID.
15867 // This can easily happen if an app sets Thread.Name before it calls Thread.Start.
15868 // Since this is just a ping-event, it's ignorable. The debugger can query the thread name at Thread.Start in this case.
15869 // This emulates whidbey semantics.
15870 if (pThread != NULL)
15872 if (pThread->GetOSThreadId() == 0)
15878 LOG((LF_CORDB, LL_INFO1000, "D::NCE: Sending NameChangeEvent 0x%x 0x%x\n",
15879 pAppDomain, pThread));
15881 Thread *curThread = g_pEEInterface->GetThread();
15882 SENDIPCEVENT_BEGIN(this, curThread);
15884 if (CORDebuggerAttached())
15887 DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer();
15889 DB_IPCE_NAME_CHANGE,
15891 curThread->GetDomain());
15896 ipce->NameChange.eventType = APP_DOMAIN_NAME_CHANGE;
15897 ipce->NameChange.vmAppDomain.SetRawPtr(pAppDomain);
15902 ipce->NameChange.eventType = THREAD_NAME_CHANGE;
15903 _ASSERTE (pThread);
15904 ipce->NameChange.vmThread.SetRawPtr(pThread);
15907 m_pRCThread->SendIPCEvent();
15909 // Stop all Runtime threads
15910 TrapAllRuntimeThreads();
15914 LOG((LF_CORDB,LL_INFO1000, "D::NCE: Skipping SendIPCEvent because RS detached."));
15923 //---------------------------------------------------------------------------------------
15925 // Send an event to the RS indicating that there's a Ctrl-C or Ctrl-Break.
15928 // dwCtrlType - represents the type of the event (Ctrl-C or Ctrl-Break)
15931 // Return TRUE if the event has been handled by the debugger.
15934 BOOL Debugger::SendCtrlCToDebugger(DWORD dwCtrlType)
15939 MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
15940 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
15944 LOG((LF_CORDB, LL_INFO1000, "D::SCCTD: Sending CtrlC Event 0x%x\n", dwCtrlType));
15946 // Prevent other Runtime threads from handling events.
15947 Thread *pThread = g_pEEInterface->GetThread();
15948 SENDIPCEVENT_BEGIN(this, pThread);
15950 if (CORDebuggerAttached())
15952 DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer();
15954 DB_IPCE_CONTROL_C_EVENT,
15958 // The RS doesn't do anything with dwCtrlType
15959 m_pRCThread->SendIPCEvent();
15961 // Stop all Runtime threads
15962 TrapAllRuntimeThreads();
15966 LOG((LF_CORDB,LL_INFO1000, "D::SCCTD: Skipping SendIPCEvent because RS detached."));
15971 // now wait for notification from the right side about whether or not
15972 // the out-of-proc debugger is handling ControlC events.
15973 ::WaitForSingleObject(GetCtrlCMutex(), INFINITE);
15975 return GetDebuggerHandlingCtrlC();
15978 // Allows the debugger to keep an up to date list of special threads
15979 HRESULT Debugger::UpdateSpecialThreadList(DWORD cThreadArrayLength,
15980 DWORD *rgdwThreadIDArray)
15982 LIMITED_METHOD_CONTRACT;
15984 _ASSERTE(g_pRCThread != NULL);
15986 DebuggerIPCControlBlock *pIPC = g_pRCThread->GetDCB();
15992 // Save the thread list information, and mark the dirty bit so
15993 // the right side knows.
15994 pIPC->m_specialThreadList = rgdwThreadIDArray;
15995 pIPC->m_specialThreadListLength = cThreadArrayLength;
15996 pIPC->m_specialThreadListDirty = true;
16001 // Updates the pointer for the debugger services
16002 void Debugger::SetIDbgThreadControl(IDebuggerThreadControl *pIDbgThreadControl)
16011 if (m_pIDbgThreadControl)
16012 m_pIDbgThreadControl->Release();
16014 m_pIDbgThreadControl = pIDbgThreadControl;
16016 if (m_pIDbgThreadControl)
16017 m_pIDbgThreadControl->AddRef();
16021 // If a thread is Win32 suspended right after hitting a breakpoint instruction, but before the OS has transitioned the
16022 // thread over to the user-level exception dispatching logic, then we may see the IP pointing after the breakpoint
16023 // instruction. There are times when the Runtime will use the IP to try to determine what code as run in the prolog or
16024 // epilog, most notably when unwinding a frame. If the thread is suspended in such a case, then the unwind will believe
16025 // that the instruction that the breakpoint replaced has really been executed, which is not true. This confuses the
16026 // unwinding logic. This function is called from Thread::HandledJITCase() to help us recgonize when this may have
16027 // happened and allow us to skip the unwind and abort the HandledJITCase.
16029 // The criteria is this:
16031 // 1) If a debugger is attached.
16033 // 2) If the instruction before the IP is a breakpoint instruction.
16035 // 3) If the IP is in the prolog or epilog of a managed function.
16037 BOOL Debugger::IsThreadContextInvalid(Thread *pThread)
16047 BOOL invalid = FALSE;
16049 // Get the thread context.
16051 ctx.ContextFlags = CONTEXT_CONTROL;
16052 BOOL success = pThread->GetThreadContext(&ctx);
16056 // Check single-step flag
16057 if (IsSSFlagEnabled(reinterpret_cast<DT_CONTEXT *>(&ctx) ARM_ARG(pThread)))
16059 // Can't hijack a thread whose SS-flag is set. This could lead to races
16060 // with the thread taking the SS-exception.
16061 // The debugger's controller filters will poll for GC to avoid starvation.
16062 STRESS_LOG0(LF_CORDB, LL_EVERYTHING, "HJC - Hardware trace flag applied\n");
16069 #ifdef _TARGET_X86_
16071 LPVOID address = (((BYTE*)GetIP(&ctx)) - 1);
16075 // Use AVInRuntimeImplOkHolder.
16076 AVInRuntimeImplOkayHolder AVOkay;
16078 // Is it a breakpoint?
16079 if (AddressIsBreakpoint((CORDB_ADDRESS_TYPE*)address))
16081 size_t prologSize; // Unused...
16082 if (g_pEEInterface->IsInPrologOrEpilog((BYTE*)GetIP(&ctx), &prologSize))
16084 LOG((LF_CORDB, LL_INFO1000, "D::ITCI: thread is after a BP and in prolog or epilog.\n"));
16091 // If we fault trying to read the byte before EIP, then we know that its not a breakpoint.
16092 // Do nothing. The default return value is FALSE.
16094 EX_END_CATCH(SwallowAllExceptions);
16095 #else // _TARGET_X86_
16096 // Non-x86 can detect whether the thread is suspended after an exception is hit but before
16097 // the kernel has dispatched the exception to user mode by trap frame reporting.
16098 // See Thread::IsContextSafeToRedirect().
16099 #endif // _TARGET_X86_
16103 // If we can't get the context, then its definetly invalid... ;)
16104 LOG((LF_CORDB, LL_INFO1000, "D::ITCI: couldn't get thread's context!\n"));
16112 // notification when a SQL connection begins
16113 void Debugger::CreateConnection(CONNID dwConnectionId, __in_z WCHAR *wzName)
16118 MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
16119 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
16123 LOG((LF_CORDB,LL_INFO1000, "D::CreateConnection %d\n.", dwConnectionId));
16125 if (CORDBUnrecoverableError(this))
16128 Thread *pThread = g_pEEInterface->GetThread();
16129 SENDIPCEVENT_BEGIN(this, pThread);
16131 if (CORDebuggerAttached())
16133 DebuggerIPCEvent* ipce;
16135 // Send a update module syns event to the Right Side.
16136 ipce = m_pRCThread->GetIPCEventSendBuffer();
16137 InitIPCEvent(ipce, DB_IPCE_CREATE_CONNECTION,
16140 ipce->CreateConnection.connectionId = dwConnectionId;
16141 _ASSERTE(wzName != NULL);
16142 ipce->CreateConnection.wzConnectionName.SetString(wzName);
16144 m_pRCThread->SendIPCEvent();
16148 LOG((LF_CORDB,LL_INFO1000, "D::CreateConnection: Skipping SendIPCEvent because RS detached."));
16151 // Stop all Runtime threads if we actually sent an event
16152 if (CORDebuggerAttached())
16154 TrapAllRuntimeThreads();
16160 // notification when a SQL connection ends
16161 void Debugger::DestroyConnection(CONNID dwConnectionId)
16166 MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
16167 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
16171 LOG((LF_CORDB,LL_INFO1000, "D::DestroyConnection %d\n.", dwConnectionId));
16173 if (CORDBUnrecoverableError(this))
16176 Thread *thread = g_pEEInterface->GetThread();
16177 // Note that the debugger lock is reentrant, so we may or may not hold it already.
16178 SENDIPCEVENT_BEGIN(this, thread);
16180 // Send a update module syns event to the Right Side.
16181 DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer();
16182 InitIPCEvent(ipce, DB_IPCE_DESTROY_CONNECTION,
16185 ipce->ConnectionChange.connectionId = dwConnectionId;
16187 // IPC event is now initialized, so we can send it over.
16188 SendSimpleIPCEventAndBlock();
16190 // This will block on the continue
16195 // notification for SQL connection changes
16196 void Debugger::ChangeConnection(CONNID dwConnectionId)
16201 MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
16202 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
16206 LOG((LF_CORDB,LL_INFO1000, "D::ChangeConnection %d\n.", dwConnectionId));
16208 if (CORDBUnrecoverableError(this))
16211 Thread *pThread = g_pEEInterface->GetThread();
16212 SENDIPCEVENT_BEGIN(this, pThread);
16214 if (CORDebuggerAttached())
16216 DebuggerIPCEvent* ipce;
16218 // Send a update module syns event to the Right Side.
16219 ipce = m_pRCThread->GetIPCEventSendBuffer();
16220 InitIPCEvent(ipce, DB_IPCE_CHANGE_CONNECTION,
16223 ipce->ConnectionChange.connectionId = dwConnectionId;
16224 m_pRCThread->SendIPCEvent();
16228 LOG((LF_CORDB,LL_INFO1000, "D::ChangeConnection: Skipping SendIPCEvent because RS detached."));
16231 // Stop all Runtime threads if we actually sent an event
16232 if (CORDebuggerAttached())
16234 TrapAllRuntimeThreads();
16242 // Are we the helper thread?
16243 // Some important things about running on the helper thread:
16244 // - there's only 1, so guaranteed to be thread-safe.
16245 // - we'll never run managed code.
16246 // - therefore, Never GC.
16247 // - It listens for events from the RS.
16248 // - It's the only thread to send a sync complete.
16250 bool ThisIsHelperThreadWorker(void)
16262 pThread = GetThreadNULLOk();
16264 // First check for a real helper thread. This will do a FLS access.
16265 bool fIsHelperThread = !!IsDbgHelperSpecialThread();
16266 if (fIsHelperThread)
16268 // If we're on the real helper thread, we never run managed code
16269 // and so we'd better not have an EE thread object.
16270 _ASSERTE((pThread == NULL) || !"The helper thread should not being running managed code.\n"
16271 "Are you running managed code inside the dllmain? If so, your scenario is invalid and this"
16272 "assert is only the tip of the iceberg.\n");
16276 // Even if we're not on the real helper thread, we may still be on a thread
16277 // pretending to be the helper. (Helper Duty, etc).
16278 DWORD id = GetCurrentThreadId();
16280 // Check for temporary helper thread.
16281 if (ThisIsTempHelperThread(id))
16290 // Make call to the static method.
16291 // This is exposed to the contracts susbsystem so that the helper thread can call
16292 // things on MODE_COOPERATIVE.
16294 bool Debugger::ThisIsHelperThread(void)
16296 WRAPPER_NO_CONTRACT;
16298 return ThisIsHelperThreadWorker();
16301 // Check if we're the temporary helper thread. Have 2 forms of this, 1 that assumes the current
16302 // thread (but has the overhead of an extra call to GetCurrentThreadId() if we laready know the tid.
16303 bool ThisIsTempHelperThread()
16305 WRAPPER_NO_CONTRACT;
16307 DWORD id = GetCurrentThreadId();
16308 return ThisIsTempHelperThread(id);
16311 bool ThisIsTempHelperThread(DWORD tid)
16313 WRAPPER_NO_CONTRACT;
16315 // If helper thread class isn't created, then there's no helper thread.
16316 // No one is doing helper thread duty either.
16317 // It's also possible we're in a shutdown case and have already deleted the
16318 // data for the helper thread.
16319 if (g_pRCThread != NULL)
16321 // May be the temporary helper thread...
16322 DebuggerIPCControlBlock * pBlock = g_pRCThread->GetDCB();
16323 if (pBlock != NULL)
16325 DWORD idTemp = pBlock->m_temporaryHelperThreadId;
16338 // This function is called when host call ICLRSecurityAttributeManager::setDacl.
16339 // It will redacl our SSE, RSEA, RSER events.
16340 HRESULT Debugger::ReDaclEvents(PSECURITY_DESCRIPTOR securityDescriptor)
16342 WRAPPER_NO_CONTRACT;
16344 return m_pRCThread->ReDaclEvents(securityDescriptor);
16348 void Debugger::AcquireDebuggerDataLock(Debugger *pDebugger)
16350 WRAPPER_NO_CONTRACT;
16352 if (!g_fProcessDetach)
16354 pDebugger->GetDebuggerDataLock()->Enter();
16359 void Debugger::ReleaseDebuggerDataLock(Debugger *pDebugger)
16361 WRAPPER_NO_CONTRACT;
16363 if (!g_fProcessDetach)
16365 pDebugger->GetDebuggerDataLock()->Leave();
16370 #else // DACCESS_COMPILE
16372 // determine whether the LS holds the data lock. If it does, we will assume the locked data is in an
16373 // inconsistent state and will throw an exception. The DAC will execute this if we are executing code
16374 // that takes the lock.
16375 // Arguments: input: pDebugger - the LS debugger data structure
16377 void Debugger::AcquireDebuggerDataLock(Debugger *pDebugger)
16381 if (pDebugger->GetDebuggerDataLock()->GetEnterCount() != 0)
16383 ThrowHR(CORDBG_E_PROCESS_NOT_SYNCHRONIZED);
16387 void Debugger::ReleaseDebuggerDataLock(Debugger *pDebugger)
16390 #endif // DACCESS_COMPILE
16392 /* ------------------------------------------------------------------------ *
16393 * Functions for DebuggerHeap executable memory allocations
16394 * ------------------------------------------------------------------------ */
16396 DebuggerHeapExecutableMemoryAllocator::~DebuggerHeapExecutableMemoryAllocator()
16398 while (m_pages != NULL)
16400 DebuggerHeapExecutableMemoryPage *temp = m_pages->GetNextPage();
16403 INDEBUG(BOOL ret =) VirtualFree(m_pages, 0, MEM_RELEASE);
16404 ASSERT(ret == TRUE);
16409 ASSERT(m_pages == NULL);
16412 void* DebuggerHeapExecutableMemoryAllocator::Allocate(DWORD numberOfBytes)
16414 if (numberOfBytes > DBG_MAX_EXECUTABLE_ALLOC_SIZE)
16416 ASSERT(!"Allocating more than DBG_MAX_EXECUTABLE_ALLOC_SIZE at once is unsupported and breaks our assumptions.");
16420 if (numberOfBytes == 0)
16422 // Should we allocate anything in this case?
16423 ASSERT(!"Allocate called with 0 for numberOfBytes!");
16427 CrstHolder execMemAllocCrstHolder(&m_execMemAllocMutex);
16429 int chunkToUse = -1;
16430 DebuggerHeapExecutableMemoryPage *pageToAllocateOn = NULL;
16431 for (DebuggerHeapExecutableMemoryPage *currPage = m_pages; currPage != NULL; currPage = currPage->GetNextPage())
16433 if (CheckPageForAvailability(currPage, &chunkToUse))
16435 pageToAllocateOn = currPage;
16440 if (pageToAllocateOn == NULL)
16442 // No existing page had availability, so create a new page and use that.
16443 pageToAllocateOn = AddNewPage();
16444 if (pageToAllocateOn == NULL)
16446 ASSERT(!"Call to AddNewPage failed!");
16450 if (!CheckPageForAvailability(pageToAllocateOn, &chunkToUse))
16452 ASSERT(!"No availability on new page?");
16457 return ChangePageUsage(pageToAllocateOn, chunkToUse, ChangePageUsageAction::ALLOCATE);
16460 int DebuggerHeapExecutableMemoryAllocator::Free(void* addr)
16462 ASSERT(addr != NULL);
16464 CrstHolder execMemAllocCrstHolder(&m_execMemAllocMutex);
16466 DebuggerHeapExecutableMemoryPage *pageToFreeIn = static_cast<DebuggerHeapExecutableMemoryChunk*>(addr)->data.startOfPage;
16468 if (pageToFreeIn == NULL)
16470 ASSERT(!"Couldn't locate page in which to free!");
16474 int chunkNum = static_cast<DebuggerHeapExecutableMemoryChunk*>(addr)->data.chunkNumber;
16476 // Sanity check: assert that the address really represents the start of a chunk.
16477 ASSERT(((uint64_t)addr - (uint64_t)pageToFreeIn) % 64 == 0);
16479 ChangePageUsage(pageToFreeIn, chunkNum, ChangePageUsageAction::FREE);
16484 DebuggerHeapExecutableMemoryPage* DebuggerHeapExecutableMemoryAllocator::AddNewPage()
16486 void* newPageAddr = VirtualAlloc(NULL, sizeof(DebuggerHeapExecutableMemoryPage), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
16488 DebuggerHeapExecutableMemoryPage *newPage = new (newPageAddr) DebuggerHeapExecutableMemoryPage;
16489 newPage->SetNextPage(m_pages);
16491 // Add the new page to the linked list of pages
16496 bool DebuggerHeapExecutableMemoryAllocator::CheckPageForAvailability(DebuggerHeapExecutableMemoryPage* page, /* _Out_ */ int* chunkToUse)
16498 uint64_t occupancy = page->GetPageOccupancy();
16499 bool available = occupancy != UINT64_MAX;
16513 // Start i at 62 because first chunk is reserved
16514 for (int i = 62; i >= 0; i--)
16516 uint64_t mask = ((uint64_t)1 << i);
16517 if ((mask & occupancy) == 0)
16519 *chunkToUse = 64 - i - 1;
16528 void* DebuggerHeapExecutableMemoryAllocator::ChangePageUsage(DebuggerHeapExecutableMemoryPage* page, int chunkNumber, ChangePageUsageAction action)
16530 ASSERT(action == ChangePageUsageAction::ALLOCATE || action == ChangePageUsageAction::FREE);
16532 uint64_t mask = (uint64_t)0x1 << (64 - chunkNumber - 1);
16534 uint64_t prevOccupancy = page->GetPageOccupancy();
16535 uint64_t newOccupancy = (action == ChangePageUsageAction::ALLOCATE) ? (prevOccupancy | mask) : (prevOccupancy ^ mask);
16536 page->SetPageOccupancy(newOccupancy);
16538 return page->GetPointerToChunk(chunkNumber);
16541 /* ------------------------------------------------------------------------ *
16542 * DebuggerHeap impl
16543 * ------------------------------------------------------------------------ */
16545 DebuggerHeap::DebuggerHeap()
16547 #ifdef USE_INTEROPSAFE_HEAP
16550 m_fExecutable = FALSE;
16553 DebuggerHeap::~DebuggerHeap()
16566 void DebuggerHeap::Destroy()
16568 #ifdef USE_INTEROPSAFE_HEAP
16571 ::HeapDestroy(m_hHeap);
16576 if (m_execMemAllocator != NULL)
16578 delete m_execMemAllocator;
16583 bool DebuggerHeap::IsInit()
16585 LIMITED_METHOD_CONTRACT;
16586 #ifdef USE_INTEROPSAFE_HEAP
16587 return m_hHeap != NULL;
16593 HRESULT DebuggerHeap::Init(BOOL fExecutable)
16603 // Have knob catch if we don't want to lazy init the debugger.
16604 _ASSERTE(!g_DbgShouldntUseDebugger);
16605 m_fExecutable = fExecutable;
16607 #ifdef USE_INTEROPSAFE_HEAP
16608 // If already inited, then we're done.
16609 // We normally don't double-init. However, we may oom between when we allocate the heap and when we do other initialization.
16610 // We don't worry about backout code to free the heap. Rather, we'll just leave it alive and nop if we try to allocate it again.
16616 #ifndef HEAP_CREATE_ENABLE_EXECUTE
16617 #define HEAP_CREATE_ENABLE_EXECUTE 0x00040000 // winnt create heap with executable pages
16620 // Create a standard, grow-able, thread-safe heap.
16621 DWORD dwFlags = ((fExecutable == TRUE)? HEAP_CREATE_ENABLE_EXECUTE : 0);
16622 m_hHeap = ::HeapCreate(dwFlags, 0, 0);
16623 if (m_hHeap == NULL)
16625 return HRESULT_FROM_GetLastError();
16630 m_execMemAllocator = new (nothrow) DebuggerHeapExecutableMemoryAllocator();
16631 ASSERT(m_execMemAllocator != NULL);
16632 if (m_execMemAllocator == NULL)
16634 return E_OUTOFMEMORY;
16641 // Only use canaries on x86 b/c they throw of alignment on Ia64.
16642 #if defined(_DEBUG) && defined(_TARGET_X86_)
16643 #define USE_INTEROPSAFE_CANARY
16646 #ifdef USE_INTEROPSAFE_CANARY
16647 // Small header to to prefix interop-heap blocks.
16648 // This lets us enforce that we don't delete interopheap data from a non-interop heap.
16649 struct InteropHeapCanary
16651 ULONGLONG m_canary;
16653 // Raw address - this is what the heap alloc + free routines use.
16654 // User address - this is what the user sees after we adjust the raw address for the canary
16656 // Given a raw address to an allocated block, get the canary + mark it.
16657 static InteropHeapCanary * GetFromRawAddr(void * pStart)
16659 _ASSERTE(pStart != NULL);
16660 InteropHeapCanary * p = (InteropHeapCanary*) pStart;
16665 // Get the raw address from this canary.
16666 void * GetRawAddr()
16668 return (void*) this;
16671 // Get a canary from a start address.
16672 static InteropHeapCanary * GetFromUserAddr(void * pStart)
16674 _ASSERTE(pStart != NULL);
16675 InteropHeapCanary * p = ((InteropHeapCanary*) pStart)-1;
16679 void * GetUserAddr()
16682 return (void*) (this + 1);
16688 CONSISTENCY_CHECK_MSGF((m_canary == kInteropHeapCookie),
16689 ("Using InteropSafe delete on non-interopsafe allocated memory.\n"));
16693 m_canary = kInteropHeapCookie;
16695 static const ULONGLONG kInteropHeapCookie = 0x12345678;
16697 #endif // USE_INTEROPSAFE_CANARY
16699 void *DebuggerHeap::Alloc(DWORD size)
16709 #ifdef USE_INTEROPSAFE_CANARY
16710 // Make sure we allocate enough space for the canary at the start.
16711 size += sizeof(InteropHeapCanary);
16715 #ifdef USE_INTEROPSAFE_HEAP
16716 _ASSERTE(m_hHeap != NULL);
16717 ret = ::HeapAlloc(m_hHeap, HEAP_ZERO_MEMORY, size);
16718 #else // USE_INTEROPSAFE_HEAP
16720 bool allocateOnHeap = true;
16721 HANDLE hExecutableHeap = NULL;
16726 allocateOnHeap = false;
16727 ret = m_execMemAllocator->Allocate(size);
16731 hExecutableHeap = ClrGetProcessHeap();
16733 #else // FEATURE_PAL
16734 hExecutableHeap = ClrGetProcessExecutableHeap();
16737 if (allocateOnHeap)
16739 if (hExecutableHeap == NULL)
16744 ret = ClrHeapAlloc(hExecutableHeap, NULL, S_SIZE_T(size));
16747 #endif // USE_INTEROPSAFE_HEAP
16749 #ifdef USE_INTEROPSAFE_CANARY
16754 InteropHeapCanary * pCanary = InteropHeapCanary::GetFromRawAddr(ret);
16755 ret = pCanary->GetUserAddr();
16762 // If this fails, the original memory is still valid.
16763 void *DebuggerHeap::Realloc(void *pMem, DWORD newSize, DWORD oldSize)
16773 _ASSERTE(pMem != NULL);
16774 _ASSERTE(newSize != 0);
16775 _ASSERTE(oldSize != 0);
16777 #if defined(USE_INTEROPSAFE_HEAP) && !defined(USE_INTEROPSAFE_CANARY) && !defined(FEATURE_PAL)
16778 // No canaries in this case.
16779 // Call into realloc.
16782 _ASSERTE(m_hHeap != NULL);
16783 ret = ::HeapReAlloc(m_hHeap, HEAP_ZERO_MEMORY, pMem, newSize);
16785 // impl Realloc on top of alloc & free.
16788 ret = this->Alloc(newSize);
16791 // Not supposed to free original memory in failure condition.
16795 memcpy(ret, pMem, oldSize);
16802 void DebuggerHeap::Free(void *pMem)
16812 #ifdef USE_INTEROPSAFE_CANARY
16813 // Check for canary
16817 InteropHeapCanary * pCanary = InteropHeapCanary::GetFromUserAddr(pMem);
16818 pMem = pCanary->GetRawAddr();
16822 #ifdef USE_INTEROPSAFE_HEAP
16825 _ASSERTE(m_hHeap != NULL);
16826 ::HeapFree(m_hHeap, 0, pMem);
16831 #ifndef FEATURE_PAL
16832 HANDLE hProcessExecutableHeap = ClrGetProcessExecutableHeap();
16833 _ASSERTE(hProcessExecutableHeap != NULL);
16834 ClrHeapFree(hProcessExecutableHeap, NULL, pMem);
16835 #else // !FEATURE_PAL
16838 HANDLE hProcessHeap = ClrGetProcessHeap();
16839 _ASSERTE(hProcessHeap != NULL);
16840 ClrHeapFree(hProcessHeap, NULL, pMem);
16844 INDEBUG(int ret =) m_execMemAllocator->Free(pMem);
16845 _ASSERTE(ret == 0);
16847 #endif // !FEATURE_PAL
16852 #ifndef DACCESS_COMPILE
16855 // Undef this so we can call them from the EE versions.
16856 #undef UtilMessageBoxVA
16858 // Message box API for the left side of the debugger. This API handles calls from the
16859 // debugger helper thread as well as from normal EE threads. It is the only one that
16860 // should be used from inside the debugger left side.
16861 int Debugger::MessageBox(
16862 UINT uText, // Resource Identifier for Text message
16863 UINT uCaption, // Resource Identifier for Caption
16864 UINT uType, // Style of MessageBox
16865 BOOL displayForNonInteractive, // Display even if the process is running non interactive
16866 BOOL showFileNameInTitle, // Flag to show FileName in Caption
16867 ...) // Additional Arguments
16871 MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
16875 PRECONDITION(ThisMaybeHelperThread());
16880 va_start(marker, showFileNameInTitle);
16882 // Add the MB_TASKMODAL style to indicate that the dialog should be displayed on top of the windows
16883 // owned by the current thread and should prevent interaction with them until dismissed.
16884 uType |= MB_TASKMODAL;
16886 int result = UtilMessageBoxVA(NULL, uText, uCaption, uType, displayForNonInteractive, showFileNameInTitle, marker);
16892 // Redefine this to an error just in case code is added after this point in the file.
16893 #define UtilMessageBoxVA __error("Use g_pDebugger->MessageBox from inside the left side of the debugger")
16895 #else // DACCESS_COMPILE
16897 Debugger::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
16901 _ASSERTE(m_rgHijackFunction != NULL);
16903 if ( flags != CLRDATA_ENUM_MEM_TRIAGE)
16905 if (m_pMethodInfos.IsValid())
16907 m_pMethodInfos->EnumMemoryRegions(flags);
16910 DacEnumMemoryRegion(dac_cast<TADDR>(m_pLazyData),
16911 sizeof(DebuggerLazyInit));
16914 // Needed for stack walking from an initial native context. If the debugger can find the
16915 // on-disk image of clr.dll, then this is not necessary.
16916 DacEnumMemoryRegion(dac_cast<TADDR>(m_rgHijackFunction), sizeof(MemoryRange)*kMaxHijackFunctions);
16920 // This code doesn't hang out in Frame/TransitionFrame/FuncEvalFrame::EnumMemoryRegions() like it would
16921 // for other normal VM objects because we don't want to have code in VM directly referencing LS types.
16922 // Frames.h's FuncEvalFrame simply does a forward decl of DebuggerEval and gets away with it because it
16923 // never does anything but a cast of a TADDR.
16925 Debugger::EnumMemoryRegionsIfFuncEvalFrame(CLRDataEnumMemoryFlags flags, Frame * pFrame)
16929 if ((pFrame != NULL) && (pFrame->GetFrameType() == Frame::TYPE_FUNC_EVAL))
16931 FuncEvalFrame * pFEF = dac_cast<PTR_FuncEvalFrame>(pFrame);
16932 DebuggerEval * pDE = pFEF->GetDebuggerEval();
16936 DacEnumMemoryRegion(dac_cast<TADDR>(pDE), sizeof(DebuggerEval), true);
16938 if (pDE->m_debuggerModule != NULL)
16939 DacEnumMemoryRegion(dac_cast<TADDR>(pDE->m_debuggerModule), sizeof(DebuggerModule), true);
16944 #endif // #ifdef DACCESS_COMPILE
16946 #ifndef DACCESS_COMPILE
16947 void Debugger::StartCanaryThread()
16949 // we need to already have the rcthread running and the pointer stored
16950 _ASSERTE(m_pRCThread != NULL && g_pRCThread == m_pRCThread);
16951 _ASSERTE(m_pRCThread->GetDCB() != NULL);
16952 _ASSERTE(GetCanary() != NULL);
16954 GetCanary()->Init();
16956 #endif // DACCESS_COMPILE
16958 #endif //DEBUGGING_SUPPORTED