diff options
author | Andrew Au <andrewau@microsoft.com> | 2018-05-10 14:49:39 -0700 |
---|---|---|
committer | Andrew Au <cshung@gmail.com> | 2018-11-06 18:34:47 -0800 |
commit | c6d26187c8ce8fc68829f262a79996f00b1e1a85 (patch) | |
tree | a804fc4d890621ecc94c5b0fa5253c4b71a6a091 /src/debug/di | |
parent | e5744ae2855ee74f8f2f8020c0ef2d54bbfb746d (diff) | |
download | coreclr-c6d26187c8ce8fc68829f262a79996f00b1e1a85.tar.gz coreclr-c6d26187c8ce8fc68829f262a79996f00b1e1a85.tar.bz2 coreclr-c6d26187c8ce8fc68829f262a79996f00b1e1a85.zip |
The GC events are now working, somewhat ...
Diffstat (limited to 'src/debug/di')
-rw-r--r-- | src/debug/di/process.cpp | 1515 | ||||
-rw-r--r-- | src/debug/di/rsmain.cpp | 155 | ||||
-rw-r--r-- | src/debug/di/shimcallback.cpp | 177 | ||||
-rw-r--r-- | src/debug/di/shimpriv.h | 113 |
4 files changed, 1006 insertions, 954 deletions
diff --git a/src/debug/di/process.cpp b/src/debug/di/process.cpp index a49addcd17..18e0ac7aaf 100644 --- a/src/debug/di/process.cpp +++ b/src/debug/di/process.cpp @@ -3,7 +3,7 @@ // See the LICENSE file in the project root for more information. //***************************************************************************** // File: process.cpp -// +// // //***************************************************************************** @@ -11,7 +11,7 @@ #include "primitives.h" #include "safewrap.h" -#include "check.h" +#include "check.h" #ifndef SM_REMOTESESSION #define SM_REMOTESESSION 0x1000 @@ -34,7 +34,7 @@ // Keep this around for retail debugging. It's very very useful because // it's global state that we can always find, regardless of how many locals the compiler // optimizes away ;) -struct RSDebuggingInfo; +struct RSDebuggingInfo; extern RSDebuggingInfo * g_pRSDebuggingInfo; //--------------------------------------------------------------------------------------- @@ -56,20 +56,20 @@ extern RSDebuggingInfo * g_pRSDebuggingInfo; // Assumptions: // // Notes: -// The outgoing process object can be cleaned up by calling Detach (which -// will reset the Attach bit.) +// The outgoing process object can be cleaned up by calling Detach (which +// will reset the Attach bit.) // @dbgtodo attach-bit: need to determine fate of attach bit. // //--------------------------------------------------------------------------------------- STDAPI OpenVirtualProcessImpl( - ULONG64 clrInstanceId, + ULONG64 clrInstanceId, IUnknown * pDataTarget, HMODULE hDacModule, CLR_DEBUGGING_VERSION * pMaxDebuggerSupportedVersion, REFIID riid, IUnknown ** ppInstance, CLR_DEBUGGING_PROCESS_FLAGS* pFlagsOut) -{ +{ HRESULT hr = S_OK; RSExtSmartPtr<CordbProcess> pProcess; PUBLIC_API_ENTRY(NULL); @@ -95,7 +95,7 @@ STDAPI OpenVirtualProcessImpl( } // This process object is intended to be used for the V3 pipeline, and so - // much of the process from V2 is not being used. For example, + // much of the process from V2 is not being used. For example, // - there is no ShimProcess object // - there is no w32et thread (all threads are effectively an event thread) // - the stop state is 'live', which corresponds to CordbProcess not knowing what @@ -104,8 +104,8 @@ STDAPI OpenVirtualProcessImpl( clrInstanceId, pDataTarget, // takes a reference hDacModule, - NULL, // Cordb - (DWORD) 0, // 0 for V3 cases (pShim == NULL). + NULL, // Cordb + (DWORD) 0, // 0 for V3 cases (pShim == NULL). NULL, // no Shim in V3 cases &pProcess)); @@ -123,7 +123,7 @@ STDAPI OpenVirtualProcessImpl( } } - // + // // Check to make sure the debugger supports debugging this version // Note that it's important that we still store the flags (above) in this case // @@ -191,17 +191,17 @@ STDAPI OpenVirtualProcessImpl2( //--------------------------------------------------------------------------------------- // DEPRECATED - use OpenVirtualProcessImpl // OpenVirtualProcess method used by the shim in CLR v4 Beta1 -// We'd like a beta1 shim/VS to still be able to open dumps using a CLR v4 Beta2+ mscordbi.dll, +// We'd like a beta1 shim/VS to still be able to open dumps using a CLR v4 Beta2+ mscordbi.dll, // so we'll leave this in place (at least until after Beta2 is in wide use). //--------------------------------------------------------------------------------------- STDAPI OpenVirtualProcess2( - ULONG64 clrInstanceId, + ULONG64 clrInstanceId, IUnknown * pDataTarget, HMODULE hDacModule, REFIID riid, IUnknown ** ppInstance, CLR_DEBUGGING_PROCESS_FLAGS* pFlagsOut) -{ +{ CLR_DEBUGGING_VERSION maxVersion = {0}; maxVersion.wMajor = 4; return OpenVirtualProcessImpl(clrInstanceId, pDataTarget, hDacModule, &maxVersion, riid, ppInstance, pFlagsOut); @@ -213,11 +213,11 @@ STDAPI OpenVirtualProcess2( // Used directly in CLR v4 pre Beta1 - can probably be safely removed now //--------------------------------------------------------------------------------------- STDAPI OpenVirtualProcess( - ULONG64 clrInstanceId, + ULONG64 clrInstanceId, IUnknown * pDataTarget, REFIID riid, IUnknown ** ppInstance) -{ +{ return OpenVirtualProcess2(clrInstanceId, pDataTarget, NULL, riid, ppInstance, NULL); }; @@ -329,7 +329,7 @@ IMDInternalImport * CordbProcess::LookupMetaData(VMPTR_PEFile vmPEFile, bool &is // There may be perf issues here. The DAC may make a lot of metadata requests, and so // this may be an area for potential perf optimizations if we find things running slow. - + // enumerate through all Modules for (CordbAppDomain * pAppDomain = m_appDomains.FindFirst(&hashFindAppDomain); pAppDomain != NULL; @@ -530,12 +530,12 @@ IMDInternalImport * CordbProcess::LookupMetaDataFromDebuggerForSingleFile( // // Notes: // Since this function is a callback from DAC, it must not take the process lock. -// If it does, we may deadlock between the DD lock and the process lock. +// If it does, we may deadlock between the DD lock and the process lock. // If we really need to take the process lock for whatever reason, we must take it in the DBI functions // which call the DAC API that ends up calling this function. // See code:InternalDacCallbackHolder for more information. // - + void * CordbProcess::Alloc(SIZE_T lenBytes) { return new BYTE[lenBytes]; // throws @@ -550,15 +550,15 @@ void * CordbProcess::Alloc(SIZE_T lenBytes) // // Notes: // Since this function is a callback from DAC, it must not take the process lock. -// If it does, we may deadlock between the DD lock and the process lock. +// If it does, we may deadlock between the DD lock and the process lock. // If we really need to take the process lock for whatever reason, we must take it in the DBI functions // which call the DAC API that ends up calling this function. // See code:InternalDacCallbackHolder for more information. // - + void CordbProcess::Free(void * p) { - // This shouldn't throw. + // This shouldn't throw. delete [] ((BYTE *) p); } @@ -566,38 +566,38 @@ void CordbProcess::Free(void * p) //--------------------------------------------------------------------------------------- // // #DBIVersionChecking -// +// // There are a few checks we need to do to make sure we are using the matching DBI and DAC for a particular // version of the runtime. -// +// // 1. Runtime vs. DBI // - Desktop // This is done by making sure that the CorDebugInterfaceVersion passed to code:CreateCordbObject is // compatible with the version of the DBI. -// +// // - Windows CoreCLR // This is done by dbgshim.dll. It checks whether the runtime DLL and the DBI DLL have the same // product version. See CreateDebuggingInterfaceForVersion() in dbgshim.cpp. -// +// // - Remote transport (Mac CoreCLR + CoreSystem CoreCLR) // Since there is no dbgshim.dll for a remote CoreCLR, we have to do this check in some other place. -// We do this in code:CordbProcess::CreateDacDbiInterface, by calling -// code:DacDbiInterfaceImpl::CheckDbiVersion right after we have created the DDMarshal. +// We do this in code:CordbProcess::CreateDacDbiInterface, by calling +// code:DacDbiInterfaceImpl::CheckDbiVersion right after we have created the DDMarshal. // The IDacDbiInterface implementation on remote device checks the product version of the device // coreclr by: // mac - looking at the Info.plist file in the CoreCLR bundle. // CoreSystem - this check is skipped at the moment, but should be implemented if we release it -// +// // The one twist here is that the DBI needs to communicate with the IDacDbiInterface // implementation on the device BEFORE it can verify the product versions. This means that we need to -// have one IDacDbiInterface API which is consistent across all versions of the IDacDbiInterface. +// have one IDacDbiInterface API which is consistent across all versions of the IDacDbiInterface. // This puts two constraints on CheckDbiVersion(): -// +// // 1. It has to be the first API on the IDacDbiInterface. -// - Otherwise, a wrong version of the DBI may end up calling a different API on the +// - Otherwise, a wrong version of the DBI may end up calling a different API on the // IDacDbiInterface and getting random results. (Really what matters is that it is // protocol message id 0, at present the source code position implies the message id) -// +// // 2. Its parameters cannot change. // - Otherwise, we may run into random errors when we marshal/unmarshal the arguments for the // call to CheckDbiVersion(). Debugging will still fail, but we won't get the @@ -624,7 +624,7 @@ void CordbProcess::Free(void * p) // // - Remote transport (Mac CoreCLR and CoreSystem CoreCLR) // Because the transport exists between DBI and DAC it becomes much more important to do a versioning check -// +// // Mac - currently does a tightly bound version check between DBI and the runtime (CheckDbiVersion() above), // which transitively gives a tightly bound check to DAC. In same function there is also a check that is // logically a DAC DBI protocol check, verifying that the m_dwProtocolBreakingChangeCounter of DbiVersion @@ -645,20 +645,20 @@ void CordbProcess::Free(void * p) // case would be changing the DDMarshal proxy generation code. In addition to the hashes we also // embed timestamps when the auto-generated code was produced. However this isn't used for version // matching, only as a hint to indicate which of two mismatched versions is newer. -// -// +// +// // 3. Runtime vs. DAC // - Desktop, Windows CoreCLR, CoreSystem CoreCLR // In both cases we check this by matching the timestamp in the debug directory of the runtime image -// and the timestamp we store in the DAC table when we generate the DAC dll. This is done in +// and the timestamp we store in the DAC table when we generate the DAC dll. This is done in // code:ClrDataAccess::VerifyDlls. -// +// // - Mac CoreCLR -// On Mac, we don't have a timestamp in the runtime image. Instead, we rely on checking the 16-byte -// UUID in the image. This UUID is used to check whether a symbol file matches the image, so -// conceptually it's the same as the timestamp we use on Windows. This is also done in +// On Mac, we don't have a timestamp in the runtime image. Instead, we rely on checking the 16-byte +// UUID in the image. This UUID is used to check whether a symbol file matches the image, so +// conceptually it's the same as the timestamp we use on Windows. This is also done in // code:ClrDataAccess::VerifyDlls. -// +// //--------------------------------------------------------------------------------------- // // Instantiates a DacDbi Interface object in a live-debugging scenario that matches @@ -681,7 +681,7 @@ CordbProcess::CreateDacDbiInterface() { _ASSERTE(m_pDACDataTarget != NULL); _ASSERTE(m_pDacPrimitives == NULL); // don't double-init - + // Caller has already determined which CLR in the target is being debugged. _ASSERTE(m_clrInstanceId != 0); @@ -699,7 +699,7 @@ CordbProcess::CreateDacDbiInterface() } // - // Get the access interface, passing our callback interfaces (data target, allocator and metadata lookup) + // Get the access interface, passing our callback interfaces (data target, allocator and metadata lookup) // IDacDbiInterface::IAllocator * pAllocator = this; @@ -707,10 +707,10 @@ CordbProcess::CreateDacDbiInterface() typedef HRESULT (STDAPICALLTYPE * PFN_DacDbiInterfaceInstance)( - ICorDebugDataTarget *, + ICorDebugDataTarget *, CORDB_ADDRESS, - IDacDbiInterface::IAllocator *, - IDacDbiInterface::IMetaDataLookup *, + IDacDbiInterface::IAllocator *, + IDacDbiInterface::IMetaDataLookup *, IDacDbiInterface **); IDacDbiInterface* pInterfacePtr = NULL; @@ -724,7 +724,7 @@ CordbProcess::CreateDacDbiInterface() IfFailThrow(hrStatus); // We now have a resource, pInterfacePtr, that needs to be freed. - m_pDacPrimitives = pInterfacePtr; + m_pDacPrimitives = pInterfacePtr; // Setup DAC target consistency checking based on what we're using for DBI m_pDacPrimitives->DacSetTargetConsistencyChecks( m_fAssertOnTargetInconsistency ); @@ -732,7 +732,7 @@ CordbProcess::CreateDacDbiInterface() //--------------------------------------------------------------------------------------- // -// Is the DAC/DBI interface initialized? +// Is the DAC/DBI interface initialized? // // Return Value: // TRUE iff init. @@ -749,14 +749,14 @@ BOOL CordbProcess::IsDacInitialized() //--------------------------------------------------------------------------------------- // -// Get the DAC interface. +// Get the DAC interface. // // Return Value: // the Dac/Dbi interface pointer to the process. // Never returns NULL. // // Assumptions: -// Caller is responsible for ensuring Data-Target is safe to access (eg, not +// Caller is responsible for ensuring Data-Target is safe to access (eg, not // currently running). // Caller is responsible for ensuring DAC-cache is flushed. Call code:CordbProcess::ForceDacFlush // as needed. @@ -778,7 +778,7 @@ IDacDbiInterface * CordbProcess::GetDAC() //--------------------------------------------------------------------------------------- // Get the Data-Target -// +// // Returns: // pointer to the data-target. Should be non-null. // Lifetime of the pointer is until this process object is neutered. @@ -793,9 +793,9 @@ ICorDebugDataTarget * CordbProcess::GetDataTarget() // // Arguments: // pDataTarget - abstracts access to the debuggee. -// clrInstanceId - identifies the CLR instance within the debuggee. (This is the +// clrInstanceId - identifies the CLR instance within the debuggee. (This is the // base address of mscorwks) -// pCordb - Pointer to the implementation of the owning Cordb object implementing the +// pCordb - Pointer to the implementation of the owning Cordb object implementing the // owning ICD interface. // This should go away - we can get the functionality from the pShim. // If this is null, then pShim must be null too. @@ -814,13 +814,13 @@ ICorDebugDataTarget * CordbProcess::GetDataTarget() // //--------------------------------------------------------------------------------------- -// static +// static HRESULT CordbProcess::OpenVirtualProcess( - ULONG64 clrInstanceId, + ULONG64 clrInstanceId, IUnknown * pDataTarget, HMODULE hDacModule, - Cordb* pCordb, - DWORD dwProcessID, + Cordb* pCordb, + DWORD dwProcessID, ShimProcess * pShim, CordbProcess ** ppProcess) { @@ -863,9 +863,9 @@ HRESULT CordbProcess::OpenVirtualProcess( // This will bump reference count. if (pShim != NULL) { - pShim->SetProcess(pProcess); + pShim->SetProcess(pProcess); - _ASSERTE(pShim->GetProcess() == pThis); + _ASSERTE(pShim->GetProcess() == pThis); _ASSERTE(pShim->GetWin32EventThread() != NULL); } @@ -889,7 +889,7 @@ HRESULT CordbProcess::OpenVirtualProcess( // In failure case, pProcess's dtor will do the final release. } - + return hr; } @@ -898,16 +898,16 @@ HRESULT CordbProcess::OpenVirtualProcess( // CordbProcess constructor // // Arguments: -// pDataTarget - Pointer to an implementation of ICorDebugDataTarget +// pDataTarget - Pointer to an implementation of ICorDebugDataTarget // (or ICorDebugMutableDataTarget), which virtualizes access to the process. // clrInstanceId - representation of the CLR to debug in the process. Must be specified // (non-zero) if pShim is NULL. If 0, use the first CLR that we see. -// pCordb - Pointer to the implementation of the owning Cordb object implementing the +// pCordb - Pointer to the implementation of the owning Cordb object implementing the // owning ICD interface. // pW32 - Pointer to the Win32 event thread to use when processing events for this // process. -// dwProcessID - For V3, 0. -// Else for shim codepaths, the processID of the process this object will represent. +// dwProcessID - For V3, 0. +// Else for shim codepaths, the processID of the process this object will represent. // pShim - Pointer to the shim for handling V2 debuggers on the V3 architecture. // //--------------------------------------------------------------------------------------- @@ -920,13 +920,13 @@ CordbProcess::CordbProcess(ULONG64 clrInstanceId, ShimProcess * pShim) : CordbBase(NULL, dwProcessID, enumCordbProcess), m_fDoDelayedManagedAttached(false), - m_cordb(pCordb), - m_handle(NULL), - m_detached(false), + m_cordb(pCordb), + m_handle(NULL), + m_detached(false), m_uninitializedStop(false), m_exiting(false), m_terminated(false), - m_unrecoverableError(false), + m_unrecoverableError(false), m_specialDeferment(false), m_helperThreadDead(false), m_loaderBPReceived(false), @@ -939,7 +939,7 @@ CordbProcess::CordbProcess(ULONG64 clrInstanceId, m_pShim(pShim), m_userThreads(11), m_dataBreakpoints(4), - m_oddSync(false), + m_oddSync(false), #ifdef FEATURE_INTEROP_DEBUGGING m_unmanagedThreads(11), #endif @@ -951,7 +951,7 @@ CordbProcess::CordbProcess(ULONG64 clrInstanceId, m_leftSideEventAvailable(NULL), m_leftSideEventRead(NULL), #if defined(FEATURE_INTEROP_DEBUGGING) - m_leftSideUnmanagedWaitEvent(NULL), + m_leftSideUnmanagedWaitEvent(NULL), #endif // FEATURE_INTEROP_DEBUGGING m_initialized(false), m_stopRequested(false), @@ -965,7 +965,7 @@ CordbProcess::CordbProcess(ULONG64 clrInstanceId, m_lastDispatchedIBEvent(NULL), m_dispatchingUnmanagedEvent(false), m_dispatchingOOBEvent(false), - m_doRealContinueAfterOOBBlock(false), + m_doRealContinueAfterOOBBlock(false), m_state(0), #endif // FEATURE_INTEROP_DEBUGGING m_helperThreadId(0), @@ -1007,8 +1007,8 @@ CordbProcess::CordbProcess(ULONG64 clrInstanceId, m_pProcess.Assign(this); #ifdef _DEBUG - // On Debug builds, we'll ASSERT by default whenever the target appears to be corrupt or - // otherwise inconsistent (both in DAC and DBI). But we also need the ability to + // On Debug builds, we'll ASSERT by default whenever the target appears to be corrupt or + // otherwise inconsistent (both in DAC and DBI). But we also need the ability to // explicitly test corrupt targets. // Tests should set COMPlus_DbgIgnoreInconsistentTarget=1 to suppress these asserts // Note that this controls two things: @@ -1077,19 +1077,19 @@ CordbProcess::~CordbProcess() // We shouldn't still be in Cordb's list of processes. Unfortunately, our root Cordb object // may have already been deleted b/c we're at the mercy of ref-counting, so we can't check. - + _ASSERTE(m_sharedAppDomain == NULL); - + m_processMutex.Destroy(); m_StopGoLock.Destroy(); // These handles were cleared in neuter - _ASSERTE(m_handle == NULL); + _ASSERTE(m_handle == NULL); #if defined(FEATURE_INTEROP_DEBUGGING) _ASSERTE(m_leftSideUnmanagedWaitEvent == NULL); #endif // FEATURE_INTEROP_DEBUGGING _ASSERTE(m_stopWaitEvent == NULL); - + // Set this to mark that we really did cleanup. } @@ -1100,7 +1100,7 @@ CordbProcess::~CordbProcess() // the Cordb object. // // Arguments: -// pCordb - Pointer to the implementation of the owning Cordb object implementing the +// pCordb - Pointer to the implementation of the owning Cordb object implementing the // owning ICD interface. // szProgramName - Name of the program to execute. // szProgramArgs - Command line arguments for the process. @@ -1151,7 +1151,7 @@ HRESULT ShimProcess::CreateProcess( hr = pShim->CreateAndStartWin32ET(pCordb); IfFailThrow(hr); - // Call out to newly created Win32-event Thread to create the process. + // Call out to newly created Win32-event Thread to create the process. // If this succeeds, new CordbProcess will add a ref to the ShimProcess hr = pShim->GetWin32EventThread()->SendCreateProcessEvent(pShim->GetMachineInfo(), szProgramName, @@ -1211,7 +1211,7 @@ HRESULT ShimProcess::DebugActiveProcess( // Indicate that this process was attached to, asopposed to being started under the debugger. pShim->m_attached = true; - + hr = pShim->CreateAndStartWin32ET(pCordb); IfFailThrow(hr); @@ -1232,7 +1232,7 @@ HRESULT ShimProcess::DebugActiveProcess( // after DebugActiveProcess completes which means we must wait here long enough to have set the debuggee // bit indicating managed attach is coming. // However in interop debugging we can't do that because there are debug events which come before the - // loader breakpoint (which is how far we need to get to set the debuggee bit). If we blocked + // loader breakpoint (which is how far we need to get to set the debuggee bit). If we blocked // DebugActiveProcess there then the debug events would be refering to an ICorDebugProcess that hasn't // yet been returned to the caller of DebugActiveProcess. Instead, for interop debugging we force the // native debugger to wait until it gets the loader breakpoint to set the event. Note we can't converge @@ -1259,7 +1259,7 @@ HRESULT ShimProcess::DebugActiveProcess( #endif //!FEATURE_DBGIPC_TRANSPORT_DI } EX_CATCH_HRESULT(hr); - + // If this succeeds, then process takes ownership of thread. Else we need to kill it. if (FAILED(hr)) { @@ -1268,7 +1268,7 @@ HRESULT ShimProcess::DebugActiveProcess( pShim->Dispose(); } } - + // Always release our ref to ShimProcess. If the Process was created, then it takes a reference. return hr; @@ -1285,29 +1285,29 @@ HRESULT ShimProcess::DebugActiveProcess( // code:CordbProcess::IsReadyForDetach) // 3. Caller did code:CordbProcess::NeuterLeftSideResources first // to clean up left-side resources. -// +// // Notes: // This could be called multiple times (code:CordbProcess::FlushAll), so // be sure to null out any potential dangling pointers. State may be rebuilt // up after each time. void CordbProcess::NeuterChildren() -{ +{ _ASSERTE(GetProcessLock()->HasLock()); - + // Frees left-side resources. See assumptions above. m_LeftSideResourceCleanupList.NeuterAndClear(this); - m_EvalTable.Clear(); - + m_EvalTable.Clear(); + - // Sweep neuter lists. + // Sweep neuter lists. m_ExitNeuterList.NeuterAndClear(this); m_ContinueNeuterList.NeuterAndClear(this); m_dataBreakpoints.NeuterAndClear(GetProcessLock()); m_userThreads.NeuterAndClear(GetProcessLock()); - + m_pDefaultAppDomain = NULL; // Frees per-appdomain left-side resources. See assumptions above. @@ -1349,10 +1349,10 @@ void CordbProcess::Neuter() // Take the process lock. RSLockHolder lockHolder(GetProcessLock()); - + NeuterChildren(); - // Release the metadata interfaces + // Release the metadata interfaces m_pMetaDispenser.Clear(); @@ -1379,7 +1379,7 @@ void CordbProcess::Neuter() // W23ET. if (m_pShim != NULL) { - m_pShim->Dispose(); + m_pShim->Dispose(); m_pShim.Clear(); } } @@ -1398,24 +1398,24 @@ void CordbProcess::Neuter() m_pEventChannel->Delete(); m_pEventChannel = NULL; } - - // Need process lock to clear the patch table + + // Need process lock to clear the patch table ClearPatchTable(); - + CordbProcess::CloseIPCHandles(); CordbBase::Neuter(); - + m_cordb.Clear(); // Need to release this reference to ourselves. Other leaf objects may still hold // strong references back to this CordbProcess object. _ASSERTE(m_pProcess == this); - m_pProcess.Clear(); + m_pProcess.Clear(); } // Wrapper to return metadata dispenser. -// +// // Notes: // Does not adjust reference count of dispenser. // Dispenser is destroyed in code:CordbProcess::Neuter @@ -1484,7 +1484,7 @@ void CordbProcess::CloseIPCHandles() // S_OK on success. //----------------------------------------------------------------------------- HRESULT ShimProcess::CreateAndStartWin32ET(Cordb * pCordb) -{ +{ // // Create the win32 event listening thread @@ -1524,13 +1524,13 @@ HRESULT ShimProcess::CreateAndStartWin32ET(Cordb * pCordb) // // Return Value: // TRUE - DAC is initialized. -// FALSE - Not initialized, but can try again later. Common case if +// FALSE - Not initialized, but can try again later. Common case if // target has not yet loaded the runtime. // Throws exception - fatal. // // Assumptions: // Target is stopped by OS, so we can safely inspect it without it moving on us. -// +// // Notes: // This can be called eagerly to sniff if the LS is initialized. // @@ -1545,9 +1545,9 @@ BOOL CordbProcess::TryInitializeDac() // Target is stopped by OS, so we can safely inspect it without it moving on us. - // We want to avoid exceptions in the normal case, so we do some pre-checks + // We want to avoid exceptions in the normal case, so we do some pre-checks // to detect failure without relying on exceptions. - // Can't initialize DAC until mscorwks is loaded. So that's a sanity test. + // Can't initialize DAC until mscorwks is loaded. So that's a sanity test. HRESULT hr = EnsureClrInstanceIdSet(); if (FAILED(hr)) { @@ -1568,7 +1568,7 @@ BOOL CordbProcess::TryInitializeDac() // Load & Init DAC, expecting to succeed. // // Return Value: -// Throws on failure. +// Throws on failure. // // Assumptions: // Caller invokes this at a point where they can expect it to succeed. @@ -1578,7 +1578,7 @@ BOOL CordbProcess::TryInitializeDac() // Notes: // This needs to succeed, and should always succeed (baring a bad installation) // so we assert on failure paths. -// This may be called mutliple times. +// This may be called mutliple times. // //--------------------------------------------------------------------------------------- void CordbProcess::InitializeDac() @@ -1601,8 +1601,8 @@ void CordbProcess::InitializeDac() { LOG((LF_CORDB, LL_INFO1000, "Dac already loaded, 0x%p\n", (HMODULE)m_hDacModule)); } - - // Always flush dac. + + // Always flush dac. ForceDacFlush(); } @@ -1611,7 +1611,7 @@ void CordbProcess::InitializeDac() // Free DAC resources // // Notes: -// This should clean up state such that code:CordbProcess::InitializeDac could be called again. +// This should clean up state such that code:CordbProcess::InitializeDac could be called again. // //--------------------------------------------------------------------------------------- void CordbProcess::FreeDac() @@ -1645,12 +1645,12 @@ IEventChannel * CordbProcess::GetEventChannel() // Mark that the process is being interop-debugged. // // Notes: -// @dbgtodo shim: this should eventually move into the shim or go away. +// @dbgtodo shim: this should eventually move into the shim or go away. // It's only to support V2 legacy interop-debugging. // Called after code:CordbProcess::Init if we want to enable interop debugging. // This allows us to separate out Interop-debugging flags from the core initialization, // and paves the way for us to eventually remove it. -// +// // Since we're always on the naitve-pipeline, the Enabling interop debugging just changes // how the native debug events are being handled. So this must be called after Init, but // before any events are actually handled. @@ -1672,7 +1672,7 @@ void CordbProcess::EnableInteropDebugging() m_state |= PS_WIN32_ATTACHED; if (GetDCB() != NULL) { - GetDCB()->m_rightSideIsWin32Debugger = true; + GetDCB()->m_rightSideIsWin32Debugger = true; UpdateLeftSideDCBField(&(GetDCB()->m_rightSideIsWin32Debugger), sizeof(GetDCB()->m_rightSideIsWin32Debugger)); } @@ -1702,7 +1702,7 @@ void CordbProcess::EnableInteropDebugging() HRESULT CordbProcess::Init() { INTERNAL_API_ENTRY(this); - + HRESULT hr = S_OK; BOOL fIsLSStarted = FALSE; // see meaning below. @@ -1735,13 +1735,13 @@ HRESULT CordbProcess::Init() m_pMetaDataLocator.Clear(); hr = m_pDACDataTarget->QueryInterface(IID_ICorDebugMetaDataLocator, reinterpret_cast<void **>(&m_pMetaDataLocator)); - - // Get the metadata dispenser. + + // Get the metadata dispenser. hr = InternalCreateMetaDataDispenser(IID_IMetaDataDispenserEx, (void **)&m_pMetaDispenser); - // We statically link in the dispenser. We expect it to succeed, except for OOM, which + // We statically link in the dispenser. We expect it to succeed, except for OOM, which // debugger doesn't yet handle. - SIMPLIFYING_ASSUMPTION_SUCCEEDED(hr); + SIMPLIFYING_ASSUMPTION_SUCCEEDED(hr); IfFailThrow(hr); _ASSERTE(m_pMetaDispenser != NULL); @@ -1764,9 +1764,9 @@ HRESULT CordbProcess::Init() // Managed debugging is built on the native-pipeline, and that will detect against double-attaches. // @dbgtodo shim: In V2, LSEA + LSER were used by the LS's helper thread. Now with the V3 pipeline, - // that helper-thread uses native-debug events. The W32ET gets those events and then uses LSEA, LSER to + // that helper-thread uses native-debug events. The W32ET gets those events and then uses LSEA, LSER to // signal existing RS infrastructure. Eventually get rid of LSEA, LSER completely. - // + // m_leftSideEventAvailable = WszCreateEvent(NULL, FALSE, FALSE, NULL); if (m_leftSideEventAvailable == NULL) @@ -1813,11 +1813,11 @@ HRESULT CordbProcess::Init() // This means there's an overlap: if we catch it at phase 5, we'll just get // an extra Startup exception from phase 6, which is safe. This overlap is good // because it means there's no bad window to do an attach in. - + // fIsLSStarted means before phase 6 (eg, RS should expect a startup exception) // Determines if the LS is started. - + { BOOL fReady = TryInitializeDac(); @@ -1827,7 +1827,7 @@ HRESULT CordbProcess::Init() _ASSERTE(m_pDacPrimitives != NULL); fIsLSStarted = m_pDacPrimitives->IsLeftSideInitialized(); } - else + else { _ASSERTE(m_pDacPrimitives == NULL); @@ -1836,8 +1836,8 @@ HRESULT CordbProcess::Init() _ASSERTE(!fIsLSStarted); } } - - + + if (fIsLSStarted) { // Left-side has started up. This is common for Attach cases when managed-code is already running. @@ -1857,7 +1857,7 @@ HRESULT CordbProcess::Init() } else { - // In the V3 pipeline case, if we have the DD-interface, then the runtime is loaded + // In the V3 pipeline case, if we have the DD-interface, then the runtime is loaded // and we consider it initialized. if (IsDacInitialized()) { @@ -1937,11 +1937,11 @@ void CordbProcess::QueueManagedAttachIfNeeded() //--------------------------------------------------------------------------------------- // Hook from Shim to request a managed attach IPC event -// +// // Notes: -// Called by shim after the loader-breakpoint is handled. +// Called by shim after the loader-breakpoint is handled. // @dbgtodo sync: ths should go away once the shim can initiate -// a sync +// a sync void CordbProcess::QueueManagedAttachIfNeededWorker() { HRESULT hrQueue = S_OK; @@ -1949,16 +1949,16 @@ void CordbProcess::QueueManagedAttachIfNeededWorker() // m_fDoDelayedManagedAttached ensures that we only send an Attach event if the LS is actually present. if (m_fDoDelayedManagedAttached && GetShim()->GetAttached()) { - RSLockHolder lockHolder(&this->m_processMutex); - GetDAC()->MarkDebuggerAttachPending(); + RSLockHolder lockHolder(&this->m_processMutex); + GetDAC()->MarkDebuggerAttachPending(); hrQueue = this->QueueManagedAttach(); - } - + } + if (m_pShim != NULL) m_pShim->SetMarkAttachPendingEvent(); - - IfFailThrow(hrQueue); + + IfFailThrow(hrQueue); } //--------------------------------------------------------------------------------------- @@ -1984,19 +1984,19 @@ HRESULT CordbProcess::QueueManagedAttach() // We don't know what Queue it. SendAttachProcessWorkItem * pItem = new (nothrow) SendAttachProcessWorkItem(this); - + if (pItem == NULL) { return E_OUTOFMEMORY; } - + this->m_cordb->m_rcEventThread->QueueAsyncWorkItem(pItem); - + return S_OK; } // However, we still want to synchronize. -// @dbgtodo sync: when we hoist attaching, we can send an DB_IPCE_ASYNC_BREAK event instead or Attach +// @dbgtodo sync: when we hoist attaching, we can send an DB_IPCE_ASYNC_BREAK event instead or Attach // (for V2 semantics, we still need to synchronize the process)? void SendAttachProcessWorkItem::Do() { @@ -2006,10 +2006,10 @@ void SendAttachProcessWorkItem::Do() RSLockHolder ch(this->GetProcess()->GetStopGoLock()); DebuggerIPCEvent *event = (DebuggerIPCEvent*) _alloca(CorDBIPC_BUFFER_SIZE); - + // This just acts like an async-break, which will kick off things. // This will not induce any faked attach events from the VM (like it did in V2). - // The Left-side will still slip foward allowing the async-break to happen, so + // The Left-side will still slip foward allowing the async-break to happen, so // we may get normal debug events in addition to the sync-complete. // // 1. In the common attach case, we should just get a sync-complete. @@ -2017,12 +2017,12 @@ void SendAttachProcessWorkItem::Do() GetProcess()->InitAsyncIPCEvent(event, DB_IPCE_ATTACHING, VMPTR_AppDomain::NullPtr()); // This should result in a sync-complete from the Left-side, which will be raised as an exception - // that the debugger passes into Filter and then internally goes through code:CordbProcess::TriageSyncComplete + // that the debugger passes into Filter and then internally goes through code:CordbProcess::TriageSyncComplete // and that triggers code:CordbRCEventThread::FlushQueuedEvents to be called on the RCET. // We already pre-queued a fake CreateProcess event. - // The left-side will also mark itself as attached in response to this event. - // We explicitly don't mark it as attached from the right-side because we want to let the left-side + // The left-side will also mark itself as attached in response to this event. + // We explicitly don't mark it as attached from the right-side because we want to let the left-side // synchronize first (to stop all running threads) before marking the debugger as attached. LOG((LF_CORDB, LL_INFO1000, "[%x] CP::S: sending attach.\n", GetCurrentThreadId())); @@ -2042,7 +2042,7 @@ void SendAttachProcessWorkItem::Do() // // Notes: // This does not create the thread object if it's not cached. Caching is unpredictable, -// and so this may appear to randomly return NULL. +// and so this may appear to randomly return NULL. // Callers should prefer code:CordbProcess::LookupOrCreateThread unless they expicitly // want to check RS state. CordbThread * CordbProcess::TryLookupThread(VMPTR_Thread vmThread) @@ -2063,7 +2063,7 @@ CordbThread * CordbProcess::TryLookupThread(VMPTR_Thread vmThread) // // Notes: // OS Thread ID is not fiber-safe, so this is a dangerous function to call. -// Avoid this as much as possible. Prefer using VMPTR_Thread and +// Avoid this as much as possible. Prefer using VMPTR_Thread and // code:CordbProcess::LookupOrCreateThread instead of OS thread IDs. // See code:CordbThread::GetID for details. CordbThread * CordbProcess::TryLookupOrCreateThreadByVolatileOSId(DWORD dwThreadId) @@ -2073,7 +2073,7 @@ CordbThread * CordbProcess::TryLookupOrCreateThreadByVolatileOSId(DWORD dwThread } //--------------------------------------------------------------------------------------- -// Lookup a cached CordbThread object by the tid. Returns null if not in the cache (which +// Lookup a cached CordbThread object by the tid. Returns null if not in the cache (which // includes unmanged thread) // // Arguments: @@ -2089,7 +2089,7 @@ CordbThread * CordbProcess::TryLookupOrCreateThreadByVolatileOSId(DWORD dwThread // * OS Thread ID is not fiber-safe, so this is a dangerous function to call. // * This is juts a Lookup, not LookupOrCreate, so it should only be used by methods // that care about the RS state (instead of just LS state). -// Prefer using VMPTR_Thread and code:CordbProcess::LookupOrCreateThread +// Prefer using VMPTR_Thread and code:CordbProcess::LookupOrCreateThread // CordbThread * CordbProcess::TryLookupThreadByVolatileOSId(DWORD dwThreadId) { @@ -2109,7 +2109,7 @@ CordbThread * CordbProcess::TryLookupThreadByVolatileOSId(DWORD dwThreadId) } // This OS thread ID does not match any managed thread id. - return NULL; + return NULL; } //--------------------------------------------------------------------------------------- @@ -2209,12 +2209,12 @@ HRESULT CordbProcess::QueryInterface(REFIID id, void **pInterface) HRESULT CordbProcess::ProcessStateChanged(CorDebugStateChange eChange) { HRESULT hr = S_OK; - PUBLIC_API_BEGIN(this) - { + PUBLIC_API_BEGIN(this) + { switch(eChange) { - case PROCESS_RUNNING: - FlushProcessRunning(); + case PROCESS_RUNNING: + FlushProcessRunning(); break; case FLUSH_ALL: @@ -2235,11 +2235,11 @@ HRESULT CordbProcess::EnumerateHeap(ICorDebugHeapEnum **ppObjects) { if (!ppObjects) return E_POINTER; - + HRESULT hr = S_OK; PUBLIC_API_ENTRY(this); ATT_REQUIRE_STOPPED_MAY_FAIL(this); - + EX_TRY { if (m_pDacPrimitives->AreGCStructuresValid()) @@ -2252,9 +2252,9 @@ HRESULT CordbProcess::EnumerateHeap(ICorDebugHeapEnum **ppObjects) { hr = CORDBG_E_GC_STRUCTURES_INVALID; } - } + } EX_CATCH_HRESULT(hr); - + return hr; } @@ -2262,17 +2262,17 @@ HRESULT CordbProcess::GetGCHeapInformation(COR_HEAPINFO *pHeapInfo) { if (!pHeapInfo) return E_INVALIDARG; - + HRESULT hr = S_OK; PUBLIC_API_ENTRY(this); ATT_REQUIRE_STOPPED_MAY_FAIL(this); - + EX_TRY { GetDAC()->GetGCHeapInformation(pHeapInfo); } EX_CATCH_HRESULT(hr); - + return hr; } @@ -2284,12 +2284,12 @@ HRESULT CordbProcess::EnumerateHeapRegions(ICorDebugHeapSegmentEnum **ppRegions) HRESULT hr = S_OK; PUBLIC_API_ENTRY(this); ATT_REQUIRE_STOPPED_MAY_FAIL(this); - + EX_TRY { DacDbiArrayList<COR_SEGMENT> segments; hr = GetDAC()->GetHeapSegments(&segments); - + if (SUCCEEDED(hr)) { if (!segments.IsEmpty()) @@ -2305,17 +2305,17 @@ HRESULT CordbProcess::EnumerateHeapRegions(ICorDebugHeapSegmentEnum **ppRegions) } } EX_CATCH_HRESULT(hr); - + return hr; } HRESULT CordbProcess::GetObject(CORDB_ADDRESS addr, ICorDebugObjectValue **pObject) { HRESULT hr = S_OK; - + PUBLIC_REENTRANT_API_ENTRY(this); ATT_REQUIRE_STOPPED_MAY_FAIL(this); - + EX_TRY { if (!m_pDacPrimitives->IsValidObject(addr)) @@ -2330,22 +2330,22 @@ HRESULT CordbProcess::GetObject(CORDB_ADDRESS addr, ICorDebugObjectValue **pObje { RSLockHolder ch(GetProcess()->GetStopGoLock()); RSLockHolder procLock(this->GetProcess()->GetProcessLock()); - + CordbAppDomain *cdbAppDomain = NULL; CordbType *pType = NULL; hr = GetTypeForObject(addr, &pType, &cdbAppDomain); - + if (SUCCEEDED(hr)) { _ASSERTE(pType != NULL); _ASSERTE(cdbAppDomain != NULL); - + DebuggerIPCE_ObjectData objData; m_pDacPrimitives->GetBasicObjectInfo(addr, ELEMENT_TYPE_CLASS, cdbAppDomain->GetADToken(), &objData); - + NewHolder<CordbObjectValue> pNewObjectValue(new CordbObjectValue(cdbAppDomain, pType, TargetBuffer(addr, (ULONG)objData.objSize), &objData)); hr = pNewObjectValue->Init(); - + if (SUCCEEDED(hr)) { hr = pNewObjectValue->QueryInterface(__uuidof(ICorDebugObjectValue), (void**)pObject); @@ -2365,11 +2365,11 @@ HRESULT CordbProcess::EnumerateGCReferences(BOOL enumerateWeakReferences, ICorDe { if (!ppEnum) return E_POINTER; - + HRESULT hr = S_OK; PUBLIC_API_ENTRY(this); ATT_REQUIRE_STOPPED_MAY_FAIL(this); - + EX_TRY { CordbRefEnum *pRefEnum = new CordbRefEnum(this, enumerateWeakReferences); @@ -2384,11 +2384,11 @@ HRESULT CordbProcess::EnumerateHandles(CorGCReferenceType types, ICorDebugGCRefe { if (!ppEnum) return E_POINTER; - + HRESULT hr = S_OK; PUBLIC_API_ENTRY(this); ATT_REQUIRE_STOPPED_MAY_FAIL(this); - + EX_TRY { CordbRefEnum *pRefEnum = new CordbRefEnum(this, types); @@ -2396,7 +2396,7 @@ HRESULT CordbProcess::EnumerateHandles(CorGCReferenceType types, ICorDebugGCRefe hr = pRefEnum->QueryInterface(IID_ICorDebugGCReferenceEnum, (void**)ppEnum); } EX_CATCH_HRESULT(hr); - + return hr; } @@ -2410,17 +2410,17 @@ HRESULT CordbProcess::GetTypeID(CORDB_ADDRESS obj, COR_TYPEID *pId) { if (pId == NULL) return E_POINTER; - + HRESULT hr = S_OK; PUBLIC_API_ENTRY(this); ATT_REQUIRE_STOPPED_MAY_FAIL(this); - + EX_TRY { hr = GetProcess()->GetDAC()->GetTypeID(obj, pId); } EX_CATCH_HRESULT(hr); - + return hr; } @@ -2428,13 +2428,13 @@ HRESULT CordbProcess::GetTypeForTypeID(COR_TYPEID id, ICorDebugType **ppType) { if (ppType == NULL) return E_POINTER; - + HRESULT hr = S_OK; - + PUBLIC_API_ENTRY(this); RSLockHolder stopGoLock(this->GetProcess()->GetStopGoLock()); RSLockHolder procLock(this->GetProcess()->GetProcessLock()); - + EX_TRY { DebuggerIPCE_ExpandedTypeData data; @@ -2445,7 +2445,7 @@ HRESULT CordbProcess::GetTypeForTypeID(COR_TYPEID id, ICorDebugType **ppType) if (SUCCEEDED(hr)) hr = type->QueryInterface(IID_ICorDebugType, (void**)ppType); - } + } EX_CATCH_HRESULT(hr); return hr; @@ -2456,12 +2456,12 @@ COM_METHOD CordbProcess::GetArrayLayout(COR_TYPEID id, COR_ARRAY_LAYOUT *pLayout { if (pLayout == NULL) return E_POINTER; - + HRESULT hr = S_OK; PUBLIC_API_BEGIN(this); hr = GetProcess()->GetDAC()->GetArrayLayout(id, pLayout); - + PUBLIC_API_END(hr); return hr; } @@ -2470,12 +2470,12 @@ COM_METHOD CordbProcess::GetTypeLayout(COR_TYPEID id, COR_TYPE_LAYOUT *pLayout) { if (pLayout == NULL) return E_POINTER; - + HRESULT hr = S_OK; PUBLIC_API_BEGIN(this); - + hr = GetProcess()->GetDAC()->GetTypeLayout(id, pLayout); - + PUBLIC_API_END(hr); return hr; } @@ -2484,9 +2484,9 @@ COM_METHOD CordbProcess::GetTypeFields(COR_TYPEID id, ULONG32 celt, COR_FIELD fi { HRESULT hr = S_OK; PUBLIC_API_BEGIN(this); - + hr = GetProcess()->GetDAC()->GetObjectFields(id, celt, fields, pceltNeeded); - + PUBLIC_API_END(hr); return hr; } @@ -2495,7 +2495,7 @@ COM_METHOD CordbProcess::SetWriteableMetadataUpdateMode(WriteableMetadataUpdateM { HRESULT hr = S_OK; PUBLIC_API_BEGIN(this); - + if(flags != LegacyCompatPolicy && flags != AlwaysShowUpdates) { @@ -2513,7 +2513,7 @@ COM_METHOD CordbProcess::SetWriteableMetadataUpdateMode(WriteableMetadataUpdateM { m_writableMetadataUpdateMode = flags; } - + PUBLIC_API_END(hr); return hr; } @@ -2653,7 +2653,7 @@ COM_METHOD CordbProcess::CreateBreakpoint(CORDB_ADDRESS address, ICorDebugValueB EX_TRY { RSInitHolder<CordbValueBreakpoint> pValueBreakpoint(new CordbValueBreakpoint(m_dataBreakpoints.GetCount(), nullptr, this)); - + if (pValueBreakpoint) { hr = pValueBreakpoint->QueryInterface(IID_ICorDebugValueBreakpoint, (void**)ppBreakpoint); @@ -2685,20 +2685,20 @@ HRESULT CordbProcess::GetTypeForObject(CORDB_ADDRESS addr, CordbType **ppType, C VMPTR_AppDomain appDomain; VMPTR_Module mod; VMPTR_DomainFile domainFile; - + HRESULT hr = E_FAIL; if (GetDAC()->GetAppDomainForObject(addr, &appDomain, &mod, &domainFile)) { CordbAppDomain *cdbAppDomain = appDomain.IsNull() ? GetSharedAppDomain() : LookupOrCreateAppDomain(appDomain); - + _ASSERTE(cdbAppDomain); - + DebuggerIPCE_ExpandedTypeData data; GetDAC()->GetObjectExpandedTypeInfo(AllBoxed, appDomain, addr, &data); CordbType *type = 0; hr = CordbType::TypeDataToType(cdbAppDomain, &data, &type); - + if (SUCCEEDED(hr)) { *ppType = type; @@ -2706,7 +2706,7 @@ HRESULT CordbProcess::GetTypeForObject(CORDB_ADDRESS addr, CordbType **ppType, C *pAppDomain = cdbAppDomain; } } - + return hr; } @@ -2738,10 +2738,10 @@ void CordbRefEnum::Neuter() } EX_CATCH { - _ASSERTE(!"Hit an error freeing a ref walk."); + _ASSERTE(!"Hit an error freeing a ref walk."); } EX_END_CATCH(SwallowAllExceptions) - + CordbBase::Neuter(); } @@ -2749,7 +2749,7 @@ HRESULT CordbRefEnum::QueryInterface(REFIID riid, void **ppInterface) { if (ppInterface == NULL) return E_INVALIDARG; - + if (riid == IID_ICorDebugGCReferenceEnum) { *ppInterface = static_cast<ICorDebugGCReferenceEnum*>(this); @@ -2786,7 +2786,7 @@ HRESULT CordbRefEnum::Reset() } } EX_CATCH_HRESULT(hr); - + return hr; } @@ -2807,52 +2807,52 @@ HRESULT CordbRefEnum::Next(ULONG celt, COR_GC_REFERENCE refs[], ULONG *pceltFetc { if (refs == NULL || pceltFetched == NULL) return E_POINTER; - + CordbProcess *process = GetProcess(); HRESULT hr = S_OK; - + PUBLIC_API_ENTRY(this); FAIL_IF_NEUTERED(this); ATT_REQUIRE_STOPPED_MAY_FAIL(process); - + RSLockHolder procLockHolder(process->GetProcessLock()); - + EX_TRY { if (!mRefHandle) hr = process->GetDAC()->CreateRefWalk(&mRefHandle, mEnumStacksFQ, mEnumStacksFQ, mHandleMask); - + if (SUCCEEDED(hr)) { DacGcReference dacRefs[32]; ULONG toFetch = _countof(dacRefs); ULONG total = 0; - + for (ULONG c = 0; SUCCEEDED(hr) && c < (celt/_countof(dacRefs) + 1); ++c) { // Fetch 32 references at a time, the last time, only fetch the remainder (that is, if // the user didn't fetch a multiple of 32). if (c == celt/_countof(dacRefs)) toFetch = celt % _countof(dacRefs); - + ULONG fetched = 0; hr = process->GetDAC()->WalkRefs(mRefHandle, toFetch, dacRefs, &fetched); - + if (SUCCEEDED(hr)) { for (ULONG i = 0; i < fetched; ++i) { CordbAppDomain *pDomain = process->LookupOrCreateAppDomain(dacRefs[i].vmDomain); - + ICorDebugAppDomain *pAppDomain; ICorDebugValue *pOutObject = NULL; if (dacRefs[i].pObject & 1) { dacRefs[i].pObject &= ~1; ICorDebugObjectValue *pObjValue = NULL; - + hr = process->GetObject(dacRefs[i].pObject, &pObjValue); - + if (SUCCEEDED(hr)) { hr = pObjValue->QueryInterface(IID_ICorDebugValue, (void**)&pOutObject); @@ -2865,32 +2865,32 @@ HRESULT CordbRefEnum::Next(ULONG celt, COR_GC_REFERENCE refs[], ULONG *pceltFetc IfFailThrow(CordbReferenceValue::BuildFromGCHandle(pDomain, dacRefs[i].objHnd, &tmpValue)); - + if (SUCCEEDED(hr)) { hr = tmpValue->QueryInterface(IID_ICorDebugValue, (void**)&pOutObject); tmpValue->Release(); } } - + if (SUCCEEDED(hr) && pDomain) { hr = pDomain->QueryInterface(IID_ICorDebugAppDomain, (void**)&pAppDomain); } - + if (FAILED(hr)) break; - + refs[total].Domain = pAppDomain; refs[total].Location = pOutObject; refs[total].Type = (CorGCReferenceType)dacRefs[i].dwType; refs[total].ExtraData = dacRefs[i].i64ExtraData; - + total++; } } } - + *pceltFetched = total; } } @@ -2912,7 +2912,7 @@ HRESULT CordbHeapEnum::QueryInterface(REFIID riid, void **ppInterface) { if (ppInterface == NULL) return E_INVALIDARG; - + if (riid == IID_ICorDebugHeapEnum) { *ppInterface = static_cast<ICorDebugHeapEnum*>(this); @@ -2954,7 +2954,7 @@ void CordbHeapEnum::Clear() } EX_CATCH { - _ASSERTE(!"Hit an error freeing the heap walk."); + _ASSERTE(!"Hit an error freeing the heap walk."); } EX_END_CATCH(SwallowAllExceptions) } @@ -2989,17 +2989,17 @@ HRESULT CordbHeapEnum::Next(ULONG celt, COR_HEAPOBJECT objects[], ULONG *pceltFe hr = GetProcess()->GetDAC()->WalkHeap(mHeapHandle, celt, objects, &fetched); _ASSERTE(fetched <= celt); } - + if (SUCCEEDED(hr)) { // Return S_FALSE if we've reached the end of the enum. if (fetched < celt) hr = S_FALSE; } - } + } EX_CATCH_HRESULT(hr); - // Set the fetched parameter to reflect the number of elements (if any) + // Set the fetched parameter to reflect the number of elements (if any) // that were successfully saved to "objects" if (pceltFetched) *pceltFetched = fetched; @@ -3009,33 +3009,33 @@ HRESULT CordbHeapEnum::Next(ULONG celt, COR_HEAPOBJECT objects[], ULONG *pceltFe //--------------------------------------------------------------------------------------- // Flush state for when the process starts running. -// +// // Notes: // Helper for code:CordbProcess::ProcessStateChanged. -// Since ICD Arrowhead does not own the eventing pipeline, it needs the debugger to +// Since ICD Arrowhead does not own the eventing pipeline, it needs the debugger to // notifying it of when the process is running again. This is like the counterpart // to code:CordbProcess::Filter void CordbProcess::FlushProcessRunning() { _ASSERTE(GetProcessLock()->HasLock()); - + // Update the continue counter. m_continueCounter++; // Safely dispose anything that should be neutered on continue. - MarkAllThreadsDirty(); + MarkAllThreadsDirty(); ForceDacFlush(); } //--------------------------------------------------------------------------------------- // Flush all cached state and bring us back to "cold startup" -// +// // Notes: // Helper for code:CordbProcess::ProcessStateChanged. // This is used if the data-target changes underneath us in a way that is // not consistent with the process running forward. For example, if for // a time-travel debugger, the data-target may flow "backwards" in time. -// +// void CordbProcess::FlushAll() { CONTRACTL @@ -3054,7 +3054,7 @@ void CordbProcess::FlushAll() hr = IsReadyForDetach(); IfFailThrow(hr); - // Check for outstanding CordbHandle values. + // Check for outstanding CordbHandle values. if (OutstandingHandles()) { ThrowHR(CORDBG_E_DETACH_FAILED_OUTSTANDING_TARGET_RESOURCES); @@ -3066,7 +3066,7 @@ void CordbProcess::FlushAll() // If we detach before the CLR is loaded into the debuggee, then we can no-op a lot of work. // We sure can't be sending IPC events to the LS before it exists. - NeuterChildren(); + NeuterChildren(); } //--------------------------------------------------------------------------------------- @@ -3090,14 +3090,14 @@ void CordbProcess::FlushAll() // in V3, especially w.r.t to an attach bit. //--------------------------------------------------------------------------------------- HRESULT CordbProcess::Detach() -{ +{ PUBLIC_API_ENTRY(this); FAIL_IF_NEUTERED(this); if (IsInteropDebugging()) { - return CORDBG_E_INTEROP_NOT_SUPPORTED; + return CORDBG_E_INTEROP_NOT_SUPPORTED; } @@ -3108,7 +3108,7 @@ HRESULT CordbProcess::Detach() // @todo- why can't we enforce that the managed event Q is drained? ATT_REQUIRE_SYNCED_OR_NONINIT_MAY_FAIL(this); - + hr = IsReadyForDetach(); if (FAILED(hr)) { @@ -3121,13 +3121,13 @@ HRESULT CordbProcess::Detach() RSSmartPtr<CordbProcess> pRef(this); - + LOG((LF_CORDB, LL_INFO1000, "CP::Detach - beginning\n")); if (m_pShim == NULL) // This API is moved off to the shim { - - // This is still invasive. - // Ignore failures. This will fail for a non-invasive target. + + // This is still invasive. + // Ignore failures. This will fail for a non-invasive target. if (IsDacInitialized()) { HRESULT hrIgnore = S_OK; @@ -3139,10 +3139,10 @@ HRESULT CordbProcess::Detach() } } else - { + { EX_TRY { - DetachShim(); + DetachShim(); } EX_CATCH_HRESULT(hr); } @@ -3156,7 +3156,7 @@ HRESULT CordbProcess::Detach() } // Free up key left-side resources -// +// // Called on detach // This does key neutering of objects that hold left-side resources and require // preemptively freeing the resources. @@ -3164,24 +3164,24 @@ HRESULT CordbProcess::Detach() void CordbProcess::NeuterChildrenLeftSideResources() { _ASSERTE(GetStopGoLock()->HasLock()); - + _ASSERTE(!GetProcessLock()->HasLock()); RSLockHolder lockHolder(GetProcessLock()); - + // Need process-lock to operate on hashtable, but can't yet Neuter under process-lock, // so we have to copy the contents to an auxilary list which we can then traverse outside the lock. RSPtrArray<CordbAppDomain> listAppDomains; m_appDomains.CopyToArray(&listAppDomains); - - + + // Must not hold process lock so that we can be safe to send IPC events // to cleanup left-side resources. lockHolder.Release(); _ASSERTE(!GetProcessLock()->HasLock()); - // Frees left-side resources. This may send IPC events. + // Frees left-side resources. This may send IPC events. // This will make normal neutering a nop. m_LeftSideResourceCleanupList.NeuterLeftSideResourcesAndClear(this); @@ -3191,20 +3191,20 @@ void CordbProcess::NeuterChildrenLeftSideResources() // CordbHandleValue is in the appdomain exit list, and that needs // to send an IPC event to cleanup and release the handle from - // the GCs handle table. + // the GCs handle table. pAppDomain->GetSweepableExitNeuterList()->NeuterLeftSideResourcesAndClear(this); } listAppDomains.Clear(); - + } //--------------------------------------------------------------------------------------- // Detach the Debugger from the LS process for the V2 case -// +// // Assumptions: // This will NeuterChildren(), caller will do the real Neuter() // Caller has already ensured that detach is safe. -// +// // @dbgtodo attach-bit: this should be moved into the shim; need // to figure out semantics for freeing left-side resources (especially GC // handles) on detach. @@ -3217,7 +3217,7 @@ void CordbProcess::DetachShim() // If we detach before the CLR is loaded into the debuggee, then we can no-op a lot of work. // We sure can't be sending IPC events to the LS before it exists. if (m_initialized) - { + { // The managed event queue is not necessarily drained. Cordbg could call detach between any callback. // While the process is still stopped, neuter all of our children. // This will make our Neuter() a nop and saves the W32ET from having to do dangerous work. @@ -3238,7 +3238,7 @@ void CordbProcess::DetachShim() else { // @dbgtodo attach-bit: push this up, once detach IPC event is hoisted. - RSLockHolder lockHolder(GetProcessLock()); + RSLockHolder lockHolder(GetProcessLock()); // Shouldn't have any appdomains. (void)hashFind; //prevent "unused variable" error from GCC @@ -3267,7 +3267,7 @@ void CordbProcess::DetachShim() m_detached = true; } IfFailThrow(hr); - + // Now that all complicated cleanup is done, caller can do a final neuter. // This will implicitly stop our Win32 event thread as well. @@ -3361,7 +3361,7 @@ HRESULT CordbProcess::Terminate(unsigned int exitCode) // @dbgtodo shutdown: eventually, all of Terminate() will be in the Shim. - // Free all the remaining events. Since this will call into the shim, do this outside of any locks. + // Free all the remaining events. Since this will call into the shim, do this outside of any locks. // (ATT_ takes locks). DeleteQueuedEvents(); @@ -3401,7 +3401,7 @@ HRESULT CordbProcess::Terminate(unsigned int exitCode) // // Note that on Windows, the process isn't really terminated until we receive the EXIT_PROCESS_DEBUG_EVENT. // Before then, we can still still access the debuggee's address space. On the other, for Mac debugging, - // the process can die any time after this call, and so we can no longer call into the DAC. + // the process can die any time after this call, and so we can no longer call into the DAC. GetShim()->GetNativePipeline()->TerminateProcess(exitCode); // We just call Continue() so that the debugger doesn't have to. (It's arguably odd @@ -3431,8 +3431,8 @@ HRESULT CordbProcess::GetID(DWORD *pdwProcessId) { // This shouldn't be used in V3 paths. Normally, we can enforce that by checking against // m_pShim. However, this API can be called after being neutered, in which case m_pShim is cleared. - // So check against 0 instead. - if (m_id == 0) + // So check against 0 instead. + if (m_id == 0) { *pdwProcessId = 0; ThrowHR(E_NOTIMPL); @@ -3512,11 +3512,11 @@ HRESULT CordbProcess::StopInternal(DWORD dwTimeout, VMPTR_AppDomain pAppDomainTo // Stop + Continue are executed under the Stop-Go lock. This makes them atomic. // We'll toggle the process-lock (b/c we communicate w/ the W32et, so just the process-lock is // not sufficient to make this atomic). - // It's ok to take this lock before checking if the CordbProcess has been neutered because + // It's ok to take this lock before checking if the CordbProcess has been neutered because // the lock is destroyed in the dtor after neutering. RSLockHolder ch(&m_StopGoLock); - // Check if this CordbProcess has been neutered under the SG lock. + // Check if this CordbProcess has been neutered under the SG lock. // Otherwise it's possible to race with Detach() and Terminate(). FAIL_IF_NEUTERED(this); CORDBFailIfOnWin32EventThread(this); @@ -3756,7 +3756,7 @@ HRESULT CordbProcess::Continue(BOOL fIsOutOfBand) if (m_pShim == NULL) // This API is moved off to the shim { // bias towards failing with CORDBG_E_NUETERED. - FAIL_IF_NEUTERED(this); + FAIL_IF_NEUTERED(this); return E_NOTIMPL; } @@ -3985,7 +3985,7 @@ HRESULT CordbProcess::ContinueInternal(BOOL fIsOutOfBand) SetSynchronized(false); // If the callback queue is not empty, then the LS is not actually continuing, and so our cached - // state is still valid. + // state is still valid. // If we're in the middle of dispatching a managed event, then simply return. This indicates to HandleRCEvent // that the user called Continue and HandleRCEvent will dispatch the next queued event. But if Continue was @@ -4032,7 +4032,7 @@ HRESULT CordbProcess::ContinueInternal(BOOL fIsOutOfBand) // may send events. Unlock(); - // This may send IPC events. + // This may send IPC events. // This will make normal neutering a nop. // This will toggle the process lock. m_LeftSideResourceCleanupList.SweepNeuterLeftSideResources(this); @@ -4055,9 +4055,9 @@ HRESULT CordbProcess::ContinueInternal(BOOL fIsOutOfBand) // CordbHandleValue is in the appdomain exit list, and that needs // to send an IPC event to cleanup and release the handle from - // the GCs handle table. + // the GCs handle table. // This will toggle the process lock. - pAppDomain->GetSweepableExitNeuterList()->SweepNeuterLeftSideResources(this); + pAppDomain->GetSweepableExitNeuterList()->SweepNeuterLeftSideResources(this); } listAppDomains.Clear(); @@ -4178,7 +4178,7 @@ HRESULT CordbProcess::ContinueInternal(BOOL fIsOutOfBand) SetSynchronized(false); SetSyncCompleteRecv(false); - // we're no longer in a callback, so set flags to indicate that we've finished. + // we're no longer in a callback, so set flags to indicate that we've finished. GetShim()->NotifyOnContinue(); // Flush will update state, including continue counter and marking @@ -4325,7 +4325,7 @@ HRESULT CordbProcess::HasQueuedCallbacks(ICorDebugThread *pThread, *pbQueued = m_pShim->GetManagedEventQueue()->HasQueuedCallbacks(pThread); return S_OK; } - return E_NOTIMPL; // Not implemented in V3. + return E_NOTIMPL; // Not implemented in V3. } // @@ -4373,7 +4373,7 @@ class ShimAssemblyCallbackData { public: // Ctor to intialize callback data - // + // // Arguments: // pAppDomain - appdomain that the assemblies are in. // pAssemblies - preallocated array of smart pointers to hold assemblies @@ -4397,10 +4397,10 @@ public: { pAssemblies[i].Clear(); } - } + } // Dtor - // + // // Notes: // This can assert end-of-enumeration invariants. ~ShimAssemblyCallbackData() @@ -4408,13 +4408,13 @@ public: // Ensure that we went through all assemblies. _ASSERTE(m_index == m_countElements); } - + // Callback invoked from DAC enumeration. - // + // // arguments: // vmDomainAssembly - VMPTR for assembly // pData - a 'this' pointer - // + // static void Callback(VMPTR_DomainAssembly vmDomainAssembly, void * pData) { ShimAssemblyCallbackData * pThis = static_cast<ShimAssemblyCallbackData *> (pData); @@ -4426,7 +4426,7 @@ public: } // Set the current index in the table and increment the cursor. - // + // // Arguments: // pAssembly - assembly from DAC enumerator void SetAndMoveNext(CordbAssembly * pAssembly) @@ -4436,8 +4436,8 @@ public: if (m_index >= m_countElements) { // Enumerating the assemblies in the target should be fixed since - // the target is not running. - // We should never get here unless the target is unstable. + // the target is not running. + // We should never get here unless the target is unstable. // The caller (the shim) pre-allocated the table of assemblies. m_pProcess->TargetConsistencyCheck(!"Target changed assembly count"); return; @@ -4457,31 +4457,31 @@ protected: //--------------------------------------------------------------------------------------- // Shim Helper to enumerate the assemblies in the load-order -// +// // Arguments: // pAppdomain - non-null appdomain to enumerate assemblies. // pAssemblies - caller pre-allocated array to hold assemblies // countAssemblies - size of the array. -// +// // Notes: // Caller preallocated array (likely from ICorDebugAssemblyEnum::GetCount), // and now this function fills in the assemblies in the order they were // loaded. -// +// // The target should be stable, such that the number of assemblies in the // target is stable, and therefore countAssemblies as determined by the // shim via ICorDebugAssemblyEnum::GetCount should match the number of -// assemblies enumerated here. -// -// Called by code:ShimProcess::QueueFakeAttachEvents. +// assemblies enumerated here. +// +// Called by code:ShimProcess::QueueFakeAttachEvents. // This provides the assemblies in load-order. In contrast, // ICorDebugAppDomain::EnumerateAssemblies is a random order. The shim needs // load-order to match Whidbey semantics for dispatching fake load-assembly // callbacks on attach. The debugger then uses the order // in its module display window. -// +// void CordbProcess::GetAssembliesInLoadOrder( - ICorDebugAppDomain * pAppDomain, + ICorDebugAppDomain * pAppDomain, RSExtSmartPtr<ICorDebugAssembly>* pAssemblies, ULONG countAssemblies) { @@ -4500,7 +4500,7 @@ void CordbProcess::GetAssembliesInLoadOrder( ShimAssemblyCallbackData::Callback, &data); // user data - // pAssemblies array has now been updated. + // pAssemblies array has now been updated. } // Callback data for code:CordbProcess::GetModulesInLoadOrder @@ -4508,7 +4508,7 @@ class ShimModuleCallbackData { public: // Ctor to intialize callback data - // + // // Arguments: // pAssembly - assembly that the Modules are in. // pModules - preallocated array of smart pointers to hold Modules @@ -4532,10 +4532,10 @@ public: { pModules[i].Clear(); } - } + } // Dtor - // + // // Notes: // This can assert end-of-enumeration invariants. ~ShimModuleCallbackData() @@ -4543,13 +4543,13 @@ public: // Ensure that we went through all Modules. _ASSERTE(m_index == m_countElements); } - + // Callback invoked from DAC enumeration. - // + // // arguments: // vmDomainFile - VMPTR for Module // pData - a 'this' pointer - // + // static void Callback(VMPTR_DomainFile vmDomainFile, void * pData) { ShimModuleCallbackData * pThis = static_cast<ShimModuleCallbackData *> (pData); @@ -4561,7 +4561,7 @@ public: } // Set the current index in the table and increment the cursor. - // + // // Arguments: // pModule - Module from DAC enumerator void SetAndMoveNext(CordbModule * pModule) @@ -4571,8 +4571,8 @@ public: if (m_index >= m_countElements) { // Enumerating the Modules in the target should be fixed since - // the target is not running. - // We should never get here unless the target is unstable. + // the target is not running. + // We should never get here unless the target is unstable. // The caller (the shim) pre-allocated the table of Modules. m_pProcess->TargetConsistencyCheck(!"Target changed Module count"); return; @@ -4592,22 +4592,22 @@ protected: //--------------------------------------------------------------------------------------- // Shim Helper to enumerate the Modules in the load-order -// +// // Arguments: // pAppdomain - non-null appdomain to enumerate Modules. // pModules - caller pre-allocated array to hold Modules // countModules - size of the array. -// +// // Notes: // Caller preallocated array (likely from ICorDebugModuleEnum::GetCount), // and now this function fills in the Modules in the order they were // loaded. -// +// // The target should be stable, such that the number of Modules in the // target is stable, and therefore countModules as determined by the // shim via ICorDebugModuleEnum::GetCount should match the number of -// Modules enumerated here. -// +// Modules enumerated here. +// // Called by code:ShimProcess::QueueFakeAssemblyAndModuleEvent. // This provides the Modules in load-order. In contrast, // ICorDebugAssembly::EnumerateModules is a random order. The shim needs @@ -4616,21 +4616,21 @@ protected: // gets a LodModule callback before any secondary modules. For dynamic // modules, this is necessary for operations on the secondary module // that rely on manifest metadata (eg. GetSimpleName). -// -// @dbgtodo : This is almost identical to GetAssembliesInLoadOrder, and -// (together wih the CallbackData classes) seems a HUGE amount of code and +// +// @dbgtodo : This is almost identical to GetAssembliesInLoadOrder, and +// (together wih the CallbackData classes) seems a HUGE amount of code and // complexity for such a simple thing. We also have extra code to order // AppDomains and Threads. We should try and rip all of this extra complexity // out, and replace it with better data structures for storing these items. -// Eg., if we used std::map, we could have efficient lookups and ordered +// Eg., if we used std::map, we could have efficient lookups and ordered // enumerations. However, we do need to be careful about exposing new invariants // through ICorDebug that customers may depend on, which could place a long-term // compatibility burden on us. We could have a simple generic data structure // (eg. built on std::hash_map and std::list) which provided efficient look-up // and both in-order and random enumeration. -// +// void CordbProcess::GetModulesInLoadOrder( - ICorDebugAssembly * pAssembly, + ICorDebugAssembly * pAssembly, RSExtSmartPtr<ICorDebugModule>* pModules, ULONG countModules) { @@ -4649,13 +4649,13 @@ void CordbProcess::GetModulesInLoadOrder( ShimModuleCallbackData::Callback, &data); // user data - // pModules array has now been updated. + // pModules array has now been updated. } //--------------------------------------------------------------------------------------- // Callback to count the number of enumerations in a process. -// +// // Arguments: // id - the connection id. // pName - name of the connection @@ -4664,14 +4664,14 @@ void CordbProcess::GetModulesInLoadOrder( // Notes: // Helper function for code:CordbProcess::QueueFakeConnectionEvents // -// static +// static void CordbProcess::CountConnectionsCallback(DWORD id, LPCWSTR pName, void * pUserData) { } //--------------------------------------------------------------------------------------- // Callback to enumerate all the connections in a process. -// +// // Arguments: // id - the connection id. // pName - name of the connection @@ -4680,7 +4680,7 @@ void CordbProcess::CountConnectionsCallback(DWORD id, LPCWSTR pName, void * pUse // Notes: // Helper function for code:CordbProcess::QueueFakeConnectionEvents // -// static +// static void CordbProcess::EnumerateConnectionsCallback(DWORD id, LPCWSTR pName, void * pUserData) { } @@ -4755,9 +4755,9 @@ void CordbProcess::DispatchRCEvent() // This gives us delayed continues w/ no extra state flags. - // The debugger may call Detach() immediately after it returns from the callback, but before this thread returns + // The debugger may call Detach() immediately after it returns from the callback, but before this thread returns // from this function. Thus after we execute the callbacks, it's possible the CordbProcess object has been neutered. - + // Since we're already sycned, the Stop from the holder here is practically a nop that just bumps up a count. // Create an extra scope for the StopContinueHolder. { @@ -4769,13 +4769,13 @@ void CordbProcess::DispatchRCEvent() } HRESULT hrCallback = S_OK; - // It's possible a ICorDebugProcess::Detach() may have occurred by now. + // It's possible a ICorDebugProcess::Detach() may have occurred by now. { // @dbgtodo shim: eventually the entire RCET should be considered outside the RS. - PUBLIC_CALLBACK_IN_THIS_SCOPE0_NO_LOCK(this); + PUBLIC_CALLBACK_IN_THIS_SCOPE0_NO_LOCK(this); - // Snag the first event off the queue. + // Snag the first event off the queue. // Holder will call Delete, which will invoke virtual Dtor that will release ICD objects. // Since these are external refs, we want to do it while "outside" the RS. NewHolder<ManagedEvent> pEvent(pShim->DequeueManagedEvent()); @@ -4796,7 +4796,7 @@ void CordbProcess::DispatchRCEvent() m_pDBGLastIPCEventType = pEvent->GetDebugCookie(); #endif - ManagedEvent::DispatchArgs args(m_cordb->m_managedCallback, m_cordb->m_managedCallback2, m_cordb->m_managedCallback3, m_cordb->m_managedCallback4); + ManagedEvent::DispatchArgs args(m_cordb->m_managedCallback, m_cordb->m_managedCallback2, m_cordb->m_managedCallback3, m_cordb->m_managedCallback4); { // Release lock around the dispatch of the event @@ -4807,7 +4807,7 @@ void CordbProcess::DispatchRCEvent() // This dispatches almost directly into the user's callbacks. // It does not update any RS state. hrCallback = pEvent->Dispatch(args); - } + } EX_CATCH_HRESULT(hrCallback); } } @@ -4819,18 +4819,18 @@ void CordbProcess::DispatchRCEvent() { ContinueInternal(FALSE); } - - + + } // forces Continue to be called - Lock(); + Lock(); }; #ifdef _DEBUG //--------------------------------------------------------------------------------------- // Debug-only callback to ensure that an appdomain is not available after the ExitAppDomain event. -// +// // Arguments: // vmAppDomain - appdomain from enumeration // pUserData - pointer to a DbgAssertAppDomainDeletedData which contains the VMAppDomain that was just deleted. @@ -4842,23 +4842,23 @@ void CordbProcess::DbgAssertAppDomainDeletedCallback(VMPTR_AppDomain vmAppDomain INTERNAL_DAC_CALLBACK(pCallbackData->m_pThis); VMPTR_AppDomain vmAppDomainDeleted = pCallbackData->m_vmAppDomainDeleted; - CONSISTENCY_CHECK_MSGF((vmAppDomain != vmAppDomainDeleted), - ("An ExitAppDomain event was sent for appdomain, but it still shows up in the enumeration.\n vmAppDomain=%p\n", + CONSISTENCY_CHECK_MSGF((vmAppDomain != vmAppDomainDeleted), + ("An ExitAppDomain event was sent for appdomain, but it still shows up in the enumeration.\n vmAppDomain=%p\n", VmPtrToCookie(vmAppDomainDeleted))); } //--------------------------------------------------------------------------------------- // Debug-only helper to Assert that VMPTR is actually removed. -// +// // Arguments: -// vmAppDomainDeleted - vmptr of appdomain that we just got exit event for. +// vmAppDomainDeleted - vmptr of appdomain that we just got exit event for. // This should not be discoverable from the RS. -// +// // Notes: // See code:IDacDbiInterface#Enumeration for rules that we're asserting. // Once the exit appdomain event is dispatched, the appdomain should not be discoverable by the RS. -// Else the RS may use the AppDomain* after it's deleted. -// This asserts that the AppDomain* is not discoverable. +// Else the RS may use the AppDomain* after it's deleted. +// This asserts that the AppDomain* is not discoverable. // // Since this is a debug-only function, it should have no side-effects. void CordbProcess::DbgAssertAppDomainDeleted(VMPTR_AppDomain vmAppDomainDeleted) @@ -4882,24 +4882,24 @@ void CordbProcess::DbgAssertAppDomainDeleted(VMPTR_AppDomain vmAppDomainDeleted) // pCallback1 - callback object to dispatch on (for V1 callbacks) // pCallback2 - 2nd callback object to dispatch on (for new V2 callbacks) // pCallback3 - 3rd callback object to dispatch on (for new V4 callbacks) -// +// // // Returns: -// Nothing. Throws on error. -// +// Nothing. Throws on error. +// // Notes: // Generally, this will dispatch exactly 1 callback. It may dispatch 0 callbacks if there is an error -// or in other corner cases (documented within the dispatch code below). +// or in other corner cases (documented within the dispatch code below). // Errors could occur because: // - the event is corrupted (exceptional case) // - the RS is corrupted / OOM (exceptional case) // Exception errors here will propogate back to the Filter() call, and there's not really anything // a debugger can do about an error here (perhaps report it to the user). -// Errors must leave IcorDebug in a consistent state. +// Errors must leave IcorDebug in a consistent state. // // This is dispatched directly on the Win32Event Thread in response to calling Filter. // Therefore, this can't send any IPC events (Not an issue once everything is DAC-ized). -// A V2 shim can provide a proxy calllack that takes these events and queues them and +// A V2 shim can provide a proxy calllack that takes these events and queues them and // does the real dispatch to the user to emulate V2 semantics. // #ifdef _PREFAST_ @@ -4907,9 +4907,9 @@ void CordbProcess::DbgAssertAppDomainDeleted(VMPTR_AppDomain vmAppDomainDeleted) #pragma warning(disable:21000) // Suppress PREFast warning about overly large function #endif void CordbProcess::RawDispatchEvent( - DebuggerIPCEvent * pEvent, + DebuggerIPCEvent * pEvent, RSLockHolder * pLockHolder, - ICorDebugManagedCallback * pCallback1, + ICorDebugManagedCallback * pCallback1, ICorDebugManagedCallback2 * pCallback2, ICorDebugManagedCallback3 * pCallback3, ICorDebugManagedCallback4 * pCallback4) @@ -4936,17 +4936,17 @@ void CordbProcess::RawDispatchEvent( // so if this flag is set, EP will wait on the miscWaitEvent (which will // get set in FlushQueuedEvents when we return from here) and let us finish here. // - StartEventDispatch(pEvent->type); + StartEventDispatch(pEvent->type); // Keep strong references to these objects in case a callback deletes them from underneath us. RSSmartPtr<CordbAppDomain> pAppDomain; CordbThread * pThread = NULL; - + // Get thread that this event is on. In attach scenarios, this may be the first time ICorDebug has seen this thread. if (!pEvent->vmThread.IsNull()) { - pThread = LookupOrCreateThread(pEvent->vmThread); + pThread = LookupOrCreateThread(pEvent->vmThread); } if (!pEvent->vmAppDomain.IsNull()) @@ -4955,7 +4955,7 @@ void CordbProcess::RawDispatchEvent( } DWORD dwVolatileThreadId = 0; - if (pThread != NULL) + if (pThread != NULL) { dwVolatileThreadId = pThread->GetUniqueId(); } @@ -4968,7 +4968,7 @@ void CordbProcess::RawDispatchEvent( { // It shouldn't be possible for us to see an exited AppDomain here _ASSERTE( !pAppDomain->IsNeutered() ); - + pThread->m_pAppDomain = pAppDomain; } @@ -4976,7 +4976,7 @@ void CordbProcess::RawDispatchEvent( _ASSERTE(pCallback1 != NULL); _ASSERTE(pCallback2 != NULL); _ASSERTE(pCallback3 != NULL); - + _ASSERTE(pCallback4 != NULL); STRESS_LOG1(LF_CORDB, LL_EVERYTHING, "Pre-Dispatch IPC event: %s\n", IPCENames::GetName(pEvent->type)); @@ -4994,11 +4994,11 @@ void CordbProcess::RawDispatchEvent( _ASSERTE(pThread != NULL); _ASSERTE(pAppDomain != NULL); - // Find the breakpoint object on this side. + // Find the breakpoint object on this side. CordbBreakpoint *pBreakpoint = NULL; // We've found cases out in the wild where we get this event on a thread we don't recognize. - // We're not sure how this happens. Add a runtime check to protect ourselves to avoid the + // We're not sure how this happens. Add a runtime check to protect ourselves to avoid the // an AV. We still assert because this should not be happening. // It likely means theres some issue where we failed to send a CreateThread notification. TargetConsistencyCheck(pThread != NULL); @@ -5017,11 +5017,20 @@ void CordbProcess::RawDispatchEvent( } break; - case DB_IPCE_SOME_WORK: + case DB_IPCE_BEFORE_GARBAGE_COLLECTION: + { + { + PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent); + pCallback4->BeforeGarbageCollection(static_cast<ICorDebugController*>(this)); + } + break; + } + + case DB_IPCE_AFTER_GARBAGE_COLLECTION: { { PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent); - pCallback4->SomeWork(pThread, pAppDomain); + pCallback4->AfterGarbageCollection(static_cast<ICorDebugController*>(this)); } break; } @@ -5107,9 +5116,9 @@ void CordbProcess::RawDispatchEvent( // even executed jitted code on the thread. We may have not received a CreateThread yet. // In V2, we detected this and sent a LogMessage on a random thread. // In V3, we lazily create the CordbThread objects (possibly before the CreateThread event), - // and so we know we should have one. + // and so we know we should have one. _ASSERTE(pThread != NULL); - + pThread->SetExInfo(pEvent->Exception.vmExceptionHandle); _ASSERTE(pThread->m_pAppDomain != NULL); @@ -5154,7 +5163,7 @@ void CordbProcess::RawDispatchEvent( _ASSERTE(pAppDomain != NULL); - // A thread is reported as dead before we get the exit event. + // A thread is reported as dead before we get the exit event. // See code:IDacDbiInterface#IsThreadMarkedDead for the invariant being asserted here. TargetConsistencyCheck(pThread->IsThreadDead()); @@ -5189,9 +5198,9 @@ void CordbProcess::RawDispatchEvent( case DB_IPCE_LOAD_MODULE: { _ASSERTE (pAppDomain != NULL); - CordbModule * pModule = pAppDomain->LookupOrCreateModule(pEvent->LoadModuleData.vmDomainFile); - - { + CordbModule * pModule = pAppDomain->LookupOrCreateModule(pEvent->LoadModuleData.vmDomainFile); + + { pModule->SetLoadEventContinueMarker(); PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent); @@ -5213,7 +5222,7 @@ void CordbProcess::RawDispatchEvent( this, pEvent->CreateConnection.connectionId, const_cast<WCHAR*> (pEvent->CreateConnection.wzConnectionName.GetString())); - } + } break; case DB_IPCE_DESTROY_CONNECTION: @@ -5245,7 +5254,7 @@ void CordbProcess::RawDispatchEvent( VmPtrToCookie(pEvent->vmAppDomain)); PREFIX_ASSUME (pAppDomain != NULL); - + CordbModule *module = pAppDomain->LookupOrCreateModule(pEvent->UnloadModuleData.vmDomainFile); if (module == NULL) @@ -5266,7 +5275,7 @@ void CordbProcess::RawDispatchEvent( PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent); pCallback1->UnloadModule(pAppDomain, module); } - + pAppDomain->m_modules.RemoveBase(VmPtrToCookie(pEvent->UnloadModuleData.vmDomainFile)); } break; @@ -5418,14 +5427,14 @@ void CordbProcess::RawDispatchEvent( // determine first whether custom notifications for this type are enabled -- if not - // we just return without doing anything. - CordbClass * pNotificationClass = LookupClass(pAppDomain, - pEvent->CustomNotification.vmDomainFile, + // we just return without doing anything. + CordbClass * pNotificationClass = LookupClass(pAppDomain, + pEvent->CustomNotification.vmDomainFile, pEvent->CustomNotification.classToken); // if the class is NULL, that means the debugger never enabled notifications for it. Otherwise, - // the CordbClass instance would already have been created when the notifications were - // enabled. + // the CordbClass instance would already have been created when the notifications were + // enabled. if ((pNotificationClass != NULL) && pNotificationClass->CustomNotificationsEnabled()) { @@ -5445,13 +5454,13 @@ void CordbProcess::RawDispatchEvent( // Enumerate may have prepopulated the appdomain, so check if it already exists. - // Either way, still send the CreateEvent. (We don't want to skip the Create event + // Either way, still send the CreateEvent. (We don't want to skip the Create event // just because the debugger did an enumerate) // We remove AppDomains from the hash as soon as they are exited. pAppDomain.Assign(LookupOrCreateAppDomain(pEvent->AppDomainData.vmAppDomain)); _ASSERTE(pAppDomain != NULL); // throws on failure - { + { PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent); hr = pCallback1->CreateAppDomain(this, pAppDomain); } @@ -5488,11 +5497,11 @@ void CordbProcess::RawDispatchEvent( m_pDefaultAppDomain = NULL; } - // Update any threads which were last seen in this AppDomain. We don't + // Update any threads which were last seen in this AppDomain. We don't // get any notification when a thread leaves an AppDomain, so our idea // of what AppDomain the thread is in may be out of date. UpdateThreadsForAdUnload( pAppDomain ); - + // This will still maintain weak references so we could call Continue. AddToNeuterOnContinueList(pAppDomain); @@ -5508,7 +5517,7 @@ void CordbProcess::RawDispatchEvent( // Remove this app domain. This means any attempt to lookup the AppDomain // will fail (which we do at the top of this method). Since any threads (incorrectly) referring - // to this AppDomain have been moved to the default AppDomain, no one should be + // to this AppDomain have been moved to the default AppDomain, no one should be // interested in looking this AppDomain up anymore. m_appDomains.RemoveBase(VmPtrToCookie(pEvent->vmAppDomain)); } @@ -5548,7 +5557,7 @@ void CordbProcess::RawDispatchEvent( _ASSERTE (pAppDomain != NULL); CordbAssembly * pAssembly = pAppDomain->LookupOrCreateAssembly(pEvent->AssemblyData.vmDomainAssembly); - + if (pAssembly == NULL) { // No assembly. This could happen if we attach right before an unload event is sent. @@ -5711,7 +5720,7 @@ void CordbProcess::RawDispatchEvent( if (symFormat == IDacDbiInterface::kSymbolFormatPDB) { PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent); - + _ASSERTE(pStream != NULL); // Shouldn't send the event if we don't have a stream. pCallback1->UpdateModuleSymbols(pAppDomain, pModule, pStream); @@ -5737,7 +5746,7 @@ void CordbProcess::RawDispatchEvent( PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent); pCallback2->MDANotification( - this, + this, pThread, // may be null pExternalMDARef); @@ -5878,21 +5887,21 @@ void CordbProcess::RawDispatchEvent( if (pThread == NULL) { // We've found cases out in the wild where we get this event on a thread we don't recognize. - // We're not sure how this happens. Add a runtime check to protect ourselves to avoid the + // We're not sure how this happens. Add a runtime check to protect ourselves to avoid the // an AV. We still assert because this should not be happening. // It likely means theres some issue where we failed to send a CreateThread notification. - STRESS_LOG1(LF_CORDB, LL_INFO1000, "BreakpointSetError on unrecognized thread. %p\n", pBreakpoint); + STRESS_LOG1(LF_CORDB, LL_INFO1000, "BreakpointSetError on unrecognized thread. %p\n", pBreakpoint); _ASSERTE(!"Missing thread on bp set error"); break; - } - + } + pBreakpoint = pAppDomain->m_breakpoints.GetBase(LsPtrToCookie(pEvent->BreakpointSetErrorData.breakpointToken)); if (pBreakpoint != NULL) { ICorDebugBreakpoint * pIBreakpoint = CordbBreakpointToInterface(pBreakpoint); - _ASSERTE(pIBreakpoint != NULL); + _ASSERTE(pIBreakpoint != NULL); { PUBLIC_CALLBACK_IN_THIS_SCOPE2(this, pLockHolder, pEvent, "thread=0x%p, bp=0x%p", pThread, pBreakpoint); pCallback1->BreakpointSetError(pAppDomain, pThread, pIBreakpoint, 0); @@ -5915,8 +5924,8 @@ void CordbProcess::RawDispatchEvent( if (pThread == NULL) { - // We've got an exception on a thread we don't know about. This could be a thread that - // has never run any managed code, so let's just ignore the exception. We should have + // We've got an exception on a thread we don't know about. This could be a thread that + // has never run any managed code, so let's just ignore the exception. We should have // already sent a log message about this situation for the EXCEPTION callback above. _ASSERTE( pEvent->ExceptionCallback2.eventType == DEBUG_EXCEPTION_UNHANDLED ); break; @@ -5934,12 +5943,12 @@ void CordbProcess::RawDispatchEvent( { // The interface forces us to to pass a FramePointer via an ICorDebugFrame. // However, we can't get a real ICDFrame without a stackwalk, and we don't - // want to do a stackwalk now. so pass a netuered proxy frame. The shim + // want to do a stackwalk now. so pass a netuered proxy frame. The shim // can map this to a real frame. // See comments at CordbPlaceHolderFrame class for details. pFrame.Assign(new CordbPlaceholderFrame(this, fp)); } - + CorDebugExceptionCallbackType type = pEvent->ExceptionCallback2.eventType; { PUBLIC_CALLBACK_IN_THIS_SCOPE3(this, pLockHolder, pEvent, "pThread=0x%p, frame=%p, type=%d", pThread, (ICorDebugFrame*) pFrame, type); @@ -6000,7 +6009,7 @@ void CordbProcess::RawDispatchEvent( } // - // Tell the debugger that the exception has been intercepted. This is similar to the + // Tell the debugger that the exception has been intercepted. This is similar to the // notification we give when we start unwinding for a non-intercepted exception, except that the // interception has been completed at this point, which means that we are conceptually at the end // of the second pass. @@ -6008,9 +6017,9 @@ void CordbProcess::RawDispatchEvent( { PUBLIC_CALLBACK_IN_THIS_SCOPE1(this, pLockHolder, pEvent, "pThread=0x%p", pThread); hr = pCallback2->ExceptionUnwind( - pThread->m_pAppDomain, - pThread, - DEBUG_EXCEPTION_INTERCEPTED, + pThread->m_pAppDomain, + pThread, + DEBUG_EXCEPTION_INTERCEPTED, 0); } } @@ -6036,7 +6045,7 @@ void CordbProcess::RawDispatchEvent( } else // the lock was already held { - // see if we threw because the lock was held + // see if we threw because the lock was held _ASSERTE(hr == CORDBG_E_PROCESS_NOT_SYNCHRONIZED); if (hr != CORDBG_E_PROCESS_NOT_SYNCHRONIZED) { @@ -6047,7 +6056,7 @@ void CordbProcess::RawDispatchEvent( } break; - + case DB_IPCE_TEST_RWLOCK: { EX_TRY @@ -6068,7 +6077,7 @@ void CordbProcess::RawDispatchEvent( } else // the lock was already held { - // see if we threw because the lock was held + // see if we threw because the lock was held _ASSERTE(hr == CORDBG_E_PROCESS_NOT_SYNCHRONIZED); if (hr != CORDBG_E_PROCESS_NOT_SYNCHRONIZED) { @@ -6096,7 +6105,7 @@ void CordbProcess::RawDispatchEvent( //--------------------------------------------------------------------------------------- // Callback for prepopulating threads. -// +// // Arugments: // vmThread - thread as part of the eunmeration. // pUserData - data supplied with callback. It's a CordbProcess* object. @@ -6128,7 +6137,7 @@ void CordbProcess::PrepopulateThreadsOrThrow() //--------------------------------------------------------------------------------------- // Create a Thread enumerator -// +// // Arguments: // pOwnerObj - object (a CordbProcess or CordbThread) that will own the enumerator. // pOwnerList - the neuter list that the enumerator will live on @@ -6137,8 +6146,8 @@ void CordbProcess::PrepopulateThreadsOrThrow() void CordbProcess::BuildThreadEnum(CordbBase * pOwnerObj, NeuterList * pOwnerList, RSInitHolder<CordbHashTableEnum> * pHolder) { CordbHashTableEnum::BuildOrThrow( - pOwnerObj, - pOwnerList, + pOwnerObj, + pOwnerList, &m_userThreads, IID_ICorDebugThreadEnum, pHolder); @@ -6153,7 +6162,7 @@ HRESULT CordbProcess::EnumerateThreads(ICorDebugThreadEnum **ppThreads) if (m_detached) { // #Detach_Check: - // + // // FUTURE: Consider adding this IF block to the PUBLIC_API macros so that // typical public APIs fail quickly if we're trying to do a detach. For // now, I'm hand-adding this check only to the few problematic APIs that get @@ -6204,7 +6213,7 @@ HRESULT CordbProcess::GetThread(DWORD dwThreadId, ICorDebugThread **ppThread) // See code:CordbProcess::EnumerateThreads#Detach_Check ThrowHR(CORDBG_E_PROCESS_DETACHED); } - CordbThread * pThread = TryLookupOrCreateThreadByVolatileOSId(dwThreadId); + CordbThread * pThread = TryLookupOrCreateThreadByVolatileOSId(dwThreadId); if (pThread == NULL) { // This is a common case because we may be looking up an unmanaged thread. @@ -6292,22 +6301,22 @@ HRESULT CordbProcess::SetAllThreadsDebugState(CorDebugThreadState state, } CordbThread * pCordbExceptThread = static_cast<CordbThread *> (pExceptThread); - LOG((LF_CORDB, LL_INFO1000, "CP::SATDS: except thread=0x%08x 0x%x\n", - pExceptThread, + LOG((LF_CORDB, LL_INFO1000, "CP::SATDS: except thread=0x%08x 0x%x\n", + pExceptThread, (pCordbExceptThread != NULL) ? pCordbExceptThread->m_id : 0)); // Send one event to the Left Side to twiddle each thread's state. DebuggerIPCEvent event; - + InitIPCEvent(&event, DB_IPCE_SET_ALL_DEBUG_STATE, true, VMPTR_AppDomain::NullPtr()); - - event.SetAllDebugState.vmThreadToken = ((pCordbExceptThread != NULL) ? + + event.SetAllDebugState.vmThreadToken = ((pCordbExceptThread != NULL) ? pCordbExceptThread->m_vmThreadToken : VMPTR_Thread::NullPtr()); - + event.SetAllDebugState.debugState = state; HRESULT hr = SendIPCEvent(&event, sizeof(DebuggerIPCEvent)); - + hr = WORST_HR(hr, event.hr); // If that worked, then loop over all the threads on this side and set their states. @@ -6318,8 +6327,8 @@ HRESULT CordbProcess::SetAllThreadsDebugState(CorDebugThreadState state, CordbThread * pThread; // We don't need to prepopulate here (to collect LS state) because we're just updating RS state. - for (pThread = m_userThreads.FindFirst(&hashFind); - pThread != NULL; + for (pThread = m_userThreads.FindFirst(&hashFind); + pThread != NULL; pThread = m_userThreads.FindNext(&hashFind)) { if (pThread != pCordbExceptThread) @@ -6345,7 +6354,7 @@ HRESULT CordbProcess::EnumerateObjects(ICorDebugObjectEnum **ppObjects) //--------------------------------------------------------------------------------------- // -// Determines if the target address is a "CLR transition stub". +// Determines if the target address is a "CLR transition stub". // // Arguments: // address - The address of an instruction to check in the target address space. @@ -6402,7 +6411,7 @@ HRESULT CordbProcess::IsTransitionStub(CORDB_ADDRESS address, BOOL *pfTransition // Check against DAC primitives { - BOOL fIsStub2 = GetDAC()->IsTransitionStub(address); + BOOL fIsStub2 = GetDAC()->IsTransitionStub(address); (void)fIsStub2; //prevent "unused variable" error from GCC CONSISTENCY_CHECK_MSGF(*pfTransitionStub == fIsStub2, ("IsStub2 failed, DAC2:%d, IPC:%d, addr:0x%p", (int) fIsStub2, (int) *pfTransitionStub, CORDB_ADDRESS_TO_PTR(address))); @@ -6480,7 +6489,7 @@ HRESULT CordbProcess::SafeReadThreadContext(LSPTR_CONTEXT pContext, DT_CONTEXT * // At a minimum we have room for a whole context up to the extended registers. #if defined(DT_CONTEXT_EXTENDED_REGISTERS) - ULONG32 minContextSize = offsetof(DT_CONTEXT, ExtendedRegisters); + ULONG32 minContextSize = offsetof(DT_CONTEXT, ExtendedRegisters); #else ULONG32 minContextSize = sizeof(DT_CONTEXT); #endif @@ -6488,7 +6497,7 @@ HRESULT CordbProcess::SafeReadThreadContext(LSPTR_CONTEXT pContext, DT_CONTEXT * // Read the minimum part. TargetBuffer tbMin = tbFull.SubBuffer(0, minContextSize); SafeReadBuffer(tbMin, (BYTE*) pCtx); - + #if defined(DT_CONTEXT_EXTENDED_REGISTERS) void *pCurExtReg = (void*)((UINT_PTR)pCtx + minContextSize); TargetBuffer tbExtended = tbFull.SubBuffer(minContextSize); @@ -6535,7 +6544,7 @@ HRESULT CordbProcess::SafeWriteThreadContext(LSPTR_CONTEXT pContext, const DT_CO } #endif -// 64 bit windows puts space for the first 6 stack parameters in the CONTEXT structure so that +// 64 bit windows puts space for the first 6 stack parameters in the CONTEXT structure so that // kernel to usermode transitions don't have to allocate a CONTEXT and do a seperate sub rsp // to allocate stack spill space for the arguments. This means that writing to P1Home - P6Home // will overwrite the arguments of some function higher on the stack, very bad. Conceptually you @@ -6555,7 +6564,7 @@ HRESULT CordbProcess::SafeWriteThreadContext(LSPTR_CONTEXT pContext, const DT_CO SafeWriteBuffer(tb, (const BYTE*) pCtxSource); } EX_CATCH_HRESULT(hr); - + return hr; } @@ -6599,7 +6608,7 @@ HRESULT CordbProcess::GetThreadContext(DWORD threadID, ULONG32 contextSize, BYTE } // Public implementation of ICorDebugProcess::SetThreadContext. -// @dbgtodo interop-debugging: this should go away in V3. Use the data-target instead. This is +// @dbgtodo interop-debugging: this should go away in V3. Use the data-target instead. This is // interop-debugging aware (and cooperates with hijacks) HRESULT CordbProcess::SetThreadContext(DWORD threadID, ULONG32 contextSize, BYTE context[]) { @@ -6648,8 +6657,8 @@ HRESULT CordbProcess::SetThreadContext(DWORD threadID, ULONG32 contextSize, BYTE { // Find the managed thread. Returns NULL if thread is not managed. // If we don't have a thread prveiously cached, then there's no state to update. - CordbThread * pThread = TryLookupThreadByVolatileOSId(threadID); - + CordbThread * pThread = TryLookupThreadByVolatileOSId(threadID); + if (pThread != NULL) { // In V2, we used to update the CONTEXT of the leaf chain if the chain is an unmanaged chain. @@ -6761,9 +6770,9 @@ LExit: // if we've written over them. And put the int3 back in for write-memory. // // Note: If we're writing memory over top of a patch, then it must be JITted or stub code. -// Writing over JITed or Stub code can be dangerous since the CLR may not expect it +// Writing over JITed or Stub code can be dangerous since the CLR may not expect it // (eg. JIT data structures about the code layout may be incorrect), but in certain -// narrow cases it may be safe (eg. replacing a constant). VS says they wouldn't expect +// narrow cases it may be safe (eg. replacing a constant). VS says they wouldn't expect // this to work, but we'll keep the support in for legacy reasons. // // address, size - describe buffer in LS memory @@ -6838,7 +6847,7 @@ HRESULT CordbProcess::AdjustBuffer( CORDB_ADDRESS address, _ASSERTE( pbUpdatePatchTable != NULL ); _ASSERTE( bufferCopy != NULL ); - //There can be multiple patches at the same address: we don't want 2nd+ patches to get the + //There can be multiple patches at the same address: we don't want 2nd+ patches to get the // break opcode, so we read from the unmodified copy. m_rgUncommitedOpcode[iNextFree] = CORDbgGetInstructionEx(*bufferCopy, address, patchAddress, opcode, size); @@ -6861,7 +6870,7 @@ HRESULT CordbProcess::AdjustBuffer( CORDB_ADDRESS address, delete [] *bufferCopy; *bufferCopy = NULL; } - + return S_OK; } @@ -6984,14 +6993,14 @@ HRESULT CordbProcess::RefreshPatchTable(CORDB_ADDRESS address, SIZE_T size, BYTE LOG((LF_CORDB, LL_INFO10000, "Wont refresh patch table because its not valid now.\n")); return S_OK; } - + EX_TRY { rgb = new BYTE[cbTableSlice]; // throws TargetBuffer tbSlice((BYTE*)m_runtimeOffsets.m_pPatches + offStart, cbTableSlice); this->SafeReadBuffer(tbSlice, rgb); // Throws; - + // Note that rgData is a pointer in the left side address space m_rgData = *(BYTE**)(rgb + m_runtimeOffsets.m_offRgData - offStart); m_cPatch = *(ULONG*)(rgb + m_runtimeOffsets.m_offCData - offStart); @@ -7013,7 +7022,7 @@ HRESULT CordbProcess::RefreshPatchTable(CORDB_ADDRESS address, SIZE_T size, BYTE TargetBuffer tb(m_rgData, cbPatchTable); this->SafeReadBuffer(tb, m_pPatchTable); // Throws - + //As we go through the patch table we do a number of things: // // 1. collect min,max address seen for quick fail check @@ -7092,7 +7101,7 @@ LExit: EX_CATCH_HRESULT(hr); } - + if (rgb != NULL ) { delete [] rgb; @@ -7108,7 +7117,7 @@ LExit: //--------------------------------------------------------------------------------------- // -// Given an address, see if there is a patch in the patch table that matches it and return +// Given an address, see if there is a patch in the patch table that matches it and return // if its an unmanaged patch or not. // // Arguments: @@ -7116,14 +7125,14 @@ LExit: // pfPatchFound - Space to store the result, TRUE if the address belongs to a // patch, FALSE if not. Only valid if this method returns a success code. // pfPatchIsUnmanaged - Space to store the result, TRUE if the address is a patch -// and the patch is unmanaged, FALSE if not. Only valid if this method returns a +// and the patch is unmanaged, FALSE if not. Only valid if this method returns a // success code. // // Return Value: // Typical HRESULT symantics, nothing abnormal. // -// Note: this method is pretty in-efficient. It refreshes the patch table, then scans it. -// Refreshing the patch table involves a scan, too, so this method could be folded +// Note: this method is pretty in-efficient. It refreshes the patch table, then scans it. +// Refreshing the patch table involves a scan, too, so this method could be folded // with that. // //--------------------------------------------------------------------------------------- @@ -7267,13 +7276,13 @@ HRESULT CordbProcess::WriteMemory(CORDB_ADDRESS address, DWORD size, "(This assert is only enabled under the COM+ knob DbgCheckInt3.)\n", CORDB_ADDRESS_TO_PTR(address))); } -#endif // DBG_TARGET_X86 || DBG_TARGET_AMD64 +#endif // DBG_TARGET_X86 || DBG_TARGET_AMD64 // check if we're replaced an opcode. if (size == 1) { RSLockHolder ch(&this->m_processMutex); - + NativePatch * p = GetNativePatch(CORDB_ADDRESS_TO_PTR(address)); if (p != NULL) { @@ -7304,7 +7313,7 @@ HRESULT CordbProcess::WriteMemory(CORDB_ADDRESS address, DWORD size, if (m_initialized) { RSLockHolder ch(&this->m_processMutex); - + if (m_pPatchTable == NULL ) { if (!SUCCEEDED( hr = RefreshPatchTable() ) ) @@ -7340,7 +7349,7 @@ HRESULT CordbProcess::WriteMemory(CORDB_ADDRESS address, DWORD size, else hrSaved = hr; } - + LOG((LF_CORDB, LL_INFO100000, "CP::WM: wrote %d bytes at 0x%08x, first byte is 0x%x\n", *written, (DWORD)address, buffer[0])); @@ -7489,7 +7498,7 @@ CordbUnmanagedThread *CordbProcess::HandleUnmanagedCreateThread(DWORD dwThreadId // Note: Throws on error //----------------------------------------------------------------------------- void CordbProcess::InitDac() -{ +{ // Go-Go DAC power!! HRESULT hr = S_OK; EX_TRY @@ -7506,7 +7515,7 @@ void CordbProcess::InitDac() // - a CLR dev built mscorwks but didn't build DAC. SIMPLIFYING_ASSUMPTION_MSGF(false, ("Failed to load DAC while for debugging. hr=0x%08x", hr)); ThrowHR(hr); - } + } } //CordbProcess::InitDac // Update the entire RS copy of the debugger control block by reading the LS copy. The RS copy is treated as @@ -7515,8 +7524,8 @@ void CordbProcess::InitDac() // update everything for simplicity; any perf hit we take by doing this instead of updating the individual // fields we want at any given point isn't significant, particularly if we are updating multiple fields. -// Arguments: -// none, but reads process memory from the LS debugger control block +// Arguments: +// none, but reads process memory from the LS debugger control block // Return Value: none (copies from LS DCB to RS buffer GetDCB()) // Note: throws if SafeReadBuffer fails void CordbProcess::UpdateRightSideDCB() @@ -7526,7 +7535,7 @@ void CordbProcess::UpdateRightSideDCB() // Update a single field with a value stored in the RS copy of the DCB. We can't update the entire LS DCB // because in some cases, the LS and RS are simultaneously initializing the DCB. If we initialize a field on -// the RS and write back the whole thing, we may overwrite something the LS has initialized in the interim. +// the RS and write back the whole thing, we may overwrite something the LS has initialized in the interim. // Arguments: // input: rsFieldAddr - the address of the field in the RS copy of the DCB that we want to write back to @@ -7545,28 +7554,28 @@ void CordbProcess::UpdateLeftSideDCBField(void * rsFieldAddr, SIZE_T size) //----------------------------------------------------------------------------- // Gets the remote address of the event block for the Target and verifies that it's valid. // We use this address when we need to read from or write to the debugger control block. -// Also allocates the RS buffer used for temporary storage for information from the DCB and +// Also allocates the RS buffer used for temporary storage for information from the DCB and // copies the LS DCB into the RS buffer. // Arguments: // output: pfBlockExists - true iff the LS DCB has been successfully allocated. Note that -// we need this information even if the function throws, so we can't simply send it back +// we need this information even if the function throws, so we can't simply send it back // as a return value. // Return value: -// None, but allocates GetDCB() on success. If the LS DCB has not -// been successfully initialized or if this throws, GetDCB() will be NULL. +// None, but allocates GetDCB() on success. If the LS DCB has not +// been successfully initialized or if this throws, GetDCB() will be NULL. // // Notes: // Throws on error // //----------------------------------------------------------------------------- void CordbProcess::GetEventBlock(BOOL * pfBlockExists) -{ +{ if (GetDCB() == NULL) // we only need to do this once { _ASSERTE(m_pShim != NULL); _ASSERTE(ThreadHoldsProcessLock()); - // This will Initialize the DAC/DBI interface. + // This will Initialize the DAC/DBI interface. BOOL fDacReady = TryInitializeDac(); if (fDacReady) @@ -7581,11 +7590,11 @@ void CordbProcess::GetEventBlock(BOOL * pfBlockExists) if (pLeftSideDCB == NULL) { *pfBlockExists = false; - ThrowHR(CORDBG_E_DEBUGGING_NOT_POSSIBLE); + ThrowHR(CORDBG_E_DEBUGGING_NOT_POSSIBLE); } - IfFailThrow(NewEventChannelForThisPlatform(pLeftSideDCB, - m_pMutableDataTarget, + IfFailThrow(NewEventChannelForThisPlatform(pLeftSideDCB, + m_pMutableDataTarget, GetPid(), m_pShim->GetMachineInfo(), &m_pEventChannel)); @@ -7595,12 +7604,12 @@ void CordbProcess::GetEventBlock(BOOL * pfBlockExists) UpdateRightSideDCB(); // Verify that the control block is valid. - // This will throw on error. - VerifyControlBlock(); - + // This will throw on error. + VerifyControlBlock(); + *pfBlockExists = true; } - else + else { // we can't initialize the DAC, so we can't get the block *pfBlockExists = false; @@ -7635,7 +7644,7 @@ void CordbProcess::VerifyControlBlock() UpdateLeftSideDCBField(&(GetDCB()->m_rightSideProtocolCurrent), sizeof(GetDCB()->m_rightSideProtocolCurrent)); GetDCB()->m_rightSideProtocolMinSupported = CorDB_RightSideProtocolMinSupported; - UpdateLeftSideDCBField(&(GetDCB()->m_rightSideProtocolMinSupported), + UpdateLeftSideDCBField(&(GetDCB()->m_rightSideProtocolMinSupported), sizeof(GetDCB()->m_rightSideProtocolMinSupported)); // For Telesto, Dbi and Wks have a more flexible versioning allowed, as described by the Debugger @@ -7650,7 +7659,7 @@ void CordbProcess::VerifyControlBlock() // But just in case the installation is corrupted, we'll check it. if (GetDCB()->m_DCBSize != sizeof(DebuggerIPCControlBlock)) { - CONSISTENCY_CHECK_MSGF(false, ("DCB in LS is %d bytes, in RS is %d bytes. Version mismatch!!\n", + CONSISTENCY_CHECK_MSGF(false, ("DCB in LS is %d bytes, in RS is %d bytes. Version mismatch!!\n", GetDCB()->m_DCBSize, sizeof(DebuggerIPCControlBlock))); ThrowHR(CORDBG_E_INCOMPATIBLE_PROTOCOL); } @@ -7740,7 +7749,7 @@ HRESULT CordbProcess::GetRuntimeOffsets() // get the remote address of the runtime offsets structure and read the structure itself HRESULT hrRead = SafeReadStruct(PTR_TO_CORDB_ADDRESS(GetDCB()->m_pRuntimeOffsets), &m_runtimeOffsets); - + if (FAILED(hrRead)) { return hrRead; @@ -7824,7 +7833,7 @@ HRESULT CordbProcess::GetRuntimeOffsets() m_runtimeOffsets.m_excepNotForRuntimeBPAddr, m_runtimeOffsets.m_notifyRSOfSyncCompleteBPAddr, }; - + const int NumFlares = NumItems(flares); // Ensure that all of the flares are unique. @@ -7971,7 +7980,7 @@ void CordbProcess::QueueUnmanagedEvent(CordbUnmanagedThread *pUThread, const DEB // the event then it did not. _ASSERTE(ue->IsEventContinuedUnhijacked()); LOG((LF_CORDB, LL_INFO10000, "CP::QUE: A previously seen event is being discarded 0x%x 0x%p\n", - ue->m_currentDebugEvent.u.Exception.ExceptionRecord.ExceptionCode, + ue->m_currentDebugEvent.u.Exception.ExceptionRecord.ExceptionCode, ue->m_currentDebugEvent.u.Exception.ExceptionRecord.ExceptionAddress)); DequeueUnmanagedEvent(ue->m_owner); } @@ -8418,12 +8427,12 @@ HRESULT CordbProcess::StartSyncFromWin32Stop(BOOL * pfAsyncBreakSent) // The process can be running free as far as Win32 events are concerned, but still not synchronized as far as the // Runtime is concerned. This can happen in a lot of cases where we end up with the Runtime not sync'd but with the // process running free due to hijacking, etc... - if (((m_state & CordbProcess::PS_WIN32_STOPPED) && (m_outOfBandEventQueue == NULL)) || + if (((m_state & CordbProcess::PS_WIN32_STOPPED) && (m_outOfBandEventQueue == NULL)) || (!GetSynchronized() && IsInteropDebugging())) { Lock(); - if (((m_state & CordbProcess::PS_WIN32_STOPPED) && (m_outOfBandEventQueue == NULL)) || + if (((m_state & CordbProcess::PS_WIN32_STOPPED) && (m_outOfBandEventQueue == NULL)) || (!GetSynchronized() && IsInteropDebugging())) { // This can't be the win32 ET b/c we need that thread to be alive and pumping win32 DE so that @@ -8575,17 +8584,17 @@ void CordbProcess::UnrecoverableError(HRESULT errorHR, // debugger while inside CordbProcess::DispatchRCEvent() (as that function deliberately // calls Unlock() while calling into the Shim). Detect such cases here & bail before we // try to access invalid fields on this CordbProcess. - // + // // Normally, we'd need to take the cordb process lock around the IsNeutered check // (and the code that follows). And perhaps this is a good thing to do in the // future. But for now we're not for two reasons: - // + // // 1) It's scary. We're in UnrecoverableError() for gosh sake. I don't know all // the possible bad states we can be in to get here. Will taking the process lock // have ordering issues? Will the process lock even be valid to take here (or might // we AV)? Since this is error handling, we should probably be as light as we can // not to cause more errors. - // + // // 2) It's unnecessary. For the Watson dump I investigated that caused this fix in // the first place, we already detached before entering UnrecoverableError() // (indeed, the only reason we're in UnrecoverableError is that we already detached @@ -8605,7 +8614,7 @@ void CordbProcess::UnrecoverableError(HRESULT errorHR, // @dbgtodo - , shim: Once everything is hoisted, we can remove // this code. // In the v3 case, we should never get an unrecoverable error. Instead, the HR should be propogated - // and returned at the top-level public API. + // and returned at the top-level public API. _ASSERTE(!"Unrecoverable error dispatched in V3 case."); } @@ -8639,7 +8648,7 @@ void CordbProcess::UnrecoverableError(HRESULT errorHR, } EX_CATCH { - _ASSERTE(!"Writing process memory failed, perhaps due to an unexpected disconnection from the target."); + _ASSERTE(!"Writing process memory failed, perhaps due to an unexpected disconnection from the target."); } EX_END_CATCH(SwallowAllExceptions); } @@ -8664,7 +8673,7 @@ HRESULT CordbProcess::CheckForUnrecoverableError() { HRESULT hr = S_OK; - if (GetDCB() != NULL) + if (GetDCB() != NULL) { // be sure we have the latest information UpdateRightSideDCB(); @@ -8743,11 +8752,11 @@ COM_METHOD CordbProcess::ModifyLogSwitch(__in_z WCHAR *pLogSwitchName, LONG lLev // cbSize - the size of local buffer // // Exceptions -// On error throws the result of WriteVirtual unless a short write is performed, +// On error throws the result of WriteVirtual unless a short write is performed, // in which case throws ERROR_PARTIAL_COPY // -void CordbProcess::SafeWriteBuffer(TargetBuffer tb, - const BYTE * pLocalBuffer) +void CordbProcess::SafeWriteBuffer(TargetBuffer tb, + const BYTE * pLocalBuffer) { _ASSERTE(m_pMutableDataTarget != NULL); HRESULT hr = m_pMutableDataTarget->WriteVirtual(tb.pAddress, @@ -8778,10 +8787,10 @@ HRESULT CordbProcess::SafeReadBuffer(TargetBuffer tb, BYTE * pLocalBuffer, BOOL ULONG32 cbRead; HRESULT hr = m_pDACDataTarget->ReadVirtual(tb.pAddress, pLocalBuffer, - tb.cbSize, + tb.cbSize, &cbRead); - if (FAILED(hr)) + if (FAILED(hr)) { if (throwOnError) ThrowHR(CORDBG_E_READVIRTUAL_FAILURE); @@ -8807,12 +8816,12 @@ HRESULT CordbProcess::SafeReadBuffer(TargetBuffer tb, BYTE * pLocalBuffer, BOOL // vmAppDomain - CLR appdomain to lookup // // Returns: -// Instance of CordbAppDomain for the given appdomain. This is a cached instance. -// If the CordbAppDomain does not yet exist, it will be created and added to the cache. +// Instance of CordbAppDomain for the given appdomain. This is a cached instance. +// If the CordbAppDomain does not yet exist, it will be created and added to the cache. // Never returns NULL. Throw on error. CordbAppDomain * CordbProcess::LookupOrCreateAppDomain(VMPTR_AppDomain vmAppDomain) { - CordbAppDomain * pAppDomain = m_appDomains.GetBase(VmPtrToCookie(vmAppDomain)); + CordbAppDomain * pAppDomain = m_appDomains.GetBase(VmPtrToCookie(vmAppDomain)); if (pAppDomain != NULL) { return pAppDomain; @@ -8831,7 +8840,7 @@ CordbAppDomain * CordbProcess::GetSharedAppDomain() } m_sharedAppDomain->InternalAddRef(); } - + return m_sharedAppDomain; } @@ -8843,12 +8852,12 @@ CordbAppDomain * CordbProcess::GetSharedAppDomain() // vmAppDomain - appdomain to add. // // Return Value: -// Pointer to newly created appdomain, which should be the normal case. +// Pointer to newly created appdomain, which should be the normal case. // Throws on failure. Never returns null. // // Assumptions: // Caller ensure the appdomain is not already cached. -// Caller should have stop-go lock, which provides thread-safety. +// Caller should have stop-go lock, which provides thread-safety. // // Notes: // This sets unrecoverable error on failure. @@ -8862,8 +8871,8 @@ CordbAppDomain * CordbProcess::CacheAppDomain(VMPTR_AppDomain vmAppDomain) RSInitHolder<CordbAppDomain> pAppDomain; pAppDomain.Assign(new CordbAppDomain(this, vmAppDomain)); // throws - - // Add to the hash. This will addref the pAppDomain. + + // Add to the hash. This will addref the pAppDomain. // Caller ensures we're not already cached. // The cache will take ownership. m_appDomains.AddBaseOrThrow(pAppDomain); @@ -8898,7 +8907,7 @@ CordbAppDomain * CordbProcess::CacheAppDomain(VMPTR_AppDomain vmAppDomain) // // // Assumptions: -// Invoked as callback from code:CordbProcess::PrepopulateAppDomains +// Invoked as callback from code:CordbProcess::PrepopulateAppDomains // // //--------------------------------------------------------------------------------------- @@ -8943,8 +8952,8 @@ void CordbProcess::PrepopulateAppDomainsOrThrow() CONTRACTL_END; INTERNAL_API_ENTRY(this); - - if (!IsDacInitialized()) + + if (!IsDacInitialized()) { return; } @@ -8966,7 +8975,7 @@ void CordbProcess::PrepopulateAppDomainsOrThrow() // S_OK on success. // // Assumptions: -// +// // // Notes: // This operation is non-invasive target. @@ -8980,16 +8989,16 @@ HRESULT CordbProcess::EnumerateAppDomains(ICorDebugAppDomainEnum **ppAppDomains) ValidateOrThrow(ppAppDomains); // Ensure list is populated. - PrepopulateAppDomainsOrThrow(); - + PrepopulateAppDomainsOrThrow(); + RSInitHolder<CordbHashTableEnum> pEnum; CordbHashTableEnum::BuildOrThrow( - this, - GetContinueNeuterList(), + this, + GetContinueNeuterList(), &m_appDomains, IID_ICorDebugAppDomainEnum, pEnum.GetAddr()); - + *ppAppDomains = static_cast<ICorDebugAppDomainEnum*> (pEnum); pEnum->ExternalAddRef(); @@ -9015,7 +9024,7 @@ HRESULT CordbProcess::GetObject(ICorDebugValue **ppObject) //--------------------------------------------------------------------------------------- // -// Given a taskid, finding the corresponding thread. The function can fail if we do not +// Given a taskid, finding the corresponding thread. The function can fail if we do not // find any thread with the given taskid // // Arguments: @@ -9042,7 +9051,7 @@ HRESULT CordbProcess::GetThreadForTaskID(TASKID taskId, ICorDebugThread2 ** ppTh ThrowHR(E_INVALIDARG); } - // On initialization, the task ID of every thread is INVALID_TASK_ID, unless a host is present and + // On initialization, the task ID of every thread is INVALID_TASK_ID, unless a host is present and // the host calls IClrTask::SetTaskIdentifier(). So we need to explicitly check for INVALID_TASK_ID // here and return NULL if necessary. We return S_FALSE because that's the return value for the case // where we can't find a thread for the specified task ID. @@ -9054,12 +9063,12 @@ HRESULT CordbProcess::GetThreadForTaskID(TASKID taskId, ICorDebugThread2 ** ppTh else { PrepopulateThreadsOrThrow(); - + // now find the ICorDebugThread corresponding to it CordbThread * pThread; HASHFIND hashFind; - + for (pThread = m_userThreads.FindFirst(&hashFind); pThread != NULL; pThread = m_userThreads.FindNext(&hashFind)) @@ -9068,7 +9077,7 @@ HRESULT CordbProcess::GetThreadForTaskID(TASKID taskId, ICorDebugThread2 ** ppTh { break; } - } + } if (pThread == NULL) { @@ -9113,7 +9122,7 @@ CordbProcess::GetVersion(COR_VERSION* pVersion) NativePatch * CordbProcess::GetNativePatch(const void * pAddress) { _ASSERTE(ThreadHoldsProcessLock()); - + int cTotal = m_NativePatchList.Count(); NativePatch * pTable = m_NativePatchList.Table(); if (pTable == NULL) @@ -9147,8 +9156,8 @@ bool CordbProcess::IsBreakOpcodeAtAddress(const void * address) #endif HRESULT hr = SafeReadStruct(PTR_TO_CORDB_ADDRESS(address), &opcodeTest); - SIMPLIFYING_ASSUMPTION_SUCCEEDED(hr); - + SIMPLIFYING_ASSUMPTION_SUCCEEDED(hr); + return (opcodeTest == CORDbg_BREAK_INSTRUCTION); } #endif // FEATURE_INTEROP_DEBUGGING @@ -9289,7 +9298,7 @@ CordbProcess::ClearUnmanagedBreakpoint(CORDB_ADDRESS address) PUBLIC_API_ENTRY(this); FAIL_IF_NEUTERED(this); FAIL_IF_MANAGED_ONLY(this); - + _ASSERTE(!ThreadHoldsProcessLock()); HRESULT hr = S_OK; @@ -9418,7 +9427,7 @@ void CordbProcess::SetSyncCompleteRecv(bool fSyncRecv) // This can be used if we ever need the RS to emulate old behavior of previous versions. // This can not be used in QIs to deny queries for new interfaces. -// QIs must be consistent across the lifetime of an object. Say CordbThread used this in a QI +// QIs must be consistent across the lifetime of an object. Say CordbThread used this in a QI // do deny returning a ICorDebugThread2 interface when emulating v1.1. Once that Thread is neutered, // it no longer has a pointer to the process, and it no longer knows if it should be denying // the v2.0 query. An object's QI can't start returning new interfaces onces its neutered. @@ -9431,12 +9440,12 @@ bool CordbProcess::SupportsVersion(CorDebugInterfaceVersion featureVersion) //--------------------------------------------------------------------------------------- // Add an object to the process's Left-Side resource cleanup list -// +// // Arguments: // pObject - non-null object to be added -// +// // Notes: -// This list tracks objects with process-scope that hold left-side +// This list tracks objects with process-scope that hold left-side // resources (like func-eval). // See code:CordbAppDomain::GetSweepableExitNeuterList for per-appdomain // objects with left-side resources. @@ -9444,7 +9453,7 @@ void CordbProcess::AddToLeftSideResourceCleanupList(CordbBase * pObject) { INTERNAL_API_ENTRY(this); _ASSERTE(pObject != NULL); - + m_LeftSideResourceCleanupList.Add(this, pObject); } @@ -9453,12 +9462,12 @@ void CordbProcess::AddToNeuterOnExitList(CordbBase *pObject) { INTERNAL_API_ENTRY(this); _ASSERTE(pObject != NULL); - + HRESULT hr = S_OK; EX_TRY { this->m_ExitNeuterList.Add(this, pObject); - } + } EX_CATCH_HRESULT(hr); SetUnrecoverableIfFailed(GetProcess(), hr); } @@ -9469,7 +9478,7 @@ void CordbProcess::AddToNeuterOnContinueList(CordbBase *pObject) INTERNAL_API_ENTRY(this); _ASSERTE(pObject != NULL); - m_ContinueNeuterList.Add(this, pObject); // throws + m_ContinueNeuterList.Add(this, pObject); // throws } @@ -9548,7 +9557,7 @@ void CordbProcess::DuplicateHandleToLocalProcess(HANDLE * pLocalHandle, RemoteHA { BOOL fSuccess = pRemoteHandle->DuplicateToLocalProcess(m_handle, pLocalHandle); if (!fSuccess) - { + { ThrowLastError(); } } @@ -9602,7 +9611,7 @@ void CordbProcess::FinishInitializeIPCChannelWorker() LOG((LF_CORDB, LL_INFO1000, "[%x] RCET::HFRCE: first event..., process %p\n", GetCurrentThreadId(), this)); BOOL fBlockExists; - GetEventBlock(&fBlockExists); // throws on error + GetEventBlock(&fBlockExists); // throws on error LOG((LF_CORDB, LL_EVERYTHING, "Size of CdbP is %d\n", sizeof(CordbProcess))); @@ -9611,7 +9620,7 @@ void CordbProcess::FinishInitializeIPCChannelWorker() #if defined(FEATURE_INTEROP_DEBUGGING) DuplicateHandleToLocalProcess(&m_leftSideUnmanagedWaitEvent, &GetDCB()->m_leftSideUnmanagedWaitEvent); #endif // FEATURE_INTEROP_DEBUGGING - + // Read the Runtime Offsets struct out of the debuggee. hr = GetRuntimeOffsets(); IfFailThrow(hr); @@ -9619,11 +9628,11 @@ void CordbProcess::FinishInitializeIPCChannelWorker() // we need to be careful here. The LS will have a thread running free that may be initializing // fields of the DCB (specifically it may be setting up the helper thread), so we need to make sure // we don't overwrite any fields that the LS is writing. We need to be sure we only write to RS - // status fields. + // status fields. m_initialized = true; GetDCB()->m_rightSideIsWin32Debugger = IsInteropDebugging(); UpdateLeftSideDCBField(&(GetDCB()->m_rightSideIsWin32Debugger), sizeof(GetDCB()->m_rightSideIsWin32Debugger)); - + LOG((LF_CORDB, LL_INFO1000, "[%x] RCET::HFRCE: ...went fine\n", GetCurrentThreadId())); _ASSERTE(SUCCEEDED(hr)); @@ -9636,7 +9645,7 @@ void CordbProcess::FinishInitializeIPCChannelWorker() // We only land here on failure cases. // We must have jumped to this label. Maybe we didn't set HR, so check now. STRESS_LOG1(LF_CORDB, LL_INFO1000, "HFCR: FAILED hr=0x%08x\n", hr); - + CloseIPCHandles(); // Rethrow @@ -9653,10 +9662,10 @@ void CordbProcess::FinishInitializeIPCChannelWorker() // Throws on error void Ls_Rs_BaseBuffer::CopyLSDataToRSWorker(ICorDebugDataTarget * pTarget) { - // + // const DWORD cbCacheSize = m_cbSize; - - // SHOULD not happen for more than once in well-behaved case. + + // SHOULD not happen for more than once in well-behaved case. if (m_pbRS != NULL) { SIMPLIFYING_ASSUMPTION(!"m_pbRS is non-null; is this a corrupted event?"); @@ -9664,7 +9673,7 @@ void Ls_Rs_BaseBuffer::CopyLSDataToRSWorker(ICorDebugDataTarget * pTarget) } NewHolder<BYTE> pData(new BYTE[cbCacheSize]); - + ULONG32 cbRead; HRESULT hrRead = pTarget->ReadVirtual(PTR_TO_CORDB_ADDRESS(m_pbLS), pData, cbCacheSize , &cbRead); @@ -9672,7 +9681,7 @@ void Ls_Rs_BaseBuffer::CopyLSDataToRSWorker(ICorDebugDataTarget * pTarget) { hrRead = CORDBG_E_READVIRTUAL_FAILURE; } - + if (SUCCEEDED(hrRead) && (cbCacheSize != cbRead)) { hrRead = HRESULT_FROM_WIN32(ERROR_PARTIAL_COPY); @@ -9681,7 +9690,7 @@ void Ls_Rs_BaseBuffer::CopyLSDataToRSWorker(ICorDebugDataTarget * pTarget) // Now do Transfer m_pbRS = pData; - pData.SuppressRelease(); + pData.SuppressRelease(); } //--------------------------------------------------------------------------------------- @@ -9704,20 +9713,20 @@ void Ls_Rs_ByteBuffer::CopyLSDataToRS(ICorDebugDataTarget * pTarget) // // Throws on error void Ls_Rs_StringBuffer::CopyLSDataToRS(ICorDebugDataTarget * pTarget) -{ +{ CopyLSDataToRSWorker(pTarget); - + // Ensure we're a valid, well-formed string. // @dbgtodo - this should only happen in corrupted scenarios. Perhaps a better HR here? // - null terminated. // - no embedded nulls. - + const WCHAR * pString = GetString(); SIZE_T dwExpectedLenWithNull = m_cbSize / sizeof(WCHAR); - + // Should at least have 1 character for the null-terminator. if (dwExpectedLenWithNull == 0) - { + { ThrowHR(CORDBG_E_TARGET_INCONSISTENT); } @@ -9749,17 +9758,17 @@ void Ls_Rs_StringBuffer::CopyLSDataToRS(ICorDebugDataTarget * pTarget) // // Assumptions: // Target is currently stopped and inspectable. -// After the event is marshalled, it has resources that must be cleaned up +// After the event is marshalled, it has resources that must be cleaned up // by calling code:DeleteIPCEventHelper. -// +// // Notes: // Call a Copy function (CopyManagedEventFromTarget, CopyRCEventFromIPCBlock)to // get the event to marshal. // This will marshal args from the target into the host. -// The debug event is fixed size. But since the debuggee is stopped, this can copy -// arbitrary-length buffers out of of the debuggee. +// The debug event is fixed size. But since the debuggee is stopped, this can copy +// arbitrary-length buffers out of of the debuggee. // -// This could be rolled into code:CordbProcess::RawDispatchEvent +// This could be rolled into code:CordbProcess::RawDispatchEvent //--------------------------------------------------------------------------------------- void CordbProcess::MarshalManagedEvent(DebuggerIPCEvent * pManagedEvent) { @@ -9799,7 +9808,7 @@ void CordbProcess::MarshalManagedEvent(DebuggerIPCEvent * pManagedEvent) break; } - + } @@ -9815,37 +9824,37 @@ void CordbProcess::MarshalManagedEvent(DebuggerIPCEvent * pManagedEvent) // loaded into the target and all sending events wit the same exception code. // * False if this does not belong to this instance of ICorDebug. (perhaps it's an event // intended for another instance of the CLR in the target, or some rogue user code happening -// to use our exception code). +// to use our exception code). // In either case, the event can still be cleaned up via code:DeleteIPCEventHelper. // // Throws on error. In the error case, the contents of pLocalManagedEvent are undefined. -// They may have been partially copied from the target. The local managed event does not own +// They may have been partially copied from the target. The local managed event does not own // any resources until it's marshalled, so the buffer can be ignored if this function fails. // // Assumptions: // // Notes: // The events are sent form the target via code:Debugger::SendRawEvent -// This just does a raw Byte copy, but does not do any Marshalling. -// This should always succeed in the well-behaved case. However, A bad debuggee can +// This just does a raw Byte copy, but does not do any Marshalling. +// This should always succeed in the well-behaved case. However, A bad debuggee can // always send a poor-formed debug event. // We don't distinguish between a badly formed event and an event that's not ours. // The event still needs to be Marshaled before being used. (see code:CordbProcess::MarshalManagedEvent) // //--------------------------------------------------------------------------------------- -#if defined(_MSC_VER) && defined(_TARGET_ARM_) +#if defined(_MSC_VER) && defined(_TARGET_ARM_) // This is a temporary workaround for an ARM specific MS C++ compiler bug (internal LKG build 18.1). // Branch < if (ptrRemoteManagedEvent == NULL) > was always taken and the function always returned false. // TODO: It should be removed once the bug is fixed. #pragma optimize("", off) #endif bool CordbProcess::CopyManagedEventFromTarget( - const EXCEPTION_RECORD * pRecord, + const EXCEPTION_RECORD * pRecord, DebuggerIPCEvent * pLocalManagedEvent) { _ASSERTE(pRecord != NULL); _ASSERTE(pLocalManagedEvent != NULL); - + // Initialize the event enough such backout code can call code:DeleteIPCEventHelper. pLocalManagedEvent->type = DB_IPCE_DEBUGGER_INVALID; @@ -9875,40 +9884,40 @@ bool CordbProcess::CopyManagedEventFromTarget( // For Mac remote debugging the address returned above is actually a local address. // Also, we need to copy the entire buffer because once a debug event is read from the debugger // transport, it won't be available afterwards. - memcpy(reinterpret_cast<BYTE *>(pLocalManagedEvent), - CORDB_ADDRESS_TO_PTR(ptrRemoteManagedEvent), + memcpy(reinterpret_cast<BYTE *>(pLocalManagedEvent), + CORDB_ADDRESS_TO_PTR(ptrRemoteManagedEvent), CorDBIPC_BUFFER_SIZE); hr = S_OK; -#endif - SIMPLIFYING_ASSUMPTION(SUCCEEDED(hr)); +#endif + SIMPLIFYING_ASSUMPTION(SUCCEEDED(hr)); IfFailThrow(hr); return true; } -#if defined(_MSC_VER) && defined(_TARGET_ARM_) +#if defined(_MSC_VER) && defined(_TARGET_ARM_) #pragma optimize("", on) #endif //--------------------------------------------------------------------------------------- // EnsureClrInstanceIdSet - Ensure we have a CLR Instance ID to debug -// +// // In Arrowhead scenarios, the debugger is required to pass a valid CLR instance ID -// to us in OpenVirtualProcess. In V2 scenarios, for compatibility, we'll allow a +// to us in OpenVirtualProcess. In V2 scenarios, for compatibility, we'll allow a // CordbProcess object to exist for a process that doesn't yet have the CLR loaded. // In this case the CLR instance ID will start off as 0, but be filled in when we see the // startup exception indicating the CLR has been loaded. // // If we don't already have an instance ID, this function sets it to the only CLR in the // target process. This requires that a CLR be loaded in the target process. -// +// // Return Value: // S_OK - if m_clrInstanceId was already set, or is now set to a valid CLR instance ID -// an error HRESULT - if m_clrInstanceId was 0, and cannot be set to a valid value +// an error HRESULT - if m_clrInstanceId was 0, and cannot be set to a valid value // (i.e. because we cannot find a CLR in the target process). -// -// Note that we need to probe for this on attach, and it's common to attach before the +// +// Note that we need to probe for this on attach, and it's common to attach before the // CLR has been loaded, so we avoid using exceptions for this common case. -// +// HRESULT CordbProcess::EnsureClrInstanceIdSet() { // If we didn't expect a specific CLR, then attempt to attach to any. @@ -9935,7 +9944,7 @@ HRESULT CordbProcess::EnsureClrInstanceIdSet() _ASSERTE(m_clrInstanceId == 0); return hr; } - } + } // We've (now) got a valid CLR instance id return S_OK; @@ -9955,7 +9964,7 @@ HRESULT CordbProcess::EnsureClrInstanceIdSet() // // Notes: // This is copying from a shared-memory block, which is treated as local memory. -// This just does a raw Byte copy, but does not do any Marshalling. +// This just does a raw Byte copy, but does not do any Marshalling. // This does no validation on the event. // The event still needs to be Marshaled before being used. (see code:CordbProcess::MarshalManagedEvent) // @@ -9975,9 +9984,9 @@ bool CordbRCEventThread::IsRCEventThread() //--------------------------------------------------------------------------------------- // Runtime assert, throws CORDBG_E_TARGET_INCONSISTENT if the expression is not true. -// +// // Arguments: -// fExpression - assert parameter. If true, this function is a nop. If false, +// fExpression - assert parameter. If true, this function is a nop. If false, // this will throw a CORDBG_E_TARGET_INCONSISTENT error. // // Notes: @@ -9987,7 +9996,7 @@ bool CordbRCEventThread::IsRCEventThread() void CordbProcess::TargetConsistencyCheck(bool fExpression) { if (!fExpression) - { + { STRESS_LOG0(LF_CORDB, LL_INFO10000, "Target consistency check failed"); // When debugging possibly corrupt targets, this failure may be expected. For debugging purposes, @@ -10135,7 +10144,7 @@ HRESULT CordbRCEventThread::SendIPCEvent(CordbProcess* process, return CORDBG_E_PROCESS_TERMINATED; } - // If the helper thread has died, we can't send an IPC event (and it's never coming back either). + // If the helper thread has died, we can't send an IPC event (and it's never coming back either). // Although we do wait on the thread's handle, there are strange windows where the thread's handle // is not yet signaled even though we've continued from the exit-thread event for the helper. if (process->m_helperThreadDead) @@ -10321,8 +10330,8 @@ HRESULT CordbRCEventThread::SendIPCEvent(CordbProcess* process, } } - - process->ForceDacFlush(); + + process->ForceDacFlush(); // The hr and hrEvent are 2 very different things. // hr tells us whether the event was sent successfully. @@ -10351,7 +10360,7 @@ HRESULT CordbRCEventThread::SendIPCEvent(CordbProcess* process, void CordbRCEventThread::FlushQueuedEvents(CordbProcess* process) { CONTRACTL - { + { NOTHROW; // This is happening on the RCET thread, so there's no place to propogate an error back up. } CONTRACTL_END; @@ -10376,9 +10385,9 @@ void CordbRCEventThread::FlushQueuedEvents(CordbProcess* process) // ShimProcess now, while we still hold the process lock. Once we release the lock, // GetShim() may not work. RSExtSmartPtr<ShimProcess> pShim(process->GetShim()); - + // Release lock before we call out to shim to Queue fake events. - { + { RSInverseLockHolder inverseLockHolder(process->GetProcessLock()); { PUBLIC_CALLBACK_IN_THIS_SCOPE0_NO_LOCK(pProcess); @@ -10443,7 +10452,7 @@ void CordbRCEventThread::FlushQueuedEvents(CordbProcess* process) // None. Throws on error. On error, caller still owns the pManagedEvent and must free it. // // Assumptions: -// This should be called once a notification event is received from the target. +// This should be called once a notification event is received from the target. // // Notes: // HandleRCEvent -- handle an IPC event received from the runtime controller. @@ -10451,8 +10460,8 @@ void CordbRCEventThread::FlushQueuedEvents(CordbProcess* process) // //--------------------------------------------------------------------------------------- void CordbProcess::HandleRCEvent( - DebuggerIPCEvent * pManagedEvent, - RSLockHolder * pLockHolder, + DebuggerIPCEvent * pManagedEvent, + RSLockHolder * pLockHolder, ICorDebugManagedCallback * pCallback) { CONTRACTL @@ -10470,23 +10479,23 @@ void CordbProcess::HandleRCEvent( } // Marshals over some standard data from event. - MarshalManagedEvent(pManagedEvent); + MarshalManagedEvent(pManagedEvent); STRESS_LOG4(LF_CORDB, LL_INFO1000, "RCET::TP: Got %s for AD 0x%x, proc 0x%x(%d)\n", IPCENames::GetName(pManagedEvent->type), VmPtrToCookie(pManagedEvent->vmAppDomain), this->m_id, this->m_id); RSExtSmartPtr<ICorDebugManagedCallback2> pCallback2; - pCallback->QueryInterface(IID_ICorDebugManagedCallback2, reinterpret_cast<void **> (&pCallback2)); + pCallback->QueryInterface(IID_ICorDebugManagedCallback2, reinterpret_cast<void **> (&pCallback2)); RSExtSmartPtr<ICorDebugManagedCallback3> pCallback3; - pCallback->QueryInterface(IID_ICorDebugManagedCallback3, reinterpret_cast<void **> (&pCallback3)); + pCallback->QueryInterface(IID_ICorDebugManagedCallback3, reinterpret_cast<void **> (&pCallback3)); RSExtSmartPtr<ICorDebugManagedCallback4> pCallback4; pCallback->QueryInterface(IID_ICorDebugManagedCallback4, reinterpret_cast<void **> (&pCallback4)); // Dispatch directly. May not necessarily dispatch an event. // Toggles the lock to dispatch callbacks. - RawDispatchEvent(pManagedEvent, pLockHolder, pCallback, pCallback2, pCallback3, pCallback4); + RawDispatchEvent(pManagedEvent, pLockHolder, pCallback, pCallback2, pCallback3, pCallback4); } // @@ -10506,7 +10515,7 @@ void CordbRCEventThread::ProcessStateChanged() //--------------------------------------------------------------------------------------- -// Primary loop of the Runtime Controller event thread. This routine loops during the +// Primary loop of the Runtime Controller event thread. This routine loops during the // debug session taking IPC events from the IPC block and calling out to process them. // // Arguments: @@ -10594,7 +10603,7 @@ void CordbRCEventThread::ThreadProc() for (pProcess = pHashTable->FindFirst(&hashFind); pProcess != NULL; pProcess = pHashTable->FindNext(&hashFind)) { _ASSERTE(waitCount < MAXIMUM_WAIT_OBJECTS); - + if( waitCount >= MAXIMUM_WAIT_OBJECTS ) { break; @@ -10608,7 +10617,7 @@ void CordbRCEventThread::ThreadProc() // per-process mutex when checking the process's synchronized flag here. if (!pProcess->GetSynchronized() && pProcess->IsSafeToSendEvents()) { - STRESS_LOG2(LF_CORDB, LL_INFO1000, "RCET::TP: listening to process 0x%x(%d)\n", + STRESS_LOG2(LF_CORDB, LL_INFO1000, "RCET::TP: listening to process 0x%x(%d)\n", pProcess->m_id, pProcess->m_id); waitSet[waitCount] = pProcess->m_leftSideEventAvailable; @@ -10640,7 +10649,7 @@ void CordbRCEventThread::ThreadProc() // Flush the queue if necessary. Note, we only do this if we've actually received a SyncComplete message // from this process. If we haven't received a SyncComplete yet, then we don't attempt to drain any // queued events yet. They'll be drained when the SyncComplete event is actually received. - if (pProcess->GetSyncCompleteRecv() && + if (pProcess->GetSyncCompleteRecv() && (pProcess->GetShim() != NULL) && !pProcess->GetSynchronized()) { @@ -10650,7 +10659,7 @@ void CordbRCEventThread::ThreadProc() // handling an event. We can get here if the event raised by the LS is a duplicate // creation event, which the shim discards without adding it to the event queue. // See code:ShimProcess::IsDuplicateCreationEvent. - // + // // To continue, we need to increment the stop count first. Also, we can't call // Continue() while holding the process lock. pProcess->SetSynchronized(true); @@ -10722,7 +10731,7 @@ void CordbRCEventThread::ThreadProc() // This is the thread's real thread proc. It simply calls to the // thread proc on the given object. // -/*static*/ +/*static*/ DWORD WINAPI CordbRCEventThread::ThreadProc(LPVOID parameter) { CordbRCEventThread * pThread = (CordbRCEventThread *) parameter; @@ -10838,7 +10847,7 @@ void CordbRCEventThread::DrainWorkerQueue() // S_OK on success. else failure. // // Assumptions: -// Caller allocates +// Caller allocates // // Notes: // WaitForIPCEventFromProcess waits for an event from just the specified @@ -10847,8 +10856,8 @@ void CordbRCEventThread::DrainWorkerQueue() // process's event, too, which would get confusing. // // @dbgtodo - this function should eventually be obsolete once everything -// is using DAC calls instead of helper-thread. -// +// is using DAC calls instead of helper-thread. +// //--------------------------------------------------------------------------------------- HRESULT CordbRCEventThread::WaitForIPCEventFromProcess(CordbProcess * pProcess, CordbAppDomain * pAppDomain, @@ -10861,7 +10870,7 @@ HRESULT CordbRCEventThread::WaitForIPCEventFromProcess(CordbProcess * pProcess, do { - dwStatus = SafeWaitForSingleObject(pProcess, + dwStatus = SafeWaitForSingleObject(pProcess, pProcess->m_leftSideEventAvailable, CordbGetWaitTimeout()); @@ -10884,9 +10893,9 @@ HRESULT CordbRCEventThread::WaitForIPCEventFromProcess(CordbProcess * pProcess, pProcess->MarshalManagedEvent(pEvent); STRESS_LOG4(LF_CORDB, LL_INFO1000, "CRCET::SIPCE: Got %s for AD 0x%x, proc 0x%x(%d)\n", - IPCENames::GetName(pEvent->type), - VmPtrToCookie(pEvent->vmAppDomain), - pProcess->m_id, + IPCENames::GetName(pEvent->type), + VmPtrToCookie(pEvent->vmAppDomain), + pProcess->m_id, pProcess->m_id); } @@ -10939,11 +10948,11 @@ HRESULT CordbRCEventThread::Start() return E_INVALIDARG; } - m_thread = CreateThread(NULL, - 0, + m_thread = CreateThread(NULL, + 0, &CordbRCEventThread::ThreadProc, - (LPVOID) this, - 0, + (LPVOID) this, + 0, &m_threadId); if (m_thread == NULL) @@ -11007,7 +11016,7 @@ enum // //--------------------------------------------------------------------------------------- CordbWin32EventThread::CordbWin32EventThread( - Cordb * pCordb, + Cordb * pCordb, ShimProcess * pShim ) : m_thread(NULL), m_threadControlEvent(NULL), @@ -11088,7 +11097,7 @@ void CordbWin32EventThread::ThreadProc() DbgRSThread::GetThread()->TakeVirtualLock(RSLock::LL_WIN32_EVENT_THREAD); #endif - // In V2, the debuggee decides what to do if the debugger rudely exits / detaches. (This is + // In V2, the debuggee decides what to do if the debugger rudely exits / detaches. (This is // handled by host policy). With the OS native-debuggging pipeline, the debugger by default // kills the debuggee if it exits. To emulate V2 behavior, we need to override that default. BOOL fOk = m_pNativePipeline->DebugSetProcessKillOnExit(FALSE); @@ -11115,7 +11124,7 @@ typedef DeleteIPCEventHolderHelper<DebuggerIPCEvent> DeleteIPCEventHolder; // This must be called after an event is marshalled via code:CordbProcess::MarshalManagedEvent // // Arguments: -// pManagedEvent - managed event to delete. +// pManagedEvent - managed event to delete. // // Notes: // This can delete a partially marshalled event. @@ -11168,8 +11177,8 @@ void DeleteIPCEventHelper(DebuggerIPCEvent *pManagedEvent) // Notes: // This is called after caller does WaitForDebugEvent. // Any exception this Filter does not recognize is treated as kNotClr. -// Currently, this includes both managed-exceptions and unmanaged ones. -// For interop-debugging, the interop logic will handle all kNotClr and triage if +// Currently, this includes both managed-exceptions and unmanaged ones. +// For interop-debugging, the interop logic will handle all kNotClr and triage if // it's really a non-CLR exception. // //--------------------------------------------------------------------------------------- @@ -11177,7 +11186,7 @@ void CordbProcess::FilterClrNotification( DebuggerIPCEvent * pManagedEvent, RSLockHolder * pLockHolder, ICorDebugManagedCallback * pCallback) -{ +{ CONTRACTL { THROWS; @@ -11192,7 +11201,7 @@ void CordbProcess::FilterClrNotification( // we need to set LSEA/wait on LSER. // 2) Sync-Complete (kind of like a special notification) // Ping the helper - // 3) Notifications (eg, Module-load): + // 3) Notifications (eg, Module-load): // these are dispatched immediately. // 4) Left-side Startup event @@ -11200,13 +11209,13 @@ void CordbProcess::FilterClrNotification( // IF we're synced, then we must be getting a "Reply". bool fReply = this->GetSynchronized(); - LOG((LF_CORDB, LL_INFO10000, "CP::FCN - Received event %s; fReply: %d\n", + LOG((LF_CORDB, LL_INFO10000, "CP::FCN - Received event %s; fReply: %d\n", IPCENames::GetName(pManagedEvent->type), fReply)); - if (fReply) - { - // + if (fReply) + { + // _ASSERTE(m_pShim != NULL); // // Case 1: Reply @@ -11219,7 +11228,7 @@ void CordbProcess::FilterClrNotification( GetEventChannel()->SaveEventFromLeftSide(pManagedEvent); SetEvent(this->m_leftSideEventAvailable); - // Some other thread called code:CordbRCEventThread::WaitForIPCEventFromProcess, and + // Some other thread called code:CordbRCEventThread::WaitForIPCEventFromProcess, and // that will respond here and set the event. DWORD dwResult = WaitForSingleObject(this->m_leftSideEventRead, CordbGetWaitTimeout()); @@ -11227,7 +11236,7 @@ void CordbProcess::FilterClrNotification( if (dwResult != WAIT_OBJECT_0) { // The wait failed. This is probably WAIT_TIMEOUT which suggests a deadlock/assert on - // the RCEventThread. + // the RCEventThread. CONSISTENCY_CHECK_MSGF(false, ("WaitForSingleObject failed: %d", dwResult)); ThrowHR(CORDBG_E_TIMEOUT); } @@ -11240,12 +11249,12 @@ void CordbProcess::FilterClrNotification( // Case 4: Left-side startup event. We'll mark that we're attached from oop. // - // Now that LS is started, we should definitely be able to instantiate DAC. + // Now that LS is started, we should definitely be able to instantiate DAC. InitializeDac(); - + // @dbgtodo 'attach-bit': we don't want the debugger automatically invading the process. - GetDAC()->MarkDebuggerAttached(TRUE); - } + GetDAC()->MarkDebuggerAttached(TRUE); + } else if (pManagedEvent->type == DB_IPCE_SYNC_COMPLETE) { // Since V3 doesn't request syncs, it shouldn't get sync-complete. @@ -11268,7 +11277,7 @@ void CordbProcess::FilterClrNotification( HandleRCEvent(pManagedEvent, pLockHolder, pCallback); } // end Notification - } + } } @@ -11284,10 +11293,10 @@ void CordbProcess::FilterClrNotification( // // Notes: // This is called from shim to emulate being synchronized at an unhandled -// exception. +// exception. // Other ICorDebug operations could calls this (eg, func-eval at 2nd chance). BOOL CordbProcess::HijackThreadForUnhandledExceptionIfNeeded(DWORD dwThreadId) -{ +{ PUBLIC_API_ENTRY(this); // from Shim BOOL fHijacked = FALSE; @@ -11297,13 +11306,13 @@ BOOL CordbProcess::HijackThreadForUnhandledExceptionIfNeeded(DWORD dwThreadId) RSLockHolder lockHolder(GetProcessLock()); // OS will not execute the Unhandled Exception Filter under native debugger, so - // we need to hijack the thread to get it to execute the UEF, which will then do + // we need to hijack the thread to get it to execute the UEF, which will then do // work for unhandled managed exceptions. CordbThread * pThread = TryLookupOrCreateThreadByVolatileOSId(dwThreadId); if (pThread != NULL) - { + { // If the thread has a managed exception, then we should have a pThread object. - + if (pThread->HasUnhandledNativeException()) { _ASSERTE(pThread->IsThreadExceptionManaged()); // should have been marked earlier @@ -11329,12 +11338,12 @@ BOOL CordbProcess::HijackThreadForUnhandledExceptionIfNeeded(DWORD dwThreadId) // // Returns: // A type-safe exception record from the raw buffer. -// +// // Notes: // This is a helper for code:CordbProcess::Filter. // This can do consistency checks on the incoming parameters such as: // * verify countBytes matches the expected size for the given format. -// * verify the format is supported. +// * verify the format is supported. // // If we let a given ICD understand multiple formats (eg, have x86 understand both Exr32 and // Exr64), this would be the spot to allow the conversion. @@ -11362,14 +11371,14 @@ const EXCEPTION_RECORD * CordbProcess::ValidateExceptionRecord( ThrowHR(E_INVALIDARG); } #endif - + // @dbgtodo cross-plat: once we do cross-plat, need to use correct EXCEPTION_RECORD variant. if (countBytes != sizeof(EXCEPTION_RECORD)) { ThrowHR(E_INVALIDARG); } - + const EXCEPTION_RECORD * pRecord = reinterpret_cast<const EXCEPTION_RECORD *> (pRawRecord); return pRecord; @@ -11385,21 +11394,21 @@ HRESULT CordbProcess::SetEnableCustomNotification(ICorDebugClass * pClass, BOOL ((CordbClass *)pClass)->SetCustomNotifications(fEnable); - PUBLIC_API_END(hr); + PUBLIC_API_END(hr); return hr; } // CordbProcess::SetEnableCustomNotification //--------------------------------------------------------------------------------------- // Public implementation of ICDProcess4::Filter // -// Arguments: +// Arguments: // pRawRecord - non-null raw bytes of the exception // countBytes - number of bytes in pRawRecord buffer. // format - format of pRawRecord // dwFlags - flags providing auxillary info for exception record. // dwThreadId - thread that exception occurred on. // pCallback - callback to dispatch potential managed events on. -// pContinueStatus - Continuation status for exception. This dictates what +// pContinueStatus - Continuation status for exception. This dictates what // to pass to kernel32!ContinueDebugEvent(). // // Return Value: @@ -11410,19 +11419,19 @@ HRESULT CordbProcess::SetEnableCustomNotification(ICorDebugClass * pClass, BOOL // // Notes: // The exception could be anything, including: -// - a CLR notification, +// - a CLR notification, // - a random managed exception (both from managed code or the runtime), // - a non-CLR exception // // This is cross-platform. The {pRawRecord, countBytes, format} describe events // on an arbitrary target architecture. On windows, this will be an EXCEPTION_RECORD. -// +// HRESULT CordbProcess::Filter( const BYTE pRawRecord[], DWORD countBytes, CorDebugRecordFormat format, - DWORD dwFlags, - DWORD dwThreadId, + DWORD dwFlags, + DWORD dwThreadId, ICorDebugManagedCallback * pCallback, DWORD * pContinueStatus ) @@ -11443,7 +11452,7 @@ HRESULT CordbProcess::Filter( DWORD dwFirstChance = (dwFlags & IS_FIRST_CHANCE); // - // Deal with 2nd-chance exceptions. Don't actually hijack now (that's too invasive), + // Deal with 2nd-chance exceptions. Don't actually hijack now (that's too invasive), // but mark that we have the exception in case a future operation (eg, func-eval) needs to hijack. // if (!dwFirstChance) @@ -11451,16 +11460,16 @@ HRESULT CordbProcess::Filter( CordbThread * pThread = TryLookupOrCreateThreadByVolatileOSId(dwThreadId); // If we don't have a managed-thread object, then it certainly can't have a throwable. - // It's possible this is still an exception from the native portion of the runtime, + // It's possible this is still an exception from the native portion of the runtime, // but that's ok, we'll just treat it as a native exception. // This could be expensive, don't want to do it often... (definitely not on every Filter). // OS will not execute the Unhandled Exception Filter under native debugger, so - // we need to hijack the thread to get it to execute the UEF, which will then do + // we need to hijack the thread to get it to execute the UEF, which will then do // work for unhandled managed exceptions. if ((pThread != NULL) && pThread->IsThreadExceptionManaged()) - { + { // Copy exception record for future use in case we decide to hijack. pThread->SetUnhandledNativeException(pRecord); } @@ -11475,30 +11484,30 @@ HRESULT CordbProcess::Filter( // // This may not be for us, or we may not have a managed thread object: // 1. Anybody can raise an exception with this exception code, so can't assume this belongs to us yet. - // 2. Notifications may come on unmanaged threads if they're coming from MDAs or CLR internal events + // 2. Notifications may come on unmanaged threads if they're coming from MDAs or CLR internal events // fired before the thread is created. // BYTE * pManagedEventBuffer = new BYTE[CorDBIPC_BUFFER_SIZE]; DeleteIPCEventHolder pManagedEvent(reinterpret_cast<DebuggerIPCEvent *>(pManagedEventBuffer)); - + bool fOwner = CopyManagedEventFromTarget(pRecord, pManagedEvent); if (fOwner) { // This toggles the lock if it dispatches callbacks FilterClrNotification(pManagedEvent, GET_PUBLIC_LOCK_HOLDER(), pCallback); - + // Cancel any notification events from target. These are just supposed to notify ICD and not // actually be real exceptions in the target. // Canceling here also prevents a VectoredExceptionHandler in the target from picking // up exceptions for the CLR. - *pContinueStatus = DBG_CONTINUE; + *pContinueStatus = DBG_CONTINUE; } // holder will invoke DeleteIPCEventHelper(pManagedEvent). } - } - PUBLIC_API_END(hr); + } + PUBLIC_API_END(hr); // we may not find the correct mscordacwks so fail gracefully _ASSERTE(SUCCEEDED(hr) || (hr != HRESULT_FROM_WIN32(ERROR_MOD_NOT_FOUND))); @@ -11516,20 +11525,20 @@ HRESULT CordbProcess::Filter( // // Notes: // Initial continue status is returned from code:CordbProcess::Filter. -// Some operations (mainly hijacking on a 2nd-chance exception), may need to +// Some operations (mainly hijacking on a 2nd-chance exception), may need to // override that continue status. // ICorDebug operations invoke a callback on the data-target to notify the debugger // of a change in status. Debugger may fail the request. // void CordbProcess::ContinueStatusChanged(DWORD dwThreadId, CORDB_CONTINUE_STATUS dwContinueStatus) -{ +{ HRESULT hr = m_pMutableDataTarget->ContinueStatusChanged(dwThreadId, dwContinueStatus); IfFailThrow(hr); } //--------------------------------------------------------------------------------------- // Request a synchronization to occur after a debug event is dispatched. -// +// // Note: // This is called in response to a managed debug event, and so we know that we have // a worker thread in the process (the one that just sent the event!) @@ -11552,7 +11561,7 @@ void CordbProcess::RequestSyncAtEvent() // None. // // Notes: -// This is it, you've found it, the main guy. This function loops as long as the +// This is it, you've found it, the main guy. This function loops as long as the // debugger is around calling the OS WaitForDebugEvent() API. It takes the OS Debug // Event and filters it thru the right-side, continuing the process if not recognized. // @@ -11567,7 +11576,7 @@ void CordbWin32EventThread::Win32EventLoop() DEBUG_EVENT event; - + // Allow the timeout for WFDE to be adjustable. Default to 25 ms based off perf numbers (see issue VSWhidbey 132368). DWORD dwWFDETimeout = CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_DbgWFDETimeout); @@ -11597,7 +11606,7 @@ void CordbWin32EventThread::Win32EventLoop() if (m_pProcess != NULL) { // Process is always built on Native debugging pipeline, so it needs to always be prepared to call WFDE - // As an optimization, if the target is stopped, then we can avoid calling WFDE. + // As an optimization, if the target is stopped, then we can avoid calling WFDE. { #ifndef FEATURE_INTEROP_DEBUGGING // Managed-only, never win32 stopped, so always check for an event. @@ -11611,7 +11620,7 @@ void CordbWin32EventThread::Win32EventLoop() const bool fIsInteropDebugging = m_pProcess->IsInteropDebugging(); (void)fIsInteropDebugging; //prevent "unused variable" error from GCC - + // Assert checks _ASSERTE(fIsInteropDebugging == m_pShim->IsInteropDebugging()); @@ -11620,14 +11629,14 @@ void CordbWin32EventThread::Win32EventLoop() dwWaitTimeout = 0; fEventAvailable = m_pNativePipeline->WaitForDebugEvent(&event, dwWFDETimeout, m_pProcess); } - else + else { // If we're managed-only debugging, then the process should always be running, // which means we always need to be calling WFDE to pump potential debug events. // If we're interop-debugging, then the process can be stopped at a native-debug event, // in which case we don't have to call WFDE until we resume it again. - // So we can only skip the WFDE when we're interop-debugging. - _ASSERTE(fIsInteropDebugging); + // So we can only skip the WFDE when we're interop-debugging. + _ASSERTE(fIsInteropDebugging); } #endif // FEATURE_INTEROP_DEBUGGING } @@ -11732,17 +11741,17 @@ void CordbWin32EventThread::Win32EventLoop() // Must flush the dac cache since we were just running. m_pProcess->ForceDacFlush(); - + // So we've filtered out CLR events. // Let the shim handle the remaining events. This will call back into Filter() if appropriate. // This will also ensure the debug event gets continued. HRESULT hrShim = S_OK; { PUBLIC_CALLBACK_IN_THIS_SCOPE0_NO_LOCK(NULL); - hrShim = m_pShim->HandleWin32DebugEvent(&event); + hrShim = m_pShim->HandleWin32DebugEvent(&event); } // Any errors from the shim (eg. failure to load DAC) are unrecoverable - SetUnrecoverableIfFailed(m_pProcess, hrShim); + SetUnrecoverableIfFailed(m_pProcess, hrShim); } // loop @@ -11767,13 +11776,13 @@ bool CordbProcess::IsWin32EventThread() //--------------------------------------------------------------------------------------- // Call when the sync complete event is received and can be processed. -// +// // Notes: // This is called when the RS gets the sync-complete from the LS and can process it. -// +// // This has a somewhat elaborate contract to fill between Interop-debugging, Async-Break, draining the // managed event-queue, and coordinating with the dispatch thread (RCET). -// +// // @dbgtodo - this should eventually get hoisted into the shim. void CordbProcess::HandleSyncCompleteRecieved() { @@ -11784,7 +11793,7 @@ void CordbProcess::HandleSyncCompleteRecieved() // If some thread is waiting for the process to sync, notify that it can go now. if (this->m_stopRequested) { - this->SetSynchronized(true); + this->SetSynchronized(true); SetEvent(this->m_stopWaitEvent); } else @@ -11817,7 +11826,7 @@ void CordbProcess::HandleSyncCompleteRecieved() // // // Notes: -// Thread may be newly allocated, or may be existing. CordbProcess holds +// Thread may be newly allocated, or may be existing. CordbProcess holds // list of all CordbUnmanagedThreads, and will handle freeing memory. // //--------------------------------------------------------------------------------------- @@ -11833,25 +11842,25 @@ CordbUnmanagedThread * CordbProcess::GetUnmanagedThreadFromEvent(const DEBUG_EVE { // We absolutely should have an unmanaged callback by this point. // That means that the client debugger should have called ICorDebug::SetUnmanagedHandler by now. - // However, we can't actually enforce that (see comment in ICorDebug::SetUnmanagedHandler for details), - // so we do a runtime check to check this. + // However, we can't actually enforce that (see comment in ICorDebug::SetUnmanagedHandler for details), + // so we do a runtime check to check this. // This is an extremely gross API misuse and an issue in the client if the callback is not set yet. - // Without the unmanaged callback, we absolutely can't do interop-debugging. We assert (checked builds) and + // Without the unmanaged callback, we absolutely can't do interop-debugging. We assert (checked builds) and // dispatch unrecoverable error (retail builds) to avoid an AV. if (this->m_cordb->m_unmanagedCallback == NULL) { - CONSISTENCY_CHECK_MSGF((this->m_cordb->m_unmanagedCallback != NULL), - ("GROSS API misuse!!\nNo unmanaged callback set by the time we've received CreateProcess debug event for proces 0x%x.\n", + CONSISTENCY_CHECK_MSGF((this->m_cordb->m_unmanagedCallback != NULL), + ("GROSS API misuse!!\nNo unmanaged callback set by the time we've received CreateProcess debug event for proces 0x%x.\n", pEvent->dwProcessId)); - + CORDBSetUnrecoverableError(this, CORDBG_E_INTEROP_NOT_SUPPORTED, 0); // Returning NULL will tell caller not to dispatch event to client. We have no callback object to dispatch upon. return NULL; } - + pUnmanagedThread = this->HandleUnmanagedCreateThread(pEvent->dwThreadId, pEvent->u.CreateProcessInfo.hThread, pEvent->u.CreateProcessInfo.lpThreadLocalBase); @@ -11875,7 +11884,7 @@ CordbUnmanagedThread * CordbProcess::GetUnmanagedThreadFromEvent(const DEBUG_EVE // If we have the debugger control block, and if that control block has the address of the thread proc for // the helper thread, then we're initialized enough on the Left Side to recgonize the helper thread based on // its thread proc's address. - if (this->GetDCB() != NULL) + if (this->GetDCB() != NULL) { // get the latest LS DCB information UpdateRightSideDCB(); @@ -11896,7 +11905,7 @@ CordbUnmanagedThread * CordbProcess::GetUnmanagedThreadFromEvent(const DEBUG_EVE EX_CATCH_HRESULT(hr) { if (fBlockExists && FAILED(hr)) - { + { _ASSERTE(IsLegalFatalError(hr)); // Send up the DebuggerError event this->UnrecoverableError(hr, 0, NULL, 0); @@ -11905,7 +11914,7 @@ CordbUnmanagedThread * CordbProcess::GetUnmanagedThreadFromEvent(const DEBUG_EVE // RS will pump events until we LS process exits. TerminateProcess(this->m_handle, hr); - return pUnmanagedThread; + return pUnmanagedThread; } } } @@ -12218,7 +12227,7 @@ Reaction CordbProcess::Triage1stChanceNonSpecial(CordbUnmanagedThread * pUnmanag } else if (dwExCode == EXCEPTION_MSVC) { - // The runtime may use C++ exceptions internally. We can still report these + // The runtime may use C++ exceptions internally. We can still report these // to the debugger as long as we're outside of a can't-stop region. if (pUnmanagedThread->IsCantStop()) { @@ -12268,7 +12277,7 @@ Reaction CordbProcess::Triage1stChanceNonSpecial(CordbUnmanagedThread * pUnmanag else { return REACTION(cInband); - } + } } UNREACHABLE(); @@ -12290,12 +12299,12 @@ Reaction CordbProcess::Triage1stChanceNonSpecial(CordbUnmanagedThread * pUnmanag // // Notes: // A 1st-chance event has a wide spectrum of possibility including: -// - It may be unmanaged or managed. -// - Or it may be an execution control exception for managed-exceution +// - It may be unmanaged or managed. +// - Or it may be an execution control exception for managed-exceution // - thread skipping an OOB event. // //--------------------------------------------------------------------------------------- -Reaction CordbProcess::TriageExcep1stChanceAndInit(CordbUnmanagedThread * pUnmanagedThread, +Reaction CordbProcess::TriageExcep1stChanceAndInit(CordbUnmanagedThread * pUnmanagedThread, const DEBUG_EVENT * pEvent) { _ASSERTE(ThreadHoldsProcessLock()); @@ -12422,8 +12431,8 @@ Reaction CordbProcess::TriageExcep1stChanceAndInit(CordbUnmanagedThread * pUnman { // If we Single-Step over an exception, then the OS never gives us the single-step event. // Thus if we're skipping a native patch, we don't care what exception event we got. - LOG((LF_CORDB, LL_INFO100000, "Done skipping native patch. Ex=0x%x\n, IsSS=%d", - dwExCode, + LOG((LF_CORDB, LL_INFO100000, "Done skipping native patch. Ex=0x%x\n, IsSS=%d", + dwExCode, (dwExCode == STATUS_SINGLE_STEP))); // This is the 2nd half of skipping a native patch. @@ -12440,9 +12449,9 @@ Reaction CordbProcess::TriageExcep1stChanceAndInit(CordbUnmanagedThread * pUnman CONSISTENCY_CHECK_MSGF(dwExCode != STATUS_SINGLE_STEP, ( "Single-Step exception on helper thread (tid=0x%x/%d) in debuggee process (pid=0x%x/%d).\n" "For more information, attach a debuggee non-invasively to the LS to get the callstack.\n", - pUnmanagedThread->m_id, - pUnmanagedThread->m_id, - this->m_id, + pUnmanagedThread->m_id, + pUnmanagedThread->m_id, + this->m_id, this->m_id)); // We ignore any first chance exceptions from the helper thread. There are lots of places @@ -12465,9 +12474,9 @@ Reaction CordbProcess::TriageExcep1stChanceAndInit(CordbUnmanagedThread * pUnman CONSISTENCY_CHECK_MSGF((dwExCode != STATUS_BREAKPOINT), ( "Assert on helper thread (tid=0x%x/%d) in debuggee process (pid=0x%x/%d).\n" "For more information, attach a debuggee non-invasively to the LS to get the callstack.\n", - pUnmanagedThread->m_id, - pUnmanagedThread->m_id, - this->m_id, + pUnmanagedThread->m_id, + pUnmanagedThread->m_id, + this->m_id, this->m_id)); // These breakpoint and single step exceptions have to be dispatched to the debugger as @@ -12528,13 +12537,13 @@ Reaction CordbProcess::TriageExcep1stChanceAndInit(CordbUnmanagedThread * pUnman return REACTION(cOOB); } - // If generichijacked and its not a flare, and the address referenced is on the stack then we've - // got our special stack overflow case. Take off generic hijacked, mark that the helper thread + // If generichijacked and its not a flare, and the address referenced is on the stack then we've + // got our special stack overflow case. Take off generic hijacked, mark that the helper thread // is dead, throw this event on the floor, and pop anyone in SendIPCEvent out of their wait. pUnmanagedThread->ClearState(CUTS_GenericHijacked); - + this->m_helperThreadDead = true; - + // This only works on Windows, not on Mac. We don't support interop-debugging on Mac anyway. SetEvent(m_pEventChannel->GetRightSideEventAckHandle()); @@ -12591,8 +12600,8 @@ Reaction CordbProcess::TriageExcep1stChanceAndInit(CordbUnmanagedThread * pUnman // Called when receiving a debug event when the process is stopped. // // Notes: -// We already hijacked 2nd-chance managed exceptions, so this is just handling -// some V2 Interop corner cases. +// We already hijacked 2nd-chance managed exceptions, so this is just handling +// some V2 Interop corner cases. // @dbgtodo interop: this should eventually completely go away with the V3 design. // //--------------------------------------------------------------------------------------- @@ -12651,7 +12660,7 @@ Reaction CordbProcess::TriageExcep2ndChanceAndInit(CordbUnmanagedThread * pUnman // from them and hope for the best. return REACTION(cCLR); } - + if(pUnmanagedThread->IsCantStop()) { return REACTION(cOOB); @@ -12848,8 +12857,8 @@ void CordbProcess::HandleDebugEventForInteropDebugging(const DEBUG_EVENT * pEven { // Note: we use ContinueDebugEvent directly here since our continue is very simple and all of our other // continue mechanisms rely on having an UnmanagedThread object to play with ;) - STRESS_LOG2(LF_CORDB, LL_INFO1000, "W32ET::W32EL: Continuing without thread on tid 0x%x, code=0x%x\n", - pEvent->dwThreadId, + STRESS_LOG2(LF_CORDB, LL_INFO1000, "W32ET::W32EL: Continuing without thread on tid 0x%x, code=0x%x\n", + pEvent->dwThreadId, pEvent->dwDebugEventCode); this->m_state &= ~CordbProcess::PS_WIN32_STOPPED; @@ -12862,13 +12871,13 @@ void CordbProcess::HandleDebugEventForInteropDebugging(const DEBUG_EVENT * pEven } // There's an innate race such that we can get a Debug Event even after we've suspended a thread. - // This can happen if the thread has already dispatched the debug event but we haven't called WFDE to pick it up + // This can happen if the thread has already dispatched the debug event but we haven't called WFDE to pick it up // yet. This is sufficiently goofy that we want to stress log it. if (pUnmanagedThread->IsSuspended()) { STRESS_LOG1(LF_CORDB, LL_INFO1000, "W32ET::W32EL: Thread 0x%x is suspended\n", pEvent->dwThreadId); } - + // For debugging crazy races in retail, we'll keep a rolling queue of win32 debug events. this->DebugRecordWin32Event(pEvent, pUnmanagedThread); @@ -12914,9 +12923,9 @@ void CordbProcess::HandleDebugEventForInteropDebugging(const DEBUG_EVENT * pEven // Stress-log the reaction. #ifdef _DEBUG - STRESS_LOG3(LF_CORDB, LL_INFO1000, "Reaction: %d (%s), line=%d\n", - reaction.GetType(), - reaction.GetReactionName(), + STRESS_LOG3(LF_CORDB, LL_INFO1000, "Reaction: %d (%s), line=%d\n", + reaction.GetType(), + reaction.GetReactionName(), reaction.GetLine()); #else STRESS_LOG1(LF_CORDB, LL_INFO1000, "Reaction: %d\n", reaction.GetType()); @@ -12950,13 +12959,13 @@ void CordbProcess::HandleDebugEventForInteropDebugging(const DEBUG_EVENT * pEven // Shouldn't be suspending in the first place with outstanding flares. _ASSERTE(!pUnmanagedThread->IsSuspended()); - + pW32EventThread->ForceDbgContinue(this, pUnmanagedThread, DBG_CONTINUE, false); goto LDone; case Reaction::cCLR: // Don't care if thread is suspended here. We'll just let the thread continue whatever it's doing. - + this->m_DbgSupport.m_TotalCLR++; // If this is for the CLR, then we just continue unhandled and know that the CLR has @@ -12986,8 +12995,8 @@ void CordbProcess::HandleDebugEventForInteropDebugging(const DEBUG_EVENT * pEven // CLR internal exceptions should be sent back to the CLR and never treated as inband events. // If this assert fires, the event was triaged wrong. - CONSISTENCY_CHECK_MSGF((pEvent->u.Exception.ExceptionRecord.ExceptionCode != EXCEPTION_COMPLUS), - ("Attempting to dispatch a CLR internal exception as an Inband event. Reaction line=%d\n", + CONSISTENCY_CHECK_MSGF((pEvent->u.Exception.ExceptionRecord.ExceptionCode != EXCEPTION_COMPLUS), + ("Attempting to dispatch a CLR internal exception as an Inband event. Reaction line=%d\n", reaction.GetLine())); @@ -13001,16 +13010,16 @@ void CordbProcess::HandleDebugEventForInteropDebugging(const DEBUG_EVENT * pEven // 2) If the process is synchronized (since that means we've already dispatched a managed event). // 3) If we've received a SyncComplete event, but aren't yet Sync. This will almost always be the same as // whether we're synced, but has a distict quality. It's always set by the w32 event thread in Interop, - // and so it's guaranteed to be serialized against this check here (also on the w32et). + // and so it's guaranteed to be serialized against this check here (also on the w32et). // 4) Special deferment - This covers the region where we're sending a Stop/Continue IPC event across. // We defer it here to keep the Helper thread alive so that it can handle these IPC events. // Queued events will be dispatched when continue is called. BOOL fHasUserUncontinuedNativeEvents = HasUserUncontinuedNativeEvents(); bool fDeferInbandEvent = (fHasUserUncontinuedNativeEvents || - GetSynchronized() || + GetSynchronized() || GetSyncCompleteRecv() || m_specialDeferment); - + // If we've got a new event, queue it. if (fNewEvent) { @@ -13036,14 +13045,14 @@ void CordbProcess::HandleDebugEventForInteropDebugging(const DEBUG_EVENT * pEven { // No need to defer the dispatch, do it now this->DispatchUnmanagedInBandEvent(); - + goto LDone; } UNREACHABLE(); } - + case Reaction::cFirstChanceHijackStarted: - { + { // determine the logical event we are handling, if any CordbUnmanagedEvent* pUnmanagedEvent = NULL; if(pUnmanagedThread->HasIBEvent()) @@ -13065,7 +13074,7 @@ void CordbProcess::HandleDebugEventForInteropDebugging(const DEBUG_EVENT * pEven { // there should be an event we hijacked in this case _ASSERTE(pUnmanagedEvent != NULL); - + // block that event LOG((LF_CORDB, LL_INFO100000, "W32ET::W32EL: blocking\n")); fcd.action = HIJACK_ACTION_WAIT; @@ -13088,7 +13097,7 @@ void CordbProcess::HandleDebugEventForInteropDebugging(const DEBUG_EVENT * pEven case Reaction::cInbandHijackComplete: { // We now execute the hijack worker even when not actually hijacked - // so can't assert this + // so can't assert this //_ASSERTE(pUnmanagedThread->IsFirstChanceHijacked()); // we should not be stepping at the end of hijacks @@ -13246,9 +13255,9 @@ void CordbProcess::HandleDebugEventForInteropDebugging(const DEBUG_EVENT * pEven { pUnmanagedThread->EndStepping(); } - pW32EventThread->ForceDbgContinue(this, pUnmanagedThread, + pW32EventThread->ForceDbgContinue(this, pUnmanagedThread, pUnmanagedEvent->IsExceptionCleared() ? DBG_CONTINUE : DBG_EXCEPTION_NOT_HANDLED, false); - + // We've handled this event. Skip further processing. goto LDone; } @@ -13257,7 +13266,7 @@ void CordbProcess::HandleDebugEventForInteropDebugging(const DEBUG_EVENT * pEven { // Don't care if this thread claimed to be suspended or not. Dispatch event anyways. After all, // OOB events can come at *any* time. - + // This thread may be suspended. We don't care. this->m_DbgSupport.m_TotalOOB++; @@ -13369,13 +13378,13 @@ bool CordbProcess::ExceptionIsFlare(DWORD exceptionCode, const void *exceptionAd #endif // FEATURE_INTEROP_DEBUGGING // Allocate a buffer in the target and copy data into it. -// +// // Arguments: -// pDomain - an appdomain associated with the allocation request. +// pDomain - an appdomain associated with the allocation request. // bufferSize - size of the buffer in bytes // bufferFrom - local buffer of data (bufferSize bytes) to copy data from. // ppRes - address into target of allocated buffer -// +// // Returns: // S_OK on success, else error. HRESULT CordbProcess::GetAndWriteRemoteBuffer(CordbAppDomain *pDomain, unsigned int bufferSize, const void *bufferFrom, void **ppRes) @@ -13389,7 +13398,7 @@ HRESULT CordbProcess::GetAndWriteRemoteBuffer(CordbAppDomain *pDomain, unsigned { TargetBuffer tbTarget = GetRemoteBuffer(bufferSize); // throws SafeWriteBuffer(tbTarget, (const BYTE*) bufferFrom); // throws - + // Succeeded. *ppRes = CORDB_ADDRESS_TO_PTR(tbTarget.pAddress); } @@ -13522,7 +13531,7 @@ void EnableDebugTrace(CordbUnmanagedThread *ut) #endif // _DEBUG //----------------------------------------------------------------------------- -// DoDbgContinue +// DoDbgContinue // // Continues from a specific Win32 DEBUG_EVENT. // @@ -13531,7 +13540,7 @@ void EnableDebugTrace(CordbUnmanagedThread *ut) // pUnmanagedEvent - The event to continue. // //----------------------------------------------------------------------------- -void CordbWin32EventThread::DoDbgContinue(CordbProcess *pProcess, +void CordbWin32EventThread::DoDbgContinue(CordbProcess *pProcess, CordbUnmanagedEvent *pUnmanagedEvent) { _ASSERTE(pProcess->ThreadHoldsProcessLock()); @@ -13586,7 +13595,7 @@ void CordbWin32EventThread::DoDbgContinue(CordbProcess *pProcess, _ASSERTE(!pUnmanagedEvent->IsEventContinuedUnhijacked()); pUnmanagedEvent->SetState(CUES_EventContinuedUnhijacked); dwContType = pUnmanagedEvent->IsExceptionCleared() ? GetDbgContinueFlag() : DBG_EXCEPTION_NOT_HANDLED; - + // The event was never hijacked and so will never need to retrigger, get rid // of it right now. If it had been hijacked then we would dequeue it either after the // hijack complete flare or one instruction after that when it has had a chance to retrigger @@ -13638,11 +13647,11 @@ void CordbWin32EventThread::DoDbgContinue(CordbProcess *pProcess, { LOG((LF_CORDB, LL_INFO1000, "W32ET::DDC: Continuing from LdrBp, doing managed attach.\n")); pProcess->QueueManagedAttachIfNeededWorker(); - } + } EX_CATCH_HRESULT(hrIgnore); SIMPLIFYING_ASSUMPTION(SUCCEEDED(hrIgnore)); } - } + } STRESS_LOG4(LF_CORDB, LL_INFO1000, "W32ET::DDC: calling ContinueDebugEvent(0x%x, 0x%x, 0x%x), process state=0x%x\n", @@ -13810,7 +13819,7 @@ HRESULT CordbWin32EventThread::SendCreateProcessEvent( { DWORD ret = WaitForSingleObject(m_actionTakenEvent, INFINITE); - LOG((LF_CORDB, LL_EVERYTHING, "Process Handle is: %x, m_threadControlEvent is %x\n", + LOG((LF_CORDB, LL_EVERYTHING, "Process Handle is: %x, m_threadControlEvent is %x\n", (UINT_PTR)m_actionData.createData.lpProcessInformation->hProcess, (UINT_PTR)m_threadControlEvent)); if (ret == WAIT_OBJECT_0) @@ -13833,7 +13842,7 @@ HRESULT CordbWin32EventThread::SendCreateProcessEvent( // // Assumptions: // This occurs on the win32 event thread. It is invokved via -// a message sent from code:CordbWin32EventThread::SendCreateProcessEvent +// a message sent from code:CordbWin32EventThread::SendCreateProcessEvent // // Notes: // Create a new process. This is called in the context of the Win32 @@ -13853,7 +13862,7 @@ void CordbWin32EventThread::CreateProcess() // Win32 debugging this process. Otherwise, we have to create // suspended to give us time to setup up our side of the IPC // channel. - BOOL fInteropDebugging = + BOOL fInteropDebugging = #if defined(FEATURE_INTEROP_DEBUGGING) (dwCreationFlags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS)); #else @@ -13896,17 +13905,17 @@ void CordbWin32EventThread::CreateProcess() // Remember the process in the global list of processes. if (SUCCEEDED(hr)) - { + { EX_TRY { // Mark if we're interop-debugging if (fInteropDebugging) { - pProcess->EnableInteropDebugging(); + pProcess->EnableInteropDebugging(); } m_cordb->AddProcess(pProcess); // will take ref if it succeeds - } + } EX_CATCH_HRESULT(hr); } @@ -13916,7 +13925,7 @@ void CordbWin32EventThread::CreateProcess() if (SUCCEEDED(hr)) { _ASSERTE(m_pProcess == NULL); - m_pProcess.Assign(pProcess); + m_pProcess.Assign(pProcess); } } @@ -14030,7 +14039,7 @@ void CordbProcess::CleanupHalfBakedLeftSide() } EX_CATCH { - _ASSERTE(!"Writing process memory failed, perhaps due to an unexpected disconnection from the target."); + _ASSERTE(!"Writing process memory failed, perhaps due to an unexpected disconnection from the target."); } EX_END_CATCH(SwallowAllExceptions); } @@ -14039,10 +14048,10 @@ void CordbProcess::CleanupHalfBakedLeftSide() CloseIPCHandles(); m_cordb.Clear(); - + // This process object is Dead-On-Arrival, so it doesn't really have anything to neuter. // But for safekeeping, we'll mark it as neutered. - UnsafeNeuterDeadObject(); + UnsafeNeuterDeadObject(); } @@ -14052,8 +14061,8 @@ void CordbProcess::CleanupHalfBakedLeftSide() // // // Assumptions: -// Called on W32Event Thread, in response to event sent by -// code:CordbWin32EventThread::SendDebugActiveProcessEvent +// Called on W32Event Thread, in response to event sent by +// code:CordbWin32EventThread::SendDebugActiveProcessEvent // // Notes: // Attach to a process. This is called in the context of the Win32 @@ -14079,8 +14088,8 @@ void CordbWin32EventThread::AttachProcess() // Always do OS attach to the target. // By this point, the pid should be valid (because OpenProcess above), pending some race where the process just exited. - // The OS will enforce that only 1 debugger is attached. - // Common failure paths here would be: access denied, double-attach + // The OS will enforce that only 1 debugger is attached. + // Common failure paths here would be: access denied, double-attach { hr = m_pNativePipeline->DebugActiveProcess(m_actionData.attachData.machineInfo, dwProcessId); @@ -14091,7 +14100,7 @@ void CordbWin32EventThread::AttachProcess() fNativeAttachSucceeded = true; } - + hr = m_pShim->InitializeDataTarget(m_actionData.attachData.processId); if (FAILED(hr)) { @@ -14100,17 +14109,17 @@ void CordbWin32EventThread::AttachProcess() // To emulate V2 semantics, we pass 0 for the clrInstanceID into // OpenVirtualProcess. This will then connect to the first CLR - // loaded. + // loaded. { const ULONG64 cFirstClrLoaded = 0; - hr = CordbProcess::OpenVirtualProcess(cFirstClrLoaded, m_pShim->GetDataTarget(), NULL, m_cordb, dwProcessId, m_pShim, &pProcess); + hr = CordbProcess::OpenVirtualProcess(cFirstClrLoaded, m_pShim->GetDataTarget(), NULL, m_cordb, dwProcessId, m_pShim, &pProcess); if (FAILED(hr)) { goto LExit; } } - // Remember the process in the global list of processes. + // Remember the process in the global list of processes. // The caller back in code:Cordb::DebugActiveProcess will then get this by fetching it from the list. EX_TRY @@ -14129,7 +14138,7 @@ void CordbWin32EventThread::AttachProcess() PUBLIC_CALLBACK_IN_THIS_SCOPE0_NO_LOCK(pProcess); m_pShim->BeginQueueFakeAttachEvents(); } - } + } EX_CATCH_HRESULT(hr); if (FAILED(hr)) { @@ -14146,7 +14155,7 @@ void CordbWin32EventThread::AttachProcess() LExit: if (FAILED(hr)) - { + { // If we succeed to do a native-attach, but then failed elsewhere, try to native-detach. if (fNativeAttachSucceeded) { @@ -14389,7 +14398,7 @@ doRealContinue: // This is either the Frozen -> Running transition or a // Synced -> Running transition _ASSERTE(pProcess->m_outOfBandEventQueue == NULL); - + pProcess->m_doRealContinueAfterOOBBlock = false; @@ -14414,7 +14423,7 @@ doRealContinue: if(pProcess->m_state & CordbProcess::PS_WIN32_STOPPED) { DoDbgContinue(pProcess, pProcess->m_lastDispatchedIBEvent); - + // This if should not be necessary, I am just being extra careful because this // fix is going in late - see issue 818301 _ASSERTE(pProcess->m_lastDispatchedIBEvent != NULL); @@ -14434,7 +14443,7 @@ doRealContinue: { // free all the hijacked threads that hit native debug events pProcess->ResumeHijackedThreads(); - + // after continuing the here the process should be running completely // free... no hijacks, no suspended threads, and of course not frozen if(pProcess->m_state & CordbProcess::PS_WIN32_STOPPED) @@ -14497,7 +14506,7 @@ void ExitProcessWorkItem::Do() // There is a race condition here where the debuggee process is killed while we are processing a process // detach. We queue the process exit event for the Win32 event thread before queueing the process detach - // event. By the time this function is executed, we may have neutered the CordbProcess already as a + // event. By the time this function is executed, we may have neutered the CordbProcess already as a // result of code:CordbProcess::Detach. Detect that case here under the SG lock. { RSLockHolder ch(GetProcess()->GetStopGoLock()); @@ -14522,7 +14531,7 @@ void ExitProcessWorkItem::Do() // This CordbProcess object now has no reservations against a client calling ICorDebug::Terminate. // That call may race against the CordbProcess::Neuter below, but since we already neutered the children, // that neuter call will not do anything interesting that will conflict with Terminate. - + LOG((LF_CORDB, LL_INFO1000,"W32ET::EP: returned from ExitProcess callback\n")); { @@ -14760,10 +14769,10 @@ HRESULT CordbWin32EventThread::Stop() // Allocate a buffer of cbBuffer bytes in the target. -// +// // Arguments: // cbBuffer - count of bytes for the buffer. -// +// // Returns: // a TargetBuffer describing the new memory region in the target. // Throws on error. @@ -14789,7 +14798,7 @@ TargetBuffer CordbProcess::GetRemoteBuffer(ULONG cbBuffer) IfFailThrow(event.GetBufferResult.hr); // The request succeeded. Return the newly allocated range. - return TargetBuffer(event.GetBufferResult.pBuffer, cbBuffer); + return TargetBuffer(event.GetBufferResult.pBuffer, cbBuffer); } /* @@ -14841,7 +14850,7 @@ HRESULT CordbProcess::SetDesiredNGENCompilerFlags(DWORD dwFlags) hr = pProcess->GetDAC()->SetNGENCompilerFlags(dwFlags); if (!SUCCEEDED(hr) && GetShim() != NULL) { - // Emulate V2 error semantics. + // Emulate V2 error semantics. hr = GetShim()->FilterSetNgenHresult(hr); } } @@ -14895,7 +14904,7 @@ HRESULT CordbProcess::GetReferenceValueFromGCHandle( { ThrowHR(CORDBG_E_BAD_REFERENCE_VALUE); } - + IDacDbiInterface* pDAC = GetProcess()->GetDAC(); VMPTR_OBJECTHANDLE vmObjHandle = pDAC->GetVmObjectHandle(gcHandle); if(!pDAC->IsVmObjectHandleValid(vmObjHandle)) @@ -15036,25 +15045,25 @@ HRESULT CordbProcess::IsReadyForDetach() if (hKernel32 == NULL) return HRESULT_FROM_GetLastError(); typedef BOOL (*DebugActiveProcessStopSig) (DWORD); - DebugActiveProcessStopSig pDebugActiveProcessStop = + DebugActiveProcessStopSig pDebugActiveProcessStop = reinterpret_cast<DebugActiveProcessStopSig>(GetProcAddress(hKernel32, "DebugActiveProcessStop")); if (pDebugActiveProcessStop == NULL) return COR_E_PLATFORMNOTSUPPORTED; #endif - } + } return S_OK; } /* - * Look for any thread which was last seen in the specified AppDomain. + * Look for any thread which was last seen in the specified AppDomain. * The CordbAppDomain object is about to be neutered due to an AD Unload * So the thread must no longer be considered to be in that domain. - * Note that this is a workaround due to the existance of the (possibly incorrect) + * Note that this is a workaround due to the existance of the (possibly incorrect) * cached AppDomain value. Ideally we would remove the cached value entirely * and there would be no need for this. - * + * * @dbgtodo: , appdomain: We should remove CordbThread::m_pAppDomain in the V3 architecture. * If we need the thread's current domain, we should get it accurately with DAC. */ @@ -15062,13 +15071,13 @@ void CordbProcess::UpdateThreadsForAdUnload(CordbAppDomain * pAppDomain) { INTERNAL_API_ENTRY(this); - // If we're doing an AD unload then we should have already seen the ATTACH + // If we're doing an AD unload then we should have already seen the ATTACH // notification for the default domain. //_ASSERTE( m_pDefaultAppDomain != NULL ); // @dbgtodo appdomain: fix Default domain invariants with DAC-izing Appdomain work. - + RSLockHolder lockHolder(GetProcessLock()); - + CordbThread* t; HASHFIND find; @@ -15079,7 +15088,7 @@ void CordbProcess::UpdateThreadsForAdUnload(CordbAppDomain * pAppDomain) { if( t->GetAppDomain() == pAppDomain ) { - // This thread cannot actually be in this AppDomain anymore (since it's being + // This thread cannot actually be in this AppDomain anymore (since it's being // unloaded). Reset it to point to the default AppDomain t->m_pAppDomain = m_pDefaultAppDomain; } @@ -15087,7 +15096,7 @@ void CordbProcess::UpdateThreadsForAdUnload(CordbAppDomain * pAppDomain) } // CordbProcess::LookupClass -// Looks up a previously constructed CordbClass instance without creating. May return NULL if the +// Looks up a previously constructed CordbClass instance without creating. May return NULL if the // CordbClass instance doesn't exist. // Argument: (in) vmDomainFile - pointer to the domainfile for the module // (in) mdTypeDef - metadata token for the class @@ -15108,39 +15117,39 @@ CordbClass * CordbProcess::LookupClass(ICorDebugAppDomain * pAppDomain, VMPTR_Do } // CordbProcess::LookupClass //--------------------------------------------------------------------------------------- -// Look for a specific module in the process. +// Look for a specific module in the process. // // Arguments: // vmDomainFile - non-null module to lookup -// +// // Returns: // a CordbModule object for the given cookie. Object may be from the cache, or created -// lazily. +// lazily. // Never returns null. Throws on error. // // Notes: // A VMPTR_DomainFile has appdomain affinity, but is ultimately scoped to a process. // So if we get a raw VMPTR_DomainFile (eg, from the stackwalker or from some other -// lookup function), then we need to do a process wide lookup since we don't know which +// lookup function), then we need to do a process wide lookup since we don't know which // appdomain it's in. If you know the appdomain, you can use code:CordbAppDomain::LookupOrCreateModule. -// +// CordbModule * CordbProcess::LookupOrCreateModule(VMPTR_DomainFile vmDomainFile) { INTERNAL_API_ENTRY(this); - + RSLockHolder lockHolder(GetProcess()->GetProcessLock()); _ASSERTE(!vmDomainFile.IsNull()); DomainFileInfo data; GetDAC()->GetDomainFileData(vmDomainFile, &data); // throws - + CordbAppDomain * pAppDomain = LookupOrCreateAppDomain(data.vmAppDomain); return pAppDomain->LookupOrCreateModule(vmDomainFile); } //--------------------------------------------------------------------------------------- // Determine if the process has any in-band queued events which have not been dispatched -// +// // Returns: // TRUE iff there are undispatched IB events // @@ -15148,7 +15157,7 @@ CordbModule * CordbProcess::LookupOrCreateModule(VMPTR_DomainFile vmDomainFile) BOOL CordbProcess::HasUndispatchedNativeEvents() { INTERNAL_API_ENTRY(this); - + CordbUnmanagedEvent* pEvent = m_unmanagedEventQueue; while(pEvent != NULL && pEvent->IsDispatched()) { @@ -15161,7 +15170,7 @@ BOOL CordbProcess::HasUndispatchedNativeEvents() //--------------------------------------------------------------------------------------- // Determine if the process has any in-band queued events which have not been user continued -// +// // Returns: // TRUE iff there are user uncontinued IB events // @@ -15169,7 +15178,7 @@ BOOL CordbProcess::HasUndispatchedNativeEvents() BOOL CordbProcess::HasUserUncontinuedNativeEvents() { INTERNAL_API_ENTRY(this); - + CordbUnmanagedEvent* pEvent = m_unmanagedEventQueue; while(pEvent != NULL && pEvent->IsEventUserContinued()) { @@ -15183,7 +15192,7 @@ BOOL CordbProcess::HasUserUncontinuedNativeEvents() //--------------------------------------------------------------------------------------- // Hijack the thread which had this event. If the thread is already hijacked this method // has no effect. -// +// // Arguments: // pUnmanagedEvent - the debug event which requires us to hijack // @@ -15197,7 +15206,7 @@ HRESULT CordbProcess::HijackIBEvent(CordbUnmanagedEvent * pUnmanagedEvent) _ASSERTE(!pUnmanagedEvent->IsEventContinuedHijacked()); // Can only hijack IB events _ASSERTE(pUnmanagedEvent->IsIBEvent()); - + // If we already hijacked the event then there is nothing left to do if(pUnmanagedEvent->m_owner->IsFirstChanceHijacked() || pUnmanagedEvent->m_owner->IsGenericHijacked()) @@ -15241,7 +15250,7 @@ HRESULT CordbProcess::GetAttachStateFlags(CLR_DEBUGGING_PROCESS_FLAGS *pFlags) // Determine if this version of ICorDebug is compatibile with the ICorDebug in the specified major CLR version bool CordbProcess::IsCompatibleWith(DWORD clrMajorVersion) { - // The debugger versioning policy is that debuggers generally need to opt-in to supporting major new + // The debugger versioning policy is that debuggers generally need to opt-in to supporting major new // versions of the CLR. Often new versions of the CLR violate some invariant that previous debuggers assume // (eg. hot/cold splitting in Whidbey, multiple CLRs in a process in CLR v4), and neither VS or the CLR // teams generally want the support burden of forward compatibility. @@ -15251,17 +15260,17 @@ bool CordbProcess::IsCompatibleWith(DWORD clrMajorVersion) // number of the clr.dll has changed. This assert is here to remind you to do a bit of other // work you may not have realized you needed to do so that our versioning works smoothly // for debugging. You probably want to contact the CLR DST team if you are a - // non-debugger person hitting this. DON'T JUST DELETE THIS ASSERT!!! + // non-debugger person hitting this. DON'T JUST DELETE THIS ASSERT!!! // // 1) You should ensure new versions of all ICorDebug users in DevDiv (VS Debugger, MDbg, etc.) - // are using a creation path that explicitly specifies that they support this new major + // are using a creation path that explicitly specifies that they support this new major // version of the CLR. // 2) You should file an issue to track blocking earlier debuggers from targetting this // version of the CLR (i.e. update requiredVersion to the new CLR major // version). To enable a smooth internal transition, this often isn't done until absolutely // necessary (sometimes as late as Beta2). // 3) You can consider updating the CLR_ID guid used by the shim to recognize a CLR, but only - // if it's important to completely hide newer CLRs from the shim. The expectation now + // if it's important to completely hide newer CLRs from the shim. The expectation now // is that we won't need to do this (i.e. we'd like VS to give a nice error message about // needed a newer version of the debugger, rather than just acting as if a process has no CLR). // 4) Update this assert so that it no longer fires for your new CLR version or any of @@ -15271,8 +15280,8 @@ bool CordbProcess::IsCompatibleWith(DWORD clrMajorVersion) _ASSERTE_MSG(clrMajorVersion <= 4, "Found major CLR version greater than 4 in mscordbi.dll from CLRv4 - contact CLRDST"); - // This knob lets us enable forward compatibility for internal scenarios, and also simulate new - // versions of the runtime for testing the failure user-experience in a version of the debugger + // This knob lets us enable forward compatibility for internal scenarios, and also simulate new + // versions of the runtime for testing the failure user-experience in a version of the debugger // before it is shipped. // We don't want to risk customers getting this, so for RTM builds this must be CHK-only. // To aid in internal transition, we may temporarily enable this in RET builds, but when @@ -15308,7 +15317,7 @@ bool CordbProcess::IsThreadSuspendedOrHijacked(ICorDebugThread * pICorDebugThrea // its entire duration. As a result, this needs to be considered a reentrant API. See // comments above code:PrivateShimCallbackHolder for more info. PUBLIC_REENTRANT_API_ENTRY_FOR_SHIM(this); - + CordbThread * pCordbThread = static_cast<CordbThread *> (pICorDebugThread); return GetDAC()->IsThreadSuspendedOrHijacked(pCordbThread->m_vmThreadToken); } diff --git a/src/debug/di/rsmain.cpp b/src/debug/di/rsmain.cpp index 39ac60d0c2..d9f25e6f83 100644 --- a/src/debug/di/rsmain.cpp +++ b/src/debug/di/rsmain.cpp @@ -3,7 +3,7 @@ // See the LICENSE file in the project root for more information. //***************************************************************************** // File: RsMain.cpp -// +// // Random RS utility stuff, plus root ICorCordbug implementation // @@ -102,7 +102,7 @@ void DbgRSThread::NotifyTakeLock(RSLock * pLock) { return; } - + int iLevel = pLock->GetLevel(); // Is it safe to take this lock? @@ -132,7 +132,7 @@ void DbgRSThread::NotifyReleaseLock(RSLock * pLock) { return; } - + int iLevel = pLock->GetLevel(); m_cLocks[iLevel]--; _ASSERTE(m_cLocks[iLevel] == 0); @@ -207,9 +207,9 @@ LONG Cordb::s_DbgMemOutstandingObjectMax = 0; // Default implementation for neutering left-side resources. void CordbBase::NeuterLeftSideResources() -{ - LIMITED_METHOD_CONTRACT; - +{ + LIMITED_METHOD_CONTRACT; + RSLockHolder lockHolder(GetProcess()->GetProcessLock()); Neuter(); } @@ -221,14 +221,14 @@ void CordbBase::Neuter() // Neutering occurs under the process lock. Neuter can be called twice // and so locking protects against races in double-delete. // @dbgtodo - , some CordbBase objects (Cordb, CordbProcessEnum), - // don't have process affinity these should eventually be hoisted to the shim, + // don't have process affinity these should eventually be hoisted to the shim, // and then we can enforce. CordbProcess * pProcess = GetProcess(); if (pProcess != NULL) { _ASSERTE(pProcess->ThreadHoldsProcessLock()); } - CordbCommonBase::Neuter(); + CordbCommonBase::Neuter(); } //----------------------------------------------------------------------------- @@ -247,7 +247,7 @@ NeuterList::~NeuterList() CONSISTENCY_CHECK_MSGF(m_pHead == NULL, ("NeuterList not empty on shutdown. this=0x%p", this)); } -// Wrapper around code:NeuterList::UnsafeAdd +// Wrapper around code:NeuterList::UnsafeAdd void NeuterList::Add(CordbProcess * pProcess, CordbBase * pObject) { CONTRACTL @@ -268,7 +268,7 @@ void NeuterList::Add(CordbProcess * pProcess, CordbBase * pObject) // // Returns: // Throws on error. -// +// // Notes: // This will add it to the list and maintain an internal reference to it. // This will take the process lock. @@ -276,13 +276,13 @@ void NeuterList::Add(CordbProcess * pProcess, CordbBase * pObject) void NeuterList::UnsafeAdd(CordbProcess * pProcess, CordbBase * pObject) { _ASSERTE(pObject != NULL); - - // Lock if needed. + + // Lock if needed. RSLock * pLock = (pProcess != NULL) ? pProcess->GetProcessLock() : NULL; RSLockHolder lockHolder(pLock, FALSE); if (pLock != NULL) lockHolder.Acquire(); - + Node * pNode = new Node(); // throws on error. pNode->m_pObject.Assign(pObject); pNode->m_pNext = m_pHead; @@ -303,10 +303,10 @@ void NeuterList::UnsafeAdd(CordbProcess * pProcess, CordbBase * pObject) // This will release all internal references and empty the list. void NeuterList::NeuterAndClear(CordbProcess * pProcess) { - RSLock * pLock = (pProcess != NULL) ? pProcess->GetProcessLock() : NULL; + RSLock * pLock = (pProcess != NULL) ? pProcess->GetProcessLock() : NULL; (void)pLock; //prevent "unused variable" error from GCC _ASSERTE((pLock == NULL) || pLock->HasLock()); - + while (m_pHead != NULL) { Node * pTemp = m_pHead; @@ -351,7 +351,7 @@ void NeuterList::SweepAllNeuterAtWillObjects(CordbProcess * pProcess) //----------------------------------------------------------------------------- // Neuters all objects in the list and empties the list. -// +// // Notes: // See also code:LeftSideResourceCleanupList::SweepNeuterLeftSideResources, // which only neuters objects that have been marked as NeuterAtWill (external @@ -360,9 +360,9 @@ void LeftSideResourceCleanupList::NeuterLeftSideResourcesAndClear(CordbProcess * { // Traversal protected under Process-lock. // SG-lock must already be held to do neutering. - // Stop-Go lock is bigger than Process-lock. + // Stop-Go lock is bigger than Process-lock. // Neutering requires the Stop-Go lock (until we get rid of IPC events) - // But we want to be able to add to the Neuter list under the Process-lock. + // But we want to be able to add to the Neuter list under the Process-lock. // So we just need to protected m_pHead under process-lock. // "Privatize" the list under the lock. @@ -378,7 +378,7 @@ void LeftSideResourceCleanupList::NeuterLeftSideResourcesAndClear(CordbProcess * // @dbgtodo - eventually everything can be under the process lock. _ASSERTE(!pLock->HasLock()); // Can't hold Process lock while calling NeuterLeftSideResources - + // Now we're operating on local data, so traversing doesn't need to be under the lock. while (pCur != NULL) { @@ -388,17 +388,17 @@ void LeftSideResourceCleanupList::NeuterLeftSideResourcesAndClear(CordbProcess * pTemp->m_pObject->NeuterLeftSideResources(); delete pTemp; // will implicitly release } - + } //----------------------------------------------------------------------------- // Only neuter objects that are marked. Removes neutered objects from the list. -// +// // Arguments: // pProcess - non-null process owning the objects in the list -// +// // Notes: -// this cleans up left-side resources held by objects in the list. +// this cleans up left-side resources held by objects in the list. // It may send IPC events to do this. void LeftSideResourceCleanupList::SweepNeuterLeftSideResources(CordbProcess * pProcess) { @@ -413,12 +413,12 @@ void LeftSideResourceCleanupList::SweepNeuterLeftSideResources(CordbProcess * pP // Lock while we "privatize" the head. RSLockHolder lockHolder(pLock); Node * pHead = m_pHead; - m_pHead = NULL; + m_pHead = NULL; lockHolder.Release(); Node ** ppLast = &pHead; Node * pCur = pHead; - + // Can't hold the process-lock while calling Neuter. while (pCur != NULL) { @@ -444,7 +444,7 @@ void LeftSideResourceCleanupList::SweepNeuterLeftSideResources(CordbProcess * pP // Now link back in. m_pHead may have changed while we were unlocked. // The list does not need to be ordered. - + lockHolder.Acquire(); *ppLast = m_pHead; m_pHead = pHead; @@ -465,7 +465,7 @@ void CordbCommonBase::InitializeCommon() { return; } - + #ifdef STRESS_LOG { bool fStressLog = false; @@ -503,14 +503,14 @@ void CordbCommonBase::InitializeCommon() // Add debug privilege. This will let us call OpenProcess() on anything, regardless of ACL. AddDebugPrivilege(); - + IsInitialized = true; } // Adjust the permissions of this process to ensure that we have // the debugging priviledge. If we can't make the adjustment, it // only means that we won't be able to attach to a service under -// NT, so we won't treat that as a critical failure. +// NT, so we won't treat that as a critical failure. // This also will let us call OpenProcess() on anything, regardless of DACL. This allows an // Admin debugger to attach to a debuggee in the guest account. // Ideally, the debugger would set this (and we wouldn't mess with privileges at all). However, we've been @@ -526,14 +526,14 @@ void CordbCommonBase::AddDebugPrivilege() fSucc = LookupPrivilegeValueW(NULL, SE_DEBUG_NAME, &SeDebugLuid); DWORD err = GetLastError(); - + if (!fSucc) { STRESS_LOG1(LF_CORDB, LL_INFO1000, "Unable to adjust permissions of this process to include SE_DEBUG. Lookup failed %d\n", err); return; } - - + + // Retrieve a handle of the access token fSucc = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, @@ -555,7 +555,7 @@ void CordbCommonBase::AddDebugPrivilege() // The return value of AdjustTokenPrivileges cannot be tested. if (err != ERROR_SUCCESS) { - STRESS_LOG1(LF_CORDB, LL_INFO1000, + STRESS_LOG1(LF_CORDB, LL_INFO1000, "Unable to adjust permissions of this process to include SE_DEBUG. Adjust failed %d\n", err); } else @@ -565,7 +565,7 @@ void CordbCommonBase::AddDebugPrivilege() CloseHandle(hToken); } #endif -} +} namespace @@ -868,7 +868,8 @@ namespace virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** pInterface); virtual ULONG STDMETHODCALLTYPE AddRef(); virtual ULONG STDMETHODCALLTYPE Release(); - COM_METHOD SomeWork(ICorDebugThread * pThread, ICorDebugAppDomain * pAppDomain); + COM_METHOD BeforeGarbageCollection(ICorDebugController* pController); + COM_METHOD AfterGarbageCollection(ICorDebugController* pController); private: // not implemented DefaultManagedCallback4(const DefaultManagedCallback4&); @@ -922,12 +923,22 @@ namespace } HRESULT - DefaultManagedCallback4::SomeWork(ICorDebugThread * pThread, ICorDebugAppDomain * pAppDomain) + DefaultManagedCallback4::BeforeGarbageCollection(ICorDebugController* pController) { // // Just ignore and continue the process. // - pAppDomain->Continue(false); + pController->Continue(false); + return S_OK; + } + + HRESULT + DefaultManagedCallback4::AfterGarbageCollection(ICorDebugController* pController) + { + // + // Just ignore and continue the process. + // + pController->Continue(false); return S_OK; } } @@ -968,13 +979,13 @@ void Cordb::Neuter() return; } - + RSLockHolder lockHolder(&m_processListMutex); m_pProcessEnumList.NeuterAndClear(NULL); - + HRESULT hr = S_OK; - EX_TRY // @dbgtodo push this up. + EX_TRY // @dbgtodo push this up. { // Iterating needs to be done under the processList lock (small), while neutering // needs to be able to take the process lock (big). @@ -983,13 +994,13 @@ void Cordb::Neuter() // can't hold list lock while calling CordbProcess::Neuter (which // will take the Process-lock). - lockHolder.Release(); + lockHolder.Release(); list.NeuterAndClear(); // List dtor calls release on each element - } + } EX_CATCH_HRESULT(hr); - SIMPLIFYING_ASSUMPTION_SUCCEEDED(hr); + SIMPLIFYING_ASSUMPTION_SUCCEEDED(hr); CordbCommonBase::Neuter(); @@ -1044,7 +1055,7 @@ HRESULT Cordb::Terminate() FAIL_IF_NEUTERED(this); - // We can't terminate the debugging services from within a callback. + // We can't terminate the debugging services from within a callback. // Caller is supposed to be out of all callbacks when they call this. // This also avoids a deadlock because we'll shutdown the RCET, which would block if we're // in the RCET. @@ -1188,7 +1199,7 @@ HRESULT Cordb::Initialize(void) if (!m_initialized) { CordbCommonBase::InitializeCommon(); - + // Since logging wasn't active when we called CordbBase, do it now. LOG((LF_CORDB, LL_EVERYTHING, "Memory: CordbBase object allocated: this=%p, count=%d, RootObject\n", this, s_TotalObjectCount)); LOG((LF_CORDB, LL_INFO10, "Initializing ICorDebug...\n")); @@ -1404,7 +1415,7 @@ HRESULT Cordb::SetTargetCLR(HMODULE hmodTargetCLR) CoreClrCallbacks cccallbacks; cccallbacks.m_hmodCoreCLR = hmodTargetCLR; cccallbacks.m_pfnIEE = NULL; - cccallbacks.m_pfnGetCORSystemDirectory = NULL; + cccallbacks.m_pfnGetCORSystemDirectory = NULL; cccallbacks.m_pfnGetCLRFunction = NULL; InitUtilcode(cccallbacks); @@ -1501,7 +1512,7 @@ bool Cordb::IsCreateProcessSupported() { #if !defined(FEATURE_DBGIPC_TRANSPORT_DI) return false; -#else +#else return true; #endif } @@ -1535,7 +1546,7 @@ bool Cordb::IsInteropDebuggingSupported() // Creates a process. // // Arguments: -// The following arguments are passed thru unmodified to the OS CreateProcess API and +// The following arguments are passed thru unmodified to the OS CreateProcess API and // are defined by that API. // lpApplicationName // lpCommandLine @@ -1850,13 +1861,13 @@ HRESULT Cordb::DebugActiveProcessCommon(ICorDebugRemoteTarget * pRemoteTarget, } #if defined(FEATURE_DBGIPC_TRANSPORT_DI) - // This is where we queue the managed attach event in Whidbey. In the new architecture, the Windows - // pipeline gets a loader breakpoint when native attach is completed, and that's where we queue the + // This is where we queue the managed attach event in Whidbey. In the new architecture, the Windows + // pipeline gets a loader breakpoint when native attach is completed, and that's where we queue the // managed attach event. See how we handle the loader breakpoint in code:ShimProcess::DefaultEventHandler. // However, the Mac debugging transport gets no such breakpoint, and so we need to do this here. - // - // @dbgtodo Mac - Ideally we should hide this in our pipeline implementation, or at least move - // this to the shim. + // + // @dbgtodo Mac - Ideally we should hide this in our pipeline implementation, or at least move + // this to the shim. _ASSERTE(!fWin32Attach); { pProcess->Lock(); @@ -1864,7 +1875,7 @@ HRESULT Cordb::DebugActiveProcessCommon(ICorDebugRemoteTarget * pRemoteTarget, pProcess->Unlock(); } #endif // FEATURE_DBGIPC_TRANSPORT_DI - + *ppProcess = (ICorDebugProcess*) pProcess; } @@ -1883,23 +1894,23 @@ void Cordb::CheckCompatibility() clrMajor = 2; else if (debuggerVersion <= CorDebugVersion_4_0) clrMajor = 4; - else + else clrMajor = 5; // some unrecognized future version if(!CordbProcess::IsCompatibleWith(clrMajor)) { // Carefully choose our error-code to get an appropriate error-message from VS 2008 // If GetDebuggerVersion is >= 4, we could consider using the more-appropriate (but not - // added until V4) HRESULT CORDBG_E_UNSUPPORTED_FORWARD_COMPAT that is used by + // added until V4) HRESULT CORDBG_E_UNSUPPORTED_FORWARD_COMPAT that is used by // OpenVirtualProcess, but it's probably simpler to keep ICorDebug APIs returning // consistent error codes. ThrowHR(CORDBG_E_INCOMPATIBLE_PROTOCOL); } } -HRESULT Cordb::DebugActiveProcessEx(ICorDebugRemoteTarget * pRemoteTarget, - DWORD dwProcessId, - BOOL fWin32Attach, +HRESULT Cordb::DebugActiveProcessEx(ICorDebugRemoteTarget * pRemoteTarget, + DWORD dwProcessId, + BOOL fWin32Attach, ICorDebugProcess ** ppProcess) { if (pRemoteTarget == NULL) @@ -1956,12 +1967,12 @@ HRESULT Cordb::EnumerateProcesses(ICorDebugProcessEnum **ppProcesses) RSInitHolder<CordbHashTableEnum> pEnum; CordbHashTableEnum::BuildOrThrow( - this, - &m_pProcessEnumList, + this, + &m_pProcessEnumList, GetProcessList(), IID_ICorDebugProcessEnum, pEnum.GetAddr()); - + pEnum.TransferOwnershipExternal(ppProcesses); } @@ -1995,7 +2006,7 @@ HRESULT Cordb::CanLaunchOrAttach(DWORD dwProcessId, BOOL fWin32DebuggingEnabled) EX_TRY { EnsureCanLaunchOrAttach(fWin32DebuggingEnabled); - } + } EX_CATCH_HRESULT(hr); return hr; @@ -2095,12 +2106,12 @@ CordbEnumFilter::CordbEnumFilter(CordbBase * pOwnerObj, NeuterList * pOwnerList) m_iCount (0) { _ASSERTE(m_pOwnerNeuterList != NULL); - + HRESULT hr = S_OK; EX_TRY { m_pOwnerNeuterList->Add(pOwnerObj->GetProcess(), this); - } + } EX_CATCH_HRESULT(hr); SetUnrecoverableIfFailed(GetProcess(), hr); @@ -2114,15 +2125,15 @@ CordbEnumFilter::CordbEnumFilter(CordbEnumFilter *src) m_pCurrent (NULL) { _ASSERTE(m_pOwnerNeuterList != NULL); - + HRESULT hr = S_OK; EX_TRY { m_pOwnerNeuterList->Add(src->GetProcess(), this); - } + } EX_CATCH_HRESULT(hr); SetUnrecoverableIfFailed(GetProcess(), hr); - + int iCountSanityCheck = 0; @@ -2214,10 +2225,10 @@ void CordbEnumFilter::Neuter() HRESULT CordbEnumFilter::QueryInterface(REFIID id, void **ppInterface) { // if we QI with the IID of the base type, we can't just return a pointer ICorDebugEnum directly, because - // the cast is ambiguous. This happens because CordbEnumFilter implements both ICorDebugModuleEnum and + // the cast is ambiguous. This happens because CordbEnumFilter implements both ICorDebugModuleEnum and // ICorDebugThreadEnum, both of which derive in turn from ICorDebugEnum. This produces a diamond inheritance - // graph. Thus we need a double cast. It doesn't really matter whether we pick ICorDebugThreadEnum or - // ICorDebugModuleEnum, because it will be backed by the same object regardless. + // graph. Thus we need a double cast. It doesn't really matter whether we pick ICorDebugThreadEnum or + // ICorDebugModuleEnum, because it will be backed by the same object regardless. if (id == IID_ICorDebugEnum) *ppInterface = static_cast<ICorDebugEnum *>(static_cast<ICorDebugThreadEnum *>(this)); else if (id == IID_ICorDebugModuleEnum) @@ -2557,7 +2568,7 @@ HRESULT CordbEnumFilter::Init (ICorDebugThreadEnum *pThreadEnum, CordbAppDomain { goto Error; } - + if (pThreadDomain == pAppDomain) { pElement = new (nothrow) EnumElement; diff --git a/src/debug/di/shimcallback.cpp b/src/debug/di/shimcallback.cpp index 35e9f38462..00501da2ae 100644 --- a/src/debug/di/shimcallback.cpp +++ b/src/debug/di/shimcallback.cpp @@ -3,7 +3,7 @@ // See the LICENSE file in the project root for more information. //***************************************************************************** // File: ShimCallback.cpp -// +// // // The V3 ICD debugging APIs have a lower abstraction level than V2. @@ -13,7 +13,7 @@ #include "stdafx.h" #include "safewrap.h" -#include "check.h" +#include "check.h" #include <limits.h> #include "shimpriv.h" @@ -78,22 +78,22 @@ HRESULT ShimProxyCallback::QueryInterface(REFIID riid, void **ppInterface) // // Map from an old frame to a new one. -// +// // Arguments: // pThread - thread that frame is on // pOldFrame - old frame before the continue, may have gotten neutered. -// +// // Returns: // a new, non-neutered frame that matches the old frame. -// +// // Notes: // Called by event handlers below (which are considered Outside the RS). // No adjust of reference, Thread already has reference. -// @dbgtodo shim-stackwalks: this is used for exception callbacks, which may change for V3. +// @dbgtodo shim-stackwalks: this is used for exception callbacks, which may change for V3. ICorDebugFrame * UpdateFrame(ICorDebugThread * pThread, ICorDebugFrame * pOldFrame) { - PUBLIC_API_ENTRY_FOR_SHIM(NULL); - + PUBLIC_API_ENTRY_FOR_SHIM(NULL); + RSExtSmartPtr<ICorDebugFrame> pNewFrame; EX_TRY @@ -102,16 +102,16 @@ ICorDebugFrame * UpdateFrame(ICorDebugThread * pThread, ICorDebugFrame * pOldFra if (pFrame != NULL) { FramePointer fp = pFrame->GetFramePointer(); - + CordbThread * pThread2 = static_cast<CordbThread *> (pThread); pThread2->FindFrame(&pNewFrame, fp); - - // + + // } } EX_CATCH { - // Do not throw out of this function. Doing so means that the debugger never gets a chance to + // Do not throw out of this function. Doing so means that the debugger never gets a chance to // continue the debuggee process. This will lead to a hang. Instead, try to make a best effort to // continue with a NULL ICDFrame. VS is able to handle this gracefully. pNewFrame.Assign(NULL); @@ -140,7 +140,7 @@ HRESULT ShimProxyCallback::Breakpoint(ICorDebugAppDomain * pAppDomain, ICorDebug public: // Ctor - BreakpointEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, ICorDebugBreakpoint * pBreakpoint) : + BreakpointEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, ICorDebugBreakpoint * pBreakpoint) : ManagedEvent(pThread) { this->m_pAppDomain.Assign(pAppDomain); @@ -173,7 +173,7 @@ HRESULT ShimProxyCallback::StepComplete(ICorDebugAppDomain * pAppDomain, ICorDeb public: // Ctor - StepCompleteEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, ICorDebugStepper * pStepper, CorDebugStepReason reason) : + StepCompleteEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, ICorDebugStepper * pStepper, CorDebugStepReason reason) : ManagedEvent(pThread) { this->m_pAppDomain.Assign(pAppDomain); @@ -205,7 +205,7 @@ HRESULT ShimProxyCallback::Break(ICorDebugAppDomain * pAppDomain, ICorDebugThrea public: // Ctor - BreakEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread) : + BreakEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread) : ManagedEvent(pThread) { this->m_pAppDomain.Assign(pAppDomain); @@ -236,7 +236,7 @@ HRESULT ShimProxyCallback::Exception(ICorDebugAppDomain * pAppDomain, ICorDebugT public: // Ctor - ExceptionEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, BOOL fUnhandled) : + ExceptionEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, BOOL fUnhandled) : ManagedEvent(pThread) { this->m_pAppDomain.Assign(pAppDomain); @@ -268,7 +268,7 @@ HRESULT ShimProxyCallback::EvalComplete(ICorDebugAppDomain * pAppDomain, ICorDeb public: // Ctor - EvalCompleteEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, ICorDebugEval * pEval) : + EvalCompleteEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, ICorDebugEval * pEval) : ManagedEvent(pThread) { this->m_pAppDomain.Assign(pAppDomain); @@ -300,7 +300,7 @@ HRESULT ShimProxyCallback::EvalException(ICorDebugAppDomain * pAppDomain, ICorDe public: // Ctor - EvalExceptionEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, ICorDebugEval * pEval) : + EvalExceptionEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, ICorDebugEval * pEval) : ManagedEvent(pThread) { this->m_pAppDomain.Assign(pAppDomain); @@ -320,10 +320,10 @@ HRESULT ShimProxyCallback::EvalException(ICorDebugAppDomain * pAppDomain, ICorDe // Implementation of ICorDebugManagedCallback::CreateProcess -// This will only be called for a Real create-process event. +// This will only be called for a Real create-process event. HRESULT ShimProxyCallback::CreateProcess(ICorDebugProcess * pProcess) { - m_pShim->PreDispatchEvent(true); + m_pShim->PreDispatchEvent(true); QueueCreateProcess(pProcess); return S_OK; } @@ -337,7 +337,7 @@ void ShimProxyCallback::QueueCreateProcess(ICorDebugProcess * pProcess) public: // Ctor - CreateProcessEvent(ICorDebugProcess * pProcess, ShimProcess * pShim) : + CreateProcessEvent(ICorDebugProcess * pProcess, ShimProcess * pShim) : ManagedEvent(), m_pShim(pShim) { @@ -351,9 +351,9 @@ void ShimProxyCallback::QueueCreateProcess(ICorDebugProcess * pProcess) return args.GetCallback1()->CreateProcess(m_pProcess); } - // we need access to the shim in Dispatch so we can set the InCreateProcess flag to keep track of + // we need access to the shim in Dispatch so we can set the InCreateProcess flag to keep track of // when we are actually in the callback. We need this information to be able to emulate - // the hresult logic in v2.0. + // the hresult logic in v2.0. ShimProcess * m_pShim; }; // end class CreateProcessEvent @@ -375,7 +375,7 @@ HRESULT ShimProxyCallback::ExitProcess(ICorDebugProcess * pProcess) public: // Ctor - ExitProcessEvent(ICorDebugProcess * pProcess) : + ExitProcessEvent(ICorDebugProcess * pProcess) : ManagedEvent() { this->m_pProcess.Assign(pProcess); @@ -405,7 +405,7 @@ HRESULT ShimProxyCallback::CreateThread(ICorDebugAppDomain * pAppDomain, ICorDeb public: // Ctor - CreateThreadEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread) : + CreateThreadEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread) : ManagedEvent(pThread) { this->m_pAppDomain.Assign(pAppDomain); @@ -438,7 +438,7 @@ HRESULT ShimProxyCallback::ExitThread(ICorDebugAppDomain * pAppDomain, ICorDebug public: // Ctor - ExitThreadEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread) : + ExitThreadEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread) : ManagedEvent(pThread) { this->m_pAppDomain.Assign(pAppDomain); @@ -461,13 +461,13 @@ HRESULT ShimProxyCallback::ExitThread(ICorDebugAppDomain * pAppDomain, ICorDebug // // Arguments: // pAppDomain - appdomain for the LoadModule debug event -// pModule - module being loaded. +// pModule - module being loaded. // // Notes: // See code:ShimProcess::QueueFakeAttachEvents // This is the fake version of code:ShimProxyCallback::LoadModule. -// It sends an IPC event to go in process to collect information that we can't yet get via -// DAC from out-of-proc. +// It sends an IPC event to go in process to collect information that we can't yet get via +// DAC from out-of-proc. void ShimProxyCallback::FakeLoadModule(ICorDebugAppDomain *pAppDomain, ICorDebugModule *pModule) { class FakeLoadModuleEvent : public ManagedEvent @@ -478,7 +478,7 @@ void ShimProxyCallback::FakeLoadModule(ICorDebugAppDomain *pAppDomain, ICorDebug public: // Ctor - FakeLoadModuleEvent(ICorDebugAppDomain * pAppDomain, ICorDebugModule * pModule, ShimProcess * pShim) : + FakeLoadModuleEvent(ICorDebugAppDomain * pAppDomain, ICorDebugModule * pModule, ShimProcess * pShim) : ManagedEvent(), m_pShim(pShim) { @@ -487,15 +487,15 @@ void ShimProxyCallback::FakeLoadModule(ICorDebugAppDomain *pAppDomain, ICorDebug } HRESULT Dispatch(DispatchArgs args) - { + { // signal that we are in the callback--this will be cleared in code:CordbProcess::ContinueInternal - m_pShim->SetInLoadModule(true); + m_pShim->SetInLoadModule(true); return args.GetCallback1()->LoadModule(m_pAppDomain, m_pModule); } - // we need access to the shim in Dispatch so we can set the InLoadModule flag to keep track + // we need access to the shim in Dispatch so we can set the InLoadModule flag to keep track // when we are actually in the callback. We need this information to be able to emulate - // the hresult logic in v2.0. + // the hresult logic in v2.0. ShimProcess * m_pShim; }; // end class LoadModuleEvent @@ -515,7 +515,7 @@ HRESULT ShimProxyCallback::LoadModule(ICorDebugAppDomain * pAppDomain, ICorDebug public: // Ctor - LoadModuleEvent(ICorDebugAppDomain * pAppDomain, ICorDebugModule * pModule) : + LoadModuleEvent(ICorDebugAppDomain * pAppDomain, ICorDebugModule * pModule) : ManagedEvent() { this->m_pAppDomain.Assign(pAppDomain); @@ -523,7 +523,7 @@ HRESULT ShimProxyCallback::LoadModule(ICorDebugAppDomain * pAppDomain, ICorDebug } HRESULT Dispatch(DispatchArgs args) - { + { return args.GetCallback1()->LoadModule(m_pAppDomain, m_pModule); } }; // end class LoadModuleEvent @@ -548,7 +548,7 @@ HRESULT ShimProxyCallback::UnloadModule(ICorDebugAppDomain * pAppDomain, ICorDeb public: // Ctor - UnloadModuleEvent(ICorDebugAppDomain * pAppDomain, ICorDebugModule * pModule) : + UnloadModuleEvent(ICorDebugAppDomain * pAppDomain, ICorDebugModule * pModule) : ManagedEvent() { this->m_pAppDomain.Assign(pAppDomain); @@ -579,7 +579,7 @@ HRESULT ShimProxyCallback::LoadClass(ICorDebugAppDomain * pAppDomain, ICorDebugC public: // Ctor - LoadClassEvent(ICorDebugAppDomain * pAppDomain, ICorDebugClass * pClass) : + LoadClassEvent(ICorDebugAppDomain * pAppDomain, ICorDebugClass * pClass) : ManagedEvent() { this->m_pAppDomain.Assign(pAppDomain); @@ -609,7 +609,7 @@ HRESULT ShimProxyCallback::UnloadClass(ICorDebugAppDomain * pAppDomain, ICorDebu public: // Ctor - UnloadClassEvent(ICorDebugAppDomain * pAppDomain, ICorDebugClass * pClass) : + UnloadClassEvent(ICorDebugAppDomain * pAppDomain, ICorDebugClass * pClass) : ManagedEvent() { this->m_pAppDomain.Assign(pAppDomain); @@ -640,7 +640,7 @@ HRESULT ShimProxyCallback::DebuggerError(ICorDebugProcess * pProcess, HRESULT er public: // Ctor - DebuggerErrorEvent(ICorDebugProcess * pProcess, HRESULT errorHR, DWORD errorCode) : + DebuggerErrorEvent(ICorDebugProcess * pProcess, HRESULT errorHR, DWORD errorCode) : ManagedEvent() { this->m_pProcess.Assign(pProcess); @@ -674,7 +674,7 @@ HRESULT ShimProxyCallback::LogMessage(ICorDebugAppDomain * pAppDomain, ICorDebug public: // Ctor - LogMessageEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, LONG lLevel, LPCWSTR pLogSwitchName, LPCWSTR pMessage) : + LogMessageEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, LONG lLevel, LPCWSTR pLogSwitchName, LPCWSTR pMessage) : ManagedEvent(pThread) { this->m_pAppDomain.Assign(pAppDomain); @@ -711,7 +711,7 @@ HRESULT ShimProxyCallback::LogSwitch(ICorDebugAppDomain * pAppDomain, ICorDebugT public: // Ctor - LogSwitchEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, LONG lLevel, ULONG ulReason, LPCWSTR pLogSwitchName, LPCWSTR pParentName) : + LogSwitchEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, LONG lLevel, ULONG ulReason, LPCWSTR pLogSwitchName, LPCWSTR pParentName) : ManagedEvent(pThread) { this->m_pAppDomain.Assign(pAppDomain); @@ -745,7 +745,7 @@ HRESULT ShimProxyCallback::CreateAppDomain(ICorDebugProcess * pProcess, ICorDebu public: // Ctor - CreateAppDomainEvent(ICorDebugProcess * pProcess, ICorDebugAppDomain * pAppDomain) : + CreateAppDomainEvent(ICorDebugProcess * pProcess, ICorDebugAppDomain * pAppDomain) : ManagedEvent() { this->m_pProcess.Assign(pProcess); @@ -778,7 +778,7 @@ HRESULT ShimProxyCallback::ExitAppDomain(ICorDebugProcess * pProcess, ICorDebugA public: // Ctor - ExitAppDomainEvent(ICorDebugProcess * pProcess, ICorDebugAppDomain * pAppDomain) : + ExitAppDomainEvent(ICorDebugProcess * pProcess, ICorDebugAppDomain * pAppDomain) : ManagedEvent() { this->m_pProcess.Assign(pProcess); @@ -809,7 +809,7 @@ HRESULT ShimProxyCallback::LoadAssembly(ICorDebugAppDomain * pAppDomain, ICorDeb public: // Ctor - LoadAssemblyEvent(ICorDebugAppDomain * pAppDomain, ICorDebugAssembly * pAssembly) : + LoadAssemblyEvent(ICorDebugAppDomain * pAppDomain, ICorDebugAssembly * pAssembly) : ManagedEvent() { this->m_pAppDomain.Assign(pAppDomain); @@ -842,7 +842,7 @@ HRESULT ShimProxyCallback::UnloadAssembly(ICorDebugAppDomain * pAppDomain, ICorD public: // Ctor - UnloadAssemblyEvent(ICorDebugAppDomain * pAppDomain, ICorDebugAssembly * pAssembly) : + UnloadAssemblyEvent(ICorDebugAppDomain * pAppDomain, ICorDebugAssembly * pAssembly) : ManagedEvent() { this->m_pAppDomain.Assign(pAppDomain); @@ -872,7 +872,7 @@ HRESULT ShimProxyCallback::ControlCTrap(ICorDebugProcess * pProcess) public: // Ctor - ControlCTrapEvent(ICorDebugProcess * pProcess) : + ControlCTrapEvent(ICorDebugProcess * pProcess) : ManagedEvent() { this->m_pProcess.Assign(pProcess); @@ -901,7 +901,7 @@ HRESULT ShimProxyCallback::NameChange(ICorDebugAppDomain * pAppDomain, ICorDebug public: // Ctor - NameChangeEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread) : + NameChangeEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread) : ManagedEvent(pThread) { this->m_pAppDomain.Assign(pAppDomain); @@ -932,7 +932,7 @@ HRESULT ShimProxyCallback::UpdateModuleSymbols(ICorDebugAppDomain * pAppDomain, public: // Ctor - UpdateModuleSymbolsEvent(ICorDebugAppDomain * pAppDomain, ICorDebugModule * pModule, IStream * pSymbolStream) : + UpdateModuleSymbolsEvent(ICorDebugAppDomain * pAppDomain, ICorDebugModule * pModule, IStream * pSymbolStream) : ManagedEvent() { this->m_pAppDomain.Assign(pAppDomain); @@ -965,7 +965,7 @@ HRESULT ShimProxyCallback::EditAndContinueRemap(ICorDebugAppDomain * pAppDomain, public: // Ctor - EditAndContinueRemapEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, ICorDebugFunction * pFunction, BOOL fAccurate) : + EditAndContinueRemapEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, ICorDebugFunction * pFunction, BOOL fAccurate) : ManagedEvent(pThread) { this->m_pAppDomain.Assign(pAppDomain); @@ -999,7 +999,7 @@ HRESULT ShimProxyCallback::BreakpointSetError(ICorDebugAppDomain * pAppDomain, I public: // Ctor - BreakpointSetErrorEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, ICorDebugBreakpoint * pBreakpoint, DWORD dwError) : + BreakpointSetErrorEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, ICorDebugBreakpoint * pBreakpoint, DWORD dwError) : ManagedEvent(pThread) { this->m_pAppDomain.Assign(pAppDomain); @@ -1034,7 +1034,7 @@ HRESULT ShimProxyCallback::FunctionRemapOpportunity(ICorDebugAppDomain * pAppDom public: // Ctor - FunctionRemapOpportunityEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, ICorDebugFunction * pOldFunction, ICorDebugFunction * pNewFunction, ULONG32 oldILOffset) : + FunctionRemapOpportunityEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, ICorDebugFunction * pOldFunction, ICorDebugFunction * pNewFunction, ULONG32 oldILOffset) : ManagedEvent(pThread) { this->m_pAppDomain.Assign(pAppDomain); @@ -1068,7 +1068,7 @@ HRESULT ShimProxyCallback::CreateConnection(ICorDebugProcess * pProcess, CONNID public: // Ctor - CreateConnectionEvent(ICorDebugProcess * pProcess, CONNID dwConnectionId, LPCWSTR pConnectionName) : + CreateConnectionEvent(ICorDebugProcess * pProcess, CONNID dwConnectionId, LPCWSTR pConnectionName) : ManagedEvent() { this->m_pProcess.Assign(pProcess); @@ -1099,7 +1099,7 @@ HRESULT ShimProxyCallback::ChangeConnection(ICorDebugProcess * pProcess, CONNID public: // Ctor - ChangeConnectionEvent(ICorDebugProcess * pProcess, CONNID dwConnectionId) : + ChangeConnectionEvent(ICorDebugProcess * pProcess, CONNID dwConnectionId) : ManagedEvent() { this->m_pProcess.Assign(pProcess); @@ -1129,7 +1129,7 @@ HRESULT ShimProxyCallback::DestroyConnection(ICorDebugProcess * pProcess, CONNID public: // Ctor - DestroyConnectionEvent(ICorDebugProcess * pProcess, CONNID dwConnectionId) : + DestroyConnectionEvent(ICorDebugProcess * pProcess, CONNID dwConnectionId) : ManagedEvent() { this->m_pProcess.Assign(pProcess); @@ -1164,7 +1164,7 @@ HRESULT ShimProxyCallback::Exception(ICorDebugAppDomain * pAppDomain, ICorDebugT public: // Ctor - ExceptionEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, ICorDebugFrame * pFrame, ULONG32 nOffset, CorDebugExceptionCallbackType dwEventType, DWORD dwFlags) : + ExceptionEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, ICorDebugFrame * pFrame, ULONG32 nOffset, CorDebugExceptionCallbackType dwEventType, DWORD dwFlags) : ManagedEvent(pThread) { this->m_pAppDomain.Assign(pAppDomain); @@ -1200,7 +1200,7 @@ HRESULT ShimProxyCallback::ExceptionUnwind(ICorDebugAppDomain * pAppDomain, ICor public: // Ctor - ExceptionUnwindEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, CorDebugExceptionUnwindCallbackType dwEventType, DWORD dwFlags) : + ExceptionUnwindEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, CorDebugExceptionUnwindCallbackType dwEventType, DWORD dwFlags) : ManagedEvent(pThread) { this->m_pAppDomain.Assign(pAppDomain); @@ -1233,7 +1233,7 @@ HRESULT ShimProxyCallback::FunctionRemapComplete(ICorDebugAppDomain * pAppDomain public: // Ctor - FunctionRemapCompleteEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, ICorDebugFunction * pFunction) : + FunctionRemapCompleteEvent(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, ICorDebugFunction * pFunction) : ManagedEvent(pThread) { this->m_pAppDomain.Assign(pAppDomain); @@ -1265,7 +1265,7 @@ HRESULT ShimProxyCallback::MDANotification(ICorDebugController * pController, IC public: // Ctor - MDANotificationEvent(ICorDebugController * pController, ICorDebugThread * pThread, ICorDebugMDA * pMDA) : + MDANotificationEvent(ICorDebugController * pController, ICorDebugThread * pThread, ICorDebugMDA * pMDA) : ManagedEvent(pThread) { this->m_pController.Assign(pController); @@ -1300,7 +1300,7 @@ HRESULT ShimProxyCallback::CustomNotification(ICorDebugThread * pThread, ICorDeb public: // Ctor - CustomNotificationEvent(ICorDebugThread * pThread, ICorDebugAppDomain * pAppDomain) : + CustomNotificationEvent(ICorDebugThread * pThread, ICorDebugAppDomain * pAppDomain) : ManagedEvent(pThread) { this->m_pAppDomain.Assign(pAppDomain); @@ -1317,39 +1317,68 @@ HRESULT ShimProxyCallback::CustomNotification(ICorDebugThread * pThread, ICorDeb return S_OK; } -// Implementation of ICorDebugManagedCallback4::SomeWork +// Implementation of ICorDebugManagedCallback4::BeforeGarbageCollection // Arguments: // input: -// pThread - thread on which the notification occurred -// pAppDomain - appDomain in which the notification occurred +// pController - controller in which the notification occurred // Return value: S_OK -HRESULT ShimProxyCallback::SomeWork(ICorDebugThread * pThread, ICorDebugAppDomain * pAppDomain) +HRESULT ShimProxyCallback::BeforeGarbageCollection(ICorDebugController* pController) { m_pShim->PreDispatchEvent(); - class SomeWorkEvent : public ManagedEvent + class BeforeGarbageCollectionEvent : public ManagedEvent { // callbacks parameters. These are strong references - RSExtSmartPtr<ICorDebugAppDomain > m_pAppDomain; - RSExtSmartPtr<ICorDebugThread > m_pThread; + RSExtSmartPtr<ICorDebugController > m_pController; public: // Ctor - SomeWorkEvent(ICorDebugThread * pThread, ICorDebugAppDomain * pAppDomain) : - ManagedEvent(pThread) + BeforeGarbageCollectionEvent(ICorDebugController* pController) : + ManagedEvent() { - this->m_pAppDomain.Assign(pAppDomain); - this->m_pThread.Assign(pThread); + this->m_pController.Assign(pController); + } + + HRESULT Dispatch(DispatchArgs args) + { + return args.GetCallback4()->BeforeGarbageCollection(m_pController); + } + }; // end class BeforeGarbageCollectionEvent + + m_pShim->GetManagedEventQueue()->QueueEvent(new BeforeGarbageCollectionEvent(pController)); + return S_OK; +} + +// Implementation of ICorDebugManagedCallback4::AfterGarbageCollection +// Arguments: +// input: +// pController - controller in which the notification occurred +// Return value: S_OK +HRESULT ShimProxyCallback::AfterGarbageCollection(ICorDebugController* pController) +{ + m_pShim->PreDispatchEvent(); + class AfterGarbageCollectionEvent : public ManagedEvent + { + // callbacks parameters. These are strong references + RSExtSmartPtr<ICorDebugController > m_pController; + + public: + // Ctor + AfterGarbageCollectionEvent(ICorDebugController* pController) : + ManagedEvent() + { + this->m_pController.Assign(pController); } HRESULT Dispatch(DispatchArgs args) { - return args.GetCallback4()->SomeWork(m_pThread, m_pAppDomain); + return args.GetCallback4()->AfterGarbageCollection(m_pController); } - }; // end class SomeWorkEvent + }; // end class AfterGarbageCollectionEvent - m_pShim->GetManagedEventQueue()->QueueEvent(new SomeWorkEvent(pThread, pAppDomain)); + m_pShim->GetManagedEventQueue()->QueueEvent(new AfterGarbageCollectionEvent(pController)); return S_OK; } + diff --git a/src/debug/di/shimpriv.h b/src/debug/di/shimpriv.h index acd3ef5e09..0f2d8031bb 100644 --- a/src/debug/di/shimpriv.h +++ b/src/debug/di/shimpriv.h @@ -3,9 +3,9 @@ // See the LICENSE file in the project root for more information. //***************************************************************************** // shimprivate.h -// +// -// +// // private header for RS shim which bridges from V2 to V3. //***************************************************************************** @@ -58,14 +58,14 @@ typedef SHash<DuplicateCreationEventsHashTableTraits> DuplicateCreationEventsHas // // Callback that shim provides, which then queues up the events. // -class ShimProxyCallback : +class ShimProxyCallback : public ICorDebugManagedCallback, - public ICorDebugManagedCallback2, + public ICorDebugManagedCallback2, public ICorDebugManagedCallback3, public ICorDebugManagedCallback4 { ShimProcess * m_pShim; // weak reference - LONG m_cRef; + LONG m_cRef; public: ShimProxyCallback(ShimProcess * pShim); @@ -83,7 +83,7 @@ public: COM_METHOD Breakpoint( ICorDebugAppDomain *pAppDomain, ICorDebugThread *pThread, ICorDebugBreakpoint *pBreakpoint); - + COM_METHOD StepComplete( ICorDebugAppDomain *pAppDomain, ICorDebugThread *pThread, ICorDebugStepper *pStepper, @@ -143,7 +143,7 @@ public: ICorDebugAppDomain *pAppDomain); COM_METHOD ExitAppDomain(ICorDebugProcess *pProcess, - ICorDebugAppDomain *pAppDomain); + ICorDebugAppDomain *pAppDomain); COM_METHOD LoadAssembly(ICorDebugAppDomain *pAppDomain, ICorDebugAssembly *pAssembly); @@ -215,8 +215,11 @@ public: /// Implementation of ICorDebugManagedCallback4 /// - // Implementation of ICorDebugManagedCallback4::SomeWork - COM_METHOD SomeWork(ICorDebugThread * pThread, ICorDebugAppDomain * pAppDomain); + // Implementation of ICorDebugManagedCallback4::BeforeGarbageCollection + COM_METHOD ShimProxyCallback::BeforeGarbageCollection(ICorDebugController* pController); + + // Implementation of ICorDebugManagedCallback4::AfterGarbageCollection + COM_METHOD ShimProxyCallback::AfterGarbageCollection(ICorDebugController* pController); }; @@ -268,7 +271,7 @@ protected: // Ctor for events without thread affinity. ManagedEvent(); - + friend class ManagedEventQueue; ManagedEvent * m_pNext; @@ -285,9 +288,9 @@ class ManagedEventQueue public: ManagedEventQueue(); - + void Init(RSLock * pLock); - + // Remove event from the top. Caller then takes ownership of Event and will call Delete on it. // Caller checks IsEmpty() first. ManagedEvent * Dequeue(); @@ -311,7 +314,7 @@ public: void RestoreSuspendedQueue(); protected: - // The lock to be used for synchronizing all access to the queue + // The lock to be used for synchronizing all access to the queue RSLock * m_pLock; // If empty, First + Last are both NULL. @@ -332,10 +335,10 @@ protected: class ShimProcess { // Delete via Ref count semantics. - ~ShimProcess(); + ~ShimProcess(); public: // Initialize ref count is 0. - ShimProcess(); + ShimProcess(); // Lifetime semantics handled by reference counting. void AddRef(); @@ -346,7 +349,7 @@ public: // Initialization phases. // 1. allocate new ShimProcess(). This lets us spin up a Win32 EventThread, which can then - // be used to + // be used to // 2. Call ShimProcess::CreateProcess/DebugActiveProcess. This will call CreateAndStartWin32ET to // craete the w32et. // 3. Create OS-debugging pipeline. This establishes the physical OS process and gets us a pid/handle @@ -388,7 +391,7 @@ public: // // Functions used by CordbProcess - // + // // Determine if the calling thread is the win32 event thread. bool IsWin32EventThread(); @@ -400,7 +403,7 @@ public: // Accessor wrapper to mark whether we're interop-debugging. void SetIsInteropDebugging(bool fIsInteropDebugging); - // Handle a debug event. + // Handle a debug event. HRESULT HandleWin32DebugEvent(const DEBUG_EVENT * pEvent); ManagedEventQueue * GetManagedEventQueue(); @@ -432,18 +435,18 @@ public: // Expose m_attached to CordbProcess. bool GetAttached(); - // We need to know whether we are in the CreateProcess callback to be able to - // return the v2.0 hresults from code:CordbProcess::SetDesiredNGENCompilerFlags + // We need to know whether we are in the CreateProcess callback to be able to + // return the v2.0 hresults from code:CordbProcess::SetDesiredNGENCompilerFlags // when we are using the shim. - // + // // Expose m_fInCreateProcess bool GetInCreateProcess(); void SetInCreateProcess(bool value); - // We need to know whether we are in the FakeLoadModule callback to be able to + // We need to know whether we are in the FakeLoadModule callback to be able to // return the v2.0 hresults from code:CordbModule::SetJITCompilerFlags when // we are using the shim. - // + // // Expose m_fInLoadModule bool GetInLoadModule(); void SetInLoadModule(bool value); @@ -469,7 +472,7 @@ public: // Clear all ShimStackWalks and flush all the caches. void ClearAllShimStackWalk(); - // Get the corresponding ICDProcess object. + // Get the corresponding ICDProcess object. ICorDebugProcess * GetProcess(); // Get the data target to access the debuggee. @@ -487,7 +490,7 @@ public: void PreDispatchEvent(bool fRealCreateProcessEvent = false); // Look for a CLR in the process and if found, return it's instance ID - HRESULT FindLoadedCLR(CORDB_ADDRESS * pClrInstanceId); + HRESULT FindLoadedCLR(CORDB_ADDRESS * pClrInstanceId); // Retrieve the IP address and the port number of the debugger proxy. MachineInfo GetMachineInfo(); @@ -495,7 +498,7 @@ public: // Add an entry in the duplicate creation event hash table for the specified key. void AddDuplicateCreationEvent(void * pKey); - // Check if a duplicate creation event entry exists for the specified key. If so, remove it. + // Check if a duplicate creation event entry exists for the specified key. If so, remove it. bool RemoveDuplicateCreationEventIfPresent(void * pKey); void SetMarkAttachPendingEvent(); @@ -515,13 +518,13 @@ protected: HRESULT CreateAndStartWin32ET(Cordb * pCordb); // - // Synchronization events to ensure that AttachPending bit is marked before DebugActiveProcess + // Synchronization events to ensure that AttachPending bit is marked before DebugActiveProcess // returns or debugger is detaching - // + // HANDLE m_markAttachPendingEvent; HANDLE m_terminatingEvent; - // Finds the base address of [core]clr.dll + // Finds the base address of [core]clr.dll CORDB_ADDRESS GetCLRInstanceBaseAddress(); // @@ -529,12 +532,12 @@ protected: // // Shim maintains event queue to emulate V2 semantics. - // In V2, IcorDebug internally queued debug events and dispatched them - // once the debuggee was synchronized. In V3, ICorDebug dispatches events immediately. + // In V2, IcorDebug internally queued debug events and dispatched them + // once the debuggee was synchronized. In V3, ICorDebug dispatches events immediately. // The event queue is moved into the shim to build V2 semantics of V3 behavior. ManagedEventQueue m_eventQueue; - - // Lock to protect Shim data structures. This is currently a small lock that + + // Lock to protect Shim data structures. This is currently a small lock that // protects leaf-level structures, but it may grow to protect larger things. RSLock m_ShimLock; @@ -559,21 +562,21 @@ protected: // True iff we are in the shim's CreateProcess callback. This is used to determine which hresult to // return from code:CordbProcess::SetDesiredNGENCompilerFlags so we correctly emulate the behavior of v2.0. - // This is set at the beginning of the callback and cleared in code:CordbProcess::ContinueInternal. + // This is set at the beginning of the callback and cleared in code:CordbProcess::ContinueInternal. bool m_fInCreateProcess; // True iff we are in the shim's FakeLoadModule callback. This is used to determine which hresult to // return from code:CordbModule::SetJITCompilerFlags so we correctly emulate the behavior of v2.0. - // This is set at the beginning of the callback and cleared in code:CordbProcess::ContinueInternal. + // This is set at the beginning of the callback and cleared in code:CordbProcess::ContinueInternal. bool m_fInLoadModule; // // Data // - // Pointer to CordbProcess. + // Pointer to CordbProcess. // @dbgtodo shim: We'd like this to eventually go through public interfaces (ICorDebugProcess) IProcessShimHooks * m_pProcess; // Reference is kept by m_pIProcess; - RSExtSmartPtr<ICorDebugProcess> m_pIProcess; + RSExtSmartPtr<ICorDebugProcess> m_pIProcess; // Win32EvenThread, which is the thread that uses the native debug API. CordbWin32EventThread * m_pWin32EventThread; @@ -604,10 +607,10 @@ protected: void DefaultEventHandler(const DEBUG_EVENT * pEvent, DWORD * pdwContinueStatus); // Given a debug event, track the file handles. - void TrackFileHandleForDebugEvent(const DEBUG_EVENT * pEvent); + void TrackFileHandleForDebugEvent(const DEBUG_EVENT * pEvent); // Have we gotten the loader breakpoint yet? - // A Debugger needs to do special work to skip the loader breakpoint, + // A Debugger needs to do special work to skip the loader breakpoint, // and that's also when it should dispatch the faked managed attach events. bool m_loaderBPReceived; @@ -616,7 +619,7 @@ protected: // Real worker to update ContinueStatusChangedData HRESULT ContinueStatusChangedWorker(DWORD dwThreadId, CORDB_CONTINUE_STATUS dwContinueStatus); - + struct ContinueStatusChangedData { void Clear(); @@ -640,8 +643,8 @@ protected: //--------------------------------------------------------------------------------------- // -// This is the container class of ShimChains, ICorDebugFrames, ShimChainEnums, and ShimFrameEnums. -// It has a 1:1 relationship with ICorDebugThreads. Upon creation, this class walks the entire stack and +// This is the container class of ShimChains, ICorDebugFrames, ShimChainEnums, and ShimFrameEnums. +// It has a 1:1 relationship with ICorDebugThreads. Upon creation, this class walks the entire stack and // caches all the stack frames and chains. The enumerators are created on demand. // @@ -693,7 +696,7 @@ private: // // This is a helper class used to store the information of a chain during a stackwalk. A chain is marked // by the CONTEXT on the leaf boundary and a FramePointer on the root boundary. Also, notice that we - // are keeping two CONTEXTs. This is because some chain types may cancel a previous unmanaged chain. + // are keeping two CONTEXTs. This is because some chain types may cancel a previous unmanaged chain. // For example, a CHAIN_FUNC_EVAL chain cancels any CHAIN_ENTER_UNMANAGED chain immediately preceding // it. In this case, the leaf boundary of the CHAIN_FUNC_EVAL chain is marked by the CONTEXT of the // previous CHAIN_ENTER_MANAGED, not the previous CHAIN_ENTER_UNMANAGED. @@ -746,7 +749,7 @@ private: // Check whether we are skipping frames because of a child frame. BOOL IsSkippingFrame(); - // Indicates whether we are dealing with a converted frame. + // Indicates whether we are dealing with a converted frame. // See code:CordbThread::ConvertFrameForILMethodWithoutMetadata. BOOL HasConvertedFrame(); @@ -757,7 +760,7 @@ private: // Store the converted frame, if any. RSExtSmartPtr<ICorDebugInternalFrame2> m_pConvertedInternalFrame2; - // Store the array of internal frames. This is an array of RSExtSmartPtrs, and so each element + // Store the array of internal frames. This is an array of RSExtSmartPtrs, and so each element // is protected, and we only need to call Clear() to release each element and free all the memory. RSExtPtrArray<ICorDebugInternalFrame2> m_ppInternalFrame2; @@ -772,10 +775,10 @@ private: bool m_fExhaustedAllStackFrames; // Indicate whether we are processing an internal frame or a stack frame. - bool m_fProcessingInternalFrame; + bool m_fProcessingInternalFrame; - // Indicate whether we should skip the current chain because it's a chain derived from a leaf frame - // of type TYPE_INTERNAL. This is the behaviour in V2. + // Indicate whether we should skip the current chain because it's a chain derived from a leaf frame + // of type TYPE_INTERNAL. This is the behaviour in V2. // See code:DebuggerWalkStackProc. bool m_fSkipChain; @@ -838,7 +841,7 @@ private: BOOL IsILFrameWithoutMetadata(ICorDebugFrame * pFrame); CDynArray<ShimChain *> m_stackChains; // growable ordered array of chains and frames - CDynArray<ICorDebugFrame *> m_stackFrames; + CDynArray<ICorDebugFrame *> m_stackFrames; ShimChainEnum * m_pChainEnumList; // linked list of ShimChainEnum and ShimFrameEnum ShimFrameEnum * m_pFrameEnumList; @@ -918,16 +921,16 @@ private: FramePointer m_fpRoot; // the root end of the chain ShimStackWalk * m_pStackWalk; // the owning ShimStackWalk - Volatile<ULONG> m_refCount; + Volatile<ULONG> m_refCount; // The 0-based index of this chain in the ShimStackWalk's chain array (m_pStackWalk->m_stackChains). UINT32 m_chainIndex; - // The 0-based index of the first frame owned by this chain in the ShimStackWalk's frame array + // The 0-based index of the first frame owned by this chain in the ShimStackWalk's frame array // (m_pStackWalk->m_stackFrames). See code::ShimChain::GetFirstFrameIndex(). UINT32 m_frameStartIndex; - // The 0-based index of the last frame owned by this chain in the ShimStackWalk's frame array + // The 0-based index of the last frame owned by this chain in the ShimStackWalk's frame array // (m_pStackWalk->m_stackFrames). This index is exlusive. See code::ShimChain::GetLastFrameIndex(). UINT32 m_frameEndIndex; @@ -978,7 +981,7 @@ public: // // accessors - // + // // used to link ShimChainEnums in a list ShimChainEnum * GetNext(); @@ -994,7 +997,7 @@ private: UINT32 m_currentChainIndex; // the index of the current ShimChain being enumerated Volatile<ULONG> m_refCount; BOOL m_fIsNeutered; - + RSLock * m_pShimLock; // shim lock from ShimProcess to protect neuteredness checks }; @@ -1038,7 +1041,7 @@ public: // // accessors - // + // // used to link ShimChainEnums in a list ShimFrameEnum * GetNext(); |