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 //*****************************************************************************
8 // Random RS utility stuff, plus root ICorCordbug implementation
10 //*****************************************************************************
12 #include "primitives.h"
20 #ifndef SM_REMOTESESSION
21 #define SM_REMOTESESSION 0x1000
25 #include "../../dlls/mscorrc/resource.h"
29 // The top level Cordb object is built around the Shim
32 //-----------------------------------------------------------------------------
33 // For debugging ease, cache some global values.
34 // Include these in retail & free because that's where we need them the most!!
35 // Optimized builds may not let us view locals & parameters. So Having these
36 // cached as global values should let us inspect almost all of
37 // the interesting parts of the RS even in a Retail build!
38 //-----------------------------------------------------------------------------
40 RSDebuggingInfo g_RSDebuggingInfo_OutOfProc = {0 }; // set to NULL
41 RSDebuggingInfo * g_pRSDebuggingInfo = &g_RSDebuggingInfo_OutOfProc;
43 // The following instances are used for invoking overloaded new/delete
47 // For logs, we can print the string name for the debug codes.
48 const char * GetDebugCodeName(DWORD dwCode)
50 if (dwCode < 1 || dwCode > 9)
52 return "!Invalid Debug Event Code!";
55 static const char * const szNames[] = {
56 "(1) EXCEPTION_DEBUG_EVENT",
57 "(2) CREATE_THREAD_DEBUG_EVENT",
58 "(3) CREATE_PROCESS_DEBUG_EVENT",
59 "(4) EXIT_THREAD_DEBUG_EVENT",
60 "(5) EXIT_PROCESS_DEBUG_EVENT",
61 "(6) LOAD_DLL_DEBUG_EVENT",
62 "(7) UNLOAD_DLL_DEBUG_EVENT",
63 "(8) OUTPUT_DEBUG_STRING_EVENT"
64 "(9) RIP_EVENT",// <-- only on Win9X
67 return szNames[dwCode - 1];
73 //-----------------------------------------------------------------------------
74 // Per-thread state for Debug builds...
75 //-----------------------------------------------------------------------------
77 DWORD DbgRSThread::s_TlsSlot = TLS_OUT_OF_INDEXES;
78 LONG DbgRSThread::s_Total = 0;
80 DbgRSThread::DbgRSThread()
83 m_fIsInCallback = false;
84 m_fIsUnrecoverableErrorCallback = false;
86 m_cTotalDbgApiLocks = 0;
87 for(int i = 0; i < RSLock::LL_MAX; i++)
92 // Initialize Identity info
93 m_Cookie = COOKIE_VALUE;
94 m_tid = GetCurrentThreadId();
97 // NotifyTakeLock & NotifyReleaseLock are called by RSLock to update the per-thread locking context.
98 // This will assert if the operation is unsafe (ie, violates lock order).
99 void DbgRSThread::NotifyTakeLock(RSLock * pLock)
101 if (pLock->HasLock())
106 int iLevel = pLock->GetLevel();
108 // Is it safe to take this lock?
109 // Must take "bigger" locks first. We shouldn't hold any locks at our current level either.
110 // If this lock is re-entrant and we're double-taking it, we would have returned already.
111 // And the locking model on the RS forbids taking multiple locks at the same level.
112 for(int i = iLevel; i >= 0; i --)
114 bool fHasLowerLock = m_cLocks[i] > 0;
115 CONSISTENCY_CHECK_MSGF(!fHasLowerLock, (
116 "RSLock violation. Trying to take lock '%s (%d)', but already have smaller lock at level %d'\n",
117 pLock->Name(), iLevel,
122 _ASSERTE(m_cLocks[iLevel] == 0);
125 if (pLock->IsDbgApiLock())
126 m_cTotalDbgApiLocks++;
129 void DbgRSThread::NotifyReleaseLock(RSLock * pLock)
131 if (pLock->HasLock())
136 int iLevel = pLock->GetLevel();
138 _ASSERTE(m_cLocks[iLevel] == 0);
140 if (pLock->IsDbgApiLock())
141 m_cTotalDbgApiLocks--;
143 _ASSERTE(m_cTotalDbgApiLocks >= 0);
146 void DbgRSThread::TakeVirtualLock(RSLock::ERSLockLevel level)
151 void DbgRSThread::ReleaseVirtualLock(RSLock::ERSLockLevel level)
154 _ASSERTE(m_cLocks[level] >= 0);
158 // Get a DbgRSThread for the current OS thread id; lazily create if needed.
159 DbgRSThread * DbgRSThread::GetThread()
161 _ASSERTE(DbgRSThread::s_TlsSlot != TLS_OUT_OF_INDEXES);
163 void * p2 = TlsGetValue(DbgRSThread::s_TlsSlot);
166 // We lazily create for threads that haven't gone through DllMain
167 // Since this is per-thread, we don't need to lock.
168 p2 = DbgRSThread::Create();
170 DbgRSThread * p = reinterpret_cast<DbgRSThread*> (p2);
172 _ASSERTE(p->m_Cookie == COOKIE_VALUE);
179 #endif // RSCONTRACTS
187 LONG CordbCommonBase::s_TotalObjectCount = 0;
188 LONG CordbCommonBase::s_CordbObjectUID = 0;
191 LONG CordbCommonBase::m_saDwInstance[enumMaxDerived];
192 LONG CordbCommonBase::m_saDwAlive[enumMaxDerived];
193 PVOID CordbCommonBase::m_sdThis[enumMaxDerived][enumMaxThis];
199 LONG Cordb::s_DbgMemTotalOutstandingCordb = 0;
200 LONG Cordb::s_DbgMemTotalOutstandingInternalRefs = 0;
203 #ifdef TRACK_OUTSTANDING_OBJECTS
204 void *Cordb::s_DbgMemOutstandingObjects[MAX_TRACKED_OUTSTANDING_OBJECTS] = { NULL };
205 LONG Cordb::s_DbgMemOutstandingObjectMax = 0;
208 // Default implementation for neutering left-side resources.
209 void CordbBase::NeuterLeftSideResources()
211 LIMITED_METHOD_CONTRACT;
213 RSLockHolder lockHolder(GetProcess()->GetProcessLock());
217 // Default implementation for neutering.
218 // All derived objects should eventually chain to this.
219 void CordbBase::Neuter()
221 // Neutering occurs under the process lock. Neuter can be called twice
222 // and so locking protects against races in double-delete.
223 // @dbgtodo - , some CordbBase objects (Cordb, CordbProcessEnum),
224 // don't have process affinity these should eventually be hoisted to the shim,
225 // and then we can enforce.
226 CordbProcess * pProcess = GetProcess();
227 if (pProcess != NULL)
229 _ASSERTE(pProcess->ThreadHoldsProcessLock());
231 CordbCommonBase::Neuter();
234 //-----------------------------------------------------------------------------
236 //-----------------------------------------------------------------------------
238 NeuterList::NeuterList()
243 NeuterList::~NeuterList()
245 // Our owner should have neutered us before deleting us.
246 // Thus we should be empty.
247 CONSISTENCY_CHECK_MSGF(m_pHead == NULL, ("NeuterList not empty on shutdown. this=0x%p", this));
250 // Wrapper around code:NeuterList::UnsafeAdd
251 void NeuterList::Add(CordbProcess * pProcess, CordbBase * pObject)
259 UnsafeAdd(pProcess, pObject);
263 // Add an object to be neutered.
266 // pProcess - process that holds lock that will protect the neuter list
267 // pObject - object to add
273 // This will add it to the list and maintain an internal reference to it.
274 // This will take the process lock.
276 void NeuterList::UnsafeAdd(CordbProcess * pProcess, CordbBase * pObject)
278 _ASSERTE(pObject != NULL);
281 RSLock * pLock = (pProcess != NULL) ? pProcess->GetProcessLock() : NULL;
282 RSLockHolder lockHolder(pLock, FALSE);
283 if (pLock != NULL) lockHolder.Acquire();
286 Node * pNode = new Node(); // throws on error.
287 pNode->m_pObject.Assign(pObject);
288 pNode->m_pNext = m_pHead;
293 // Neuter everything on the list and clear it
296 // pProcess - process tree that this neuterlist belongs in
297 // ticket - neuter ticket proving caller ensured we're safe to neuter.
300 // Caller ensures we're safe to neuter (required to obtain NeuterTicket)
303 // This will release all internal references and empty the list.
304 void NeuterList::NeuterAndClear(CordbProcess * pProcess)
306 RSLock * pLock = (pProcess != NULL) ? pProcess->GetProcessLock() : NULL;
307 (void)pLock; //prevent "unused variable" error from GCC
308 _ASSERTE((pLock == NULL) || pLock->HasLock());
310 while (m_pHead != NULL)
312 Node * pTemp = m_pHead;
313 m_pHead = m_pHead->m_pNext;
315 pTemp->m_pObject->Neuter();
316 delete pTemp; // will implicitly release
320 // Only neuter objects that are marked.
321 // Removes neutered objects from the list.
322 void NeuterList::SweepAllNeuterAtWillObjects(CordbProcess * pProcess)
324 _ASSERTE(pProcess != NULL);
325 RSLock * pLock = pProcess->GetProcessLock();
326 RSLockHolder lockHolder(pLock);
328 Node ** ppLast = &m_pHead;
329 Node * pCur = m_pHead;
333 CordbBase * pObject = pCur->m_pObject;
334 if (pObject->IsNeuterAtWill() || pObject->IsNeutered())
339 Node * pNext = pCur->m_pNext;
340 delete pCur; // dtor will implicitly release the internal ref to pObject
341 pCur = *ppLast = pNext;
346 ppLast = &pCur->m_pNext;
347 pCur = pCur->m_pNext;
352 //-----------------------------------------------------------------------------
353 // Neuters all objects in the list and empties the list.
356 // See also code:LeftSideResourceCleanupList::SweepNeuterLeftSideResources,
357 // which only neuters objects that have been marked as NeuterAtWill (external
358 // ref count has gone to 0).
359 void LeftSideResourceCleanupList::NeuterLeftSideResourcesAndClear(CordbProcess * pProcess)
361 // Traversal protected under Process-lock.
362 // SG-lock must already be held to do neutering.
363 // Stop-Go lock is bigger than Process-lock.
364 // Neutering requires the Stop-Go lock (until we get rid of IPC events)
365 // But we want to be able to add to the Neuter list under the Process-lock.
366 // So we just need to protected m_pHead under process-lock.
368 // "Privatize" the list under the lock.
369 _ASSERTE(pProcess != NULL);
370 RSLock * pLock = pProcess->GetProcessLock();
374 RSLockHolder lockHolder(pLock); // only acquire lock if we have one
379 // @dbgtodo - eventually everything can be under the process lock.
380 _ASSERTE(!pLock->HasLock()); // Can't hold Process lock while calling NeuterLeftSideResources
382 // Now we're operating on local data, so traversing doesn't need to be under the lock.
386 pCur = pCur->m_pNext;
388 pTemp->m_pObject->NeuterLeftSideResources();
389 delete pTemp; // will implicitly release
394 //-----------------------------------------------------------------------------
395 // Only neuter objects that are marked. Removes neutered objects from the list.
398 // pProcess - non-null process owning the objects in the list
401 // this cleans up left-side resources held by objects in the list.
402 // It may send IPC events to do this.
403 void LeftSideResourceCleanupList::SweepNeuterLeftSideResources(CordbProcess * pProcess)
405 _ASSERTE(pProcess != NULL);
407 // Must be safe to send IPC events.
408 _ASSERTE(pProcess->GetStopGoLock()->HasLock()); // holds this for neutering
409 _ASSERTE(pProcess->GetSynchronized());
411 RSLock * pLock = pProcess->GetProcessLock();
413 // Lock while we "privatize" the head.
414 RSLockHolder lockHolder(pLock);
415 Node * pHead = m_pHead;
417 lockHolder.Release();
419 Node ** ppLast = &pHead;
422 // Can't hold the process-lock while calling Neuter.
425 CordbBase * pObject = pCur->m_pObject;
426 if (pObject->IsNeuterAtWill() || pObject->IsNeutered())
428 // HeavyNueter can not be done under the process-lock because
429 // it may take the Stop-Go lock and send events.
430 pObject->NeuterLeftSideResources();
433 Node * pNext = pCur->m_pNext;
434 delete pCur; // dtor will implicitly release the internal ref to pObject
435 pCur = *ppLast = pNext;
440 ppLast = &pCur->m_pNext;
441 pCur = pCur->m_pNext;
445 // Now link back in. m_pHead may have changed while we were unlocked.
446 // The list does not need to be ordered.
448 lockHolder.Acquire();
455 /* ------------------------------------------------------------------------- *
457 * ------------------------------------------------------------------------- */
459 // Do any initialization necessary for both CorPublish and CorDebug
460 // This includes enabling logging and adding the SEDebug priv.
461 void CordbCommonBase::InitializeCommon()
463 static bool IsInitialized = false;
471 bool fStressLog = false;
474 // default for stress log is on debug build
478 // StressLog will turn on stress logging for the entire runtime.
479 // RSStressLog is only used here and only effects just the RS.
481 (REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_StressLog, fStressLog) != 0) ||
482 (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_RSStressLog) != 0);
484 if (fStressLog == true)
486 unsigned facilities = REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::INTERNAL_LogFacility, LF_ALL);
487 unsigned level = REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::EXTERNAL_LogLevel, LL_INFO1000);
488 unsigned bytesPerThread = REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_StressLogSize, STRESSLOG_CHUNK_SIZE * 2);
489 unsigned totalBytes = REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_TotalStressLogSize, STRESSLOG_CHUNK_SIZE * 1024);
491 StressLog::Initialize(facilities, level, bytesPerThread, totalBytes, GetModuleInst());
493 StressLog::Initialize(facilities, level, bytesPerThread, totalBytes, NULL);
504 // Add debug privilege. This will let us call OpenProcess() on anything, regardless of ACL.
507 IsInitialized = true;
510 // Adjust the permissions of this process to ensure that we have
511 // the debugging priviledge. If we can't make the adjustment, it
512 // only means that we won't be able to attach to a service under
513 // NT, so we won't treat that as a critical failure.
514 // This also will let us call OpenProcess() on anything, regardless of DACL. This allows an
515 // Admin debugger to attach to a debuggee in the guest account.
516 // Ideally, the debugger would set this (and we wouldn't mess with privileges at all). However, we've been
517 // setting this since V1.0 and removing it may be a breaking change.
518 void CordbCommonBase::AddDebugPrivilege()
522 TOKEN_PRIVILEGES Privileges;
525 LUID SeDebugLuid = {0, 0};
527 fSucc = LookupPrivilegeValueW(NULL, SE_DEBUG_NAME, &SeDebugLuid);
528 DWORD err = GetLastError();
532 STRESS_LOG1(LF_CORDB, LL_INFO1000, "Unable to adjust permissions of this process to include SE_DEBUG. Lookup failed %d\n", err);
537 // Retrieve a handle of the access token
538 fSucc = OpenProcessToken(GetCurrentProcess(),
539 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
544 Privileges.PrivilegeCount = 1;
545 Privileges.Privileges[0].Luid = SeDebugLuid;
546 Privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
548 AdjustTokenPrivileges(hToken,
551 sizeof(TOKEN_PRIVILEGES),
552 (PTOKEN_PRIVILEGES) NULL,
554 err = GetLastError();
555 // The return value of AdjustTokenPrivileges cannot be tested.
556 if (err != ERROR_SUCCESS)
558 STRESS_LOG1(LF_CORDB, LL_INFO1000,
559 "Unable to adjust permissions of this process to include SE_DEBUG. Adjust failed %d\n", err);
563 LOG((LF_CORDB, LL_INFO1000, "Adjusted process permissions to include SE_DEBUG.\n"));
575 // DefaultManagedCallback2
577 // In the event that the debugger is of an older version than the Right Side & Left Side, the Right Side may issue
578 // new callbacks that the debugger is not expecting. In this case, we need to provide a default behavior for those
579 // new callbacks, if for nothing else than to force the debugger to Continue().
581 class DefaultManagedCallback2 : public ICorDebugManagedCallback2
584 DefaultManagedCallback2(ICorDebug* pDebug);
585 virtual ~DefaultManagedCallback2() { }
586 virtual HRESULT __stdcall QueryInterface(REFIID iid, void** pInterface);
587 virtual ULONG __stdcall AddRef();
588 virtual ULONG __stdcall Release();
589 COM_METHOD FunctionRemapOpportunity(ICorDebugAppDomain* pAppDomain,
590 ICorDebugThread* pThread,
591 ICorDebugFunction* pOldFunction,
592 ICorDebugFunction* pNewFunction,
593 ULONG32 oldILOffset);
594 COM_METHOD FunctionRemapComplete(ICorDebugAppDomain *pAppDomain,
595 ICorDebugThread *pThread,
596 ICorDebugFunction *pFunction);
598 COM_METHOD CreateConnection(ICorDebugProcess *pProcess,
599 CONNID dwConnectionId,
600 __in_z WCHAR* pConnectionName);
601 COM_METHOD ChangeConnection(ICorDebugProcess *pProcess, CONNID dwConnectionId);
602 COM_METHOD DestroyConnection(ICorDebugProcess *pProcess, CONNID dwConnectionId);
604 COM_METHOD Exception(ICorDebugAppDomain *pAddDomain,
605 ICorDebugThread *pThread,
606 ICorDebugFrame *pFrame,
608 CorDebugExceptionCallbackType eventType,
611 COM_METHOD ExceptionUnwind(ICorDebugAppDomain *pAddDomain,
612 ICorDebugThread *pThread,
613 CorDebugExceptionUnwindCallbackType eventType,
615 COM_METHOD MDANotification(
616 ICorDebugController * pController,
617 ICorDebugThread *pThread,
619 ) { return E_NOTIMPL; }
623 DefaultManagedCallback2(const DefaultManagedCallback2&);
624 DefaultManagedCallback2& operator=(const DefaultManagedCallback2&);
633 DefaultManagedCallback2::DefaultManagedCallback2(ICorDebug* pDebug) : m_pDebug(pDebug), m_refCount(0)
638 DefaultManagedCallback2::QueryInterface(REFIID iid, void** pInterface)
640 if (IID_ICorDebugManagedCallback2 == iid)
642 *pInterface = static_cast<ICorDebugManagedCallback2*>(this);
644 else if (IID_IUnknown == iid)
646 *pInterface = static_cast<IUnknown*>(this);
651 return E_NOINTERFACE;
659 DefaultManagedCallback2::AddRef()
661 return InterlockedIncrement(&m_refCount);
665 DefaultManagedCallback2::Release()
667 ULONG ulRef = InterlockedDecrement(&m_refCount);
677 DefaultManagedCallback2::FunctionRemapOpportunity(ICorDebugAppDomain* pAppDomain,
678 ICorDebugThread* pThread,
679 ICorDebugFunction* pOldFunction,
680 ICorDebugFunction* pNewFunction,
685 // In theory, this function should never be reached. To get here, we'd have to have a debugger which doesn't
686 // support edit and continue somehow turn on edit & continue features.
688 _ASSERTE(!"Edit & Continue callback reached when debugger doesn't support Edit And Continue");
691 // If you ignore this assertion, or you're in a retail build, there are two options as far as how to proceed
693 // o We can do nothing, and let the debugee process hang, or
694 // o We can silently ignore the FunctionRemapOpportunity, and tell the debugee to Continue running.
696 // For now, we'll silently ignore the function remapping.
697 pAppDomain->Continue(false);
698 pAppDomain->Release();
705 DefaultManagedCallback2::FunctionRemapComplete(ICorDebugAppDomain *pAppDomain,
706 ICorDebugThread *pThread,
707 ICorDebugFunction *pFunction)
710 // In theory, this function should never be reached. To get here, we'd have to have a debugger which doesn't
711 // support edit and continue somehow turn on edit & continue features.
713 _ASSERTE(!"Edit & Continue callback reached when debugger doesn't support Edit And Continue");
719 // These methods are current left unimplemented.
721 // Create/Change/Destroy Connection *should* force the Process/AppDomain/Thread to Continue(). Currently the
722 // arguments to these functions don't provide the relevant Process/AppDomain/Thread, so there is no way to figure
723 // out which Threads should be forced to Continue().
728 DefaultManagedCallback2::CreateConnection(ICorDebugProcess *pProcess,
729 CONNID dwConnectionId,
730 __in_z WCHAR* pConnectionName)
732 _ASSERTE(!"DefaultManagedCallback2::CreateConnection not implemented");
737 DefaultManagedCallback2::ChangeConnection(ICorDebugProcess *pProcess, CONNID dwConnectionId)
739 _ASSERTE(!"DefaultManagedCallback2::ChangeConnection not implemented");
744 DefaultManagedCallback2::DestroyConnection(ICorDebugProcess *pProcess, CONNID dwConnectionId)
746 _ASSERTE(!"DefaultManagedCallback2::DestroyConnection not implemented");
751 DefaultManagedCallback2::Exception(ICorDebugAppDomain *pAppDomain,
752 ICorDebugThread *pThread,
753 ICorDebugFrame *pFrame,
755 CorDebugExceptionCallbackType eventType,
759 // Just ignore and continue the process.
761 pAppDomain->Continue(false);
766 DefaultManagedCallback2::ExceptionUnwind(ICorDebugAppDomain *pAppDomain,
767 ICorDebugThread *pThread,
768 CorDebugExceptionUnwindCallbackType eventType,
772 // Just ignore and continue the process.
774 pAppDomain->Continue(false);
779 // DefaultManagedCallback3
781 // In the event that the debugger is of an older version than the Right Side & Left Side, the Right Side may issue
782 // new callbacks that the debugger is not expecting. In this case, we need to provide a default behavior for those
783 // new callbacks, if for nothing else than to force the debugger to Continue().
785 class DefaultManagedCallback3 : public ICorDebugManagedCallback3
788 DefaultManagedCallback3(ICorDebug* pDebug);
789 virtual ~DefaultManagedCallback3() { }
790 virtual HRESULT __stdcall QueryInterface(REFIID iid, void** pInterface);
791 virtual ULONG __stdcall AddRef();
792 virtual ULONG __stdcall Release();
793 COM_METHOD CustomNotification(ICorDebugThread * pThread, ICorDebugAppDomain * pAppDomain);
796 DefaultManagedCallback3(const DefaultManagedCallback3&);
797 DefaultManagedCallback3& operator=(const DefaultManagedCallback3&);
803 DefaultManagedCallback3::DefaultManagedCallback3(ICorDebug* pDebug) : m_pDebug(pDebug), m_refCount(0)
808 DefaultManagedCallback3::QueryInterface(REFIID iid, void** pInterface)
810 if (IID_ICorDebugManagedCallback3 == iid)
812 *pInterface = static_cast<ICorDebugManagedCallback3*>(this);
814 else if (IID_IUnknown == iid)
816 *pInterface = static_cast<IUnknown*>(this);
821 return E_NOINTERFACE;
829 DefaultManagedCallback3::AddRef()
831 return InterlockedIncrement(&m_refCount);
835 DefaultManagedCallback3::Release()
837 ULONG ulRef = InterlockedDecrement(&m_refCount);
847 DefaultManagedCallback3::CustomNotification(ICorDebugThread * pThread, ICorDebugAppDomain * pAppDomain)
850 // Just ignore and continue the process.
852 pAppDomain->Continue(false);
857 /* ------------------------------------------------------------------------- *
859 * ------------------------------------------------------------------------- */
862 Cordb::Cordb(CorDebugInterfaceVersion iDebuggerVersion)
863 : CordbBase(NULL, 0, enumCordb),
865 m_initialized(false),
866 m_debuggerSpecifiedVersion(iDebuggerVersion)
870 g_pRSDebuggingInfo->m_Cordb = this;
873 // Memory leak detection
874 InterlockedIncrement(&s_DbgMemTotalOutstandingCordb);
880 LOG((LF_CORDB, LL_INFO10, "C::~C Terminating Cordb object.\n"));
881 g_pRSDebuggingInfo->m_Cordb = NULL;
886 if (this->IsNeutered())
892 RSLockHolder lockHolder(&m_processListMutex);
893 m_pProcessEnumList.NeuterAndClear(NULL);
897 EX_TRY // @dbgtodo push this up.
899 // Iterating needs to be done under the processList lock (small), while neutering
900 // needs to be able to take the process lock (big).
901 RSPtrArray<CordbProcess> list;
902 m_processes.TransferToArray(&list); // throws
904 // can't hold list lock while calling CordbProcess::Neuter (which
905 // will take the Process-lock).
906 lockHolder.Release();
908 list.NeuterAndClear();
909 // List dtor calls release on each element
911 EX_CATCH_HRESULT(hr);
912 SIMPLIFYING_ASSUMPTION_SUCCEEDED(hr);
914 CordbCommonBase::Neuter();
916 // Implicit release from smart ptr.
922 // Memory leak detection.
923 LONG l = InterlockedDecrement(&Cordb::s_DbgMemTotalOutstandingCordb);
926 // If we just released our final Cordb root object, then we expect no internal references at all.
927 // Note that there may still be external references (and thus not all objects may have been
929 bool fLeakedInternal = (Cordb::s_DbgMemTotalOutstandingInternalRefs > 0);
931 // Some Cordb objects (such as CordbValues) may not be rooted, and thus we can't neuter
932 // them and thus an external ref may keep them alive. Since these objects may have internal refs,
933 // This means that external refs can keep internal refs.
934 // Thus this assert must be tempered if unrooted objects are leaked. (But that means we can always
935 // assert the tempered version; regardless of bugs in Cordbg).
936 CONSISTENCY_CHECK_MSGF(!fLeakedInternal,
937 ("'%d' Outstanding internal references at final Cordb::Terminate\n",
938 Cordb::s_DbgMemTotalOutstandingInternalRefs));
940 DWORD dLeakCheck = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DbgLeakCheck);
943 // We have 1 ref for this Cordb root object. All other refs should have been deleted.
944 CONSISTENCY_CHECK_MSGF(Cordb::s_TotalObjectCount == 1, ("'%d' total cordbBase objects are leaked.\n",
945 Cordb::s_TotalObjectCount-1));
951 // This shuts down ICorDebug.
952 // All CordbProcess objects owned by this Cordb object must have either:
953 // - returned for a Detach() call
954 // - returned from dispatching the ExitProcess() callback.
955 // In both cases, CordbProcess::NeuterChildren has been called, although the Process object itself
956 // may not yet be neutered. This condition will ensure that the CordbProcess objects don't need
957 // any resources that we're about to release.
958 HRESULT Cordb::Terminate()
960 LOG((LF_CORDB, LL_INFO10000, "[%x] Terminating Cordb\n", GetCurrentThreadId()));
965 FAIL_IF_NEUTERED(this);
967 // We can't terminate the debugging services from within a callback.
968 // Caller is supposed to be out of all callbacks when they call this.
969 // This also avoids a deadlock because we'll shutdown the RCET, which would block if we're
971 if (m_rcEventThread->IsRCEventThread())
973 STRESS_LOG0(LF_CORDB, LL_INFO10, "C::T: failed on RCET\n");
974 _ASSERTE(!"Gross API Misuse: Debugger shouldn't call ICorDebug::Terminate from within a managed callback.");
975 return CORDBG_E_CANT_CALL_ON_THIS_THREAD;
978 // @todo - do we need to throw some switch to prevent new processes from being added now?
980 // VS must stop all debugging before terminating. Fail if we have any non-neutered processes
981 // (b/c those processes should have been either shutdown or detached).
982 // We are in an undefined state if this check fails.
983 // Process are removed from this list before Process::Detach() returns and before the ExitProcess callback is dispatched.
984 // Thus any processes in this list should be live or have an unrecoverable error.
986 RSLockHolder ch(&m_processListMutex);
989 CordbProcess * pProcess;
991 for (pProcess= (CordbProcess*) m_processes.FindFirst(&hfDT);
993 pProcess = (CordbProcess*) m_processes.FindNext(&hfDT))
995 _ASSERTE(pProcess->IsSafeToSendEvents() || pProcess->m_unrecoverableError);
996 if (pProcess->IsSafeToSendEvents() && !pProcess->m_unrecoverableError)
998 CONSISTENCY_CHECK_MSGF(false, ("Gross API misuses. Callling terminate with live process:0x%p\n", pProcess));
999 STRESS_LOG1(LF_CORDB, LL_INFO10, "Cordb::Terminate b/c of non-neutered process '%p'\n", pProcess);
1000 // This is very bad.
1001 // GROSS API MISUSES - Debugger is calling ICorDebug::Terminate while there
1002 // are still outstanding (non-neutered) ICorDebugProcess.
1003 // ICorDebug is now in an undefined state.
1004 // We will also leak memory b/c we're leaving the EventThreads up (which will in turn
1005 // keep a reference to this Cordb object).
1006 return ErrWrapper(CORDBG_E_ILLEGAL_SHUTDOWN_ORDER);
1011 // @todo- ideally, we'd wait for all threads to get outside of ICorDebug before we proceed.
1012 // That's tough to implement in practice; but we at least wait for both ET to exit. As these
1013 // guys dispatch callbacks, that means at least we'll wait until VS is outside of any callback.
1015 // Stop the event handling threads.
1017 if (m_rcEventThread != NULL)
1019 // Stop may do significant work b/c if it drains the worker queue.
1020 m_rcEventThread->Stop();
1021 delete m_rcEventThread;
1022 m_rcEventThread = NULL;
1027 // @todo - this disables thread-safety asserts on the process-list-hash. We clearly
1028 // can't hold the lock while neutering it. (lock violation since who knows what neuter may do)
1029 // @todo- we may have races beteen Cordb::Terminate and Cordb::CreateProcess as both
1030 // modify the process list. This is mitigated since Terminate is supposed to be the last method called.
1031 m_processes.DebugSetRSLock(NULL);
1035 // We expect the debugger to neuter all processes before calling Terminate(), so do not neuter them here.
1041 _ASSERTE(m_processes.FindFirst(&find) == NULL); // should be emptied by neuter
1045 // Officially mark us as neutered.
1048 m_processListMutex.Destroy();
1051 // Release the callbacks
1053 m_managedCallback.Clear();
1054 m_managedCallback2.Clear();
1055 m_managedCallback3.Clear();
1056 m_unmanagedCallback.Clear();
1058 // The Shell may still have outstanding references, so we don't want to shutdown logging yet.
1059 // But everything should be neutered anyways.
1061 m_initialized = FALSE;
1064 // After this, all outstanding Cordb objects should be neutered.
1065 LOG((LF_CORDB, LL_EVERYTHING, "Cordb finished terminating.\n"));
1069 // Assert that there are no outstanding object references within the debugging
1078 HRESULT Cordb::QueryInterface(REFIID id, void **pInterface)
1080 if (id == IID_ICorDebug)
1081 *pInterface = static_cast<ICorDebug*>(this);
1082 else if (id == IID_IUnknown)
1083 *pInterface = static_cast<IUnknown*>(static_cast<ICorDebug*>(this));
1087 return E_NOINTERFACE;
1097 // Initialize -- setup the ICorDebug object by creating any objects
1098 // that the object needs to operate and starting the two needed IPC
1101 HRESULT Cordb::Initialize(void)
1105 FAIL_IF_NEUTERED(this);
1109 CordbCommonBase::InitializeCommon();
1111 // Since logging wasn't active when we called CordbBase, do it now.
1112 LOG((LF_CORDB, LL_EVERYTHING, "Memory: CordbBase object allocated: this=%p, count=%d, RootObject\n", this, s_TotalObjectCount));
1113 LOG((LF_CORDB, LL_INFO10, "Initializing ICorDebug...\n"));
1115 // Ensure someone hasn't messed up the IPC buffer size
1116 _ASSERTE(sizeof(DebuggerIPCEvent) <= CorDBIPC_BUFFER_SIZE);
1119 // Init things that the Cordb will need to operate
1121 m_processListMutex.Init("Process-List Lock", RSLock::cLockReentrant, RSLock::LL_PROCESS_LIST_LOCK);
1124 m_processes.DebugSetRSLock(&m_processListMutex);
1128 // Create the runtime controller event listening thread
1130 m_rcEventThread = new (nothrow) CordbRCEventThread(this);
1132 if (m_rcEventThread == NULL)
1138 // This stuff only creates events & starts the thread
1139 hr = m_rcEventThread->Init();
1142 hr = m_rcEventThread->Start();
1146 delete m_rcEventThread;
1147 m_rcEventThread = NULL;
1154 m_initialized = TRUE;
1161 //---------------------------------------------------------------------------------------
1163 // Throw if no more process can be debugged with this Cordb object.
1166 // This is highly dependent on the wait sets in the Win32 & RCET threads.
1167 // @dbgtodo- this will end up in the shim.
1169 void Cordb::EnsureAllowAnotherProcess()
1177 RSLockHolder ch(&m_processListMutex);
1179 // Cordb, Win32, and RCET all have process sets, but Cordb's is the
1180 // best count of total debuggees. The RCET set is volatile (processes
1181 // are added / removed when they become synchronized), and Win32's set
1182 // doesn't include all processes.
1183 int cCurProcess = GetProcessList()->GetCount();
1185 // In order to accept another debuggee, we must have a free slot in all
1186 // wait sets. Currently, we don't expose the size of those sets, but
1187 // we know they're MAXIMUM_WAIT_OBJECTS. Note that we lose one slot
1188 // to the control event.
1189 if (cCurProcess >= MAXIMUM_WAIT_OBJECTS - 1)
1191 ThrowHR(CORDBG_E_TOO_MANY_PROCESSES);
1195 //---------------------------------------------------------------------------------------
1197 // Add process to the list.
1200 // AddProcess -- add a process object to this ICorDebug's hash of processes.
1201 // This also tells this ICorDebug's runtime controller thread that the
1202 // process set has changed so it can update its list of wait events.
1204 void Cordb::AddProcess(CordbProcess* process)
1206 // At this point, we should have already checked that we
1207 // can have another debuggee.
1208 STRESS_LOG1(LF_CORDB, LL_INFO10, "Cordb::AddProcess %08x...\n", process);
1210 if ((m_managedCallback == NULL) || (m_managedCallback2 == NULL) || (m_managedCallback3 == NULL))
1217 RSLockHolder lockHolder(&m_processListMutex);
1219 // Once we add another process, all outstanding process-enumerators become invalid.
1220 m_pProcessEnumList.NeuterAndClear(NULL);
1222 GetProcessList()->AddBaseOrThrow(process);
1223 m_rcEventThread->ProcessStateChanged();
1227 // RemoveProcess -- remove a process object from this ICorDebug's hash of
1228 // processes. This also tells this ICorDebug's runtime controller thread
1229 // that the process set has changed so it can update its list of wait events.
1231 void Cordb::RemoveProcess(CordbProcess* process)
1233 STRESS_LOG1(LF_CORDB, LL_INFO10, "Cordb::RemoveProcess %08x...\n", process);
1236 GetProcessList()->RemoveBase((ULONG_PTR)process->m_id);
1238 m_rcEventThread->ProcessStateChanged();
1240 UnlockProcessList();
1244 // LockProcessList -- Lock the process list.
1246 void Cordb::LockProcessList(void)
1248 m_processListMutex.Lock();
1252 // UnlockProcessList -- Unlock the process list.
1254 void Cordb::UnlockProcessList(void)
1256 m_processListMutex.Unlock();
1260 // Return true iff this thread owns the ProcessList lock
1261 bool Cordb::ThreadHasProcessListLock()
1263 return m_processListMutex.HasLock();
1268 // Get the hash that has the process.
1269 CordbSafeHashTable<CordbProcess> *Cordb::GetProcessList()
1271 // If we're accessing the hash, we'd better be locked.
1272 _ASSERTE(ThreadHasProcessListLock());
1274 return &m_processes;
1278 HRESULT Cordb::SendIPCEvent(CordbProcess * pProcess,
1279 DebuggerIPCEvent * pEvent,
1284 LOG((LF_CORDB, LL_EVERYTHING, "SendIPCEvent in Cordb called\n"));
1287 hr = m_rcEventThread->SendIPCEvent(pProcess, pEvent, eventSize);
1289 EX_CATCH_HRESULT(hr)
1294 void Cordb::ProcessStateChanged(void)
1296 m_rcEventThread->ProcessStateChanged();
1300 HRESULT Cordb::WaitForIPCEventFromProcess(CordbProcess* process,
1301 CordbAppDomain *pAppDomain,
1302 DebuggerIPCEvent* event)
1304 return m_rcEventThread->WaitForIPCEventFromProcess(process,
1309 HRESULT Cordb::SetTargetCLR(HMODULE hmodTargetCLR)
1314 m_targetCLR = hmodTargetCLR;
1316 // @REVIEW: are we happy with this workaround? It allows us to use the existing
1317 // infrastructure for instance name decoration, but it really doesn't fit
1318 // the same model because coreclr.dll isn't in this process and hmodTargetCLR
1319 // is the debuggee target, not the coreclr.dll to bind utilcode to..
1321 CoreClrCallbacks cccallbacks;
1322 cccallbacks.m_hmodCoreCLR = hmodTargetCLR;
1323 cccallbacks.m_pfnIEE = NULL;
1324 cccallbacks.m_pfnGetCORSystemDirectory = NULL;
1325 cccallbacks.m_pfnGetCLRFunction = NULL;
1326 InitUtilcode(cccallbacks);
1331 //-----------------------------------------------------------
1333 //-----------------------------------------------------------
1335 // Set the handler for callbacks on managed events
1336 // This can not be NULL.
1337 // If we're debugging V2.0 apps, pCallback must implement ICDManagedCallback2
1338 // @todo- what if somebody calls this after we've already initialized? (eg, changes
1339 // the callback underneath us)
1340 HRESULT Cordb::SetManagedHandler(ICorDebugManagedCallback *pCallback)
1345 FAIL_IF_NEUTERED(this);
1346 VALIDATE_POINTER_TO_OBJECT(pCallback, ICorDebugManagedCallback*);
1348 m_managedCallback.Clear();
1349 m_managedCallback2.Clear();
1350 m_managedCallback3.Clear();
1352 // For SxS, V2.0 debuggers must implement ManagedCallback2 to handle v2.0 debug events.
1353 // For Single-CLR, A v1.0 debugger may actually geta V2.0 debuggee.
1354 pCallback->QueryInterface(IID_ICorDebugManagedCallback2, (void **)&m_managedCallback2);
1355 if (m_managedCallback2 == NULL)
1357 if (GetDebuggerVersion() >= CorDebugVersion_2_0)
1359 // This will leave our internal callbacks null, which future operations (Create/Attach) will
1360 // use to know that we're not sufficiently initialized.
1361 return E_NOINTERFACE;
1365 // This should only be used in a single-CLR shimming scenario.
1366 m_managedCallback2.Assign(new (nothrow) DefaultManagedCallback2(this));
1368 if (m_managedCallback2 == NULL)
1370 return E_OUTOFMEMORY;
1376 pCallback->QueryInterface(IID_ICorDebugManagedCallback3, (void **)&m_managedCallback3);
1377 if (m_managedCallback3 == NULL)
1379 m_managedCallback3.Assign(new (nothrow) DefaultManagedCallback3(this));
1382 if (m_managedCallback3 == NULL)
1384 return E_OUTOFMEMORY;
1387 m_managedCallback.Assign(pCallback);
1391 HRESULT Cordb::SetUnmanagedHandler(ICorDebugUnmanagedCallback *pCallback)
1396 FAIL_IF_NEUTERED(this);
1397 VALIDATE_POINTER_TO_OBJECT_OR_NULL(pCallback, ICorDebugUnmanagedCallback*);
1399 m_unmanagedCallback.Assign(pCallback);
1404 // CreateProcess() isn't supported on Windows CoreCLR.
1405 // It is currently supported on Mac CoreCLR, but that may change.
1406 bool Cordb::IsCreateProcessSupported()
1408 #if !defined(FEATURE_DBGIPC_TRANSPORT_DI)
1415 // Given everything we know about our configuration, can we support interop-debugging
1416 bool Cordb::IsInteropDebuggingSupported()
1418 // We explicitly refrain from checking the unmanaged callback. See comment in
1419 // ICorDebug::SetUnmanagedHandler for details.
1420 #ifdef FEATURE_INTEROP_DEBUGGING
1430 //---------------------------------------------------------------------------------------
1432 // Implementation of ICorDebug::CreateProcess.
1433 // Creates a process.
1436 // The following arguments are passed thru unmodified to the OS CreateProcess API and
1437 // are defined by that API.
1438 // lpApplicationName
1440 // lpProcessAttributes
1441 // lpThreadAttributes
1444 // lpCurrentDirectory
1446 // lpProcessInformation
1449 // ppProcess - Space to fill in for the resulting process, returned as a valid pointer
1450 // on any success HRESULT.
1453 // Normal HRESULT semantics.
1455 //---------------------------------------------------------------------------------------
1456 HRESULT Cordb::CreateProcess(LPCWSTR lpApplicationName,
1457 __in_z LPWSTR lpCommandLine,
1458 LPSECURITY_ATTRIBUTES lpProcessAttributes,
1459 LPSECURITY_ATTRIBUTES lpThreadAttributes,
1460 BOOL bInheritHandles,
1461 DWORD dwCreationFlags,
1462 PVOID lpEnvironment,
1463 LPCWSTR lpCurrentDirectory,
1464 LPSTARTUPINFOW lpStartupInfo,
1465 LPPROCESS_INFORMATION lpProcessInformation,
1466 CorDebugCreateProcessFlags debuggingFlags,
1467 ICorDebugProcess **ppProcess)
1469 return CreateProcessCommon(NULL,
1472 lpProcessAttributes,
1479 lpProcessInformation,
1484 HRESULT Cordb::CreateProcessCommon(ICorDebugRemoteTarget * pRemoteTarget,
1485 LPCWSTR lpApplicationName,
1486 __in_z LPWSTR lpCommandLine,
1487 LPSECURITY_ATTRIBUTES lpProcessAttributes,
1488 LPSECURITY_ATTRIBUTES lpThreadAttributes,
1489 BOOL bInheritHandles,
1490 DWORD dwCreationFlags,
1491 PVOID lpEnvironment,
1492 LPCWSTR lpCurrentDirectory,
1493 LPSTARTUPINFOW lpStartupInfo,
1494 LPPROCESS_INFORMATION lpProcessInformation,
1495 CorDebugCreateProcessFlags debuggingFlags,
1496 ICorDebugProcess ** ppProcess)
1498 // If you hit this assert, it means that you are attempting to create a process without specifying the version
1500 _ASSERTE(CorDebugInvalidVersion != m_debuggerSpecifiedVersion);
1502 PUBLIC_API_ENTRY(this);
1503 FAIL_IF_NEUTERED(this);
1504 VALIDATE_POINTER_TO_OBJECT(ppProcess, ICorDebugProcess**);
1515 // Check that we support the debugger version
1516 CheckCompatibility();
1518 #ifdef FEATURE_INTEROP_DEBUGGING
1519 // DEBUG_PROCESS (=0x1) means debug this process & all future children.
1520 // DEBUG_ONLY_THIS_PROCESS =(0x2) means just debug the immediate process.
1521 // If we want to support DEBUG_PROCESS, then we need to have the RS sniff for new CREATE_PROCESS
1522 // events and spawn new CordbProcess for them.
1523 switch(dwCreationFlags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS))
1525 // 1) managed-only debugging
1529 // 2) failure - returns E_NOTIMPL. (as this would involve debugging all of our children processes).
1533 // 3) Interop-debugging.
1534 // Note that MSDN (at least as of Jan 2003) is wrong about this flag. MSDN claims
1535 // DEBUG_ONLY_THIS_PROCESS w/o DEBUG_PROCESS should be ignored.
1536 // But it really should do launch as a debuggee (but not auto-attach to child processes).
1537 case DEBUG_ONLY_THIS_PROCESS:
1538 // Emprically, this is the common case for native / interop-debugging.
1542 // The spec for ICorDebug::CreateProcess says this is the one to use for interop-debugging.
1543 case DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS:
1544 // Win2k does not honor these flags properly. So we just use
1545 // It treats (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS) as if it were DEBUG_PROCESS.
1546 // We'll just always touch up the flags, even though WinXP and above is fine here.
1547 // Per win2k issue, strip off DEBUG_PROCESS, so that we're just left w/ DEBUG_ONLY_THIS_PROCESS.
1548 dwCreationFlags &= ~(DEBUG_PROCESS);
1555 #endif // FEATURE_INTEROP_DEBUGGING
1557 // Must have a managed-callback by now.
1558 if ((m_managedCallback == NULL) || (m_managedCallback2 == NULL) || (m_managedCallback3 == NULL))
1563 if (!IsCreateProcessSupported())
1568 if (!IsInteropDebuggingSupported() &&
1569 ((dwCreationFlags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS)) != 0))
1571 ThrowHR(CORDBG_E_INTEROP_NOT_SUPPORTED);
1574 // Check that we can even accept another debuggee before trying anything.
1575 EnsureAllowAnotherProcess();
1577 } EX_CATCH_HRESULT(hr);
1583 hr = ShimProcess::CreateProcess(this,
1587 lpProcessAttributes,
1594 lpProcessInformation,
1598 LOG((LF_CORDB, LL_EVERYTHING, "Handle in Cordb::CreateProcess is: %.I64x\n", lpProcessInformation->hProcess));
1604 CordbProcess * pProcess = GetProcessList()->GetBase(lpProcessInformation->dwProcessId);
1606 UnlockProcessList();
1608 PREFIX_ASSUME(pProcess != NULL);
1610 pProcess->ExternalAddRef();
1611 *ppProcess = (ICorDebugProcess *)pProcess;
1618 HRESULT Cordb::CreateProcessEx(ICorDebugRemoteTarget * pRemoteTarget,
1619 LPCWSTR lpApplicationName,
1620 __in_z LPWSTR lpCommandLine,
1621 LPSECURITY_ATTRIBUTES lpProcessAttributes,
1622 LPSECURITY_ATTRIBUTES lpThreadAttributes,
1623 BOOL bInheritHandles,
1624 DWORD dwCreationFlags,
1625 PVOID lpEnvironment,
1626 LPCWSTR lpCurrentDirectory,
1627 LPSTARTUPINFOW lpStartupInfo,
1628 LPPROCESS_INFORMATION lpProcessInformation,
1629 CorDebugCreateProcessFlags debuggingFlags,
1630 ICorDebugProcess ** ppProcess)
1632 if (pRemoteTarget == NULL)
1634 return E_INVALIDARG;
1637 return CreateProcessCommon(pRemoteTarget,
1640 lpProcessAttributes,
1647 lpProcessInformation,
1653 //---------------------------------------------------------------------------------------
1655 // Attachs to an existing process.
1658 // dwProcessID - The PID to attach to
1659 // fWin32Attach - Flag to tell whether to attach as the Win32 debugger or not.
1660 // ppProcess - Space to fill in for the resulting process, returned as a valid pointer
1661 // on any success HRESULT.
1664 // Normal HRESULT semantics.
1666 //---------------------------------------------------------------------------------------
1667 HRESULT Cordb::DebugActiveProcess(DWORD dwProcessId,
1669 ICorDebugProcess **ppProcess)
1671 return DebugActiveProcessCommon(NULL, dwProcessId, fWin32Attach, ppProcess);
1674 HRESULT Cordb::DebugActiveProcessCommon(ICorDebugRemoteTarget * pRemoteTarget,
1677 ICorDebugProcess ** ppProcess)
1679 PUBLIC_API_ENTRY(this);
1680 FAIL_IF_NEUTERED(this);
1681 VALIDATE_POINTER_TO_OBJECT(ppProcess, ICorDebugProcess **);
1692 // Must have a managed-callback by now.
1693 if ((m_managedCallback == NULL) || (m_managedCallback2 == NULL) || (m_managedCallback3 == NULL))
1698 // See the comment in Cordb::CreateProcess
1699 _ASSERTE(CorDebugInvalidVersion != m_debuggerSpecifiedVersion);
1701 // Check that we support the debugger version
1702 CheckCompatibility();
1704 // Check that we can even accept another debuggee before trying anything.
1705 EnsureAllowAnotherProcess();
1707 // Check if we're allowed to do interop.
1708 bool fAllowInterop = IsInteropDebuggingSupported();
1710 if (!fAllowInterop && fWin32Attach)
1712 ThrowHR(CORDBG_E_INTEROP_NOT_SUPPORTED);
1715 } EX_CATCH_HRESULT(hr)
1721 hr = ShimProcess::DebugActiveProcess(
1725 fWin32Attach == TRUE);
1727 // If that worked, then there will be a process object...
1731 CordbProcess * pProcess = GetProcessList()->GetBase(dwProcessId);
1733 if (pProcess != NULL)
1735 // Add a reference now so process won't go away
1736 pProcess->ExternalAddRef();
1738 UnlockProcessList();
1740 if (pProcess == NULL)
1742 // This can happen if we add the process into process hash in
1743 // SendDebugActiveProcessEvent and then process exit
1744 // before we attemp to retrieve it again from GetBase.
1750 #if defined(FEATURE_DBGIPC_TRANSPORT_DI)
1751 // This is where we queue the managed attach event in Whidbey. In the new architecture, the Windows
1752 // pipeline gets a loader breakpoint when native attach is completed, and that's where we queue the
1753 // managed attach event. See how we handle the loader breakpoint in code:ShimProcess::DefaultEventHandler.
1754 // However, the Mac debugging transport gets no such breakpoint, and so we need to do this here.
1756 // @dbgtodo Mac - Ideally we should hide this in our pipeline implementation, or at least move
1757 // this to the shim.
1758 _ASSERTE(!fWin32Attach);
1761 hr = pProcess->QueueManagedAttach();
1764 #endif // FEATURE_DBGIPC_TRANSPORT_DI
1766 *ppProcess = (ICorDebugProcess*) pProcess;
1772 // Make sure we want to support the debugger that's using us
1773 void Cordb::CheckCompatibility()
1775 // Get the debugger version specified by the startup APIs and convert it to a CLR major version number
1776 CorDebugInterfaceVersion debuggerVersion = GetDebuggerVersion();
1778 if (debuggerVersion <= CorDebugVersion_1_0 || debuggerVersion == CorDebugVersion_1_1)
1780 else if (debuggerVersion <= CorDebugVersion_2_0)
1782 else if (debuggerVersion <= CorDebugVersion_4_0)
1785 clrMajor = 5; // some unrecognized future version
1787 if(!CordbProcess::IsCompatibleWith(clrMajor))
1789 // Carefully choose our error-code to get an appropriate error-message from VS 2008
1790 // If GetDebuggerVersion is >= 4, we could consider using the more-appropriate (but not
1791 // added until V4) HRESULT CORDBG_E_UNSUPPORTED_FORWARD_COMPAT that is used by
1792 // OpenVirtualProcess, but it's probably simpler to keep ICorDebug APIs returning
1793 // consistent error codes.
1794 ThrowHR(CORDBG_E_INCOMPATIBLE_PROTOCOL);
1798 HRESULT Cordb::DebugActiveProcessEx(ICorDebugRemoteTarget * pRemoteTarget,
1801 ICorDebugProcess ** ppProcess)
1803 if (pRemoteTarget == NULL)
1805 return E_INVALIDARG;
1808 return DebugActiveProcessCommon(pRemoteTarget, dwProcessId, fWin32Attach, ppProcess);
1812 HRESULT Cordb::GetProcess(DWORD dwProcessId, ICorDebugProcess **ppProcess)
1814 PUBLIC_API_ENTRY(this);
1815 FAIL_IF_NEUTERED(this);
1816 VALIDATE_POINTER_TO_OBJECT(ppProcess, ICorDebugProcess**);
1824 CordbProcess *p = GetProcessList()->GetBase(dwProcessId);
1825 UnlockProcessList();
1828 return E_INVALIDARG;
1830 p->ExternalAddRef();
1831 *ppProcess = static_cast<ICorDebugProcess*> (p);
1836 HRESULT Cordb::EnumerateProcesses(ICorDebugProcessEnum **ppProcesses)
1838 PUBLIC_API_ENTRY(this);
1839 FAIL_IF_NEUTERED(this);
1840 VALIDATE_POINTER_TO_OBJECT(ppProcesses, ICorDebugProcessEnum **);
1850 // Locking here just means that the enumerator gets initialized against a consistent
1851 // process-list. If we add/remove processes w/ an outstanding enumerator, things
1852 // could still get out of sync.
1853 RSLockHolder lockHolder(&this->m_processListMutex);
1855 RSInitHolder<CordbHashTableEnum> pEnum;
1856 CordbHashTableEnum::BuildOrThrow(
1858 &m_pProcessEnumList,
1860 IID_ICorDebugProcessEnum,
1864 pEnum.TransferOwnershipExternal(ppProcesses);
1866 EX_CATCH_HRESULT(hr);
1872 // Note: the following defs and structs are copied from various NT headers. I wasn't able to include those headers (like
1873 // ntexapi.h) due to loads of redef problems and other conflicts with headers that we already pull in.
1875 typedef LONG NTSTATUS;
1878 typedef BOOL (*NTQUERYSYSTEMINFORMATION)(SYSTEM_INFORMATION_CLASS SystemInformationClass,
1879 PVOID SystemInformation,
1880 ULONG SystemInformationLength,
1881 PULONG ReturnLength);
1884 // Implementation of ICorDebug::CanLaunchOrAttach
1885 // @dbgtodo- this all goes away in V3.
1886 // @dbgtodo- this should go away in Dev11.
1887 HRESULT Cordb::CanLaunchOrAttach(DWORD dwProcessId, BOOL fWin32DebuggingEnabled)
1889 PUBLIC_API_ENTRY(this);
1890 FAIL_IF_NEUTERED(this);
1895 EnsureCanLaunchOrAttach(fWin32DebuggingEnabled);
1897 EX_CATCH_HRESULT(hr);
1902 //---------------------------------------------------------------------------------------
1904 // Throw an expcetion if we can't launch/attach.
1907 // fWin32DebuggingEnabled - true if interop-debugging, else false
1910 // None. If this returns, then it's safe to launch/attach.
1911 // Else this throws an exception on failure.
1916 // It should always be safe to launch/attach except in exceptional cases.
1917 // @dbgtodo- this all goes away in V3.
1918 // @dbgtodo- this should go away in Dev11.
1920 void Cordb::EnsureCanLaunchOrAttach(BOOL fWin32DebuggingEnabled)
1932 EnsureAllowAnotherProcess();
1934 if (!IsInteropDebuggingSupported() && fWin32DebuggingEnabled)
1936 ThrowHR(CORDBG_E_INTEROP_NOT_SUPPORTED);
1939 // Made it this far, we succeeded.
1942 HRESULT Cordb::CreateObjectV1(REFIID id, void **object)
1944 return CreateObject(CorDebugVersion_1_0, id, object);
1947 #if defined(FEATURE_DBGIPC_TRANSPORT_DI)
1948 // CoreCLR activates debugger objects via direct COM rather than the shim (just like V1). For now we share the
1949 // same debug engine version as V2, though this may change in the future.
1950 HRESULT Cordb::CreateObjectTelesto(REFIID id, void ** pObject)
1952 return CreateObject(CorDebugVersion_2_0, id, pObject);
1954 #endif // FEATURE_DBGIPC_TRANSPORT_DI
1957 // Used to create an instance for a ClassFactory (thus an external ref).
1958 HRESULT Cordb::CreateObject(CorDebugInterfaceVersion iDebuggerVersion, REFIID id, void **object)
1960 if (id != IID_IUnknown && id != IID_ICorDebug)
1961 return (E_NOINTERFACE);
1963 Cordb *db = new (nothrow) Cordb(iDebuggerVersion);
1966 return (E_OUTOFMEMORY);
1968 *object = static_cast<ICorDebug*> (db);
1969 db->ExternalAddRef();
1975 // This is the version of the ICorDebug APIs that the debugger believes it's consuming.
1976 // If this is a different version than that of the debuggee, we have the option of shimming
1978 CorDebugInterfaceVersion
1979 Cordb::GetDebuggerVersion() const
1981 return m_debuggerSpecifiedVersion;
1984 //***********************************************************************
1985 // ICorDebugTMEnum (Thread and Module enumerator)
1986 //***********************************************************************
1987 CordbEnumFilter::CordbEnumFilter(CordbBase * pOwnerObj, NeuterList * pOwnerList)
1988 : CordbBase (pOwnerObj->GetProcess(), 0),
1989 m_pOwnerObj(pOwnerObj),
1990 m_pOwnerNeuterList(pOwnerList),
1995 _ASSERTE(m_pOwnerNeuterList != NULL);
2000 m_pOwnerNeuterList->Add(pOwnerObj->GetProcess(), this);
2002 EX_CATCH_HRESULT(hr);
2003 SetUnrecoverableIfFailed(GetProcess(), hr);
2007 CordbEnumFilter::CordbEnumFilter(CordbEnumFilter *src)
2008 : CordbBase (src->GetProcess(), 0),
2009 m_pOwnerObj(src->m_pOwnerObj),
2010 m_pOwnerNeuterList(src->m_pOwnerNeuterList),
2014 _ASSERTE(m_pOwnerNeuterList != NULL);
2019 m_pOwnerNeuterList->Add(src->GetProcess(), this);
2021 EX_CATCH_HRESULT(hr);
2022 SetUnrecoverableIfFailed(GetProcess(), hr);
2026 int iCountSanityCheck = 0;
2027 EnumElement *pElementCur = NULL;
2028 EnumElement *pElementNew = NULL;
2029 EnumElement *pElementNewPrev = NULL;
2031 m_iCount = src->m_iCount;
2033 pElementCur = src->m_pFirst;
2035 while (pElementCur != NULL)
2037 pElementNew = new (nothrow) EnumElement;
2038 if (pElementNew == NULL)
2040 // Out of memory. Clean up and bail out.
2044 if (pElementNewPrev == NULL)
2046 m_pFirst = pElementNew;
2050 pElementNewPrev->SetNext(pElementNew);
2053 pElementNewPrev = pElementNew;
2055 // Copy the element, including the AddRef part
2056 pElementNew->SetData(pElementCur->GetData());
2057 IUnknown *iu = (IUnknown *)pElementCur->GetData();
2060 if (pElementCur == src->m_pCurrent)
2061 m_pCurrent = pElementNew;
2063 pElementCur = pElementCur->GetNext();
2064 iCountSanityCheck++;
2067 _ASSERTE(iCountSanityCheck == m_iCount);
2071 // release all the allocated memory before returning
2072 pElementCur = m_pFirst;
2074 while (pElementCur != NULL)
2076 pElementNewPrev = pElementCur;
2077 pElementCur = pElementCur->GetNext();
2079 ((ICorDebugModule *)pElementNewPrev->GetData())->Release();
2080 delete pElementNewPrev;
2084 CordbEnumFilter::~CordbEnumFilter()
2086 _ASSERTE(this->IsNeutered());
2088 _ASSERTE(m_pFirst == NULL);
2091 void CordbEnumFilter::Neuter()
2093 EnumElement *pElement = m_pFirst;
2094 EnumElement *pPrevious = NULL;
2096 while (pElement != NULL)
2098 pPrevious = pElement;
2099 pElement = pElement->GetNext();
2103 // Null out the head in case we get neutered again.
2107 CordbBase::Neuter();
2112 HRESULT CordbEnumFilter::QueryInterface(REFIID id, void **ppInterface)
2114 // if we QI with the IID of the base type, we can't just return a pointer ICorDebugEnum directly, because
2115 // the cast is ambiguous. This happens because CordbEnumFilter implements both ICorDebugModuleEnum and
2116 // ICorDebugThreadEnum, both of which derive in turn from ICorDebugEnum. This produces a diamond inheritance
2117 // graph. Thus we need a double cast. It doesn't really matter whether we pick ICorDebugThreadEnum or
2118 // ICorDebugModuleEnum, because it will be backed by the same object regardless.
2119 if (id == IID_ICorDebugEnum)
2120 *ppInterface = static_cast<ICorDebugEnum *>(static_cast<ICorDebugThreadEnum *>(this));
2121 else if (id == IID_ICorDebugModuleEnum)
2122 *ppInterface = (ICorDebugModuleEnum*)this;
2123 else if (id == IID_ICorDebugThreadEnum)
2124 *ppInterface = (ICorDebugThreadEnum*)this;
2125 else if (id == IID_IUnknown)
2126 *ppInterface = this;
2129 *ppInterface = NULL;
2130 return E_NOINTERFACE;
2137 HRESULT CordbEnumFilter::Skip(ULONG celt)
2140 PUBLIC_API_BEGIN(this);
2142 while ((celt-- > 0) && (m_pCurrent != NULL))
2144 m_pCurrent = m_pCurrent->GetNext();
2151 HRESULT CordbEnumFilter::Reset()
2154 PUBLIC_API_BEGIN(this);
2156 m_pCurrent = m_pFirst;
2162 HRESULT CordbEnumFilter::Clone(ICorDebugEnum **ppEnum)
2165 PUBLIC_API_BEGIN(this);
2167 ValidateOrThrow(ppEnum);
2169 CordbEnumFilter * pClone = new CordbEnumFilter(this);
2171 // Ambigous conversion from CordbEnumFilter to ICorDebugEnum, so
2172 // we explicitly convert it through ICorDebugThreadEnum.
2173 pClone->ExternalAddRef();
2174 (*ppEnum) = static_cast<ICorDebugThreadEnum *> (pClone);
2180 HRESULT CordbEnumFilter::GetCount(ULONG *pcelt)
2183 PUBLIC_API_BEGIN(this);
2185 ValidateOrThrow(pcelt);
2186 *pcelt = (ULONG)m_iCount;
2192 HRESULT CordbEnumFilter::Next(ULONG celt,
2193 ICorDebugModule *objects[],
2194 ULONG *pceltFetched)
2197 PUBLIC_API_BEGIN(this);
2199 hr = NextWorker(celt, objects, pceltFetched);
2205 HRESULT CordbEnumFilter::NextWorker(ULONG celt, ICorDebugModule *objects[], ULONG *pceltFetched)
2209 // nickbe 11/20/2002 10:43:39
2210 // This function allows you to enumerate threads that "belong" to a
2211 // particular AppDomain. While this operation makes some sense, it makes
2212 // very little sense to
2213 // (a) enumerate the list of threads in the enter process
2214 // (b) build up a hand-rolled singly linked list (grrr)
2216 VALIDATE_POINTER_TO_OBJECT_ARRAY(objects, ICorDebugModule *,
2218 VALIDATE_POINTER_TO_OBJECT_OR_NULL(pceltFetched, ULONG *);
2220 if ((pceltFetched == NULL) && (celt != 1))
2222 return E_INVALIDARG;
2227 if (pceltFetched != NULL)
2238 while ((m_pCurrent != NULL) && (count < celt))
2240 objects[count] = (ICorDebugModule *)m_pCurrent->GetData();
2241 m_pCurrent = m_pCurrent->GetNext();
2245 if (pceltFetched != NULL)
2247 *pceltFetched = count;
2251 // If we reached the end of the enumeration, but not the end
2252 // of the number of requested items, we return S_FALSE.
2263 HRESULT CordbEnumFilter::Next(ULONG celt,
2264 ICorDebugThread *objects[],
2265 ULONG *pceltFetched)
2268 PUBLIC_API_BEGIN(this);
2270 hr = NextWorker(celt, objects, pceltFetched);
2276 HRESULT CordbEnumFilter::NextWorker(ULONG celt, ICorDebugThread *objects[], ULONG *pceltFetched)
2278 // @TODO remove this class
2279 VALIDATE_POINTER_TO_OBJECT_ARRAY(objects, ICorDebugThread *, celt, true, true);
2280 VALIDATE_POINTER_TO_OBJECT_OR_NULL(pceltFetched, ULONG *);
2282 if ((pceltFetched == NULL) && (celt != 1))
2284 return E_INVALIDARG;
2289 if (pceltFetched != NULL)
2300 while ((m_pCurrent != NULL) && (count < celt))
2302 objects[count] = (ICorDebugThread *)m_pCurrent->GetData();
2303 m_pCurrent = m_pCurrent->GetNext();
2307 if (pceltFetched != NULL)
2309 *pceltFetched = count;
2313 // If we reached the end of the enumeration, but not the end
2314 // of the number of requested items, we return S_FALSE.
2326 HRESULT CordbEnumFilter::Init (ICorDebugModuleEnum * pModEnum, CordbAssembly *pAssembly)
2328 INTERNAL_API_ENTRY(GetProcess());
2330 ICorDebugModule *pCorModule = NULL;
2331 CordbModule *pModule = NULL;
2334 HRESULT hr = pModEnum->Next(1, &pCorModule, &ulDummy);
2337 // Next returns E_FAIL if there is no next item, along with
2338 // the count being 0. Convert that to just being S_OK.
2340 if ((hr == E_FAIL) && (ulDummy == 0))
2348 EnumElement *pPrevious = NULL;
2349 EnumElement *pElement = NULL;
2351 while (ulDummy != 0)
2353 pModule = (CordbModule *)(ICorDebugModule *)pCorModule;
2354 // Is this module part of the assembly for which we're enumerating?
2355 if (pModule->m_pAssembly == pAssembly)
2357 pElement = new (nothrow) EnumElement;
2358 if (pElement == NULL)
2360 // Out of memory. Clean up and bail out.
2365 pElement->SetData ((void *)pCorModule);
2368 if (m_pFirst == NULL)
2370 m_pFirst = pElement;
2374 PREFIX_ASSUME(pPrevious != NULL);
2375 pPrevious->SetNext (pElement);
2377 pPrevious = pElement;
2380 ((ICorDebugModule *)pModule)->Release();
2382 hr = pModEnum->Next(1, &pCorModule, &ulDummy);
2385 // Next returns E_FAIL if there is no next item, along with
2386 // the count being 0. Convert that to just being S_OK.
2388 if ((hr == E_FAIL) && (ulDummy == 0))
2397 m_pCurrent = m_pFirst;
2402 // release all the allocated memory before returning
2403 pElement = m_pFirst;
2405 while (pElement != NULL)
2407 pPrevious = pElement;
2408 pElement = pElement->GetNext();
2410 ((ICorDebugModule *)pPrevious->GetData())->Release();
2417 HRESULT CordbEnumFilter::Init (ICorDebugThreadEnum *pThreadEnum, CordbAppDomain *pAppDomain)
2419 INTERNAL_API_ENTRY(GetProcess());
2421 ICorDebugThread *pCorThread = NULL;
2422 CordbThread *pThread = NULL;
2425 HRESULT hr = pThreadEnum->Next(1, &pCorThread, &ulDummy);
2428 // Next returns E_FAIL if there is no next item, but we want to consider this
2429 // ok in this context.
2431 if ((hr == E_FAIL) && (ulDummy == 0))
2441 EnumElement *pPrevious = NULL;
2442 EnumElement *pElement = NULL;
2446 pThread = (CordbThread *)(ICorDebugThread *) pCorThread;
2448 // Is this module part of the appdomain for which we're enumerating?
2449 // Note that this is rather inefficient (we call into the left side for every AppDomain),
2450 // but the whole idea of enumerating the threads of an AppDomain is pretty bad,
2451 // and we don't expect this to be used much if at all.
2452 CordbAppDomain* pThreadDomain;
2453 hr = pThread->GetCurrentAppDomain( &pThreadDomain );
2459 if (pThreadDomain == pAppDomain)
2461 pElement = new (nothrow) EnumElement;
2462 if (pElement == NULL)
2464 // Out of memory. Clean up and bail out.
2469 pElement->SetData ((void *)pCorThread);
2472 if (m_pFirst == NULL)
2474 m_pFirst = pElement;
2478 PREFIX_ASSUME(pPrevious != NULL);
2479 pPrevious->SetNext (pElement);
2482 pPrevious = pElement;
2486 ((ICorDebugThread *)pThread)->Release();
2489 // get the next thread in the thread list
2490 hr = pThreadEnum->Next(1, &pCorThread, &ulDummy);
2493 // Next returns E_FAIL if there is no next item, along with
2494 // the count being 0. Convert that to just being S_OK.
2496 if ((hr == E_FAIL) && (ulDummy == 0))
2505 m_pCurrent = m_pFirst;
2510 // release all the allocated memory before returning
2511 pElement = m_pFirst;
2513 while (pElement != NULL)
2515 pPrevious = pElement;
2516 pElement = pElement->GetNext();
2518 ((ICorDebugThread *)pPrevious->GetData())->Release();