diff options
Diffstat (limited to 'src/debug/di')
-rw-r--r-- | src/debug/di/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/debug/di/cordb.cpp | 62 | ||||
-rw-r--r-- | src/debug/di/dbgtransportmanager.cpp | 1929 | ||||
-rw-r--r-- | src/debug/di/dbgtransportmanager.h | 225 | ||||
-rw-r--r-- | src/debug/di/dbgtransportpipeline.cpp | 54 | ||||
-rw-r--r-- | src/debug/di/ddpack.cpp | 3731 | ||||
-rw-r--r-- | src/debug/di/ddpack.h | 346 | ||||
-rw-r--r-- | src/debug/di/eventchannel.h | 2 | ||||
-rw-r--r-- | src/debug/di/platformspecific.cpp | 2 | ||||
-rw-r--r-- | src/debug/di/process.cpp | 67 | ||||
-rw-r--r-- | src/debug/di/remoteeventchannel.cpp | 21 | ||||
-rw-r--r-- | src/debug/di/shimlocaldatatarget.cpp | 4 | ||||
-rw-r--r-- | src/debug/di/shimpriv.h | 4 | ||||
-rw-r--r-- | src/debug/di/shimprocess.cpp | 41 | ||||
-rw-r--r-- | src/debug/di/shimremotedatatarget.cpp | 43 |
15 files changed, 288 insertions, 6245 deletions
diff --git a/src/debug/di/CMakeLists.txt b/src/debug/di/CMakeLists.txt index 6546b69920..b360aa4e97 100644 --- a/src/debug/di/CMakeLists.txt +++ b/src/debug/di/CMakeLists.txt @@ -13,9 +13,11 @@ set(CORDBDI_SOURCES breakpoint.cpp cordb.cpp divalue.cpp + dbgtransportmanager.cpp hash.cpp module.cpp nativepipeline.cpp + eventredirectionpipeline.cpp platformspecific.cpp process.cpp rsappdomain.cpp diff --git a/src/debug/di/cordb.cpp b/src/debug/di/cordb.cpp index 1267748fc5..04f3099b44 100644 --- a/src/debug/di/cordb.cpp +++ b/src/debug/di/cordb.cpp @@ -210,7 +210,12 @@ BOOL WINAPI DbgDllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) #endif #if defined(FEATURE_DBGIPC_TRANSPORT_DI) - g_pDbgTransportManager = NULL; + g_pDbgTransportTarget = new (nothrow) DbgTransportTarget(); + if (g_pDbgTransportTarget == NULL) + return FALSE; + + if (FAILED(g_pDbgTransportTarget->Init())) + return FALSE; #endif // FEATURE_DBGIPC_TRANSPORT_DI } break; @@ -238,58 +243,31 @@ BOOL WINAPI DbgDllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) TlsFree(DbgRSThread::s_TlsSlot); DbgRSThread::s_TlsSlot = TLS_OUT_OF_INDEXES; #endif - } - break; - } - - return TRUE; -} #if defined(FEATURE_DBGIPC_TRANSPORT_DI) -// Routines to initialize and shutdown the debugger transport manager. Can't do these operations from DllMain -// since they perform blocking network operations which can easily cause deadlocks on the loader lock. -// Note: These routines are *not* thread safe (it's assumed the caller implements its own serialization). -extern "C" HRESULT __stdcall InitDbgTransportManager() -{ - if (g_pDbgTransportManager) - return S_OK; - - DbgTransportManager *pManager = new (nothrow) DbgTransportManager(); - if (pManager == NULL) - return E_OUTOFMEMORY; + if (g_pDbgTransportTarget != NULL) + { + g_pDbgTransportTarget->Shutdown(); + delete g_pDbgTransportTarget; + g_pDbgTransportTarget = NULL; + } +#endif // FEATURE_DBGIPC_TRANSPORT_DI - HRESULT hr = pManager->Init(); - if (FAILED(hr)) - { - pManager->Shutdown(); - delete pManager; - return hr; + } + break; } - _ASSERTE(g_pDbgTransportManager == NULL); - g_pDbgTransportManager = pManager; - - return S_OK; + return TRUE; } -extern "C" void __stdcall ShutdownDbgTransportManager() -{ - if (g_pDbgTransportManager) - { - g_pDbgTransportManager->Shutdown(); - delete g_pDbgTransportManager; - g_pDbgTransportManager = NULL; - } -} -#endif // FEATURE_DBGIPC_TRANSPORT_DI // The obsolete v1 CLSID - see comment above for details. static const GUID CLSID_CorDebug_V1 = {0x6fef44d0,0x39e7,0x4c77, { 0xbe,0x8e,0xc9,0xf8,0xcf,0x98,0x86,0x30}}; #if defined(FEATURE_DBGIPC_TRANSPORT_DI) -// include the GUID for Mac SilverLight debugging -#include <maccoreclrdebugguids.h> +// GUID for pipe-based debugging (Unix platforms) +const GUID CLSID_CorDebug_Telesto = {0x8bd1daae, 0x188e, 0x42f4, {0xb0, 0x09, 0x08, 0xfa, 0xfd, 0x17, 0x81, 0x3b}}; // The debug engine needs to implement an internal Visual Studio debugger interface (defined by the CPDE) // which augments launch and attach requests so that we can obtain information from the port supplier (the @@ -321,7 +299,7 @@ STDAPI DllGetClassObjectInternal( // Return code. else #endif #if defined(FEATURE_DBGIPC_TRANSPORT_DI) - if (rclsid == CLSID_CorDebug_Mac_SilverLight) + if (rclsid == CLSID_CorDebug_Telesto) { pfnCreateObject = Cordb::CreateObjectTelesto; } @@ -571,7 +549,7 @@ DbiSetThreadContext(HANDLE hThread, *ctx = *(CONTEXT*)lpContext; res = ::SetThreadContext(hThread, ctx); _aligned_free(ctx); - } + } else { // malloc does not set the last error, but the caller of SetThreadContext diff --git a/src/debug/di/dbgtransportmanager.cpp b/src/debug/di/dbgtransportmanager.cpp index e00e3f9c82..e9b619de18 100644 --- a/src/debug/di/dbgtransportmanager.cpp +++ b/src/debug/di/dbgtransportmanager.cpp @@ -3,185 +3,16 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // - #include "stdafx.h" #include "dbgtransportsession.h" #include "dbgtransportmanager.h" #include "coreclrremotedebugginginterfaces.h" -#ifdef FEATURE_DBGIPC_TRANSPORT_DI - -// -// Provides access to various process enumeration and control facilities for a remote machine. -// - -// The one and only instance of the DbgTransportManager in the process. -DbgTransportManager *g_pDbgTransportManager = NULL; - -DbgTransportManager::DbgTransportManager() -{ - memset(this, 0, sizeof(*this)); -} - -// Startup/shutdown calls. These are ref-counted (cordbg, for instance, is constructed in such a way that -// the command shell will attempt to load mscordbi and initialize an associated DbgTransportManager -// multiple times). -HRESULT DbgTransportManager::Init() -{ - if (InterlockedIncrement(&m_lRefCount) == 1) - { - m_sLock.Init("DbgTransportManager Lock", RSLock::cLockFlat, RSLock::LL_DBG_TRANSPORT_MANAGER_LOCK); - m_pTargets = NULL; - } - - return S_OK; -} - -void DbgTransportManager::Shutdown() -{ - if (InterlockedDecrement(&m_lRefCount) == 0) - { - m_sLock.Destroy(); - - while (m_pTargets) - { - TargetRef *pTargetRef = m_pTargets; - m_pTargets = pTargetRef->m_pNext; - - pTargetRef->m_pTarget->Shutdown(); - delete pTargetRef->m_pTarget; - - delete pTargetRef; - } - } -} - -// Attempt to connect to a debugging proxy on the machine at the given address and with the specified port -// number. If the port number is given as zero use the port stored in user debugger configuration. On success -// a pointer to a DbgTransportTarget object will be returned. -HRESULT DbgTransportManager::ConnectToTarget(DWORD dwIPAddress, USHORT usPort, DbgTransportTarget **ppTarget) -{ - RSLockHolder lock(&m_sLock); - - // Look for an existing target with matching IP address and port number. - TargetRef *pTargetRef = m_pTargets; - while (pTargetRef) - { - // Matches must have identical IP address and port number and must also be in a good connection state - // (otherwise we're looking at a target that hit a network error and is just waiting until outstanding - // references to it have been released -- in these circumstances we allow a new target to be allocated - // in order to re-attempt connection to the proxy). - if (pTargetRef->m_dwIPAddress == dwIPAddress && - pTargetRef->m_usPort == usPort && - !pTargetRef->m_pTarget->IsProxyConnectionBad()) - { - pTargetRef->m_dwRefCount++; - *ppTarget = pTargetRef->m_pTarget; - return S_OK; - } - - pTargetRef = pTargetRef->m_pNext; - } - // If we get here there wasn't an appropriate existing entry, so create one. - - // First the reference structure used to track the target. - pTargetRef = new (nothrow) TargetRef(); - if (pTargetRef == NULL) - return E_OUTOFMEMORY; - - // Then the target object itself. - DbgTransportTarget *pTarget = new (nothrow) DbgTransportTarget(); - if (pTargetRef == NULL) - { - delete pTargetRef; - return E_OUTOFMEMORY; - } - - // Initialize the target (this will attempt a connection to the proxy immediately). - HRESULT hr = pTarget->Init(dwIPAddress, usPort); - if (FAILED(hr)) - { - pTarget->Shutdown(); - delete pTarget; - delete pTargetRef; - return hr; - } - - // Everything's good, go ahead and initialize and link in the target reference. - pTargetRef->m_dwRefCount = 1; - pTargetRef->m_pTarget = pTarget; - pTargetRef->m_dwIPAddress = dwIPAddress; - pTargetRef->m_usPort = usPort; - - pTargetRef->m_pNext = m_pTargets; - m_pTargets = pTargetRef; - - *ppTarget = pTarget; - return S_OK; -} - -// Add another reference to a target already acquired by ConnectToTarget (used by clients when they want -// to hand a target out to independent code). -void DbgTransportManager::ReferenceTarget(DbgTransportTarget *pTarget) -{ - RSLockHolder lock(&m_sLock); - - // We need to locate the target reference for this target. - TargetRef *pTargetRef = m_pTargets; - while (pTargetRef) - { - if (pTargetRef->m_pTarget == pTarget) - { - pTargetRef->m_dwRefCount++; - return; - } - pTargetRef = pTargetRef->m_pNext; - } - - // Shouldn't get here. - _ASSERTE(FALSE); -} - -// Release reference to a DbgTransportTarget. If this is the last active reference then the connection to the -// proxy will be severed and the object deallocated. -void DbgTransportManager::ReleaseTarget(DbgTransportTarget *pTarget) -{ - RSLockHolder lock(&m_sLock); - - // We need to locate the target reference for this target (and the previous reference so we can perform - // the fixup to remove the entry from the queue if this was the last reference to the target). - TargetRef *pTargetRef = m_pTargets; - TargetRef *pLastRef = NULL; - while (pTargetRef) - { - if (pTargetRef->m_pTarget == pTarget) - { - pTargetRef->m_dwRefCount--; - if (pTargetRef->m_dwRefCount == 0) - { - // This was the last reference to this particular target. Remove it from the queue and - // deallocate it. - if (pLastRef) - pLastRef->m_pNext = pTargetRef->m_pNext; - else - m_pTargets = pTargetRef->m_pNext; - - delete pTargetRef; - - pTarget->Shutdown(); - delete pTarget; - } - return; - } - pLastRef = pTargetRef; - pTargetRef = pTargetRef->m_pNext; - } +#ifdef FEATURE_DBGIPC_TRANSPORT_DI - // Shouldn't get here. - _ASSERTE(FALSE); -} +DbgTransportTarget *g_pDbgTransportTarget = NULL; DbgTransportTarget::DbgTransportTarget() { @@ -189,136 +20,9 @@ DbgTransportTarget::DbgTransportTarget() } // Initialization routine called only by the DbgTransportManager. -HRESULT DbgTransportTarget::Init(DWORD dwIPAddress, USHORT usPort) +HRESULT DbgTransportTarget::Init() { - m_ullLastUpdate = 0; - m_fShutdown = false; - - // Target platform is initially unknown. This gets set when the proxy replies to our initial GetSystemInfo - // message. - m_ePlatform = DTP_Unknown; - - // If a port number hasn't been specified query the debugger configuration for the current user, this will - // give us the default. - if (usPort == 0) - { - DbgConfiguration sDbgConfig; - if (!GetDebuggerConfiguration(&sDbgConfig)) - { - DbgTransportLog(LC_Always, "Failed to locate debugger configuration"); - return CORDBG_E_REMOTE_INVALID_CONFIG; - } - _ASSERTE(sDbgConfig.m_fEnabled); // Debugging is always enabled on right side. - m_usProxyPort = sDbgConfig.m_usProxyPort; - } - else - m_usProxyPort = usPort; - - // Do the same for IP address except the fallback is an environment variable (and after that 127.0.0.1 for - // local debugging). - if (dwIPAddress == 0) - { - LPWSTR wszProxyIP = CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_DbgTransportProxyAddress); - if (wszProxyIP != NULL) - { - int cbReq = WszWideCharToMultiByte(CP_UTF8, 0, wszProxyIP, -1, 0, 0, 0, 0); - char *szProxyIP = new (nothrow) char[cbReq + 1]; - if (szProxyIP != NULL) - { - WszWideCharToMultiByte(CP_UTF8, 0, wszProxyIP, -1, szProxyIP, cbReq + 1, 0,0); - m_dwProxyIP = DBGIPC_NTOHL(inet_addr(szProxyIP)); - } - - REGUTIL::FreeConfigString(wszProxyIP); - } - if (m_dwProxyIP == 0) - m_dwProxyIP = DBGIPC_NTOHL(inet_addr("127.0.0.1")); - } - else - m_dwProxyIP = dwIPAddress; - - // Allocate the connection manager and initialize it. - m_pConnectionManager = AllocateSecConnMgr(); - if (m_pConnectionManager == NULL) - return E_OUTOFMEMORY; - - SecConnStatus eStatus = m_pConnectionManager->Initialize(); - if (eStatus != SCS_Success) - { - DbgTransportLog(LC_Always, "Failed to initialize connection manager with %u", eStatus); - switch (eStatus) - { - case SCS_OutOfMemory: - return E_OUTOFMEMORY; - case SCS_InvalidConfiguration: - return CORDBG_E_REMOTE_INVALID_CONFIG; - default: - return E_FAIL; - } - } - m_sLock.Init("DbgTransportTarget Lock", RSLock::cLockFlat, RSLock::LL_DBG_TRANSPORT_TARGET_LOCK); - m_fInitLock = true; - - // Outgoing requests are identified with a monotonically increasing ID starting from 1. - m_dwNextRequestID = 1; - - // We store a singly-linked list of requests to the proxy that haven't been replied yet. - m_pRequestList = NULL; - - // Attempt to contact the proxy and form a connection to it. - eStatus = m_pConnectionManager->AllocateConnection(m_dwProxyIP, m_usProxyPort, &m_pConnection); - if (eStatus == SCS_Success) - eStatus = m_pConnection->Connect(); - if (eStatus != SCS_Success) - { - DbgTransportLog(LC_Always, "Failed to connect to proxy with %u", eStatus); - switch (eStatus) - { - case SCS_OutOfMemory: - return E_OUTOFMEMORY; - case SCS_UnknownTarget: - return CORDBG_E_REMOTE_UNKNOWN_TARGET; - case SCS_NoListener: - return CORDBG_E_REMOTE_NO_LISTENER; - case SCS_NetworkFailure: - return CORDBG_E_REMOTE_NETWORK_FAILURE; - case SCS_MismatchedCerts: - return CORDBG_E_REMOTE_MISMATCHED_CERTS; - default: - return E_ABORT; - } - } - - // Create a thread used to monitor remote process state. - m_hProcessEventThread = CreateThread(NULL, 0, ProcessEventWorkerStatic, this, 0, NULL); - if (m_hProcessEventThread == NULL) - return E_OUTOFMEMORY; - - // Send the initial message to the proxy which informs it of our protocol version and queries the target - // platform and protocol version. This must be done after the thread above is started since we rely on - // this thread to process replies. - DWORD dwProxyMajorVersion; - DWORD dwProxyMinorVersion; - HRESULT hr = MakeProxyRequest(DPMT_GetSystemInfo, - &dwProxyMajorVersion, - &dwProxyMinorVersion, - &m_ePlatform); - if (FAILED(hr)) - { - DbgTransportLog(LC_Always, "GetSystemInfo request to proxy failed with %08X", hr); - return hr; - } - - // Check that we can deal with the proxy's protocol. - if (dwProxyMajorVersion != kCurrentMajorVersion) - { - DbgTransportLog(LC_Always, "Don't understand proxy protocol v%u.%u", - dwProxyMajorVersion, dwProxyMinorVersion); - return CORDBG_E_REMOTE_MISMATCHED_PROTOCOLS; - } - - m_fProxyConnectionBad = false; return S_OK; } @@ -328,89 +32,19 @@ void DbgTransportTarget::Shutdown() { DbgTransportLog(LC_Always, "DbgTransportTarget shutting down"); - m_fShutdown = true; - m_fProxyConnectionBad = true; - - if (m_hProcessEventThread) - { - // Unwedge the process event thread if it's blocked in a Receive(). - m_pConnection->CancelReceive(); - - // Wait for the process event thread to see the shutdown status and close itself down. - WaitForSingleObject(m_hProcessEventThread, INFINITE); - CloseHandle(m_hProcessEventThread); - } - - // Cleanup process list. - DeallocateProcessList(m_pProcessList); - - if (m_pConnection) - m_pConnection->Destroy(); - - if (m_pConnectionManager) - m_pConnectionManager->Destroy(); - - if (m_fInitLock) - m_sLock.Destroy(); -} - -// Indicates when the connection to a proxy has failed: this target object will remain until the last -// reference to it is released (DbgTransportManager::ReleaseTransport) but will fail all further requests. The -// manager will then allow a new attempt to create a connection to the proxy to be made (wrapped in a new -// DbgTransportTarget). -bool DbgTransportTarget::IsProxyConnectionBad() -{ - return m_fProxyConnectionBad; -} - -// Fill caller allocated table at pdwProcesses with the pids of processes currently alive on the target -// system. Return the number of slots filled in *pcProcesses. The size of the table is given by cSlots. If -// more than this number of processes are alive then *pcProcesses is set to the total number and E_ABORT -// returned. -HRESULT DbgTransportTarget::EnumProcesses(DWORD *pdwProcesses, DWORD cSlots, DWORD *pcProcesses) -{ - if (m_fProxyConnectionBad) - return E_ABORT; - - *pcProcesses = 0; - - // Get an up-to-date process list from the proxy. - UpdateProcessList(); - - // Must access the process list under the lock. { RSLockHolder lock(&m_sLock); - - // Populate the output table from the new process list. - DWORD i = 0; - DWORD cSlotsLeft = cSlots; - - // Fill the output table with as many process IDs as we have (or until we run out of slots). Carry on - // to the end of the process regardless so we can report how many processes there actually are. - for (ProcessEntry *pProcess = m_pProcessList; pProcess; pProcess = pProcess->m_pNext) + while (m_pProcessList) { - // Entries for dead processes can persist until an associated transport is released. Don't report - // these. - if (pProcess->m_fExited) - continue; - - if (cSlotsLeft) - { - pdwProcesses[i] = pProcess->m_dwPID; - cSlotsLeft--; - } - - i++; + ProcessEntry *pDelProcess = m_pProcessList; + m_pProcessList = m_pProcessList->m_pNext; + delete pDelProcess; } - - // Return total count to caller. - *pcProcesses = i; - - } // Leave lock - - return *pcProcesses > cSlots ? E_ABORT : S_OK; + } + m_sLock.Destroy(); } + // Given a PID attempt to find or create a DbgTransportSession instance to manage a connection to a runtime in // that process. Returns E_UNEXPECTED if the process can't be found. Also returns a handle that can be waited // on for process termination. @@ -418,455 +52,167 @@ HRESULT DbgTransportTarget::GetTransportForProcess(DWORD dwPID DbgTransportSession **ppTransport, HANDLE *phProcessHandle) { - if (m_fProxyConnectionBad) - return E_ABORT; + RSLockHolder lock(&m_sLock); + HRESULT hr = S_OK; - // Get an up-to-date process list from the proxy. - UpdateProcessList(); + ProcessEntry *entry = LocateProcessByPID(dwPID); - // Process list can only be examined under the lock. + if (entry == NULL) { - RSLockHolder lock(&m_sLock); - - // Scan each process in the list. - ProcessEntry *pProcess = m_pProcessList; - while (pProcess) - { - if (pProcess->m_dwPID == dwPID) - { - // We've found a match. - if (pProcess->m_fExited) - { - // But it was for a dead process. Don't report this one (though we know the process is dead so - // return E_UNEXPECTED). - return E_UNEXPECTED; - } - RetryTransport: - // If we already know about runtimes in this process then attempt to attach to the first one. - // CORECLRTODO: In the next version we'll wire up the additional logic to enable the caller to - // indicate which runtime they want to target within a single process. - if (pProcess->m_pRuntimes) - { - RuntimeEntry *pRuntime = pProcess->m_pRuntimes; + NewHolder<ProcessEntry> newEntry = new(nothrow) ProcessEntry(); + if (newEntry == NULL) + return E_OUTOFMEMORY; - // If we have a runtime entry already then the LS is already present and we know the port - // to connect to. If there's already a transport in place then we can (and must) use that. - // Otherwise we can allocate and initialize one based on the port information. - DbgTransportSession *pTransport = pRuntime->m_pDbgTransport; - if (pTransport == NULL) - { - // No transport yet, allocate one. - pTransport = new (nothrow) DbgTransportSession(); - if (pTransport == NULL) - return E_OUTOFMEMORY; + NewHolder<DbgTransportSession> transport = new(nothrow) DbgTransportSession(); + if (transport == NULL) + { + return E_OUTOFMEMORY; + } - // Initialize it (this immediately starts the remote connection process). - HRESULT hr = pTransport->Init(m_dwProxyIP, pRuntime->m_usPort, pProcess->m_hExitedEvent); - if (FAILED(hr)) - { - lock.Release(); - pTransport->Shutdown(); - delete pTransport; - return hr; - } - pRuntime->m_pDbgTransport = pTransport; - } + HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID); + if (hProcess == NULL) + { + return HRESULT_FROM_GetLastError(); + } - // One more caller knows about this transport instance. (Which in turn is another reason - // the process can't be deleted yet). - pRuntime->m_cTransportRef++; - pProcess->m_cProcessRef++; + // Initialize it (this immediately starts the remote connection process). + hr = transport->Init(dwPID, hProcess); + if (FAILED(hr)) + { + transport->Shutdown(); + CloseHandle(hProcess); + return hr; + } - *ppTransport = pTransport; - if (!DuplicateHandle(GetCurrentProcess(), - pProcess->m_hExitedEvent, - GetCurrentProcess(), - phProcessHandle, - 0, // ignored since we are going to pass DUPLICATE_SAME_ACCESS - FALSE, - DUPLICATE_SAME_ACCESS)) - { - lock.Release(); - return HRESULT_FROM_GetLastError(); - } - return S_OK; - } + entry = newEntry; + newEntry.SuppressRelease(); + entry->m_dwPID = dwPID; + entry->m_hProcess = hProcess; + entry->m_transport = transport; + transport.SuppressRelease(); + entry->m_cProcessRef = 0; - // If we get here we've found the process record but there's no known runtime yet. The proxy - // will send us an event if either a runtime starts up or the process dies, so we'll wait on - // both of these. We can't wait with the lock held so increment the ref count on the process - // (to keep the entry and the events we're about to wait on valid) and drop the lock first. - - pProcess->m_cProcessRef++; - lock.Release(); - - // We need to send an early attach notification to the proxy so that when the next runtime - // starts up and registers it will know to suspend itself until we attach (i.e. this is the - // early attach). Obviously we're racing with runtime startup here but that's by definition. - bool fProcessExited; - HRESULT hr = MakeProxyRequest(DPMT_EarlyAttach, pProcess->m_pruidProcess, &fProcessExited); - if (FAILED(hr)) - { - lock.Acquire(); - pProcess->m_cProcessRef--; - return hr; - } - - // The process might have managed to exit before we even built a process entry for it on this - // side. In that case a process termination might have been missed. Checking for the exit - // status again with the EarlyAttach request above closes the hole (we establish a process - // entry and lock it in place so any termination events from that point on will be caught, - // then we fire an EarlyAttach and check the current status). - if (fProcessExited) - { - lock.Acquire(); - pProcess->m_cProcessRef--; - pProcess->m_fExited = true; - SetEvent(pProcess->m_hExitedEvent); - return E_UNEXPECTED; - } - - DbgTransportLog(LC_Always, "Waiting on runtime starting or process termination for %08X(%u, %u)", - pProcess, pProcess->m_dwPID, pProcess->m_pruidProcess); - - HANDLE rgEvents[] = { pProcess->m_hRuntimeStartedEvent, pProcess->m_hExitedEvent }; - DWORD dwResult = WaitForMultipleObjectsEx(2, rgEvents, FALSE, INFINITE, FALSE); - _ASSERTE(dwResult == WAIT_OBJECT_0 || dwResult == (WAIT_OBJECT_0 + 1)); - - DbgTransportLog(LC_Always, " %s", dwResult == WAIT_OBJECT_0 ? "Runtime started" : "Process terminated"); - - // Take the lock again and determine what our status is. - lock.Acquire(); - - // We have no further need to keep this process record alive (once we drop the lock). - _ASSERTE(pProcess->m_cProcessRef > 0); - pProcess->m_cProcessRef--; - - // If the process terminated then exit with E_UNEXPECTED. Note that this might be a zombie - // entry marked with m_fExited = true in this case, but rather than duplicate entry cleanup - // code we'll let the next process list update flush this record (now that the ref count has - // been decremented). - if (dwResult == (WAIT_OBJECT_0 + 1)) - return E_UNEXPECTED; - - // We should have at least one runtime entry now; just jump back to the code that knows how to - // re-use or allocate a transport on it. - _ASSERTE(pProcess->m_pRuntimes); - goto RetryTransport; - } - - pProcess = pProcess->m_pNext; - } - } // Leave lock - - // Didn't find a process with a matching PID. - return E_UNEXPECTED; -} + // Adding new entry to the list. + entry->m_pNext = m_pProcessList; + m_pProcessList = entry; + } -// Returns true if the given PID identifies a running process which is hosting at least one CoreCLR -// runtime. -bool DbgTransportTarget::IsManagedProcess(DWORD dwPID) -{ - // Maybe we already know the process is managed. + entry->m_cProcessRef++; + _ASSERTE(entry->m_cProcessRef > 0); + _ASSERTE(entry->m_transport != NULL); + _ASSERTE(entry->m_hProcess > 0); + + *ppTransport = entry->m_transport; + if (!DuplicateHandle(GetCurrentProcess(), + entry->m_hProcess, + GetCurrentProcess(), + phProcessHandle, + 0, // ignored since we are going to pass DUPLICATE_SAME_ACCESS + FALSE, + DUPLICATE_SAME_ACCESS)) { - RSLockHolder lock(&m_sLock); - ProcessEntry *pProcess = LocateProcessByPID(dwPID); -#ifdef _PREFAST_ -#pragma warning(push) -#pragma warning(disable:6011) // Prefast doesn't understand the guard to avoid de-referencing a NULL pointer below. -#endif // _PREFAST_ - if (pProcess && pProcess->m_pRuntimes) - return true; -#ifdef _PREFAST_ -#pragma warning(pop) -#endif // _PREFAST_ - } // Leave lock - - // Get an up-to-date process list from the proxy in case we've haven't done this for a while and a runtime - // has started up in the meantime. - UpdateProcessList(); + return HRESULT_FROM_GetLastError(); + } - // Try once again. - { - RSLockHolder lock(&m_sLock); - ProcessEntry *pProcess = LocateProcessByPID(dwPID); - return pProcess ? pProcess->m_pRuntimes != NULL : false; - } // Leave lock + return hr; } + // Release another reference to the transport associated with dwPID. Once all references are gone (modulo the // manager's own weak reference) clean up the transport and deallocate it. void DbgTransportTarget::ReleaseTransport(DbgTransportSession *pTransport) { - DbgTransportSession *pTransportToShutdown = NULL; - - // Process list can only be examined under the lock. - { - RSLockHolder lock(&m_sLock); - - // Scan all processes we know about. - ProcessEntry *pProcess = m_pProcessList; - while (pProcess) - { - // Scan each runtime we know about in the current process. - RuntimeEntry *pRuntime = pProcess->m_pRuntimes; - while (pRuntime) - { - if (pRuntime->m_pDbgTransport == pTransport) - { - // Found it. + RSLockHolder lock(&m_sLock); - // Decrement the transport ref count. This is also one less reason to hold onto the - // process record. - _ASSERTE(pRuntime->m_cTransportRef > 0 && pProcess->m_cProcessRef > 0); - pRuntime->m_cTransportRef--; - pProcess->m_cProcessRef--; + ProcessEntry *entry = m_pProcessList; - // If nobody references this transport any more we can shut it down and delete it. Don't - // do this under the lock however. - if (pRuntime->m_cTransportRef == 0) - { - pTransportToShutdown = pRuntime->m_pDbgTransport; - pRuntime->m_pDbgTransport = NULL; - } + // Pointer to the pointer that points to *entry. + // It either points to m_pProcessList or m_pNext of some entry. + // It is used to fix the linked list after deletion of an entry. + ProcessEntry **prevPtr = &m_pProcessList; - lock.Release(); + // Looking for ProcessEntry with a given transport + while (entry) + { - // If we made the transport inaccessible above we can shut it down and deallocate it now. - if (pTransportToShutdown) - { - pTransportToShutdown->Shutdown(); - delete pTransportToShutdown; - } + _ASSERTE(entry->m_cProcessRef > 0); + _ASSERTE(entry->m_transport != NULL); + _ASSERTE(entry->m_hProcess > 0); - return; - } + if (entry->m_transport == pTransport) + { + // Mark that it has one less holder now + entry->m_cProcessRef--; - pRuntime = pRuntime->m_pNext; + // If no more holders remove the entry from the list and free resources + if (entry->m_cProcessRef == 0) + { + *prevPtr = entry->m_pNext; + delete entry; } - - pProcess = pProcess->m_pNext; + return; } - } // Leave lock + prevPtr = &entry->m_pNext; + entry = entry->m_pNext; + } - _ASSERTE(!"Failed to find ProcessEntry to release transport reference"); + _ASSERTE(!"Trying to release transport that doesn't belong to this DbgTransportTarget"); + pTransport->Shutdown(); + delete pTransport; } -// Run the command line given on the remote machine to create a process. Return the PID of this process. When -// and if the process starts a runtime and registers with the proxy it will be told to halt and wait for a -// debugger attach. -HRESULT DbgTransportTarget::CreateProcess(LPCWSTR wszCommand, - LPCWSTR wszArgs, - LPCWSTR wszCurrentDirectory, - LPVOID pvEnvironment, - DWORD *pdwPID) +HRESULT DbgTransportTarget::CreateProcess(LPCWSTR lpApplicationName, + LPCWSTR lpCommandLine, + LPSECURITY_ATTRIBUTES lpProcessAttributes, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + BOOL bInheritHandles, + DWORD dwCreationFlags, + LPVOID lpEnvironment, + LPCWSTR lpCurrentDirectory, + LPSTARTUPINFOW lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInformation) { - if (m_fProxyConnectionBad) - return E_ABORT; - DWORD cchCommand = wszCommand ? wcslen(wszCommand) : 0; - DWORD cchArgs = wszArgs ? wcslen(wszArgs) : 0; + BOOL result = WszCreateProcess(lpApplicationName, + lpCommandLine, + lpProcessAttributes, + lpThreadAttributes, + bInheritHandles, + dwCreationFlags, + lpEnvironment, + lpCurrentDirectory, + lpStartupInfo, + lpProcessInformation); - // Proxy expects the command line as a single string. - LPWSTR wszCommandLine = (LPWSTR)_alloca((cchCommand + 1 + cchArgs + 1) * sizeof(WCHAR)); - wszCommandLine[0] = W('\0'); - if (wszCommand) + if (!result) { - wcscat(wszCommandLine, wszCommand); - wcscat(wszCommandLine, W(" ")); + return HRESULT_FROM_GetLastError(); } - if (wszArgs) - wcscat(wszCommandLine, wszArgs); - // Check how big a UTF8 version of the command line would be. - int cbReqd = WszWideCharToMultiByte(CP_UTF8, 0, wszCommandLine, -1, 0, 0, 0, 0); - - LPSTR szCommandLine = (LPSTR)_alloca(cbReqd); - - // Do the conversion from 16-bit. - WszWideCharToMultiByte(CP_UTF8, 0, wszCommandLine, -1, szCommandLine, cbReqd, 0, 0); - - // If a default directory is supplied then convert it to UTF8. - LPSTR szCurrentDirectory = NULL; - if (wszCurrentDirectory) - { - cbReqd = WszWideCharToMultiByte(CP_UTF8, 0, wszCurrentDirectory, -1, 0, 0, 0, 0); - szCurrentDirectory = (LPSTR)_alloca(cbReqd); - WszWideCharToMultiByte(CP_UTF8, 0, wszCurrentDirectory, -1, szCurrentDirectory, cbReqd, 0, 0); - } - - // Prepare to format an attribute block containing all the launch parameters we'll send to the proxy. - // There are two phases: first we plan how much space will be required in the block then we allocate the - // block and fill it in. - DbgAttributeBlockWriter sAttrWriter; - - sAttrWriter.ScheduleStringValue(szCommandLine); - - if (szCurrentDirectory) - sAttrWriter.ScheduleStringValue(szCurrentDirectory); - - // Determine how large the environment block is (if it's supplied). - DWORD cbEnvironment = 0; - if (pvEnvironment) - { - char *szEnv = (char *)pvEnvironment; - - // The environment is a series of nul-terminated strings followed by a final nul. - while (*szEnv) - { - DWORD cbString = strlen(szEnv) + 1; - cbEnvironment += cbString; - szEnv += cbString; - } - - // Account for final nul. - cbEnvironment++; - } - - if (cbEnvironment) - sAttrWriter.ScheduleValue(cbEnvironment); - - // By now we know how large an attribute block we need. - DWORD cbAttributeBlock = sAttrWriter.GetRequiredBufferSize(); - BYTE *pbAttributeBlock = new (nothrow) BYTE[cbAttributeBlock]; - if (pbAttributeBlock == NULL) - return E_OUTOFMEMORY; - - // Initialize the attribute block. - sAttrWriter.BeginFormatting((char*)pbAttributeBlock); - - sAttrWriter.AddStringValue(DAT_CommandLine, szCommandLine); - if (szCurrentDirectory) - sAttrWriter.AddStringValue(DAT_DefaultDirectory, szCurrentDirectory); - if (cbEnvironment) - sAttrWriter.AddValue(DAT_Environment, (char*)pvEnvironment, cbEnvironment); - - // Allocate a new process entry up front (but don't link it into the list until we know we've created the - // remote process). - ProcessEntry *pProcess = new (nothrow) ProcessEntry(); - if (pProcess == NULL) - { - delete [] pbAttributeBlock; - return E_OUTOFMEMORY; - } - memset(pProcess, 0, sizeof(ProcessEntry)); - - strncpy(pProcess->m_szCommandLine, szCommandLine, kMaxCommandLine); - pProcess->m_szCommandLine[kMaxCommandLine - 1] = '\0'; - - pProcess->m_hExitedEvent = WszCreateEvent(NULL, TRUE, FALSE, NULL); // Manual reset, not signalled - if (pProcess->m_hExitedEvent == NULL) - { - delete [] pbAttributeBlock; - delete pProcess; - return E_OUTOFMEMORY; - } - - pProcess->m_hRuntimeStartedEvent = WszCreateEvent(NULL, TRUE, FALSE, NULL); // Manual reset, not signalled - if (pProcess->m_hRuntimeStartedEvent == NULL) - { - delete [] pbAttributeBlock; - delete pProcess; - return E_OUTOFMEMORY; - } - - // Send the launch request to the proxy. It will reply with a PID or an hresult on failure. - HRESULT hr = MakeProxyRequest(DPMT_LaunchProcess, - pbAttributeBlock, - &pProcess->m_dwPID, - &pProcess->m_pruidProcess); - - delete [] pbAttributeBlock; - - if (SUCCEEDED(hr)) - { - // The remote process has been created. - *pdwPID = pProcess->m_dwPID; - - // Take the lock and check whether we already have an entry for this process (this can happen due to - // an EnumProcesses from another thread). - { - RSLockHolder lock(&m_sLock); - ProcessEntry *pSearchProcess = m_pProcessList; - while (pSearchProcess) - { - if (pSearchProcess->m_pruidProcess == pProcess->m_pruidProcess) - break; - pSearchProcess = pSearchProcess->m_pNext; - } - - if (pSearchProcess) - { - // Someone else has already made the update. Discard our unneeded copy. - delete pProcess; - } - else - { - // No current entry for this process, link it in. - pProcess->m_pNext = m_pProcessList; - m_pProcessList = pProcess; - } - } // Leave lock - } - else - { - // The process was not created, throw away the process entry we'd prepared. - delete pProcess; - } - - return hr; + return S_OK; } // Kill the process identified by PID. void DbgTransportTarget::KillProcess(DWORD dwPID) { - if (m_fProxyConnectionBad) - return; - - PRUID pruidTarget = 0; - - // Look up the process by PID so we can find the corresponding PRUID (which is the proxy's version of the - // PID). - { - RSLockHolder lock(&m_sLock); - ProcessEntry *pProcess = LocateProcessByPID(dwPID); - if (pProcess) - pruidTarget = pProcess->m_pruidProcess; - } // Leave lock - - if (pruidTarget) + HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, dwPID); + if (hProcess != NULL) { - HRESULT hr = MakeProxyRequest(DPMT_TerminateProcess, pruidTarget); - if (FAILED(hr)) - { - // Network failure could prevent our terminate from getting through. We don't currently support - // rebuilding a network connection and retrying, so report the process as dead to prevent a hang - // in the debugger on this end. - RSLockHolder lock(&m_sLock); - ProcessEntry *pProcess = LocateProcessByPID(dwPID); - if (pProcess) - { - pProcess->m_fExited = true; - SetEvent(pProcess->m_hExitedEvent); - } - } // Leave lock + TerminateProcess(hProcess, 0); + CloseHandle(hProcess); } } -// Ask the remote debugger proxy for an updated list of processes and reflect these changes into our local -// process list. Any failure will leave the current process list state unchanged. -void DbgTransportTarget::UpdateProcessList() +DbgTransportTarget::ProcessEntry::~ProcessEntry() { - // As an optimization, don't update the process list more than once a second. - if ((CLRGetTickCount64() - m_ullLastUpdate) <= 1000) - return; - m_ullLastUpdate = CLRGetTickCount64(); + CloseHandle(m_hProcess); + m_hProcess = NULL; - // Send message to the proxy asking for a list of processes and CoreCLR instances. By the time the - // MakeProxyRequest request call below completes the process/runtime database will have been updated. - MakeProxyRequest(DPMT_EnumProcesses); + m_transport->Shutdown(); + delete m_transport; + m_transport = NULL; } // Locate a process entry by PID. Assumes the lock is already held. @@ -884,1031 +230,4 @@ DbgTransportTarget::ProcessEntry *DbgTransportTarget::LocateProcessByPID(DWORD d return NULL; } -DbgTransportTarget::RuntimeEntry::~RuntimeEntry() -{ - // If there's still a transport attached to the remote runtime shut it down and delete it. - if (m_pDbgTransport) - { - m_pDbgTransport->Shutdown(); - delete m_pDbgTransport; - } -} - -DbgTransportTarget::ProcessEntry::~ProcessEntry() -{ - // Clean up any records for runtimes hosted within this process. - while (m_pRuntimes) - { - RuntimeEntry *pDelRuntime = m_pRuntimes; - m_pRuntimes = m_pRuntimes->m_pNext; - delete pDelRuntime; - } - - if (m_hExitedEvent) - CloseHandle(m_hExitedEvent); - - if (m_hRuntimeStartedEvent) - CloseHandle(m_hRuntimeStartedEvent); -} - -// Deallocate all resources associated with a process list. -void DbgTransportTarget::DeallocateProcessList(ProcessEntry *pProcessList) -{ - while (pProcessList) - { - ProcessEntry *pDelProcess = pProcessList; - pProcessList = pProcessList->m_pNext; - delete pDelProcess; - } -} - -// Format and send a request to the proxy then wait on a reply (if appropriate) and return results to the -// caller. -HRESULT DbgTransportTarget::MakeProxyRequest(DbgProxyMessageType eType, ...) -{ - va_list args; - - va_start(args, eType); - - // We allocate space for some request related context on the stack. For the duration of the request (until - // a reply is received) this context is linked on a global request queue so the process event thread can - // handle matching replies to requests. - Request sRequest; - sRequest.m_pNext = NULL; - sRequest.m_hrResult = S_OK; - - // DPMT_TerminateProcess requests don't expect a reply. - if (eType != DPMT_TerminateProcess) - { - sRequest.m_hCompletionEvent = WszCreateEvent(NULL, FALSE, FALSE, NULL); // Auto-reset, not signalled - if (sRequest.m_hCompletionEvent == NULL) - return E_OUTOFMEMORY; - } - else - sRequest.m_hCompletionEvent = NULL; - - // Space for the message header. - DbgProxyMessageHeader sMessage; - - // Format common message fields. - memset(&sMessage, 0, sizeof(sMessage)); - sMessage.m_eType = eType; - - // Based on request type fill in the remainder of the request fields and record the addresses of the - // caller's output buffer(s) if any. - BYTE *pbAttributeBlock = NULL; - DWORD cbAttributeBlock = 0; - switch (eType) - { - case DPMT_GetSystemInfo: - DbgTransportLog(LC_Always, "Sending 'GetSystemInfo'"); - sMessage.VariantData.GetSystemInfo.m_uiMajorVersion = kCurrentMajorVersion; - sMessage.VariantData.GetSystemInfo.m_uiMinorVersion = kCurrentMinorVersion; - sRequest.OutputBuffers.GetSystemInfo.m_pdwMajorVersion = va_arg(args, DWORD*); - sRequest.OutputBuffers.GetSystemInfo.m_pdwMinorVersion = va_arg(args, DWORD*); - sRequest.OutputBuffers.GetSystemInfo.m_pePlatform = va_arg(args, DbgTargetPlatform*); - break; - - case DPMT_EnumProcesses: - DbgTransportLog(LC_Always, "Sending 'EnumProcesses'"); - break; - - case DPMT_LaunchProcess: - { - DbgTransportLog(LC_Always, "Sending 'LaunchProcess'"); - pbAttributeBlock = va_arg(args, BYTE*); - DbgAttributeBlockReader sAttrReader((char*)pbAttributeBlock); - cbAttributeBlock = sAttrReader.GetBlockSize(); - sMessage.VariantData.LaunchProcess.m_cbAttributeBlock = cbAttributeBlock; - sRequest.OutputBuffers.LaunchProcess.m_pdwPID = va_arg(args, DWORD*); - sRequest.OutputBuffers.LaunchProcess.m_ppruidProcess = va_arg(args, PRUID*); - break; - } - - case DPMT_EarlyAttach: - DbgTransportLog(LC_Always, "Sending 'EarlyAttach'"); - sMessage.VariantData.EarlyAttach.m_pruidProcess = va_arg(args, DWORD); - sRequest.OutputBuffers.EarlyAttach.m_pfProcessExited = va_arg(args, bool*); - break; - - case DPMT_TerminateProcess: - DbgTransportLog(LC_Always, "Sending 'TerminateProcess'"); - sMessage.VariantData.TerminateProcess.m_pruidProcess = va_arg(args, DWORD); - break; - - default: - _ASSERTE(!"Illegal message type for MakeProxyRequest"); - va_end(args); - return E_FAIL; - } - va_end(args); - - // We must hold the lock in order to send messages, allocate request IDs or touch the request queue. - { - RSLockHolder lock(&m_sLock); - - // While under the lock we can check the connection state without races. We either see the connection - // state is bad and abort the operation now or we successfully queue the request (in which case it is - // the process event thread's responsibility to abort the request if an error occurs). - if (m_fProxyConnectionBad) - { - if (sRequest.m_hCompletionEvent) - CloseHandle(sRequest.m_hCompletionEvent); - return E_ABORT; - } - - // Allocate a request ID and add the request to the queue (except for messages that don't expect a - // reply). - if (sRequest.m_hCompletionEvent != NULL) - { - // Allocate a unique ID for this request. This will allow us to match the reply that comes back. - sRequest.m_dwID = sMessage.m_uiRequestID = m_dwNextRequestID++; - - // The request queue is not ordered, so just place the new request at the head. - sRequest.m_pNext = m_pRequestList; - m_pRequestList = &sRequest; - } - else - sMessage.m_uiRequestID = 0; - - // Now the type and request ID have been filled in we can calculate the value of the magic field used - // as an extra layer of validation in the message format. - sMessage.m_uiMagic = DBGPROXY_MAGIC_VALUE(&sMessage); - - // Send the message header. - if (!m_pConnection->Send((unsigned char*)&sMessage, sizeof(sMessage))) - { - DbgTransportLog(LC_Always, "DbgTransportTarget::MakeProxyRequest(): Send() failed"); - if (sRequest.m_hCompletionEvent) - { - m_pRequestList = sRequest.m_pNext; - CloseHandle(sRequest.m_hCompletionEvent); - } - - return E_ABORT; - } - - // Launch requests have additional data (an attribute block). - if (eType == DPMT_LaunchProcess) - { - _ASSERTE(pbAttributeBlock && cbAttributeBlock); - - if (!m_pConnection->Send(pbAttributeBlock, cbAttributeBlock)) - { - DbgTransportLog(LC_Always, "DbgTransportTarget::MakeProxyRequest(): Send() failed"); - - m_pRequestList = sRequest.m_pNext; - CloseHandle(sRequest.m_hCompletionEvent); - - return E_ABORT; - } - } - - } // Leave lock - - // We're done if we don't expect a reply. - if (sRequest.m_hCompletionEvent == NULL) - return S_OK; - - // Now wait on the completion event (this will be signalled by the process event thread once it has - // matched a reply to our request successfully). - WaitForSingleObject(sRequest.m_hCompletionEvent, INFINITE); - - // No more need for the completionm event. - CloseHandle(sRequest.m_hCompletionEvent); - - // Return the completion result from the transmission record. - return sRequest.m_hrResult; -} - -// Static entry point for the process event thread. -DWORD WINAPI DbgTransportTarget::ProcessEventWorkerStatic(LPVOID lpvContext) -{ - // Just dispatch straight to the version that's an instance method. - ((DbgTransportTarget*)lpvContext)->ProcessEventWorker(); - return 0; -} - -// Instance method version of the worker, called from ProcessEventWorkerStatic(). -void DbgTransportTarget::ProcessEventWorker() -{ - // Loop handling requests until we're told to shutdown or hit a network error. - while (!m_fShutdown) - { - // How the worker reacts to the incoming data is driven by shared state set up by other threads in - // this process calling MakeProxyRequest(). These calls cause a message to be sent directly to the - // proxy but also set up state so that this thread will know how to dispatch replies from the proxy - // back to the originating thread. - - // There are three sizes of message that we can receive: most messages will fit in the common message - // header but DPMT_RuntimeStarted needs something a little larger (an additional DbgProxyRuntimeInfo - // structure) and DPMT_ProcessList includes an variable sized list of process and runtime records. - // Allocate storage for a common header on the stack and always receive the header into this. We'll - // handle any extra data required on a case by case basis (which is easy since there's no requirement - // to actually assemble the incoming message into a single contiguous buffer at any point). - DbgProxyMessageHeader sMessage; - - if (!m_pConnection->Receive((unsigned char *)&sMessage, sizeof(sMessage))) - { - DbgTransportLog(LC_Always, "DbgTransportTarget: Receive() failed"); - goto NetworkError; - } - - // Validate the magic number in the header that we use as an additional check of the messages's - // integrity (this makes it much harder to launch a network attack based on sending random data). - if (sMessage.m_uiMagic != DBGPROXY_MAGIC_VALUE(&sMessage)) - { - DbgTransportLog(LC_Always, "DbgTransportTarget: message failed magic number test"); - goto NetworkError; - } - - // Most of the incoming messages are replies to requests that we have on our request queue. Locate the - // original request (keyed off the ID returned in the reply). - Request *pRequest = NULL; - if (sMessage.m_eType != DPMT_RuntimeStarted && - sMessage.m_eType != DPMT_ProcessTerminated) - { - pRequest = LocateOriginalRequest(&sMessage); - if (pRequest == NULL) - { - DbgTransportLog(LC_Always, "DbgTransportTarget: can't find request for reply %u", - (unsigned)sMessage.m_uiRequestID); - goto NetworkError; - } - } - - // Process the rest of the message based on the type. - switch (sMessage.m_eType) - { - case DPMT_SystemInfo: - DbgTransportLog(LC_Always, "Received 'SystemInfo'"); - PREFIX_ASSUME(pRequest != NULL); - - *pRequest->OutputBuffers.GetSystemInfo.m_pdwMajorVersion = - sMessage.VariantData.SystemInfo.m_uiMajorVersion; - *pRequest->OutputBuffers.GetSystemInfo.m_pdwMinorVersion = - sMessage.VariantData.SystemInfo.m_uiMinorVersion; - *pRequest->OutputBuffers.GetSystemInfo.m_pePlatform = - sMessage.VariantData.SystemInfo.m_ePlatform; - break; - - case DPMT_ProcessList: - DbgTransportLog(LC_Always, "Received 'ProcessList(%u, %u)'", - (unsigned)sMessage.VariantData.ProcessList.m_uiProcessRecords, - (unsigned)sMessage.VariantData.ProcessList.m_uiRuntimeRecords); - PREFIX_ASSUME(pRequest != NULL); - - ProcessProcessList(&sMessage, pRequest); - if (FAILED(pRequest->m_hrResult)) - goto NetworkError; - break; - - case DPMT_ProcessLaunched: - DbgTransportLog(LC_Always, "Received 'ProcessLaunched'"); - PREFIX_ASSUME(pRequest != NULL); - - // We successfully launched a process remotely (or an error code indicating why we could not). - // On success copy PID and PRUID of the new process back to the requester. - switch (sMessage.VariantData.ProcessLaunched.m_eResult) - { - case DPLR_Success: - pRequest->m_hrResult = S_OK; - *pRequest->OutputBuffers.LaunchProcess.m_pdwPID = - sMessage.VariantData.ProcessLaunched.m_uiPID; - *pRequest->OutputBuffers.LaunchProcess.m_ppruidProcess = - sMessage.VariantData.ProcessLaunched.m_pruidProcess; - break; - case DPLR_OutOfMemory: - pRequest->m_hrResult = E_OUTOFMEMORY; - break; - case DPLR_Denied: - pRequest->m_hrResult = E_ACCESSDENIED; - break; - case DPLR_NotFound: - pRequest->m_hrResult = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); - break; - case DPLR_UnspecifiedError: - pRequest->m_hrResult = E_FAIL; - break; - default: - _ASSERTE(!"Unknown ProcessLaunched result code"); - pRequest->m_hrResult = E_FAIL; - } - break; - - case DPMT_RuntimeStarted: - { - DbgTransportLog(LC_Always, "Received 'RuntimeStarted'"); - - // RuntimeStarted sends a process info block as well as runtime info (in case the process is new - // as well). - - // Read DbgProxyProcessInfo structure. - DbgProxyProcessInfo sProcessInfo; - if (!m_pConnection->Receive((unsigned char *)&sProcessInfo, sizeof(sProcessInfo))) - { - DbgTransportLog(LC_Always, "DbgTransportTarget: Receive() failed"); - goto NetworkError; - } - - // Read DbgProxyRuntimeInfo structure. - DbgProxyRuntimeInfo sRuntimeInfo; - if (!m_pConnection->Receive((unsigned char *)&sRuntimeInfo, sizeof(sRuntimeInfo))) - { - DbgTransportLog(LC_Always, "DbgTransportTarget: Receive() failed"); - goto NetworkError; - } - - // A runtime has started up in some process on the target machine. - // Add a runtime record to our database (if it's not already there). - if (!ProcessRuntimeStarted(&sProcessInfo, &sRuntimeInfo)) - goto NetworkError; - break; - } - - case DPMT_ProcessTerminated: - { - DbgTransportLog(LC_Always, "Received 'ProcessTerminated'"); - - // A process has terminated on the target machine. - // See if we were tracking the process on our side and if so either delete the entry (if it's - // not being used) or fire the process termination event. - { - RSLockHolder lock(&m_sLock); - - ProcessEntry *pProcess = m_pProcessList; - ProcessEntry *pLastProcess = NULL; - while (pProcess) - { - if (pProcess->m_pruidProcess == sMessage.VariantData.ProcessTerminated.m_pruidProcess) - { - // Found a matching entry. Is it in use? - if (pProcess->m_cProcessRef > 0) - { - // Can't delete the entry. Signal the process exited event (which will move some - // users off). - SetEvent(pProcess->m_hExitedEvent); - pProcess->m_fExited = true; - } - else - { - // Nobody's using this process entry, we can unlink and deallocate it. - if (pLastProcess) - pLastProcess->m_pNext = pProcess->m_pNext; - else - m_pProcessList = pProcess->m_pNext; - delete pProcess; - } - break; - } - pLastProcess = pProcess; - pProcess = pProcess->m_pNext; - } - } // Leave lock - break; - } - - case DPMT_EarlyAttachDone: - DbgTransportLog(LC_Always, "Received 'EarlyAttachDone(%s)'", - sMessage.VariantData.EarlyAttachDone.m_fProcessExited ? "dead" : "alive"); - PREFIX_ASSUME(pRequest != NULL); - - // The only thing we need to do here is pass back the indication of whether the process - // managed to exit before the attach was registered. - *pRequest->OutputBuffers.EarlyAttach.m_pfProcessExited = - sMessage.VariantData.EarlyAttachDone.m_fProcessExited; - break; - - default: - _ASSERTE(!"Invalid message typr"); - } - - // If this was a reply then the original request has been updated at this point. We only need to - // remove it from the global queue and signal the completion event to unblock the requesting thread. - if (pRequest) - { - RSLockHolder lock(&m_sLock); - - // Look for the previous item in the queue. - Request *pSearchRequest = m_pRequestList; - while (pSearchRequest) - { - if (pSearchRequest->m_pNext == pRequest) - { - pSearchRequest->m_pNext = pRequest->m_pNext; - break; - } - pSearchRequest = pSearchRequest->m_pNext; - } - - // No match, maybe the transmission was at the head of the queue. - if (pSearchRequest == NULL) - { - _ASSERTE(m_pRequestList == pRequest); - m_pRequestList = pRequest->m_pNext; - } - - // Now complete the request to the caller. - SetEvent(pRequest->m_hCompletionEvent); - } // Leave lock - - // Loop round for the next message. - } - - NetworkError: - - // We get here if we were asked to shutdown or hit a network error. - m_fProxyConnectionBad = true; - - // Abort any outstanding requests. - { - RSLockHolder lock(&m_sLock); - - Request *pRequest = m_pRequestList; - while (pRequest) - { - Request *pAbortRequest = pRequest; - pRequest = pRequest->m_pNext; - - pAbortRequest->m_hrResult = E_ABORT; - SetEvent(pAbortRequest->m_hCompletionEvent); - } - } // Leave lock - - // If this isn't shutdown (i.e. we got here as the result of a network error) run through the process list - // and report them all as terminated (better than having the debugger time-out some request and then hang - // forever as it tries to terminate the process itself). - if (!m_fShutdown) - { - for (ProcessEntry *pProcess = m_pProcessList; pProcess; pProcess = pProcess->m_pNext) - { - if (!pProcess->m_fExited) - { - pProcess->m_fExited = true; - SetEvent(pProcess->m_hExitedEvent); - } - } - } -} - -// If this message is a reply to a right-side request locate that request. Otherwise return NULL. -DbgTransportTarget::Request *DbgTransportTarget::LocateOriginalRequest(DbgProxyMessageHeader *pMessage) -{ - // Search the request queue for a matching ID. - Request *pRequest; - { - RSLockHolder lock(&m_sLock); - - pRequest = m_pRequestList; - while (pRequest) - { - if (pRequest->m_dwID == pMessage->m_uiRequestID) - break; - pRequest = pRequest->m_pNext; - } - } // Leave lock - - return pRequest; -} - -// Process an incoming ProcessList message. -void DbgTransportTarget::ProcessProcessList(DbgProxyMessageHeader *pMessage, - Request *pRequest) -{ - // The message header is followed by a sequence of DbgProxyProcessInfo records then a sequence of - // DbgProxyRuntimeInfo records. The lengths of both of these sequences are provided in the header. - DWORD cProcessRecords = pMessage->VariantData.ProcessList.m_uiProcessRecords; - DWORD cRuntimeRecords = pMessage->VariantData.ProcessList.m_uiRuntimeRecords; - - // Impose some reasonable bounds to catch badly formed replies (and so we don't have to worry about - // integer overflow in the allocation code that follows). - if (cProcessRecords > 1024 || cRuntimeRecords > 1024) - { - _ASSERTE(!"Badly formed ProcessList message"); - pRequest->m_hrResult = E_UNEXPECTED; - return; - } - - // Allocate space for all the process and runtime records in one contiguous block. - DWORD cbRecordBuffer = (cProcessRecords * sizeof(DbgProxyProcessInfo)) + - (cRuntimeRecords * sizeof(DbgProxyRuntimeInfo)); - BYTE *pbRecordBuffer = new (nothrow) BYTE[cbRecordBuffer]; - if (pbRecordBuffer == NULL) - { - DbgTransportLog(LC_Always, "Failed to allocate memory for %u process records and %u runtime records", - cProcessRecords, cRuntimeRecords); - pRequest->m_hrResult = E_OUTOFMEMORY; - return; - } - - DbgProxyProcessInfo *pProcessRecords = (DbgProxyProcessInfo*)pbRecordBuffer; - DbgProxyRuntimeInfo *pRuntimeRecords = (DbgProxyRuntimeInfo*)(pProcessRecords + cProcessRecords); - - // If we've gotten to this point we believe the message looks valid and we have all resources - // allocated necessary to receive the response for this portion of the reply. - if (!m_pConnection->Receive(pbRecordBuffer, cbRecordBuffer)) - { - DbgTransportLog(LC_Always, "ProcessProcessList: Receive() failed"); - pRequest->m_hrResult = E_FAIL; - return; - } - - // Now parse the records and make any necessary updates to the cached process/runtime state we already - // have. - { - RSLockHolder lock(&m_sLock); - - // First we walk the current list of processes and mark each entry as potentially removeable. This is - // part of the algorithm to detect processes which have terminated, see the next stage for the rest. - ProcessEntry *pProcess = m_pProcessList; - while (pProcess) - { - pProcess->m_fRemove = true; - pProcess = pProcess->m_pNext; - } - - // Next we traverse the incoming list of process records, determining which we already know about - // (and marking the corresponding ProcessEntry) and those that are new (for which we create new - // ProcessEntry structures). - for (DWORD i = 0; i < cProcessRecords; i++) - { - // See if we can locate an existing ProcessEntry (i.e. one with the same PRUID as the current - // process record). - pProcess = m_pProcessList; - while (pProcess) - { - if (pProcess->m_pruidProcess == pProcessRecords[i].m_pruidProcess) - { - _ASSERTE(pProcess->m_dwPID == pProcessRecords[i].m_uiPID); - - // We've found a match so we indicate that this ProcessEntry is still live. - pProcess->m_fRemove = false; - break; - } - - pProcess = pProcess->m_pNext; - } - - // If we didn't find a matching ProcessEntry create one now. - if (pProcess == NULL) - { - pProcess = new (nothrow) ProcessEntry(); - if (pProcess == NULL) - goto FailedUpdate; - - pProcess->m_pNext = m_pProcessList; - pProcess->m_dwPID = pProcessRecords[i].m_uiPID; - pProcess->m_pruidProcess = pProcessRecords[i].m_pruidProcess; - strcpy_s(pProcess->m_szCommandLine, kMaxCommandLine, pProcessRecords[i].m_szCommandLine); - pProcess->m_pRuntimes = NULL; - pProcess->m_hExitedEvent = NULL; - pProcess->m_hRuntimeStartedEvent = NULL; - pProcess->m_fExited = false; - pProcess->m_fRemove = false; - pProcess->m_cProcessRef = 0; - - // Allocate event used to signal this process' termination. - pProcess->m_hExitedEvent = WszCreateEvent(NULL, TRUE, FALSE, NULL); // Manual reset, not signalled - if (pProcess->m_hExitedEvent == NULL) - { - delete pProcess; - goto FailedUpdate; - } - - // Allocate event used to signal the first runtime has started within this process. - pProcess->m_hRuntimeStartedEvent = WszCreateEvent(NULL, TRUE, FALSE, NULL); // Manual reset, not signalled - if (pProcess->m_hRuntimeStartedEvent == NULL) - { - delete pProcess; - goto FailedUpdate; - } - - // Link the new process entry to the database. - m_pProcessList = pProcess; - } - } - - // Now walk the updated ProcessEntry structures. Each that wasn't marked as being present in the - // incoming process infos indicates a dead process. We either remove such entries or, if they're being - // used currently (have a connected debugger session etc.), we simply mark them as dead so they won't - // appear in process enumerations and we'll delete them as soon as their use count falls to zero. - pProcess = m_pProcessList; - ProcessEntry *pLastProcess = NULL; - while (pProcess) - { - if (pProcess->m_fRemove) - { - // The process has terminated. Can we release the ProcessEntry yet? - if (pProcess->m_cProcessRef == 0) - { - // Nobody is using the process, we can get rid of it. - - // Unlink the entry from the list. - if (pLastProcess) - pLastProcess->m_pNext = pProcess->m_pNext; - else - m_pProcessList = pProcess->m_pNext; - - // Since we've removed this entry from the list the last entry remains the same for the - // next iteration of the loop. We have to extract the next entry from the current one - // before we deallocate it. - ProcessEntry *pDeleteEntry = pProcess; - pProcess = pProcess->m_pNext; - - // Finally we can delete the current entry (this automatically takes care of any runtime - // entries and other process entry owned resources). - delete pDeleteEntry; - - continue; - } - else - { - // Process is in use. Simply mark it as exited for now. - pProcess->m_fExited = true; - SetEvent(pProcess->m_hExitedEvent); - } - } - - pLastProcess = pProcess; - pProcess = pProcess->m_pNext; - } - - // Next we walk the incoming runtime records. Here we're just looking for new runtimes to add since we - // don't currently support shutting down a runtime without terminating the process. - for (DWORD i = 0; i < cRuntimeRecords; i++) - { - // First find the parent ProcessEntry record. This must exist (if the proxy sent a runtime record - // it must send the parent process record). - pProcess = m_pProcessList; - while (pProcess) - { - if (pProcess->m_pruidProcess == pRuntimeRecords[i].m_pruidProcess) - { - pProcess->m_fRemove = false; - break; - } - - pProcess = pProcess->m_pNext; - } - PREFIX_ASSUME(pProcess != NULL); - - // Walk the list of RuntimeEntry records associated with this ProcessEntry to see if we already - // have this entry. - RuntimeEntry *pRuntime = pProcess->m_pRuntimes; - while (pRuntime) - { - if (pRuntime->m_pruidRuntime == pRuntimeRecords[i].m_pruidRuntime) - { - // We already have this entry. - _ASSERTE(pRuntime->m_usPort == pRuntimeRecords[i].m_usPort); - break; - } - - pRuntime = pRuntime->m_pNext; - } - - // If this is a new runtime add a corresponding RuntimeEntry. - if (pRuntime == NULL) - { - pRuntime = new (nothrow) RuntimeEntry(); - if (pRuntime == NULL) - goto FailedUpdate; - - pRuntime->m_pruidRuntime = pRuntimeRecords[i].m_pruidRuntime; - pRuntime->m_usPort = pRuntimeRecords[i].m_usPort; - pRuntime->m_pDbgTransport = NULL; - pRuntime->m_cTransportRef = 0; - - // Link the runtime entry onto the process. - pRuntime->m_pNext = pProcess->m_pRuntimes; - pProcess->m_pRuntimes = pRuntime; - - // Since there's at least one runtime for this process make sure the runtime started event is set. - SetEvent(pProcess->m_hRuntimeStartedEvent); - } - } - } - - // We're done, all incoming data has been consumed. - delete [] pbRecordBuffer; - return; - - FailedUpdate: - pRequest->m_hrResult = E_OUTOFMEMORY; - delete [] pbRecordBuffer; -} - -// Process an incoming RuntimeStarted datagram. -bool DbgTransportTarget::ProcessRuntimeStarted(DbgProxyProcessInfo *pProcessInfo, - DbgProxyRuntimeInfo *pRuntimeInfo) -{ - // A runtime has started up in some process on the target machine. - // Add a runtime record to our database (if it's not already there). - { - RSLockHolder lock(&m_sLock); - - // Search for the parent process in our list. - ProcessEntry *pProcess = m_pProcessList; - while (pProcess) - { - if (pProcess->m_pruidProcess == pRuntimeInfo->m_pruidProcess) - break; - pProcess = pProcess->m_pNext; - } - - DbgTransportLog(LC_Always, "Processing 'RuntimeStarted' for (%u, %u, %u)", - (unsigned)pProcessInfo->m_uiPID, - (PRUID)pRuntimeInfo->m_pruidProcess, - (PRUID)pRuntimeInfo->m_pruidRuntime); - - // If we haven't recorded the process yet create an entry for it. - if (pProcess == NULL) - { - pProcess = new (nothrow) ProcessEntry(); - if (pProcess == NULL) - return false; - - DbgTransportLog(LC_Always, " No existing process record, created %08X", pProcess); - - memset(pProcess, 0, sizeof(ProcessEntry)); - pProcess->m_dwPID = pProcessInfo->m_uiPID; - pProcess->m_pruidProcess = pProcessInfo->m_pruidProcess; - strcpy(pProcess->m_szCommandLine, pProcessInfo->m_szCommandLine); - - pProcess->m_hExitedEvent = WszCreateEvent(NULL, TRUE, FALSE, NULL); // Manual reset, not signalled - if (pProcess->m_hExitedEvent == NULL) - { - delete pProcess; - return false; - } - - pProcess->m_hRuntimeStartedEvent = WszCreateEvent(NULL, TRUE, FALSE, NULL); // Manual reset, not signalled - if (pProcess->m_hRuntimeStartedEvent == NULL) - { - delete pProcess; - return false; - } - - // Link the new process entry into the list. - pProcess->m_pNext = m_pProcessList; - m_pProcessList = pProcess; - } - else - DbgTransportLog(LC_Always, " Found existing process record %08X", pProcess); - - // Now we have a process record we can look for a runtime entry. - RuntimeEntry *pRuntime = pProcess->m_pRuntimes; - while (pRuntime) - { - if (pRuntime->m_pruidRuntime == pRuntimeInfo->m_pruidRuntime) - break; - pRuntime = pRuntime->m_pNext; - } - - // If we didn't have an entry for this runtime create one now. - if (pRuntime == NULL) - { - pRuntime = new (nothrow) RuntimeEntry(); - if (pRuntime == NULL) - return false; - - DbgTransportLog(LC_Always, " No existing runtime record, created %08X", pRuntime); - - pRuntime->m_pruidRuntime = pRuntimeInfo->m_pruidRuntime; - pRuntime->m_usPort = pRuntimeInfo->m_usPort; - pRuntime->m_pDbgTransport = NULL; - pRuntime->m_cTransportRef = 0; - - // Link the runtime entry onto the process. - pRuntime->m_pNext = pProcess->m_pRuntimes; - pProcess->m_pRuntimes = pRuntime; - - // Since there's at least one runtime for this process make sure the runtime started event is set. - SetEvent(pProcess->m_hRuntimeStartedEvent); - } - else - DbgTransportLog(LC_Always, " Found existing runtime record %08X", pRuntime); - } // Leave lock - - return true; -} - -// A version of EnumProcesses used when we're controlled by the Visual Studio debugger. This API is exposed to -// our port supplier implementation via the ICoreClrDebugTarget interface implemented by the -// CoreClrDebugTarget class implemented in DbgTransportManager.cpp. -HRESULT DbgTransportTarget::EnumProcessesForVS(DWORD *pcProcs, CoreClrDebugProcInfo **ppProcs) -{ - *pcProcs = 0; - *ppProcs = NULL; - - // Update our process and runtime view from the remote target. - UpdateProcessList(); - - // Acquire the lock to get a consistent view of current state. - { - RSLockHolder lock(&m_sLock); - - ProcessEntry *pProcess; - DWORD cProcesses = 0; - - // Count the number of processes we know about. - for (pProcess = m_pProcessList; pProcess; pProcess = pProcess->m_pNext) - { - // Skip reporting of processes that have already exited (and we're waiting to clean up). - if (pProcess->m_fExited) - continue; - cProcesses++; - } - - // We're done if there aren't any. - if (cProcesses == 0) - return S_OK; - - // Otherwise allocate an array large enough to hold information about each process. - CoreClrDebugProcInfo *pProcInfos = new (nothrow) CoreClrDebugProcInfo[cProcesses]; - if (pProcInfos == NULL) - return E_OUTOFMEMORY; - - // Iterate over the processes again, this time filling in the data for each one in the output array. - DWORD idxCurrentProc = 0; - for (pProcess = m_pProcessList; pProcess; pProcess = pProcess->m_pNext) - { - // Skip reporting of processes that have already exited (and we're waiting to clean up). - if (pProcess->m_fExited) - continue; - - pProcInfos[idxCurrentProc].m_dwPID = pProcess->m_dwPID; - pProcInfos[idxCurrentProc].m_dwInternalID = pProcess->m_pruidProcess; - - if (MultiByteToWideChar(CP_UTF8, 0, pProcess->m_szCommandLine, -1, pProcInfos[idxCurrentProc].m_wszName, kMaxCommandLine) == 0) - { - delete [] pProcInfos; - return E_OUTOFMEMORY; - } - - idxCurrentProc++; - } - - *pcProcs = cProcesses; - *ppProcs = pProcInfos; - } - - return S_OK; -} - -// A similar API for VS that enumerates runtimes running within the given process. Returns S_FALSE if -// there are none. -HRESULT DbgTransportTarget::EnumRuntimesForVS(PRUID pruidProcess, DWORD *pcRuntimes, CoreClrDebugRuntimeInfo **ppRuntimes) -{ - *pcRuntimes = 0; - *ppRuntimes = NULL; - - // Update our process and runtime view from the remote target. - UpdateProcessList(); - - // Acquire the lock to get a consistent view of current state. - { - RSLockHolder lock(&m_sLock); - - // Look for the process record with the matching PRUID. - ProcessEntry *pProcess; - for (pProcess = m_pProcessList; pProcess; pProcess = pProcess->m_pNext) - { - if (pProcess->m_fExited) - continue; - if (pProcess->m_pruidProcess == pruidProcess) - break; - } - - // We couldn't find a match -- the process must have terminated so it certainly doesn't have any - // runtimes. - if (pProcess == NULL) - return S_FALSE; - - // Count the runtime instances running in the process. - DWORD cRuntimes = 0; - RuntimeEntry *pRuntime; - for (pRuntime = pProcess->m_pRuntimes; pRuntime; pRuntime = pRuntime->m_pNext) - cRuntimes++; - - // We're done if there aren't any. - if (cRuntimes == 0) - return S_OK; - - // Otherwise allocate an array large enough to hold information about each runtime. - CoreClrDebugRuntimeInfo *pRuntimeInfos = new (nothrow) CoreClrDebugRuntimeInfo[cRuntimes]; - if (pRuntimeInfos == NULL) - return E_OUTOFMEMORY; - - // Iterate over the runtimes again, this time filling in data for each one in the output array. - DWORD idxCurrentRuntime = 0; - for (pRuntime = pProcess->m_pRuntimes; pRuntime; pRuntime = pRuntime->m_pNext) - { - pRuntimeInfos[idxCurrentRuntime].m_dwInternalID = pRuntime->m_pruidRuntime; - idxCurrentRuntime++; - } - - *pcRuntimes = cRuntimes; - *ppRuntimes = pRuntimeInfos; - } - - return S_OK; -} - - -// When we're being driven by the Visual Studio debugger CoreCLR supplies an entity known as a port supplier -// to handle interactions between VS and the remote system when setting up debug sessions. The port supplier -// implements the connection to the remote proxy by talking to DbgTransportTarget instances controlled via the -// following class through a psuedo-COM interface, ICoreClrDebugTarget, described in -// debug\inc\CoreClrRemoteDebuggingInterfaces.h. -class CoreClrDebugTarget : public ICoreClrDebugTarget -{ -public: - CoreClrDebugTarget(DWORD dwAddress) : - m_lRefCount(1), - m_dwAddress(dwAddress), - m_pTarget(NULL) - { - } - - ~CoreClrDebugTarget() - { - if (m_pTarget) - g_pDbgTransportManager->ReleaseTarget(m_pTarget); - } - - STDMETHODIMP_(void) AddRef() - { - InterlockedIncrement(&m_lRefCount); - } - - STDMETHODIMP_(void) Release() - { - LONG lRef = InterlockedDecrement(&m_lRefCount); - if (lRef == 0) - delete this; - } - - // Enumerate all processes on the target system (whether they have managed code or not). The memory - // returned is deallocated via FreeMemory(). - STDMETHODIMP EnumProcesses(DWORD *pcProcs, CoreClrDebugProcInfo **ppProcs) - { - return m_pTarget->EnumProcessesForVS(pcProcs, ppProcs); - } - - // Enumerate all runtimes running in the given process on the target system. The memory returned is - // deallocated via FreeMemory(). - STDMETHODIMP EnumRuntimes(DWORD dwInternalProcessID, DWORD *pcRuntimes, CoreClrDebugRuntimeInfo **ppRuntimes) - { - return m_pTarget->EnumRuntimesForVS((PRUID)dwInternalProcessID, pcRuntimes, ppRuntimes); - } - - // Free memory allocated via EnumProcesses or EnumRuntimes. - STDMETHODIMP_(void) FreeMemory(void *pMemory) - { - delete [] (BYTE*)pMemory; - } - - // Non-exported method used by CreateCoreClrDebugTarget below to connect an instance of DbgTransportTarget - // to the remote system's proxy process. - HRESULT Init() - { - HRESULT hr = g_pDbgTransportManager->ConnectToTarget(m_dwAddress, 0, &m_pTarget); - if (FAILED(hr)) - return hr; - - return S_OK; - } - -private: - LONG m_lRefCount; // COM-style ref count - DWORD m_dwAddress; // IPv4 address of target system - DbgTransportTarget *m_pTarget; // Currently connected DbgTransportTarget -}; - -// Function exported by mscordbi_mac* to allow the port supplier used by Visual Studio to query remote system -// state. -extern "C" HRESULT __stdcall CreateCoreClrDebugTarget(DWORD dwAddress, ICoreClrDebugTarget **ppTarget) -{ - HRESULT hr; - - *ppTarget = NULL; - - // Allocate a new object implementing ICoreClrDebugTarget. - CoreClrDebugTarget *pTarget = new (nothrow) CoreClrDebugTarget(dwAddress); - if (pTarget == NULL) - return E_OUTOFMEMORY; - - // Attempt to connect it to the remote system. - hr = pTarget->Init(); - if (FAILED(hr)) - { - delete pTarget; - return hr; - } - - *ppTarget = static_cast<ICoreClrDebugTarget*>(pTarget); - return S_OK; -} - #endif // FEATURE_DBGIPC_TRANSPORT_DI diff --git a/src/debug/di/dbgtransportmanager.h b/src/debug/di/dbgtransportmanager.h index a28d1c718a..c94083595d 100644 --- a/src/debug/di/dbgtransportmanager.h +++ b/src/debug/di/dbgtransportmanager.h @@ -9,35 +9,32 @@ #ifdef FEATURE_DBGIPC_TRANSPORT_DI -#include "dbgproxy.h" #include "coreclrremotedebugginginterfaces.h" -// -// Provides access to various process enumeration and control facilities for a remote machine. -// -// The top-level entity is a DbgTransportManager. Usually one of these will be allocated per debugger process. -// The manager maintains a pool of DbgTransportTarget objects. Each of these track a connection to the proxy -// on a single target machine. In addition to managing the proxy connection a collection of -// DbgTransportSession objects is maintained, each corresponding to a debug session with a specific CoreCLR -// runtime instance. -// -// Target machine specific state. +// TODO: Ideally we'd like to remove this class and don't do any process related book keeping in DBI. + +// This is a registry of all the processes a debugger knows about, different components call it in order to +// obtain right instance of DbgTransportSession for a given PID. It keeps list of processes and transports for them. +// It also handles things like creating and killing a process. + +// Usual lifecycle looks like this: +// Debug a new process: +// * CreateProcess(&pid) +// * GetTransportForProcess(pid, &transport) +// * ReleaseTransport(transport) +// * KillProcess(pid) + +// Attach to an existing process: +// * Obtain pid from a user +// * GetTransportForProcess(pid, &transport) +// * ReleaseTransport(transport) + class DbgTransportTarget { public: DbgTransportTarget(); - // Fill caller allocated table at pdwProcesses with the pids of processes currently alive on the target - // system. Return the number of slots filled in *pcProcesses. The size of the table is given by cSlots. If - // more than this number of processes are alive then *pcProcesses is set to the total number and - // E_OUTOFMEMORY returned. - HRESULT EnumProcesses(DWORD *pdwProcesses, DWORD cSlots, DWORD *pcProcesses); - - // Returns true if the given PID identifies a running process which is hosting at least one CoreCLR - // runtime. - bool IsManagedProcess(DWORD dwPID); - // Given a PID attempt to find or create a DbgTransportSession instance to manage a connection to a // runtime in that process. Returns E_UNEXPECTED if the process can't be found. Also returns a handle that // can be waited on for process termination. @@ -47,194 +44,44 @@ public: // connection at this point). void ReleaseTransport(DbgTransportSession *pTransport); - // Run the command line given on the remote machine to create a process. Return the PID of this process. - // When and if the process starts a runtime and registers with the proxy it will be told to halt and wait - // for a debugger attach. - HRESULT CreateProcess(LPCWSTR wszCommand, - LPCWSTR wszArgs, - LPCWSTR wszCurrentDirectory, - LPVOID pvEnvironment, - DWORD *pdwPID); + // When and if the process starts the runtime will be told to halt and wait for a debugger attach. + HRESULT CreateProcess(LPCWSTR lpApplicationName, + LPCWSTR lpCommandLine, + LPSECURITY_ATTRIBUTES lpProcessAttributes, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + BOOL bInheritHandles, + DWORD dwCreationFlags, + LPVOID lpEnvironment, + LPCWSTR lpCurrentDirectory, + LPSTARTUPINFOW lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInformation); // Kill the process identified by PID. void KillProcess(DWORD dwPID); - // Indicates when the connection to a proxy has failed: this target object will remain until the last - // reference to it is released (DbgTransportManager::ReleaseTransport) but will fail all further requests. - // The manager will then allow a new attempt to create a connection to the proxy to be made (wrapped in a - // new DbgTransportTarget). - bool IsProxyConnectionBad(); - - // A version of EnumProcesses used when we're controlled by the Visual Studio debugger. This API is - // exposed to our port supplier implementation via the ICoreClrDebugTarget interface implemented by the - // CoreClrDebugTarget class implemented in DbgTransportManager.cpp. - HRESULT EnumProcessesForVS(DWORD *pcProcs, CoreClrDebugProcInfo **ppProcs); - - // A similar API for VS that enumerates runtimes running within the given process. Returns S_FALSE if - // there are none. - HRESULT EnumRuntimesForVS(PRUID pruidProcess, DWORD *pcRuntimes, CoreClrDebugRuntimeInfo **ppRuntimes); - -private: - friend class DbgTransportManager; - - // Initialization and shutdown routines called only by the DbgTransportManager. - HRESULT Init(DWORD dwIPAddress, USHORT usPort); + HRESULT Init(); void Shutdown(); - // Data saved for each runtime instance the manager currently knows about. Saved in a singly linked, NULL - // terminated list on each ProcessEntry (m_pRuntimes). - struct RuntimeEntry - { - RuntimeEntry *m_pNext; // Next entry in the list - PRUID m_pruidRuntime; // Proxy ID for this specific runtime instance - USHORT m_usPort; // Port number to connect session to. - DbgTransportSession *m_pDbgTransport; // Transport to this runtime or NULL - DWORD m_cTransportRef; // Number of references to the transport still outstanding - - ~RuntimeEntry(); - }; - - // Data saved for each process the manager currently knows about. Saved in a singly linked, NULL - // terminated list (m_pProcessList). +private: struct ProcessEntry { ProcessEntry *m_pNext; // Next entry in the list DWORD m_dwPID; // Process ID for this entry - PRUID m_pruidProcess; // Proxy's ID for this process - char m_szCommandLine[kMaxCommandLine]; // Command line process is running - RuntimeEntry *m_pRuntimes; // Singly linked list of runtimes in process - HANDLE m_hExitedEvent; // Event signalled once process terminates - HANDLE m_hRuntimeStartedEvent; //Event signalled when first runtime is created in this process - bool m_fExited; // Marks processes that have exited but still have a transport - bool m_fRemove; // Used only during process list updates, see ProcessProcessList - DWORD m_cProcessRef; // Reasons the process can't be deleted yet + HANDLE m_hProcess; // Process handle + DbgTransportSession *m_transport; // Debugger's connection to the process + DWORD m_cProcessRef; // Ref count ~ProcessEntry(); }; - // Record of outgoing request that requires a reply. - struct Request - { - Request *m_pNext; // Next in queue of outstanding requests - DWORD m_dwID; // ID assigned to request (to match reply) - HANDLE m_hCompletionEvent; // Event to signal once the request is completed - HRESULT m_hrResult; // Completion result of request - union // Request specific output buffers - { - struct - { - DWORD *m_pdwMajorVersion; // Protocol version employed by the proxy - DWORD *m_pdwMinorVersion; // Protocol version employed by the proxy - DbgTargetPlatform *m_pePlatform; // Platform type of target system - } GetSystemInfo; - - struct - { - DWORD *m_pdwPID; // PID of launched process - PRUID *m_ppruidProcess; // PRUID of launched process - } LaunchProcess; - - struct - { - bool *m_pfProcessExited; // Process exited before we could record the attach - } EarlyAttach; - - } OutputBuffers; - }; - - ULONGLONG m_ullLastUpdate; // tick count of the last time the process list is updated - bool m_fInitLock; // Used to track whether we initialized m_sLock in Init() - DWORD m_dwProxyIP; // Proxy IP address in host byte order - USHORT m_usProxyPort; // Proxy port number in host byte order - DbgTargetPlatform m_ePlatform; // Platform type of the target (e.g. MacX86) ProcessEntry *m_pProcessList; // Head of list of currently alive processes (unsorted) - RSLock m_sLock; // Lock protecting read and write access to the process list - bool m_fShutdown; // Flag set once Shutdown() has been called - HANDLE m_hProcessEventThread; // Handle for the process event thread - SecConnMgr *m_pConnectionManager; // Factory for network connections - SecConn *m_pConnection; // Connection to the proxy - SOCKET m_hSocket; // UDP socket used to communicate with proxy - DWORD m_dwNextRequestID; // Next ID to be assigned to an outgoing request - Request *m_pRequestList; // List of requests to proxy that haven't had a reply - bool m_fProxyConnectionBad; // Initially false, any network failure will transition it - // to true for good and all further requests on this - // target will fail. - - // Ask the remote debugger proxy for an updated list of processes and reflect these changes into our local - // process list. Any failure will leave the current process list state unchanged. - void UpdateProcessList(); + RSLock m_sLock; // Lock protecting read and write access to the target list // Locate a process entry by PID. Assumes the lock is already held. ProcessEntry *LocateProcessByPID(DWORD dwPID); - - // Deallocate all resources associated with a process list. - void DeallocateProcessList(ProcessEntry *pProcessList); - - // Format and send a request to the proxy then wait on a reply (if appropriate) and return results to the - // caller. - HRESULT MakeProxyRequest(DbgProxyMessageType eType, ...); - - // Static entry point for the process event thread. - static DWORD WINAPI ProcessEventWorkerStatic(LPVOID lpvContext); - - // Instance method version of the worker, called from ProcessEventWorkerStatic(). - void ProcessEventWorker(); - - // If this message is a reply to a right-side request locate that request. Otherwise return NULL. - Request *LocateOriginalRequest(DbgProxyMessageHeader *pMessage); - - // Process an incoming ProcessList message. - void ProcessProcessList(DbgProxyMessageHeader *pMessage, - Request *pRequest); - - // Process an incoming RuntimeStarted message. - bool ProcessRuntimeStarted(DbgProxyProcessInfo *pProcessInfo, - DbgProxyRuntimeInfo *pRuntimeInfo); -}; - -// Process level state. -class DbgTransportManager -{ -public: - DbgTransportManager(); - - // Startup/shutdown calls. These are ref-counted (cordbg, for instance, is constructed in such a way that - // the command shell will attempt to load mscordbi and initialize an associated DbgTransportManager - // multiple times). - HRESULT Init(); - void Shutdown(); - - // Attempt to connect to a debugging proxy on the machine at the given address and with the specified port - // number. If the port number is given as zero use the port stored in user debugger configuration. On - // success a pointer to a DbgTransportTarget object will be returned. - HRESULT ConnectToTarget(DWORD dwIPAddress, USHORT usPort, DbgTransportTarget **ppTarget); - - // Add another reference to a target already acquired by ConnectToTarget (used by clients when they want - // to hand a target out to independent code). - void ReferenceTarget(DbgTransportTarget *pTarget); - - // Release reference to a DbgTransportTarget. If this is the last active reference then the connection to - // the proxy will be severed and the object deallocated. - void ReleaseTarget(DbgTransportTarget *pTarget); - -private: - // Private structure used to track references to DbgTransportTargets we've allocated. - struct TargetRef - { - TargetRef *m_pNext; // Next target in singly linked list (or NULL for end of list) - DbgTransportTarget *m_pTarget; // The actual target object - DWORD m_dwIPAddress; // IP address of the target machine - USHORT m_usPort; // TCP port of the proxy on the machine - DWORD m_dwRefCount; // Number of clients with a reference to this target - }; - - LONG m_lRefCount; // Number of references to this manager outstanding - TargetRef *m_pTargets; // Singly linked list of targets allocated so far - RSLock m_sLock; // Lock protecting read and write access to the target list }; -// The one and only instance of the DbgTransportManager in the process. -extern DbgTransportManager *g_pDbgTransportManager; +extern DbgTransportTarget *g_pDbgTransportTarget; #endif // FEATURE_DBGIPC_TRANSPORT_DI diff --git a/src/debug/di/dbgtransportpipeline.cpp b/src/debug/di/dbgtransportpipeline.cpp index b03e59e6c8..9fd1d9090b 100644 --- a/src/debug/di/dbgtransportpipeline.cpp +++ b/src/debug/di/dbgtransportpipeline.cpp @@ -137,11 +137,6 @@ private: m_pProxy->ReleaseTransport(m_pTransport); } m_pTransport = NULL; - - if (m_pProxy) - { - g_pDbgTransportManager->ReleaseTarget(m_pProxy); - } m_pProxy = NULL; } @@ -209,16 +204,17 @@ HRESULT DbgTransportPipeline::CreateProcessUnderDebugger( // Connect to the debugger proxy on the remote machine and ask it to create a process for us. HRESULT hr = E_FAIL; - // Establish a connection to the proxy of the remote machine. - hr = g_pDbgTransportManager->ConnectToTarget(machineInfo.GetIPAddress(), machineInfo.GetPort(), &m_pProxy); - if (SUCCEEDED(hr)) - { - hr = m_pProxy->CreateProcess(lpApplicationName, - lpCommandLine, - lpCurrentDirectory, - lpEnvironment, - &(lpProcessInformation->dwProcessId)); - } + m_pProxy = g_pDbgTransportTarget; + hr = m_pProxy->CreateProcess(lpApplicationName, + lpCommandLine, + lpProcessAttributes, + lpThreadAttributes, + bInheritHandles, + dwCreationFlags, + lpEnvironment, + lpCurrentDirectory, + lpStartupInfo, + lpProcessInformation); if (SUCCEEDED(hr)) { @@ -288,25 +284,23 @@ HRESULT DbgTransportPipeline::DebugActiveProcess(MachineInfo machineInfo, DWORD HRESULT hr = E_FAIL; - // Establish a connection to the proxy of the remote machine. - hr = g_pDbgTransportManager->ConnectToTarget(machineInfo.GetIPAddress(), machineInfo.GetPort(), &m_pProxy); + m_pProxy = g_pDbgTransportTarget; + + // Establish a connection to the actual runtime to be debugged. + hr = m_pProxy->GetTransportForProcess(processId, &m_pTransport, &m_hProcess); if (SUCCEEDED(hr)) { - // Establish a connection to the actual runtime to be debugged. - hr = m_pProxy->GetTransportForProcess(processId, &m_pTransport, &m_hProcess); - if (SUCCEEDED(hr)) + // TODO: Pass this timeout as a parameter all the way from debugger + // Wait for the connection to become useable (or time out). + if (!m_pTransport->WaitForSessionToOpen(10000)) { - // Wait for the connection to become useable (or time out). - if (!m_pTransport->WaitForSessionToOpen(10000)) - { - hr = CORDBG_E_TIMEOUT; - } - else + hr = CORDBG_E_TIMEOUT; + } + else + { + if (!m_pTransport->UseAsDebugger(&m_ticket)) { - if (!m_pTransport->UseAsDebugger(&m_ticket)) - { - hr = CORDBG_E_DEBUGGER_ALREADY_ATTACHED; - } + hr = CORDBG_E_DEBUGGER_ALREADY_ATTACHED; } } } diff --git a/src/debug/di/ddpack.cpp b/src/debug/di/ddpack.cpp deleted file mode 100644 index 5f68c6a34a..0000000000 --- a/src/debug/di/ddpack.cpp +++ /dev/null @@ -1,3731 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -// DDPack.cpp -// Implementation of DDMarshal. -// Lives on DI side. Packs DDInterface calls into a byte stream. -// -// Note that this file is generated by ndp\clr\src\Debug\tools\BuildDDMarshal\. -// Changes should be made to output\DDPack_template.cpp in that directory. -// - - -#include "stdafx.h" - -#ifdef FEATURE_DBGIPC_TRANSPORT_DI -#include "dacdbiinterface.h" - -#include "ddpack.h" - -#include "rspriv.h" // for StringCopyHolder - -#include "ddshared.h" - -// Get common marshaling utilities -#include "ddmarshalutil.h" - - -// Suppress PREFast warning about overly large function -// These functions are automatically generated. -#if defined(_PREFAST_) -#pragma warning(disable:21000) -#endif - -/* -// Called in Real DacDbi-Implementation space. Part of the unpacking stubs. -// Needs -//void HandleDDMessage(ReadBuffer * pSend, WriteBuffer * pResult); - -// Called by Packing stubs from Right-side. -void DDMarshal::SendDDMessage(WriteBuffer * pSend, ReadBuffer * pResult) -{ - // For now, this is an in-memory transport. Simulate sending an event. - // When this becomes IPC events, we'll need a CordbProcess* - ReadBuffer pSend2; - pSend2.Open(pSend); - - WriteBuffer pResult2; - m_pUnpack->HandleDDMessage(&pSend2, &pResult2); - pResult->Open(&pResult2); -} -*/ - -HRESULT DDMarshal::Init() -{ - HandleHolder hDummy; - HRESULT hr = E_FAIL; - - MachineInfo machineInfo = m_pProcess->GetShim()->GetMachineInfo(); - - hr = g_pDbgTransportManager->ConnectToTarget(machineInfo.GetIPAddress(), machineInfo.GetPort(), &m_pProxy); - if (FAILED(hr)) - { - goto Label_Exit; - } - - hr = m_pProxy->GetTransportForProcess(m_pProcess->GetPid(), &m_pTransport, &hDummy); - if (FAILED(hr)) - { - goto Label_Exit; - } - - if (!m_pTransport->WaitForSessionToOpen(10000)) - { - hr = CORDBG_E_TIMEOUT; - goto Label_Exit; - } - -Label_Exit: - if (FAILED(hr)) - { - if (m_pTransport != NULL) - { - m_pProxy->ReleaseTransport(m_pTransport); - } - - if (m_pProxy != NULL) - { - g_pDbgTransportManager->ReleaseTarget(m_pProxy); - } - } - return hr; -} - -void DDMarshal::Destroy() -{ - // The LS DAC resources will be cleaned up when InProcDac is destructed. - if (m_pTransport != NULL) - { - m_pProxy->ReleaseTransport(m_pTransport); - } - - if (m_pProxy != NULL) - { - g_pDbgTransportManager->ReleaseTarget(m_pProxy); - } -} - - - -// {%PackImpls%} - -// -// Impls -// - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::CheckDbiVersion -HRESULT DDMarshal::CheckDbiVersion(const DbiVersion * pVersion) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_CheckDbiVersion); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, pVersion); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - HRESULT _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method CheckDbiVersion - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetLocalInterfaceHashAndTimestamp -void DDMarshal::GetLocalInterfaceHashAndTimestamp(DWORD & hash1, DWORD & hash2, DWORD & hash3, DWORD & hash4, DWORD & timestamp1, DWORD & timestamp2) -{ - hash1 = 0xe5ffdbe6; - hash2 = 0xf26b43be; - hash3 = 0x6c9685ac; - hash4 = 0xdd723940; - timestamp1 = 0x1cc67fb; - timestamp2 = 0xe3ad5a06; -} // end method GetLocalInterfaceHashAndTimestamp - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetRemoteInterfaceHashAndTimestamp -void DDMarshal::GetRemoteInterfaceHashAndTimestamp(DWORD & hash1, DWORD & hash2, DWORD & hash3, DWORD & hash4, DWORD & timestamp1, DWORD & timestamp2) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetRemoteInterfaceHashAndTimestamp); // message id - // Copy in-parameters to the send-buffer - // hash1 does not need to be copied on input - // hash2 does not need to be copied on input - // hash3 does not need to be copied on input - // hash4 does not need to be copied on input - // timestamp1 does not need to be copied on input - // timestamp2 does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, hash1); - ReadFromBuffer(&bRecv, hash2); - ReadFromBuffer(&bRecv, hash3); - ReadFromBuffer(&bRecv, hash4); - ReadFromBuffer(&bRecv, timestamp1); - ReadFromBuffer(&bRecv, timestamp2); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetRemoteInterfaceHashAndTimestamp - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::FlushCache -HRESULT DDMarshal::FlushCache() -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_FlushCache); // message id - // Copy in-parameters to the send-buffer - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - HRESULT _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method FlushCache - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::DacSetTargetConsistencyChecks -void DDMarshal::DacSetTargetConsistencyChecks(bool fEnableAsserts) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_DacSetTargetConsistencyChecks); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, fEnableAsserts); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method DacSetTargetConsistencyChecks - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::IsLeftSideInitialized -BOOL DDMarshal::IsLeftSideInitialized() -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_IsLeftSideInitialized); // message id - // Copy in-parameters to the send-buffer - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - BOOL _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method IsLeftSideInitialized - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetAppDomainFromId -VMPTR_AppDomain DDMarshal::GetAppDomainFromId(ULONG appdomainId) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetAppDomainFromId); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, appdomainId); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - VMPTR_AppDomain _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetAppDomainFromId - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetAppDomainId -ULONG DDMarshal::GetAppDomainId(VMPTR_AppDomain vmAppDomain) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetAppDomainId); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmAppDomain); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - ULONG _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetAppDomainId - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetAppDomainObject -VMPTR_OBJECTHANDLE DDMarshal::GetAppDomainObject(VMPTR_AppDomain vmAppDomain) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetAppDomainObject); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmAppDomain); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - VMPTR_OBJECTHANDLE _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetAppDomainObject - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::IsDefaultDomain -BOOL DDMarshal::IsDefaultDomain(VMPTR_AppDomain vmAppDomain) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_IsDefaultDomain); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmAppDomain); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - BOOL _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method IsDefaultDomain - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetAssemblyFromDomainAssembly -void DDMarshal::GetAssemblyFromDomainAssembly(VMPTR_DomainAssembly vmDomainAssembly, VMPTR_Assembly * vmAssembly) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetAssemblyFromDomainAssembly); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmDomainAssembly); - // vmAssembly does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, vmAssembly); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetAssemblyFromDomainAssembly - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::IsAssemblyFullyTrusted -BOOL DDMarshal::IsAssemblyFullyTrusted(VMPTR_DomainAssembly vmDomainAssembly) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_IsAssemblyFullyTrusted); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmDomainAssembly); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - BOOL _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method IsAssemblyFullyTrusted - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetAppDomainFullName -void DDMarshal::GetAppDomainFullName(VMPTR_AppDomain vmAppDomain, IStringHolder * pStrName) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetAppDomainFullName); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmAppDomain); - // pStrName does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pStrName); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetAppDomainFullName - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetModuleSimpleName -void DDMarshal::GetModuleSimpleName(VMPTR_Module vmModule, IStringHolder * pStrFilename) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetModuleSimpleName); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmModule); - // pStrFilename does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pStrFilename); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetModuleSimpleName - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetAssemblyPath -BOOL DDMarshal::GetAssemblyPath(VMPTR_Assembly vmAssembly, IStringHolder * pStrFilename) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetAssemblyPath); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmAssembly); - // pStrFilename does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pStrFilename); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - BOOL _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetAssemblyPath - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::ResolveTypeReference -void DDMarshal::ResolveTypeReference(const TypeRefData * pTypeRefInfo, TypeRefData * pTargetRefInfo) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_ResolveTypeReference); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, pTypeRefInfo); - WriteToBuffer(&bSend, pTargetRefInfo); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pTargetRefInfo); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method ResolveTypeReference - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetModulePath -BOOL DDMarshal::GetModulePath(VMPTR_Module vmModule, IStringHolder * pStrFilename) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetModulePath); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmModule); - // pStrFilename does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pStrFilename); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - BOOL _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetModulePath - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetModuleNGenPath -BOOL DDMarshal::GetModuleNGenPath(VMPTR_Module vmModule, IStringHolder * pStrFilename) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetModuleNGenPath); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmModule); - // pStrFilename does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pStrFilename); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - BOOL _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetModuleNGenPath - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetMetadata -void DDMarshal::GetMetadata(VMPTR_Module vmModule, TargetBuffer * pTargetBuffer) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetMetadata); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmModule); - // pTargetBuffer does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pTargetBuffer); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetMetadata - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetSymbolsBuffer -void DDMarshal::GetSymbolsBuffer(VMPTR_Module vmModule, TargetBuffer * pTargetBuffer, IDacDbiInterface::SymbolFormat * pSymbolFormat) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetSymbolsBuffer); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmModule); - // pTargetBuffer does not need to be copied on input - // pSymbolFormat does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pTargetBuffer); - ReadFromBuffer(&bRecv, pSymbolFormat); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetSymbolsBuffer - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetModuleData -void DDMarshal::GetModuleData(VMPTR_Module vmModule, ModuleInfo * pData) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetModuleData); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmModule); - // pData does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pData); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetModuleData - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetDomainFileData -void DDMarshal::GetDomainFileData(VMPTR_DomainFile vmDomainFile, DomainFileInfo * pData) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetDomainFileData); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmDomainFile); - // pData does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pData); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetDomainFileData - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetModuleForDomainFile -void DDMarshal::GetModuleForDomainFile(VMPTR_DomainFile vmDomainFile, VMPTR_Module * pModule) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetModuleForDomainFile); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmDomainFile); - // pModule does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pModule); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetModuleForDomainFile - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetAddressType -IDacDbiInterface::AddressType DDMarshal::GetAddressType(CORDB_ADDRESS address) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetAddressType); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, address); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - IDacDbiInterface::AddressType _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetAddressType - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::IsTransitionStub -BOOL DDMarshal::IsTransitionStub(CORDB_ADDRESS address) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_IsTransitionStub); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, address); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - BOOL _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method IsTransitionStub - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetCompilerFlags -void DDMarshal::GetCompilerFlags(VMPTR_DomainFile vmDomainFile, BOOL * pfAllowJITOpts, BOOL * pfEnableEnC) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetCompilerFlags); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmDomainFile); - // pfAllowJITOpts does not need to be copied on input - // pfEnableEnC does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pfAllowJITOpts); - ReadFromBuffer(&bRecv, pfEnableEnC); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetCompilerFlags - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::SetCompilerFlags -HRESULT DDMarshal::SetCompilerFlags(VMPTR_DomainFile vmDomainFile, BOOL fAllowJitOpts, BOOL fEnableEnC) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_SetCompilerFlags); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmDomainFile); - WriteToBuffer(&bSend, fAllowJitOpts); - WriteToBuffer(&bSend, fEnableEnC); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - HRESULT _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method SetCompilerFlags - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::EnumerateAppDomains -void DDMarshal::EnumerateAppDomains(IDacDbiInterface::FP_APPDOMAIN_ENUMERATION_CALLBACK fpCallback, CALLBACK_DATA pUserData) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_EnumerateAppDomains); // message id - // Copy in-parameters to the send-buffer - // fpCallback does not need to be copied on input - // pUserData does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - // Result buffer contains the entire enumeration. Now iterate through that - // locally and invoke the user's callback. - while (true) - { - // Check status word before each element. - // 1 means there's another item. 2 means it's the end of the enumeration. - DWORD dw; - ReadFromBuffer(&bRecv, dw); - if (dw == 2) - break; - _ASSERTE(dw == 1); - - VMPTR_AppDomain data; - ReadFromBuffer(&bRecv, data); - - // Invoke user callback. This may throw. - fpCallback(data, pUserData); - } - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method EnumerateAppDomains - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::EnumerateAssembliesInAppDomain -void DDMarshal::EnumerateAssembliesInAppDomain(VMPTR_AppDomain vmAppDomain, IDacDbiInterface::FP_ASSEMBLY_ENUMERATION_CALLBACK fpCallback, CALLBACK_DATA pUserData) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_EnumerateAssembliesInAppDomain); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmAppDomain); - // fpCallback does not need to be copied on input - // pUserData does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - // Result buffer contains the entire enumeration. Now iterate through that - // locally and invoke the user's callback. - while (true) - { - // Check status word before each element. - // 1 means there's another item. 2 means it's the end of the enumeration. - DWORD dw; - ReadFromBuffer(&bRecv, dw); - if (dw == 2) - break; - _ASSERTE(dw == 1); - - VMPTR_DomainAssembly data; - ReadFromBuffer(&bRecv, data); - - // Invoke user callback. This may throw. - fpCallback(data, pUserData); - } - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method EnumerateAssembliesInAppDomain - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::EnumerateModulesInAssembly -void DDMarshal::EnumerateModulesInAssembly(VMPTR_DomainAssembly vmAssembly, IDacDbiInterface::FP_MODULE_ENUMERATION_CALLBACK fpCallback, CALLBACK_DATA pUserData) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_EnumerateModulesInAssembly); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmAssembly); - // fpCallback does not need to be copied on input - // pUserData does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - // Result buffer contains the entire enumeration. Now iterate through that - // locally and invoke the user's callback. - while (true) - { - // Check status word before each element. - // 1 means there's another item. 2 means it's the end of the enumeration. - DWORD dw; - ReadFromBuffer(&bRecv, dw); - if (dw == 2) - break; - _ASSERTE(dw == 1); - - VMPTR_DomainFile data; - ReadFromBuffer(&bRecv, data); - - // Invoke user callback. This may throw. - fpCallback(data, pUserData); - } - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method EnumerateModulesInAssembly - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::RequestSyncAtEvent -void DDMarshal::RequestSyncAtEvent() -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_RequestSyncAtEvent); // message id - // Copy in-parameters to the send-buffer - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method RequestSyncAtEvent - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::MarkDebuggerAttachPending -void DDMarshal::MarkDebuggerAttachPending() -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_MarkDebuggerAttachPending); // message id - // Copy in-parameters to the send-buffer - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method MarkDebuggerAttachPending - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::MarkDebuggerAttached -void DDMarshal::MarkDebuggerAttached(BOOL fAttached) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_MarkDebuggerAttached); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, fAttached); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method MarkDebuggerAttached - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::Hijack -void DDMarshal::Hijack(VMPTR_Thread vmThread, ULONG32 dwThreadId, const EXCEPTION_RECORD * pRecord, T_CONTEXT * pOriginalContext, ULONG32 cbSizeContext, EHijackReason::EHijackReason reason, void * pUserData, CORDB_ADDRESS * pRemoteContextAddr) -{ - _ASSERTE(!"Calling unimplemented callback:Hijack"); -} // end method Hijack - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::EnumerateConnections -void DDMarshal::EnumerateConnections(IDacDbiInterface::FP_CONNECTION_CALLBACK fpCallback, CALLBACK_DATA pUserData) -{ - _ASSERTE(!"Calling unimplemented callback:EnumerateConnections"); -} // end method EnumerateConnections - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::EnumerateThreads -void DDMarshal::EnumerateThreads(IDacDbiInterface::FP_THREAD_ENUMERATION_CALLBACK fpCallback, CALLBACK_DATA pUserData) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_EnumerateThreads); // message id - // Copy in-parameters to the send-buffer - // fpCallback does not need to be copied on input - // pUserData does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - // Result buffer contains the entire enumeration. Now iterate through that - // locally and invoke the user's callback. - while (true) - { - // Check status word before each element. - // 1 means there's another item. 2 means it's the end of the enumeration. - DWORD dw; - ReadFromBuffer(&bRecv, dw); - if (dw == 2) - break; - _ASSERTE(dw == 1); - - VMPTR_Thread data; - ReadFromBuffer(&bRecv, data); - - // Invoke user callback. This may throw. - fpCallback(data, pUserData); - } - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method EnumerateThreads - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::IsThreadMarkedDead -bool DDMarshal::IsThreadMarkedDead(VMPTR_Thread vmThread) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_IsThreadMarkedDead); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmThread); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - bool _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method IsThreadMarkedDead - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetThreadHandle -HANDLE DDMarshal::GetThreadHandle(VMPTR_Thread vmThread) -{ - _ASSERTE(!"Calling unimplemented callback:GetThreadHandle"); - ThrowHR(E_NOTIMPL); -} // end method GetThreadHandle - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetThreadObject -VMPTR_OBJECTHANDLE DDMarshal::GetThreadObject(VMPTR_Thread vmThread) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetThreadObject); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmThread); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - VMPTR_OBJECTHANDLE _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetThreadObject - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::SetDebugState -void DDMarshal::SetDebugState(VMPTR_Thread vmThread, CorDebugThreadState debugState) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_SetDebugState); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmThread); - WriteToBuffer(&bSend, debugState); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method SetDebugState - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::HasUnhandledException -BOOL DDMarshal::HasUnhandledException(VMPTR_Thread vmThread) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_HasUnhandledException); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmThread); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - BOOL _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method HasUnhandledException - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetUserState -CorDebugUserState DDMarshal::GetUserState(VMPTR_Thread vmThread) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetUserState); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmThread); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - CorDebugUserState _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetUserState - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetConnectionID -CONNID DDMarshal::GetConnectionID(VMPTR_Thread vmThread) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetConnectionID); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmThread); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - CONNID _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetConnectionID - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetTaskID -TASKID DDMarshal::GetTaskID(VMPTR_Thread vmThread) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetTaskID); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmThread); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - TASKID _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetTaskID - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::TryGetVolatileOSThreadID -DWORD DDMarshal::TryGetVolatileOSThreadID(VMPTR_Thread vmThread) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_TryGetVolatileOSThreadID); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmThread); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - DWORD _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method TryGetVolatileOSThreadID - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetUniqueThreadID -DWORD DDMarshal::GetUniqueThreadID(VMPTR_Thread vmThread) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetUniqueThreadID); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmThread); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - DWORD _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetUniqueThreadID - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetCurrentException -VMPTR_OBJECTHANDLE DDMarshal::GetCurrentException(VMPTR_Thread vmThread) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetCurrentException); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmThread); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - VMPTR_OBJECTHANDLE _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetCurrentException - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetCurrentCustomDebuggerNotification -VMPTR_OBJECTHANDLE DDMarshal::GetCurrentCustomDebuggerNotification(VMPTR_Thread vmThread) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetCurrentCustomDebuggerNotification); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmThread); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - VMPTR_OBJECTHANDLE _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetCurrentCustomDebuggerNotification - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetCurrentAppDomain -VMPTR_AppDomain DDMarshal::GetCurrentAppDomain(VMPTR_Thread vmThread) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetCurrentAppDomain); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmThread); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - VMPTR_AppDomain _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetCurrentAppDomain - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::ResolveAssembly -VMPTR_DomainAssembly DDMarshal::ResolveAssembly(VMPTR_DomainFile vmScope, mdToken tkAssemblyRef) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_ResolveAssembly); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmScope); - WriteToBuffer(&bSend, tkAssemblyRef); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - VMPTR_DomainAssembly _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method ResolveAssembly - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetNativeCodeSequencePointsAndVarInfo -void DDMarshal::GetNativeCodeSequencePointsAndVarInfo(VMPTR_MethodDesc vmMethodDesc, CORDB_ADDRESS startAddress, BOOL fCodeAvailabe, NativeVarData * pNativeVarData, SequencePoints * pSequencePoints) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetNativeCodeSequencePointsAndVarInfo); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmMethodDesc); - WriteToBuffer(&bSend, startAddress); - WriteToBuffer(&bSend, fCodeAvailabe); - // pNativeVarData does not need to be copied on input - // pSequencePoints does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pNativeVarData); - ReadFromBuffer(&bRecv, pSequencePoints); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetNativeCodeSequencePointsAndVarInfo - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetManagedStoppedContext -VMPTR_CONTEXT DDMarshal::GetManagedStoppedContext(VMPTR_Thread vmThread) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetManagedStoppedContext); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmThread); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - VMPTR_CONTEXT _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetManagedStoppedContext - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::CreateStackWalk -void DDMarshal::CreateStackWalk(VMPTR_Thread vmThread, DT_CONTEXT * pInternalContextBuffer, StackWalkHandle * ppSFIHandle) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_CreateStackWalk); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmThread); - WriteToBuffer(&bSend, pInternalContextBuffer); - // ppSFIHandle does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pInternalContextBuffer); - ReadFromBuffer(&bRecv, ppSFIHandle); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method CreateStackWalk - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::DeleteStackWalk -void DDMarshal::DeleteStackWalk(StackWalkHandle ppSFIHandle) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_DeleteStackWalk); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, ppSFIHandle); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method DeleteStackWalk - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetStackWalkCurrentContext -void DDMarshal::GetStackWalkCurrentContext(StackWalkHandle pSFIHandle, DT_CONTEXT * pContext) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetStackWalkCurrentContext); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, pSFIHandle); - WriteToBuffer(&bSend, pContext); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pContext); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetStackWalkCurrentContext - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::SetStackWalkCurrentContext -void DDMarshal::SetStackWalkCurrentContext(VMPTR_Thread vmThread, StackWalkHandle pSFIHandle, CorDebugSetContextFlag flag, DT_CONTEXT * pContext) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_SetStackWalkCurrentContext); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmThread); - WriteToBuffer(&bSend, pSFIHandle); - WriteToBuffer(&bSend, flag); - WriteToBuffer(&bSend, pContext); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pContext); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method SetStackWalkCurrentContext - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::UnwindStackWalkFrame -BOOL DDMarshal::UnwindStackWalkFrame(StackWalkHandle pSFIHandle) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_UnwindStackWalkFrame); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, pSFIHandle); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - BOOL _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method UnwindStackWalkFrame - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::CheckContext -HRESULT DDMarshal::CheckContext(VMPTR_Thread vmThread, const DT_CONTEXT * pContext) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_CheckContext); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmThread); - WriteToBuffer(&bSend, pContext); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - HRESULT _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method CheckContext - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetStackWalkCurrentFrameInfo -IDacDbiInterface::FrameType DDMarshal::GetStackWalkCurrentFrameInfo(StackWalkHandle pSFIHandle, DebuggerIPCE_STRData * pFrameData) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetStackWalkCurrentFrameInfo); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, pSFIHandle); - DebuggerIPCE_STRData temp_pFrameData; // backing storage for optional parameter - if (pFrameData == NULL) - pFrameData = &temp_pFrameData; - WriteToBuffer(&bSend, pFrameData); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pFrameData); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - IDacDbiInterface::FrameType _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetStackWalkCurrentFrameInfo - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetCountOfInternalFrames -ULONG32 DDMarshal::GetCountOfInternalFrames(VMPTR_Thread vmThread) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetCountOfInternalFrames); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmThread); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - ULONG32 _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetCountOfInternalFrames - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::EnumerateInternalFrames -void DDMarshal::EnumerateInternalFrames(VMPTR_Thread vmThread, IDacDbiInterface::FP_INTERNAL_FRAME_ENUMERATION_CALLBACK fpCallback, CALLBACK_DATA pUserData) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_EnumerateInternalFrames); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmThread); - // fpCallback does not need to be copied on input - // pUserData does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - // Result buffer contains the entire enumeration. Now iterate through that - // locally and invoke the user's callback. - while (true) - { - // Check status word before each element. - // 1 means there's another item. 2 means it's the end of the enumeration. - DWORD dw; - ReadFromBuffer(&bRecv, dw); - if (dw == 2) - break; - _ASSERTE(dw == 1); - - DebuggerIPCE_STRData data; - ReadFromBuffer(&bRecv, data); - - // Invoke user callback. This may throw. - fpCallback(&data, pUserData); - } - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method EnumerateInternalFrames - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::IsMatchingParentFrame -BOOL DDMarshal::IsMatchingParentFrame(FramePointer fpToCheck, FramePointer fpParent) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_IsMatchingParentFrame); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, fpToCheck); - WriteToBuffer(&bSend, fpParent); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - BOOL _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method IsMatchingParentFrame - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetStackParameterSize -ULONG32 DDMarshal::GetStackParameterSize(CORDB_ADDRESS controlPC) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetStackParameterSize); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, controlPC); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - ULONG32 _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetStackParameterSize - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetFramePointer -FramePointer DDMarshal::GetFramePointer(StackWalkHandle pSFIHandle) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetFramePointer); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, pSFIHandle); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - FramePointer _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetFramePointer - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::IsLeafFrame -BOOL DDMarshal::IsLeafFrame(VMPTR_Thread vmThread, const DT_CONTEXT * pContext) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_IsLeafFrame); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmThread); - WriteToBuffer(&bSend, pContext); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - BOOL _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method IsLeafFrame - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetContext -void DDMarshal::GetContext(VMPTR_Thread vmThread, DT_CONTEXT * pContextBuffer) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetContext); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmThread); - WriteToBuffer(&bSend, pContextBuffer); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pContextBuffer); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetContext - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::ConvertContextToDebuggerRegDisplay -void DDMarshal::ConvertContextToDebuggerRegDisplay(const DT_CONTEXT * pInContext, DebuggerREGDISPLAY * pOutDRD, BOOL fActive) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_ConvertContextToDebuggerRegDisplay); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, pInContext); - WriteToBuffer(&bSend, pOutDRD); - WriteToBuffer(&bSend, fActive); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pOutDRD); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method ConvertContextToDebuggerRegDisplay - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::IsILStubOrLCGMethod -IDacDbiInterface::DynamicMethodType DDMarshal::IsILStubOrLCGMethod(VMPTR_MethodDesc vmMethodDesc) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_IsILStubOrLCGMethod); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmMethodDesc); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - IDacDbiInterface::DynamicMethodType _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method IsILStubOrLCGMethod - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetVarArgSig -TargetBuffer DDMarshal::GetVarArgSig(CORDB_ADDRESS VASigCookieAddr, CORDB_ADDRESS * pArgBase) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetVarArgSig); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, VASigCookieAddr); - // pArgBase does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pArgBase); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - TargetBuffer _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetVarArgSig - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::RequiresAlign8 -BOOL DDMarshal::RequiresAlign8(VMPTR_TypeHandle thExact) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_RequiresAlign8); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, thExact); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - BOOL _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method RequiresAlign8 - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::ResolveExactGenericArgsToken -GENERICS_TYPE_TOKEN DDMarshal::ResolveExactGenericArgsToken(DWORD dwExactGenericArgsTokenIndex, GENERICS_TYPE_TOKEN rawToken) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_ResolveExactGenericArgsToken); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, dwExactGenericArgsTokenIndex); - WriteToBuffer(&bSend, rawToken); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - GENERICS_TYPE_TOKEN _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method ResolveExactGenericArgsToken - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetILCodeAndSig -void DDMarshal::GetILCodeAndSig(VMPTR_DomainFile vmDomainFile, mdToken functionToken, TargetBuffer * pCodeInfo, mdToken * pLocalSigToken) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetILCodeAndSig); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmDomainFile); - WriteToBuffer(&bSend, functionToken); - // pCodeInfo does not need to be copied on input - // pLocalSigToken does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pCodeInfo); - ReadFromBuffer(&bRecv, pLocalSigToken); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetILCodeAndSig - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetNativeCodeInfo -void DDMarshal::GetNativeCodeInfo(VMPTR_DomainFile vmDomainFile, mdToken functionToken, NativeCodeFunctionData * pCodeInfo) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetNativeCodeInfo); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmDomainFile); - WriteToBuffer(&bSend, functionToken); - // pCodeInfo does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pCodeInfo); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetNativeCodeInfo - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetNativeCodeInfoForAddr -void DDMarshal::GetNativeCodeInfoForAddr(VMPTR_MethodDesc vmMethodDesc, CORDB_ADDRESS hotCodeStartAddr, NativeCodeFunctionData * pCodeInfo) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetNativeCodeInfoForAddr); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmMethodDesc); - WriteToBuffer(&bSend, hotCodeStartAddr); - WriteToBuffer(&bSend, pCodeInfo); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pCodeInfo); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetNativeCodeInfoForAddr - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetClassInfo -void DDMarshal::GetClassInfo(VMPTR_AppDomain vmAppDomain, VMPTR_Module vmModule, mdTypeDef metadataToken, VMPTR_TypeHandle thExact, VMPTR_TypeHandle thApprox, ClassInfo * pData) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetClassInfo); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmAppDomain); - WriteToBuffer(&bSend, vmModule); - WriteToBuffer(&bSend, metadataToken); - WriteToBuffer(&bSend, thExact); - WriteToBuffer(&bSend, thApprox); - WriteToBuffer(&bSend, pData); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pData); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetClassInfo - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetInstantiationFieldInfo -void DDMarshal::GetInstantiationFieldInfo(VMPTR_DomainFile vmDomainFile, mdTypeDef metadataToken, VMPTR_TypeHandle vmThExact, VMPTR_TypeHandle vmThApprox, DacDbiArrayList<FieldData> * pFieldList, SIZE_T * pObjectSize) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetInstantiationFieldInfo); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmDomainFile); - WriteToBuffer(&bSend, metadataToken); - WriteToBuffer(&bSend, vmThExact); - WriteToBuffer(&bSend, vmThApprox); - // pFieldList does not need to be copied on input - // pObjectSize does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pFieldList); - ReadFromBuffer(&bRecv, pObjectSize); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetInstantiationFieldInfo - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::TypeHandleToExpandedTypeInfo -void DDMarshal::TypeHandleToExpandedTypeInfo(AreValueTypesBoxed boxed, VMPTR_AppDomain vmAppDomain, VMPTR_TypeHandle vmTypeHandle, DebuggerIPCE_ExpandedTypeData * pTypeInfo) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_TypeHandleToExpandedTypeInfo); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, boxed); - WriteToBuffer(&bSend, vmAppDomain); - WriteToBuffer(&bSend, vmTypeHandle); - WriteToBuffer(&bSend, pTypeInfo); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pTypeInfo); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method TypeHandleToExpandedTypeInfo - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetObjectExpandedTypeInfo -void DDMarshal::GetObjectExpandedTypeInfo(AreValueTypesBoxed boxed, VMPTR_AppDomain vmAppDomain, CORDB_ADDRESS addr, DebuggerIPCE_ExpandedTypeData * pTypeInfo) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetObjectExpandedTypeInfo); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, boxed); - WriteToBuffer(&bSend, vmAppDomain); - WriteToBuffer(&bSend, addr); - // pTypeInfo does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pTypeInfo); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetObjectExpandedTypeInfo - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetObjectExpandedTypeInfoFromID -void DDMarshal::GetObjectExpandedTypeInfoFromID(AreValueTypesBoxed boxed, VMPTR_AppDomain vmAppDomain, COR_TYPEID id, DebuggerIPCE_ExpandedTypeData * pTypeInfo) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetObjectExpandedTypeInfoFromID); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, boxed); - WriteToBuffer(&bSend, vmAppDomain); - WriteToBuffer(&bSend, id); - // pTypeInfo does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pTypeInfo); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetObjectExpandedTypeInfoFromID - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetApproxTypeHandle -VMPTR_TypeHandle DDMarshal::GetApproxTypeHandle(TypeInfoList * pTypeData) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetApproxTypeHandle); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, pTypeData); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pTypeData); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - VMPTR_TypeHandle _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetApproxTypeHandle - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetExactTypeHandle -HRESULT DDMarshal::GetExactTypeHandle(DebuggerIPCE_ExpandedTypeData * pTypeData, ArgInfoList * pArgInfo, VMPTR_TypeHandle & vmTypeHandle) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetExactTypeHandle); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, pTypeData); - WriteToBuffer(&bSend, pArgInfo); - WriteToBuffer(&bSend, vmTypeHandle); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pTypeData); - ReadFromBuffer(&bRecv, pArgInfo); - ReadFromBuffer(&bRecv, vmTypeHandle); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - HRESULT _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetExactTypeHandle - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetMethodDescParams -void DDMarshal::GetMethodDescParams(VMPTR_AppDomain vmAppDomain, VMPTR_MethodDesc vmMethodDesc, GENERICS_TYPE_TOKEN genericsToken, UINT32 * pcGenericClassTypeParams, TypeParamsList * pGenericTypeParams) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetMethodDescParams); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmAppDomain); - WriteToBuffer(&bSend, vmMethodDesc); - WriteToBuffer(&bSend, genericsToken); - // pcGenericClassTypeParams does not need to be copied on input - // pGenericTypeParams does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pcGenericClassTypeParams); - ReadFromBuffer(&bRecv, pGenericTypeParams); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetMethodDescParams - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetThreadOrContextStaticAddress -CORDB_ADDRESS DDMarshal::GetThreadOrContextStaticAddress(VMPTR_FieldDesc vmField, VMPTR_Thread vmRuntimeThread) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetThreadOrContextStaticAddress); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmField); - WriteToBuffer(&bSend, vmRuntimeThread); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - CORDB_ADDRESS _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetThreadOrContextStaticAddress - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetCollectibleTypeStaticAddress -CORDB_ADDRESS DDMarshal::GetCollectibleTypeStaticAddress(VMPTR_FieldDesc vmField, VMPTR_AppDomain vmAppDomain) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetCollectibleTypeStaticAddress); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmField); - WriteToBuffer(&bSend, vmAppDomain); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - CORDB_ADDRESS _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetCollectibleTypeStaticAddress - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetEnCHangingFieldInfo -void DDMarshal::GetEnCHangingFieldInfo(const EnCHangingFieldInfo * pEnCFieldInfo, FieldData * pFieldData, BOOL * pfStatic) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetEnCHangingFieldInfo); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, pEnCFieldInfo); - // pFieldData does not need to be copied on input - // pfStatic does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pFieldData); - ReadFromBuffer(&bRecv, pfStatic); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetEnCHangingFieldInfo - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetTypeHandleParams -void DDMarshal::GetTypeHandleParams(VMPTR_AppDomain vmAppDomain, VMPTR_TypeHandle vmTypeHandle, TypeParamsList * pParams) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetTypeHandleParams); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmAppDomain); - WriteToBuffer(&bSend, vmTypeHandle); - // pParams does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pParams); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetTypeHandleParams - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetSimpleType -void DDMarshal::GetSimpleType(VMPTR_AppDomain vmAppDomain, CorElementType simpleType, mdTypeDef * pMetadataToken, VMPTR_Module * pVmModule, VMPTR_DomainFile * pVmDomainFile) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetSimpleType); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmAppDomain); - WriteToBuffer(&bSend, simpleType); - // pMetadataToken does not need to be copied on input - // pVmModule does not need to be copied on input - // pVmDomainFile does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pMetadataToken); - ReadFromBuffer(&bRecv, pVmModule); - ReadFromBuffer(&bRecv, pVmDomainFile); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetSimpleType - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::IsExceptionObject -BOOL DDMarshal::IsExceptionObject(VMPTR_Object vmObject) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_IsExceptionObject); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmObject); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - BOOL _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method IsExceptionObject - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetStackFramesFromException -void DDMarshal::GetStackFramesFromException(VMPTR_Object vmObject, DacDbiArrayList<DacExceptionCallStackData> & dacStackFrames) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetStackFramesFromException); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmObject); - WriteToBuffer(&bSend, dacStackFrames); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, dacStackFrames); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetStackFramesFromException - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::IsRcw -BOOL DDMarshal::IsRcw(VMPTR_Object vmObject) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_IsRcw); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmObject); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - BOOL _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method IsRcw - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetRcwCachedInterfaceTypes -void DDMarshal::GetRcwCachedInterfaceTypes(VMPTR_Object vmObject, VMPTR_AppDomain vmAppDomain, BOOL bIInspectableOnly, DacDbiArrayList<DebuggerIPCE_ExpandedTypeData> * pDacInterfaces) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetRcwCachedInterfaceTypes); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmObject); - WriteToBuffer(&bSend, vmAppDomain); - WriteToBuffer(&bSend, bIInspectableOnly); - // pDacInterfaces does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pDacInterfaces); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetRcwCachedInterfaceTypes - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetRcwCachedInterfacePointers -void DDMarshal::GetRcwCachedInterfacePointers(VMPTR_Object vmObject, BOOL bIInspectableOnly, DacDbiArrayList<CORDB_ADDRESS> * pDacItfPtrs) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetRcwCachedInterfacePointers); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmObject); - WriteToBuffer(&bSend, bIInspectableOnly); - // pDacItfPtrs does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pDacItfPtrs); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetRcwCachedInterfacePointers - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetCachedWinRTTypesForIIDs -void DDMarshal::GetCachedWinRTTypesForIIDs(VMPTR_AppDomain vmAppDomain, DacDbiArrayList<GUID> & iids, DacDbiArrayList<DebuggerIPCE_ExpandedTypeData> * pTypes) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetCachedWinRTTypesForIIDs); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmAppDomain); - WriteToBuffer(&bSend, iids); - // pTypes does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, iids); - ReadFromBuffer(&bRecv, pTypes); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetCachedWinRTTypesForIIDs - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetCachedWinRTTypes -void DDMarshal::GetCachedWinRTTypes(VMPTR_AppDomain vmAppDomain, DacDbiArrayList<GUID> * piids, DacDbiArrayList<DebuggerIPCE_ExpandedTypeData> * pTypes) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetCachedWinRTTypes); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmAppDomain); - // piids does not need to be copied on input - // pTypes does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, piids); - ReadFromBuffer(&bRecv, pTypes); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetCachedWinRTTypes - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetTypedByRefInfo -void DDMarshal::GetTypedByRefInfo(CORDB_ADDRESS pTypedByRef, VMPTR_AppDomain vmAppDomain, DebuggerIPCE_ObjectData * pObjectData) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetTypedByRefInfo); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, pTypedByRef); - WriteToBuffer(&bSend, vmAppDomain); - WriteToBuffer(&bSend, pObjectData); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pObjectData); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetTypedByRefInfo - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetStringData -void DDMarshal::GetStringData(CORDB_ADDRESS objectAddress, DebuggerIPCE_ObjectData * pObjectData) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetStringData); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, objectAddress); - WriteToBuffer(&bSend, pObjectData); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pObjectData); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetStringData - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetArrayData -void DDMarshal::GetArrayData(CORDB_ADDRESS objectAddress, DebuggerIPCE_ObjectData * pObjectData) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetArrayData); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, objectAddress); - WriteToBuffer(&bSend, pObjectData); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pObjectData); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetArrayData - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetBasicObjectInfo -void DDMarshal::GetBasicObjectInfo(CORDB_ADDRESS objectAddress, CorElementType type, VMPTR_AppDomain vmAppDomain, DebuggerIPCE_ObjectData * pObjectData) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetBasicObjectInfo); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, objectAddress); - WriteToBuffer(&bSend, type); - WriteToBuffer(&bSend, vmAppDomain); - WriteToBuffer(&bSend, pObjectData); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pObjectData); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetBasicObjectInfo - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::TestCrst -void DDMarshal::TestCrst(VMPTR_Crst vmCrst) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_TestCrst); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmCrst); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method TestCrst - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::TestRWLock -void DDMarshal::TestRWLock(VMPTR_SimpleRWLock vmRWLock) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_TestRWLock); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmRWLock); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method TestRWLock - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetDebuggerControlBlockAddress -CORDB_ADDRESS DDMarshal::GetDebuggerControlBlockAddress() -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetDebuggerControlBlockAddress); // message id - // Copy in-parameters to the send-buffer - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - CORDB_ADDRESS _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetDebuggerControlBlockAddress - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetObjectFromRefPtr -VMPTR_Object DDMarshal::GetObjectFromRefPtr(CORDB_ADDRESS ptr) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetObjectFromRefPtr); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, ptr); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - VMPTR_Object _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetObjectFromRefPtr - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetObject -VMPTR_Object DDMarshal::GetObject(CORDB_ADDRESS ptr) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetObject); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, ptr); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - VMPTR_Object _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetObject - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::EnableNGENPolicy -HRESULT DDMarshal::EnableNGENPolicy(CorDebugNGENPolicy ePolicy) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_EnableNGENPolicy); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, ePolicy); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - HRESULT _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method EnableNGENPolicy - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetVmObjectHandle -VMPTR_OBJECTHANDLE DDMarshal::GetVmObjectHandle(CORDB_ADDRESS handleAddress) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetVmObjectHandle); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, handleAddress); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - VMPTR_OBJECTHANDLE _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetVmObjectHandle - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::IsVmObjectHandleValid -BOOL DDMarshal::IsVmObjectHandleValid(VMPTR_OBJECTHANDLE vmHandle) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_IsVmObjectHandleValid); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmHandle); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - BOOL _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method IsVmObjectHandleValid - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::IsWinRTModule -HRESULT DDMarshal::IsWinRTModule(VMPTR_Module vmModule, BOOL & isWinRT) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_IsWinRTModule); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmModule); - WriteToBuffer(&bSend, isWinRT); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, isWinRT); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - HRESULT _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method IsWinRTModule - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetAppDomainIdFromVmObjectHandle -ULONG DDMarshal::GetAppDomainIdFromVmObjectHandle(VMPTR_OBJECTHANDLE vmHandle) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetAppDomainIdFromVmObjectHandle); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmHandle); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - ULONG _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetAppDomainIdFromVmObjectHandle - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetHandleAddressFromVmHandle -CORDB_ADDRESS DDMarshal::GetHandleAddressFromVmHandle(VMPTR_OBJECTHANDLE vmHandle) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetHandleAddressFromVmHandle); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmHandle); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - CORDB_ADDRESS _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetHandleAddressFromVmHandle - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetObjectContents -TargetBuffer DDMarshal::GetObjectContents(VMPTR_Object obj) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetObjectContents); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, obj); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - TargetBuffer _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetObjectContents - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::EnumerateBlockingObjects -void DDMarshal::EnumerateBlockingObjects(VMPTR_Thread vmThread, IDacDbiInterface::FP_BLOCKINGOBJECT_ENUMERATION_CALLBACK fpCallback, CALLBACK_DATA pUserData) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_EnumerateBlockingObjects); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmThread); - // fpCallback does not need to be copied on input - // pUserData does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - // Result buffer contains the entire enumeration. Now iterate through that - // locally and invoke the user's callback. - while (true) - { - // Check status word before each element. - // 1 means there's another item. 2 means it's the end of the enumeration. - DWORD dw; - ReadFromBuffer(&bRecv, dw); - if (dw == 2) - break; - _ASSERTE(dw == 1); - - DacBlockingObject data; - ReadFromBuffer(&bRecv, data); - - // Invoke user callback. This may throw. - fpCallback(data, pUserData); - } - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method EnumerateBlockingObjects - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetThreadOwningMonitorLock -MonitorLockInfo DDMarshal::GetThreadOwningMonitorLock(VMPTR_Object vmObject) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetThreadOwningMonitorLock); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmObject); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - MonitorLockInfo _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetThreadOwningMonitorLock - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::EnumerateMonitorEventWaitList -void DDMarshal::EnumerateMonitorEventWaitList(VMPTR_Object vmObject, IDacDbiInterface::FP_THREAD_ENUMERATION_CALLBACK fpCallback, CALLBACK_DATA pUserData) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_EnumerateMonitorEventWaitList); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmObject); - // fpCallback does not need to be copied on input - // pUserData does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - // Result buffer contains the entire enumeration. Now iterate through that - // locally and invoke the user's callback. - while (true) - { - // Check status word before each element. - // 1 means there's another item. 2 means it's the end of the enumeration. - DWORD dw; - ReadFromBuffer(&bRecv, dw); - if (dw == 2) - break; - _ASSERTE(dw == 1); - - VMPTR_Thread data; - ReadFromBuffer(&bRecv, data); - - // Invoke user callback. This may throw. - fpCallback(data, pUserData); - } - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method EnumerateMonitorEventWaitList - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetAttachStateFlags -CLR_DEBUGGING_PROCESS_FLAGS DDMarshal::GetAttachStateFlags() -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetAttachStateFlags); // message id - // Copy in-parameters to the send-buffer - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - CLR_DEBUGGING_PROCESS_FLAGS _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetAttachStateFlags - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetMetaDataFileInfoFromPEFile -bool DDMarshal::GetMetaDataFileInfoFromPEFile(VMPTR_PEFile vmPEFile, DWORD & dwTimeStamp, DWORD & dwImageSize, bool & isNGEN, IStringHolder * pStrFilename) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetMetaDataFileInfoFromPEFile); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmPEFile); - WriteToBuffer(&bSend, dwTimeStamp); - WriteToBuffer(&bSend, dwImageSize); - WriteToBuffer(&bSend, isNGEN); - // pStrFilename does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, dwTimeStamp); - ReadFromBuffer(&bRecv, dwImageSize); - ReadFromBuffer(&bRecv, isNGEN); - ReadFromBuffer(&bRecv, pStrFilename); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - bool _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetMetaDataFileInfoFromPEFile - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetILImageInfoFromNgenPEFile -bool DDMarshal::GetILImageInfoFromNgenPEFile(VMPTR_PEFile vmPEFile, DWORD & dwTimeStamp, DWORD & dwSize, IStringHolder * pStrFilename) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetILImageInfoFromNgenPEFile); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmPEFile); - WriteToBuffer(&bSend, dwTimeStamp); - WriteToBuffer(&bSend, dwSize); - // pStrFilename does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, dwTimeStamp); - ReadFromBuffer(&bRecv, dwSize); - ReadFromBuffer(&bRecv, pStrFilename); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - bool _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetILImageInfoFromNgenPEFile - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::IsThreadSuspendedOrHijacked -bool DDMarshal::IsThreadSuspendedOrHijacked(VMPTR_Thread vmThread) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_IsThreadSuspendedOrHijacked); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, vmThread); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - bool _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method IsThreadSuspendedOrHijacked - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::AreGCStructuresValid -bool DDMarshal::AreGCStructuresValid() -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_AreGCStructuresValid); // message id - // Copy in-parameters to the send-buffer - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - bool _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method AreGCStructuresValid - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::CreateHeapWalk -HRESULT DDMarshal::CreateHeapWalk(HeapWalkHandle * pHandle) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_CreateHeapWalk); // message id - // Copy in-parameters to the send-buffer - // pHandle does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pHandle); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - HRESULT _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method CreateHeapWalk - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::DeleteHeapWalk -void DDMarshal::DeleteHeapWalk(HeapWalkHandle handle) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_DeleteHeapWalk); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, handle); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method DeleteHeapWalk - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::WalkHeap -HRESULT DDMarshal::WalkHeap(HeapWalkHandle handle, ULONG count, COR_HEAPOBJECT * objects, ULONG * pFetched) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_WalkHeap); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, handle); - WriteToBuffer(&bSend, count); - // objects does not need to be copied on input - // pFetched does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, objects); - ReadFromBuffer(&bRecv, pFetched); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - HRESULT _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method WalkHeap - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetHeapSegments -HRESULT DDMarshal::GetHeapSegments(DacDbiArrayList<COR_SEGMENT> * pSegments) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetHeapSegments); // message id - // Copy in-parameters to the send-buffer - // pSegments does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pSegments); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - HRESULT _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetHeapSegments - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::IsValidObject -bool DDMarshal::IsValidObject(CORDB_ADDRESS obj) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_IsValidObject); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, obj); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - bool _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method IsValidObject - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetAppDomainForObject -bool DDMarshal::GetAppDomainForObject(CORDB_ADDRESS obj, VMPTR_AppDomain * pApp, VMPTR_Module * pModule, VMPTR_DomainFile * pDomainFile) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetAppDomainForObject); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, obj); - // pApp does not need to be copied on input - // pModule does not need to be copied on input - // pDomainFile does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pApp); - ReadFromBuffer(&bRecv, pModule); - ReadFromBuffer(&bRecv, pDomainFile); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - bool _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetAppDomainForObject - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::CreateRefWalk -HRESULT DDMarshal::CreateRefWalk(RefWalkHandle * pHandle, BOOL walkStacks, BOOL walkFQ, UINT32 handleWalkMask) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_CreateRefWalk); // message id - // Copy in-parameters to the send-buffer - // pHandle does not need to be copied on input - WriteToBuffer(&bSend, walkStacks); - WriteToBuffer(&bSend, walkFQ); - WriteToBuffer(&bSend, handleWalkMask); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pHandle); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - HRESULT _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method CreateRefWalk - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::DeleteRefWalk -void DDMarshal::DeleteRefWalk(RefWalkHandle handle) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_DeleteRefWalk); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, handle); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method DeleteRefWalk - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::WalkRefs -HRESULT DDMarshal::WalkRefs(RefWalkHandle handle, ULONG count, DacGcReference * refs, ULONG * pFetched) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_WalkRefs); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, handle); - WriteToBuffer(&bSend, count); - // refs does not need to be copied on input - // pFetched does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, refs); - ReadFromBuffer(&bRecv, pFetched); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - HRESULT _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method WalkRefs - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetTypeID -HRESULT DDMarshal::GetTypeID(CORDB_ADDRESS obj, COR_TYPEID * pType) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetTypeID); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, obj); - WriteToBuffer(&bSend, pType); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pType); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - HRESULT _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetTypeID - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetObjectFields -HRESULT DDMarshal::GetObjectFields(COR_TYPEID id, ULONG32 celt, COR_FIELD * layout, ULONG32 * pceltFetched) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetObjectFields); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, id); - WriteToBuffer(&bSend, celt); - // layout does not need to be copied on input - // pceltFetched does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, layout); - ReadFromBuffer(&bRecv, pceltFetched); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - HRESULT _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetObjectFields - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetTypeLayout -HRESULT DDMarshal::GetTypeLayout(COR_TYPEID id, COR_TYPE_LAYOUT * pLayout) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetTypeLayout); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, id); - WriteToBuffer(&bSend, pLayout); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pLayout); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - HRESULT _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetTypeLayout - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetArrayLayout -HRESULT DDMarshal::GetArrayLayout(COR_TYPEID id, COR_ARRAY_LAYOUT * pLayout) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetArrayLayout); // message id - // Copy in-parameters to the send-buffer - WriteToBuffer(&bSend, id); - WriteToBuffer(&bSend, pLayout); - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pLayout); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - // Check return value - HRESULT _retValue; - ReadFromBuffer(&bRecv, _retValue); - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read - return _retValue; -} // end method GetArrayLayout - -//--------------------------------------------------------------------- -// Stub for virtual IDacDbiInterface::GetGCHeapInformation -void DDMarshal::GetGCHeapInformation(COR_HEAPINFO * pHeapInfo) -{ - WriteBuffer bSend; - ReadBuffer bRecv; - - WriteToBuffer(&bSend, DDID_GetGCHeapInformation); // message id - // Copy in-parameters to the send-buffer - // pHeapInfo does not need to be copied on input - - SendDDMessage(&bSend, &bRecv); - - //Copy out-parameters (including status and return value) from receive buffer - ReadFromBuffer(&bRecv, pHeapInfo); - - // Throw last so that any out-params are still updated. - HRESULT hrException; - ReadFromBuffer(&bRecv, hrException); - IfFailThrow(hrException); - - _ASSERTE(bRecv.IsAtEnd()); // ensure buffer is fully read -} // end method GetGCHeapInformation - - -#endif //FEATURE_DBGIPC_TRANSPORT_DI - -// end of file - diff --git a/src/debug/di/ddpack.h b/src/debug/di/ddpack.h deleted file mode 100644 index a83eb1ccb7..0000000000 --- a/src/debug/di/ddpack.h +++ /dev/null @@ -1,346 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -// Packer -// -// Lives on debugger right-side -// -// Note that this file is generated by ndp\clr\src\Debug\tools\BuildDDMarshal\. -// Changes should be made to output\DDPack_template.h in that directory. -// - - -#ifndef _DD_PACK_H_ -#define _DD_PACK_H_ - -#ifdef FEATURE_DBGIPC_TRANSPORT_DI - - class WriteBuffer; - class ReadBuffer; - - // Flow is: - // RS --> DDPack --> byte streams --> DDUnpack --> Real IDacDbiInterface - - // PAck up DD interface to a byte-sream. - class DDMarshal : public IDacDbiInterface - { - public: - /* - DDMarshal(IDacDbiInterface * pReal, DDUnpack * pUnpack) - { - m_pReal = pReal; - m_pUnpack = pUnpack; - } - // Used for trivial wrappers where we can't marshal yet. - IDacDbiInterface * m_pReal; - - // The unpacker that gets called on the other side. - DDUnpack * m_pUnpack; - - */ - - DDMarshal(CordbProcess * pProcess) - { - m_pProcess = pProcess; - m_sLock.Init("DDMarshal Lock", RSLock::cLockFlat, RSLock::LL_DD_MARSHAL_LOCK); - } - - ~DDMarshal() - { - m_sLock.Destroy(); - } - - HRESULT Init(); - - DbgTransportTarget * m_pProxy; - DbgTransportSession * m_pTransport; - CordbProcess * m_pProcess; - RSLock m_sLock; - - // Each DD interface boils down to calling Send. - void SendDDMessage(WriteBuffer * pSend, ReadBuffer * pResult); - - - // Sig without '=0' at end; - // virtual BOOL IsAssemblyFullyTrusted(VMPTR_DomainAssembly vmDomainAssembly, T* myRef, MyStruct * pStruct); -// -// Signature definitions -// -virtual HRESULT CheckDbiVersion(const DbiVersion * pVersion); - -virtual void GetLocalInterfaceHashAndTimestamp(DWORD & hash1, DWORD & hash2, DWORD & hash3, DWORD & hash4, DWORD & timestamp1, DWORD & timestamp2); - -virtual void GetRemoteInterfaceHashAndTimestamp(DWORD & hash1, DWORD & hash2, DWORD & hash3, DWORD & hash4, DWORD & timestamp1, DWORD & timestamp2); - -virtual HRESULT FlushCache(); - -virtual void DacSetTargetConsistencyChecks(bool fEnableAsserts); - -virtual void Destroy(); - -virtual BOOL IsLeftSideInitialized(); - -virtual VMPTR_AppDomain GetAppDomainFromId(ULONG appdomainId); - -virtual ULONG GetAppDomainId(VMPTR_AppDomain vmAppDomain); - -virtual VMPTR_OBJECTHANDLE GetAppDomainObject(VMPTR_AppDomain vmAppDomain); - -virtual BOOL IsDefaultDomain(VMPTR_AppDomain vmAppDomain); - -virtual void GetAssemblyFromDomainAssembly(VMPTR_DomainAssembly vmDomainAssembly, VMPTR_Assembly * vmAssembly); - -virtual BOOL IsAssemblyFullyTrusted(VMPTR_DomainAssembly vmDomainAssembly); - -virtual void GetAppDomainFullName(VMPTR_AppDomain vmAppDomain, IStringHolder * pStrName); - -virtual void GetModuleSimpleName(VMPTR_Module vmModule, IStringHolder * pStrFilename); - -virtual BOOL GetAssemblyPath(VMPTR_Assembly vmAssembly, IStringHolder * pStrFilename); - -virtual void ResolveTypeReference(const TypeRefData * pTypeRefInfo, TypeRefData * pTargetRefInfo); - -virtual BOOL GetModulePath(VMPTR_Module vmModule, IStringHolder * pStrFilename); - -virtual BOOL GetModuleNGenPath(VMPTR_Module vmModule, IStringHolder * pStrFilename); - -virtual void GetMetadata(VMPTR_Module vmModule, TargetBuffer * pTargetBuffer); - -virtual void GetSymbolsBuffer(VMPTR_Module vmModule, TargetBuffer * pTargetBuffer, IDacDbiInterface::SymbolFormat * pSymbolFormat); - -virtual void GetModuleData(VMPTR_Module vmModule, ModuleInfo * pData); - -virtual void GetDomainFileData(VMPTR_DomainFile vmDomainFile, DomainFileInfo * pData); - -virtual void GetModuleForDomainFile(VMPTR_DomainFile vmDomainFile, VMPTR_Module * pModule); - -virtual IDacDbiInterface::AddressType GetAddressType(CORDB_ADDRESS address); - -virtual BOOL IsTransitionStub(CORDB_ADDRESS address); - -virtual void GetCompilerFlags(VMPTR_DomainFile vmDomainFile, BOOL * pfAllowJITOpts, BOOL * pfEnableEnC); - -virtual HRESULT SetCompilerFlags(VMPTR_DomainFile vmDomainFile, BOOL fAllowJitOpts, BOOL fEnableEnC); - -virtual void EnumerateAppDomains(IDacDbiInterface::FP_APPDOMAIN_ENUMERATION_CALLBACK fpCallback, CALLBACK_DATA pUserData); - -virtual void EnumerateAssembliesInAppDomain(VMPTR_AppDomain vmAppDomain, IDacDbiInterface::FP_ASSEMBLY_ENUMERATION_CALLBACK fpCallback, CALLBACK_DATA pUserData); - -virtual void EnumerateModulesInAssembly(VMPTR_DomainAssembly vmAssembly, IDacDbiInterface::FP_MODULE_ENUMERATION_CALLBACK fpCallback, CALLBACK_DATA pUserData); - -virtual void RequestSyncAtEvent(); - -virtual void MarkDebuggerAttachPending(); - -virtual void MarkDebuggerAttached(BOOL fAttached); - -virtual void Hijack(VMPTR_Thread vmThread, ULONG32 dwThreadId, const EXCEPTION_RECORD * pRecord, T_CONTEXT * pOriginalContext, ULONG32 cbSizeContext, EHijackReason::EHijackReason reason, void * pUserData, CORDB_ADDRESS * pRemoteContextAddr); - -virtual void EnumerateConnections(IDacDbiInterface::FP_CONNECTION_CALLBACK fpCallback, CALLBACK_DATA pUserData); - -virtual void EnumerateThreads(IDacDbiInterface::FP_THREAD_ENUMERATION_CALLBACK fpCallback, CALLBACK_DATA pUserData); - -virtual bool IsThreadMarkedDead(VMPTR_Thread vmThread); - -virtual HANDLE GetThreadHandle(VMPTR_Thread vmThread); - -virtual VMPTR_OBJECTHANDLE GetThreadObject(VMPTR_Thread vmThread); - -virtual void SetDebugState(VMPTR_Thread vmThread, CorDebugThreadState debugState); - -virtual BOOL HasUnhandledException(VMPTR_Thread vmThread); - -virtual CorDebugUserState GetUserState(VMPTR_Thread vmThread); - -virtual CONNID GetConnectionID(VMPTR_Thread vmThread); - -virtual TASKID GetTaskID(VMPTR_Thread vmThread); - -virtual DWORD TryGetVolatileOSThreadID(VMPTR_Thread vmThread); - -virtual DWORD GetUniqueThreadID(VMPTR_Thread vmThread); - -virtual VMPTR_OBJECTHANDLE GetCurrentException(VMPTR_Thread vmThread); - -virtual VMPTR_OBJECTHANDLE GetCurrentCustomDebuggerNotification(VMPTR_Thread vmThread); - -virtual VMPTR_AppDomain GetCurrentAppDomain(VMPTR_Thread vmThread); - -virtual VMPTR_DomainAssembly ResolveAssembly(VMPTR_DomainFile vmScope, mdToken tkAssemblyRef); - -virtual void GetNativeCodeSequencePointsAndVarInfo(VMPTR_MethodDesc vmMethodDesc, CORDB_ADDRESS startAddress, BOOL fCodeAvailabe, NativeVarData * pNativeVarData, SequencePoints * pSequencePoints); - -virtual VMPTR_CONTEXT GetManagedStoppedContext(VMPTR_Thread vmThread); - -virtual void CreateStackWalk(VMPTR_Thread vmThread, DT_CONTEXT * pInternalContextBuffer, StackWalkHandle * ppSFIHandle); - -virtual void DeleteStackWalk(StackWalkHandle ppSFIHandle); - -virtual void GetStackWalkCurrentContext(StackWalkHandle pSFIHandle, DT_CONTEXT * pContext); - -virtual void SetStackWalkCurrentContext(VMPTR_Thread vmThread, StackWalkHandle pSFIHandle, CorDebugSetContextFlag flag, DT_CONTEXT * pContext); - -virtual BOOL UnwindStackWalkFrame(StackWalkHandle pSFIHandle); - -virtual HRESULT CheckContext(VMPTR_Thread vmThread, const DT_CONTEXT * pContext); - -virtual IDacDbiInterface::FrameType GetStackWalkCurrentFrameInfo(StackWalkHandle pSFIHandle, DebuggerIPCE_STRData * pFrameData); - -virtual ULONG32 GetCountOfInternalFrames(VMPTR_Thread vmThread); - -virtual void EnumerateInternalFrames(VMPTR_Thread vmThread, IDacDbiInterface::FP_INTERNAL_FRAME_ENUMERATION_CALLBACK fpCallback, CALLBACK_DATA pUserData); - -virtual BOOL IsMatchingParentFrame(FramePointer fpToCheck, FramePointer fpParent); - -virtual ULONG32 GetStackParameterSize(CORDB_ADDRESS controlPC); - -virtual FramePointer GetFramePointer(StackWalkHandle pSFIHandle); - -virtual BOOL IsLeafFrame(VMPTR_Thread vmThread, const DT_CONTEXT * pContext); - -virtual void GetContext(VMPTR_Thread vmThread, DT_CONTEXT * pContextBuffer); - -virtual void ConvertContextToDebuggerRegDisplay(const DT_CONTEXT * pInContext, DebuggerREGDISPLAY * pOutDRD, BOOL fActive); - -virtual IDacDbiInterface::DynamicMethodType IsILStubOrLCGMethod(VMPTR_MethodDesc vmMethodDesc); - -virtual TargetBuffer GetVarArgSig(CORDB_ADDRESS VASigCookieAddr, CORDB_ADDRESS * pArgBase); - -virtual BOOL RequiresAlign8(VMPTR_TypeHandle thExact); - -virtual GENERICS_TYPE_TOKEN ResolveExactGenericArgsToken(DWORD dwExactGenericArgsTokenIndex, GENERICS_TYPE_TOKEN rawToken); - -virtual void GetILCodeAndSig(VMPTR_DomainFile vmDomainFile, mdToken functionToken, TargetBuffer * pCodeInfo, mdToken * pLocalSigToken); - -virtual void GetNativeCodeInfo(VMPTR_DomainFile vmDomainFile, mdToken functionToken, NativeCodeFunctionData * pCodeInfo); - -virtual void GetNativeCodeInfoForAddr(VMPTR_MethodDesc vmMethodDesc, CORDB_ADDRESS hotCodeStartAddr, NativeCodeFunctionData * pCodeInfo); - -virtual void GetClassInfo(VMPTR_AppDomain vmAppDomain, VMPTR_Module vmModule, mdTypeDef metadataToken, VMPTR_TypeHandle thExact, VMPTR_TypeHandle thApprox, ClassInfo * pData); - -virtual void GetInstantiationFieldInfo(VMPTR_DomainFile vmDomainFile, mdTypeDef metadataToken, VMPTR_TypeHandle vmThExact, VMPTR_TypeHandle vmThApprox, DacDbiArrayList<FieldData> * pFieldList, SIZE_T * pObjectSize); - -virtual void TypeHandleToExpandedTypeInfo(AreValueTypesBoxed boxed, VMPTR_AppDomain vmAppDomain, VMPTR_TypeHandle vmTypeHandle, DebuggerIPCE_ExpandedTypeData * pTypeInfo); - -virtual void GetObjectExpandedTypeInfo(AreValueTypesBoxed boxed, VMPTR_AppDomain vmAppDomain, CORDB_ADDRESS addr, DebuggerIPCE_ExpandedTypeData * pTypeInfo); - -virtual void GetObjectExpandedTypeInfoFromID(AreValueTypesBoxed boxed, VMPTR_AppDomain vmAppDomain, COR_TYPEID id, DebuggerIPCE_ExpandedTypeData * pTypeInfo); - -virtual VMPTR_TypeHandle GetApproxTypeHandle(TypeInfoList * pTypeData); - -virtual HRESULT GetExactTypeHandle(DebuggerIPCE_ExpandedTypeData * pTypeData, ArgInfoList * pArgInfo, VMPTR_TypeHandle & vmTypeHandle); - -virtual void GetMethodDescParams(VMPTR_AppDomain vmAppDomain, VMPTR_MethodDesc vmMethodDesc, GENERICS_TYPE_TOKEN genericsToken, UINT32 * pcGenericClassTypeParams, TypeParamsList * pGenericTypeParams); - -virtual CORDB_ADDRESS GetThreadOrContextStaticAddress(VMPTR_FieldDesc vmField, VMPTR_Thread vmRuntimeThread); - -virtual CORDB_ADDRESS GetCollectibleTypeStaticAddress(VMPTR_FieldDesc vmField, VMPTR_AppDomain vmAppDomain); - -virtual void GetEnCHangingFieldInfo(const EnCHangingFieldInfo * pEnCFieldInfo, FieldData * pFieldData, BOOL * pfStatic); - -virtual void GetTypeHandleParams(VMPTR_AppDomain vmAppDomain, VMPTR_TypeHandle vmTypeHandle, TypeParamsList * pParams); - -virtual void GetSimpleType(VMPTR_AppDomain vmAppDomain, CorElementType simpleType, mdTypeDef * pMetadataToken, VMPTR_Module * pVmModule, VMPTR_DomainFile * pVmDomainFile); - -virtual BOOL IsExceptionObject(VMPTR_Object vmObject); - -virtual void GetStackFramesFromException(VMPTR_Object vmObject, DacDbiArrayList<DacExceptionCallStackData> & dacStackFrames); - -virtual BOOL IsRcw(VMPTR_Object vmObject); - -virtual void GetRcwCachedInterfaceTypes(VMPTR_Object vmObject, VMPTR_AppDomain vmAppDomain, BOOL bIInspectableOnly, DacDbiArrayList<DebuggerIPCE_ExpandedTypeData> * pDacInterfaces); - -virtual void GetRcwCachedInterfacePointers(VMPTR_Object vmObject, BOOL bIInspectableOnly, DacDbiArrayList<CORDB_ADDRESS> * pDacItfPtrs); - -virtual void GetCachedWinRTTypesForIIDs(VMPTR_AppDomain vmAppDomain, DacDbiArrayList<GUID> & iids, DacDbiArrayList<DebuggerIPCE_ExpandedTypeData> * pTypes); - -virtual void GetCachedWinRTTypes(VMPTR_AppDomain vmAppDomain, DacDbiArrayList<GUID> * piids, DacDbiArrayList<DebuggerIPCE_ExpandedTypeData> * pTypes); - -virtual void GetTypedByRefInfo(CORDB_ADDRESS pTypedByRef, VMPTR_AppDomain vmAppDomain, DebuggerIPCE_ObjectData * pObjectData); - -virtual void GetStringData(CORDB_ADDRESS objectAddress, DebuggerIPCE_ObjectData * pObjectData); - -virtual void GetArrayData(CORDB_ADDRESS objectAddress, DebuggerIPCE_ObjectData * pObjectData); - -virtual void GetBasicObjectInfo(CORDB_ADDRESS objectAddress, CorElementType type, VMPTR_AppDomain vmAppDomain, DebuggerIPCE_ObjectData * pObjectData); - -virtual void TestCrst(VMPTR_Crst vmCrst); - -virtual void TestRWLock(VMPTR_SimpleRWLock vmRWLock); - -virtual CORDB_ADDRESS GetDebuggerControlBlockAddress(); - -virtual VMPTR_Object GetObjectFromRefPtr(CORDB_ADDRESS ptr); - -virtual VMPTR_Object GetObject(CORDB_ADDRESS ptr); - -virtual HRESULT EnableNGENPolicy(CorDebugNGENPolicy ePolicy); - -virtual VMPTR_OBJECTHANDLE GetVmObjectHandle(CORDB_ADDRESS handleAddress); - -virtual BOOL IsVmObjectHandleValid(VMPTR_OBJECTHANDLE vmHandle); - -virtual HRESULT IsWinRTModule(VMPTR_Module vmModule, BOOL & isWinRT); - -virtual ULONG GetAppDomainIdFromVmObjectHandle(VMPTR_OBJECTHANDLE vmHandle); - -virtual CORDB_ADDRESS GetHandleAddressFromVmHandle(VMPTR_OBJECTHANDLE vmHandle); - -virtual TargetBuffer GetObjectContents(VMPTR_Object obj); - -virtual void EnumerateBlockingObjects(VMPTR_Thread vmThread, IDacDbiInterface::FP_BLOCKINGOBJECT_ENUMERATION_CALLBACK fpCallback, CALLBACK_DATA pUserData); - -virtual MonitorLockInfo GetThreadOwningMonitorLock(VMPTR_Object vmObject); - -virtual void EnumerateMonitorEventWaitList(VMPTR_Object vmObject, IDacDbiInterface::FP_THREAD_ENUMERATION_CALLBACK fpCallback, CALLBACK_DATA pUserData); - -virtual CLR_DEBUGGING_PROCESS_FLAGS GetAttachStateFlags(); - -virtual bool GetMetaDataFileInfoFromPEFile(VMPTR_PEFile vmPEFile, DWORD & dwTimeStamp, DWORD & dwImageSize, bool & isNGEN, IStringHolder * pStrFilename); - -virtual bool GetILImageInfoFromNgenPEFile(VMPTR_PEFile vmPEFile, DWORD & dwTimeStamp, DWORD & dwSize, IStringHolder * pStrFilename); - -virtual bool IsThreadSuspendedOrHijacked(VMPTR_Thread vmThread); - -virtual bool AreGCStructuresValid(); - -virtual HRESULT CreateHeapWalk(HeapWalkHandle * pHandle); - -virtual void DeleteHeapWalk(HeapWalkHandle handle); - -virtual HRESULT WalkHeap(HeapWalkHandle handle, ULONG count, COR_HEAPOBJECT * objects, ULONG * pFetched); - -virtual HRESULT GetHeapSegments(DacDbiArrayList<COR_SEGMENT> * pSegments); - -virtual bool IsValidObject(CORDB_ADDRESS obj); - -virtual bool GetAppDomainForObject(CORDB_ADDRESS obj, VMPTR_AppDomain * pApp, VMPTR_Module * pModule, VMPTR_DomainFile * pDomainFile); - -virtual HRESULT CreateRefWalk(RefWalkHandle * pHandle, BOOL walkStacks, BOOL walkFQ, UINT32 handleWalkMask); - -virtual void DeleteRefWalk(RefWalkHandle handle); - -virtual HRESULT WalkRefs(RefWalkHandle handle, ULONG count, DacGcReference * refs, ULONG * pFetched); - -virtual HRESULT GetTypeID(CORDB_ADDRESS obj, COR_TYPEID * pType); - -virtual HRESULT GetObjectFields(COR_TYPEID id, ULONG32 celt, COR_FIELD * layout, ULONG32 * pceltFetched); - -virtual HRESULT GetTypeLayout(COR_TYPEID id, COR_TYPE_LAYOUT * pLayout); - -virtual HRESULT GetArrayLayout(COR_TYPEID id, COR_ARRAY_LAYOUT * pLayout); - -virtual void GetGCHeapInformation(COR_HEAPINFO * pHeapInfo); - - - - }; - -#endif //FEATURE_DBGIPC_TRANSPORT_DI - - -#endif // _DD_PACK_H_ - -// end of file diff --git a/src/debug/di/eventchannel.h b/src/debug/di/eventchannel.h index 232f6e0a10..9bdd2c7479 100644 --- a/src/debug/di/eventchannel.h +++ b/src/debug/di/eventchannel.h @@ -58,7 +58,7 @@ // - LS: code:DebuggerRCThread::SendIPCEvent // // In a sense, you can think of the LS and the RS sharing 3 channels: one for debug events (see -// code:INativeEventPipeline), one for DDI calls (see code:IDacDbiInterface and code:DDMarshal::SendDDMessage), +// code:INativeEventPipeline), one for DDI calls (see code:IDacDbiInterface), // and one for "IPC" events. This is the interface for the "IPC" events. // diff --git a/src/debug/di/platformspecific.cpp b/src/debug/di/platformspecific.cpp index b7cdfe228e..1acd4fc186 100644 --- a/src/debug/di/platformspecific.cpp +++ b/src/debug/di/platformspecific.cpp @@ -17,8 +17,6 @@ #include "dbgtransportpipeline.cpp" #include "shimremotedatatarget.cpp" #include "remoteeventchannel.cpp" -#include "ddpack.cpp" -#elif FEATURE_PAL #else #include "WindowsPipeline.cpp" #include "EventRedirectionPipeline.cpp" diff --git a/src/debug/di/process.cpp b/src/debug/di/process.cpp index fcf9d8ff35..2653f5627f 100644 --- a/src/debug/di/process.cpp +++ b/src/debug/di/process.cpp @@ -1198,6 +1198,7 @@ HRESULT ShimProcess::DebugActiveProcess( _ASSERTE(SUCCEEDED(hr)); +#if !defined(FEATURE_DBGIPC_TRANSPORT_DI) // Don't do this when we are remote debugging since we won't be getting the loader breakpoint. // We don't support JIT attach in remote debugging scenarios anyway. // @@ -1229,6 +1230,7 @@ HRESULT ShimProcess::DebugActiveProcess( // Wait for the completion of marking pending attach bit or debugger detaching WaitForMultipleObjectsEx(dwHandles, arrHandles, FALSE, INFINITE, FALSE); } +#endif //!FEATURE_DBGIPC_TRANSPORT_DI } EX_CATCH_HRESULT(hr); @@ -2138,10 +2140,10 @@ HRESULT CordbProcess::QueryInterface(REFIID id, void **pInterface) { *pInterface = static_cast<ICorDebugProcess7*>(this); } - else if (id == IID_ICorDebugProcess8) - { - *pInterface = static_cast<ICorDebugProcess8*>(this); - } + else if (id == IID_ICorDebugProcess8) + { + *pInterface = static_cast<ICorDebugProcess8*>(this); + } #ifdef FEATURE_LEGACYNETCF_DBG_HOST_CONTROL else if (id == IID_ICorDebugLegacyNetCFHostCallbackInvoker_PrivateWindowsPhoneOnly) { @@ -7491,7 +7493,7 @@ void CordbProcess::GetEventBlock(BOOL * pfBlockExists) // Verify that the control block is valid. // This will throw on error. VerifyControlBlock(); - + *pfBlockExists = true; } else @@ -7654,8 +7656,8 @@ HRESULT CordbProcess::GetRuntimeOffsets() #elif FEATURE_PAL m_hHelperThread = NULL; //RS is supposed to be able to live without a helper thread handle. #else - m_hHelperThread = OpenThread(SYNCHRONIZE, FALSE, dwHelperTid); - CONSISTENCY_CHECK_MSGF(m_hHelperThread != NULL, ("Failed to get helper-thread handle. tid=0x%x\n", dwHelperTid)); + m_hHelperThread = OpenThread(SYNCHRONIZE, FALSE, dwHelperTid); + CONSISTENCY_CHECK_MSGF(m_hHelperThread != NULL, ("Failed to get helper-thread handle. tid=0x%x\n", dwHelperTid)); #endif } @@ -9825,12 +9827,11 @@ HRESULT CordbProcess::EnsureClrInstanceIdSet() { #ifdef FEATURE_CORESYSTEM - _ASSERTE(m_cordb->GetTargetCLR() != 0); - if(m_cordb->GetTargetCLR() != 0) - { - m_clrInstanceId = PTR_TO_CORDB_ADDRESS(m_cordb->GetTargetCLR()); - return S_OK; - } + if(m_cordb->GetTargetCLR() != 0) + { + m_clrInstanceId = PTR_TO_CORDB_ADDRESS(m_cordb->GetTargetCLR()); + return S_OK; + } #endif // The only case in which we're allowed to request the "default" CLR instance @@ -11827,26 +11828,26 @@ CordbUnmanagedThread * CordbProcess::GetUnmanagedThreadFromEvent(const DEBUG_EVE this->GetEventBlock(&fBlockExists); - // 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) - { - // get the latest LS DCB information - UpdateRightSideDCB(); - if ((this->GetDCB()->m_helperThreadStartAddr != NULL) && (pUnmanagedThread != NULL)) - { - void * pStartAddr = GetThreadUserStartAddr(pEvent); - - if (pStartAddr == this->GetDCB()->m_helperThreadStartAddr) - { - // Remember the ID of the helper thread. - this->m_helperThreadId = pEvent->dwThreadId; - - LOG((LF_CORDB, LL_INFO1000, "W32ET::W32EL: Left Side Helper Thread is 0x%x\n", pEvent->dwThreadId)); - } - } - } + // 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) + { + // get the latest LS DCB information + UpdateRightSideDCB(); + if ((this->GetDCB()->m_helperThreadStartAddr != NULL) && (pUnmanagedThread != NULL)) + { + void * pStartAddr = GetThreadUserStartAddr(pEvent); + + if (pStartAddr == this->GetDCB()->m_helperThreadStartAddr) + { + // Remember the ID of the helper thread. + this->m_helperThreadId = pEvent->dwThreadId; + + LOG((LF_CORDB, LL_INFO1000, "W32ET::W32EL: Left Side Helper Thread is 0x%x\n", pEvent->dwThreadId)); + } + } + } } EX_CATCH_HRESULT(hr) { diff --git a/src/debug/di/remoteeventchannel.cpp b/src/debug/di/remoteeventchannel.cpp index 7699808f55..f57ecff884 100644 --- a/src/debug/di/remoteeventchannel.cpp +++ b/src/debug/di/remoteeventchannel.cpp @@ -101,15 +101,9 @@ HRESULT NewEventChannelForThisPlatform(CORDB_ADDRESS pLeftSideDCB, RemoteEventChannel * pEventChannel = NULL; DebuggerIPCControlBlock * pDCBBuffer = NULL; - DbgTransportTarget * pProxy = NULL; + DbgTransportTarget * pProxy = g_pDbgTransportTarget; DbgTransportSession * pTransport = NULL; - hr = g_pDbgTransportManager->ConnectToTarget(machineInfo.GetIPAddress(), machineInfo.GetPort(), &pProxy); - if (FAILED(hr)) - { - goto Label_Exit; - } - hr = pProxy->GetTransportForProcess(dwProcessId, &pTransport, &hDummy); if (FAILED(hr)) { @@ -154,12 +148,6 @@ Label_Exit: { pProxy->ReleaseTransport(pTransport); } - - if (pProxy != NULL) - { - g_pDbgTransportManager->ReleaseTarget(pProxy); - } - if (pDCBBuffer != NULL) { delete pDCBBuffer; @@ -222,11 +210,6 @@ void RemoteEventChannel::Delete() m_pProxy->ReleaseTransport(m_pTransport); } - if (m_pProxy != NULL) - { - g_pDbgTransportManager->ReleaseTarget(m_pProxy); - } - delete this; } @@ -315,7 +298,7 @@ HRESULT RemoteEventChannel::SendEventToLeftSide(DebuggerIPCEvent * pEvent, SIZE_ HRESULT RemoteEventChannel::GetReplyFromLeftSide(DebuggerIPCEvent * pReplyEvent, SIZE_T eventSize) { // Delegate to the transport. - m_pTransport->GetNextEvent(pReplyEvent, eventSize); + m_pTransport->GetNextEvent(pReplyEvent, (DWORD)eventSize); return S_OK; } diff --git a/src/debug/di/shimlocaldatatarget.cpp b/src/debug/di/shimlocaldatatarget.cpp index 66dd64a02d..45d0b6cebe 100644 --- a/src/debug/di/shimlocaldatatarget.cpp +++ b/src/debug/di/shimlocaldatatarget.cpp @@ -80,6 +80,9 @@ private: // Note: throws BOOL CompatibleHostAndTargetPlatforms(HANDLE hTargetProcess) { +#if defined(FEATURE_PAL) + return TRUE; +#else // get the platform for the host process BOOL fHostProcessIsWow64 = FALSE; BOOL fSuccess = FALSE; @@ -118,6 +121,7 @@ BOOL CompatibleHostAndTargetPlatforms(HANDLE hTargetProcess) { return TRUE; } +#endif } // CompatibleHostAndTargetPlatforms // Helper macro to check for failure conditions at the start of data-target methods. diff --git a/src/debug/di/shimpriv.h b/src/debug/di/shimpriv.h index a402abf503..c3a505175c 100644 --- a/src/debug/di/shimpriv.h +++ b/src/debug/di/shimpriv.h @@ -518,10 +518,8 @@ protected: HANDLE m_markAttachPendingEvent; HANDLE m_terminatingEvent; -#if !defined(FEATURE_CORESYSTEM) - // Finds the base address of mscorwks.dll + // Finds the base address of [core]clr.dll CORDB_ADDRESS GetCLRInstanceBaseAddress(); -#endif // !defined(FEATURE_CORESYSTEM) // // Event Queues diff --git a/src/debug/di/shimprocess.cpp b/src/debug/di/shimprocess.cpp index d289923302..39d41ddac9 100644 --- a/src/debug/di/shimprocess.cpp +++ b/src/debug/di/shimprocess.cpp @@ -19,7 +19,11 @@ #include <limits.h> #include "shimpriv.h" +#if defined(FEATURE_PAL) +#include "debug-pal.h" +#else #include <tlhelp32.h> +#endif //--------------------------------------------------------------------------------------- // @@ -1083,8 +1087,8 @@ HRESULT ShimProcess::QueueFakeThreadAttachEventsNoOrder() HRESULT ShimProcess::QueueFakeThreadAttachEventsNativeOrder() { #ifdef FEATURE_CORESYSTEM - _ASSERTE("NYI"); - return E_FAIL; + _ASSERTE("NYI"); + return E_FAIL; #else ICorDebugProcess * pProcess = GetProcess(); @@ -1731,22 +1735,22 @@ void ShimProcess::PreDispatchEvent(bool fRealCreateProcessEvent /*= false*/) } -#if !defined(FEATURE_CORESYSTEM) - // ---------------------------------------------------------------------------- // ShimProcess::GetCLRInstanceBaseAddress -// Finds the base address of mscorwks.dll +// Finds the base address of [core]clr.dll // Arguments: none -// Return value: returns the base address of mscorwks.dll if possible or NULL otherwise +// Return value: returns the base address of [core]clr.dll if possible or NULL otherwise // CORDB_ADDRESS ShimProcess::GetCLRInstanceBaseAddress() { - // get a "snapshot" of all modules in the target + CORDB_ADDRESS baseAddress = CORDB_ADDRESS(NULL); DWORD dwPid = m_pLiveDataTarget->GetPid(); +#if defined(FEATURE_PAL) + baseAddress = PTR_TO_CORDB_ADDRESS (GetDynamicLibraryAddressInProcess(dwPid, MAKEDLLNAME_A(MAIN_CLR_MODULE_NAME_A))); +#elif !defined(FEATURE_CORESYSTEM) + // get a "snapshot" of all modules in the target HandleHolder hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPid); MODULEENTRY32 moduleEntry = { 0 }; - CORDB_ADDRESS baseAddress = CORDB_ADDRESS(NULL); - if (hSnapshot == INVALID_HANDLE_VALUE) { @@ -1775,10 +1779,9 @@ CORDB_ADDRESS ShimProcess::GetCLRInstanceBaseAddress() } while (Module32Next(hSnapshot, &moduleEntry)); } } - +#endif return baseAddress; } // ShimProcess::GetCLRInstanceBaseAddress -#endif // ---------------------------------------------------------------------------- // ShimProcess::FindLoadedCLR @@ -1799,18 +1802,11 @@ CORDB_ADDRESS ShimProcess::GetCLRInstanceBaseAddress() // HRESULT ShimProcess::FindLoadedCLR(CORDB_ADDRESS * pClrInstanceId) { - // - // Look up the image base of mscorwks from shared memory. - // Note that we could instead use OS facilities to look at the real module list, - // such as CreateToolHelp32Snapshot, and LoadModuleFirst - // - -#if !defined(FEATURE_CORESYSTEM) - *pClrInstanceId = GetCLRInstanceBaseAddress(); -#else - _ASSERTE(!"Attempting to get CLR base address on non-Windows platform"); +#if defined(FEATURE_CORESYSTEM) && !defined(FEATURE_PAL) + _ASSERTE(!"Attempting to get CLR base address on Windows-core platform"); return E_NOTIMPL; -#endif +#else + *pClrInstanceId = GetCLRInstanceBaseAddress(); if (*pClrInstanceId == 0) { @@ -1818,6 +1814,7 @@ HRESULT ShimProcess::FindLoadedCLR(CORDB_ADDRESS * pClrInstanceId) } return S_OK; +#endif } //--------------------------------------------------------------------------------------- diff --git a/src/debug/di/shimremotedatatarget.cpp b/src/debug/di/shimremotedatatarget.cpp index 77b834fa15..3498700ac1 100644 --- a/src/debug/di/shimremotedatatarget.cpp +++ b/src/debug/di/shimremotedatatarget.cpp @@ -130,11 +130,6 @@ void ShimRemoteDataTarget::Dispose() m_pProxy->ReleaseTransport(m_pTransport); } - if (m_pProxy != NULL) - { - g_pDbgTransportManager->ReleaseTarget(m_pProxy); - } - m_hr = CORDBG_E_OBJECT_NEUTERED; } @@ -163,15 +158,9 @@ HRESULT BuildPlatformSpecificDataTarget(MachineInfo machineInfo, HRESULT hr = E_FAIL; ShimRemoteDataTarget * pRemoteDataTarget = NULL; - DbgTransportTarget * pProxy = NULL; + DbgTransportTarget * pProxy = g_pDbgTransportTarget; DbgTransportSession * pTransport = NULL; - hr = g_pDbgTransportManager->ConnectToTarget(machineInfo.GetIPAddress(), machineInfo.GetPort(), &pProxy); - if (FAILED(hr)) - { - goto Label_Exit; - } - hr = pProxy->GetTransportForProcess(processId, &pTransport, &hDummy); if (FAILED(hr)) { @@ -210,10 +199,6 @@ Label_Exit: { pProxy->ReleaseTransport(pTransport); } - if (pProxy != NULL) - { - g_pDbgTransportManager->ReleaseTarget(pProxy); - } } } @@ -225,14 +210,28 @@ HRESULT STDMETHODCALLTYPE ShimRemoteDataTarget::GetPlatform( CorDebugPlatform *pPlatform) { - // Assume that we're running on Windows debugging a process on Mac for now. -#if defined(DBG_TARGET_ARM) - *pPlatform = CORDB_PLATFORM_WINDOWS_ARM; -#elif defined(DBG_TARGET_X86) - *pPlatform = CORDB_PLATFORM_WINDOWS_X86; +#ifdef FEATURE_PAL + #if defined(DBG_TARGET_X86) + *pPlatform = CORDB_PLATFORM_MAC_X86; + #elif defined(DBG_TARGET_AMD64) + *pPlatform = CORDB_PLATFORM_MAC_AMD64; + #else + #error Unknown Processor. + #endif #else -#error Unknown Processor. + #if defined(DBG_TARGET_X86) + *pPlatform = CORDB_PLATFORM_WINDOWS_X86; + #elif defined(DBG_TARGET_AMD64) + *pPlatform = CORDB_PLATFORM_WINDOWS_AMD64; + #elif defined(DBG_TARGET_ARM) + *pPlatform = CORDB_PLATFORM_WINDOWS_ARM; + #elif defined(DBG_TARGET_ARM64) + *pPlatform = CORDB_PLATFORM_WINDOWS_ARM64; + #else + #error Unknown Processor. + #endif #endif + return S_OK; } |