summaryrefslogtreecommitdiff
path: root/src/debug/di
diff options
context:
space:
mode:
authorAndrew Au <andrewau@microsoft.com>2018-05-10 14:49:39 -0700
committerAndrew Au <cshung@gmail.com>2018-11-06 18:34:47 -0800
commitc6d26187c8ce8fc68829f262a79996f00b1e1a85 (patch)
treea804fc4d890621ecc94c5b0fa5253c4b71a6a091 /src/debug/di
parente5744ae2855ee74f8f2f8020c0ef2d54bbfb746d (diff)
downloadcoreclr-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.cpp1515
-rw-r--r--src/debug/di/rsmain.cpp155
-rw-r--r--src/debug/di/shimcallback.cpp177
-rw-r--r--src/debug/di/shimpriv.h113
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();