diff options
Diffstat (limited to 'src/debug/ee/inprocdac.cpp')
-rw-r--r-- | src/debug/ee/inprocdac.cpp | 432 |
1 files changed, 0 insertions, 432 deletions
diff --git a/src/debug/ee/inprocdac.cpp b/src/debug/ee/inprocdac.cpp deleted file mode 100644 index e451cf08bb..0000000000 --- a/src/debug/ee/inprocdac.cpp +++ /dev/null @@ -1,432 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// -//***************************************************************************** -// File: InProcDac.cpp -// - -// -// -// -//***************************************************************************** - -#include "stdafx.h" - -#if defined(FEATURE_DBGIPC_TRANSPORT_VM) - -#include "inprocdac.h" -#include "dacdbiinterface.h" -#include "cordebug.h" -#include "metadata.h" - -InProcDac::InProcDac() : - m_pDacDbi(NULL), - m_pUnpacker(NULL) -{ -} - -InProcDac::~InProcDac() -{ - Cleanup(); -} - -// -// Debugger::InitializeDAC -// -// DAC is used in-process on the Mac and ARM devices. -// This is similar to CordbProcess::CreateDacDbiInterface on Windows. -// @dbgtodo : try and share some of this code with the RS equivalent? -// -void InProcDac::Initialize() -{ - CONTRACTL - { - THROWS; - } - CONTRACTL_END; - - // don't double-init - _ASSERTE(m_pDataTarget == NULL); - _ASSERTE(m_pDacDbi == NULL); - _ASSERTE(m_pUnpacker == NULL); - - HRESULT hrStatus = S_OK; - HModuleHolder hDacDll; - - // - // Load the access DLL from the same directory as the the current CLR DLL. - // - WCHAR wszRuntimePath[MAX_PATH]; // base directory of the runtime (including trailing /) - WCHAR wszAccessDllPath[MAX_PATH]; // full path to the DAC Dll - - if (!WszGetModuleFileName(GetCLRModule(), wszRuntimePath, NumItems(wszRuntimePath))) - { - ThrowLastError(); - } - - const char pathSep = '\\'; - - // remove CLR filename - PWSTR pPathTail = wcsrchr(wszRuntimePath, pathSep); - if (!pPathTail) - { - ThrowHR(E_INVALIDARG); - } - pPathTail[1] = '\0'; - - // In the case where this function is called multiple times, save the module handle to the DAC shared - // library so that we won't try to free and load it multiple times. - if (m_hDacModule == NULL) - { - if (wcscpy_s(wszAccessDllPath, _countof(wszAccessDllPath), wszRuntimePath) || - wcscat_s(wszAccessDllPath, _countof(wszAccessDllPath), MAKEDLLNAME_W(MAIN_DAC_MODULE_NAME_W))) - { - ThrowHR(E_INVALIDARG); - } - - hDacDll.Assign(WszLoadLibrary(wszAccessDllPath)); - if (!hDacDll) - { - CONSISTENCY_CHECK_MSGF(false,("Unable to find DAC dll: %s", wszAccessDllPath)); - - DWORD dwLastError = GetLastError(); - if (dwLastError == ERROR_MOD_NOT_FOUND) - { - // Give a more specific error in the case where we can't find the DAC dll. - ThrowHR(CORDBG_E_DEBUG_COMPONENT_MISSING); - } - else - { - ThrowWin32(dwLastError); - } - } - - // Succeeded. Now copy out. - m_hDacModule.Assign(hDacDll); - hDacDll.SuppressRelease(); - } - - // Create the data target - ReleaseHolder<InProcDataTarget> pDataTarget = new InProcDataTarget(); - - // - // Get the access interface, passing our callback interfaces (data target, and metadata lookup) - // - - IDacDbiInterface::IMetaDataLookup * pMetaDataLookup = this; - IDacDbiInterface::IAllocator * pAllocator = this; - - // Get the CLR instance ID - the base address of the CLR module - CORDB_ADDRESS clrInstanceId = reinterpret_cast<CORDB_ADDRESS>(GetCLRModule()); - - typedef HRESULT (STDAPICALLTYPE * PFN_DacDbiInterfaceInstance)( - ICorDebugDataTarget *, - CORDB_ADDRESS, - IDacDbiInterface::IAllocator *, - IDacDbiInterface::IMetaDataLookup *, - IDacDbiInterface **); - - IDacDbiInterface* pInterfacePtr = NULL; - PFN_DacDbiInterfaceInstance pfnEntry = (PFN_DacDbiInterfaceInstance) - GetProcAddress(m_hDacModule, "DacDbiInterfaceInstance"); - - if (!pfnEntry) - { - ThrowLastError(); - } - - hrStatus = pfnEntry(pDataTarget, clrInstanceId, - pAllocator, pMetaDataLookup, &pInterfacePtr); - IfFailThrow(hrStatus); - - // We now have a resource, pInterfacePtr, that needs to be freed. - - m_pDacDbi = pInterfacePtr; - m_pDataTarget = pDataTarget.Extract(); - - // Enable DAC target consistency checking - we're in-proc and so better always be consistent - m_pDacDbi->DacSetTargetConsistencyChecks( true ); - m_pUnpacker = new DDUnpack(pInterfacePtr, pAllocator); // throws -} - -void InProcDac::Cleanup() -{ - CONTRACTL - { - NOTHROW; // backout code. - } - CONTRACTL_END; - - if (m_pDacDbi != NULL) - { - m_pDacDbi->Destroy(); - m_pDacDbi = NULL; - } - - if(m_pUnpacker != NULL) - { - delete m_pUnpacker; - m_pUnpacker = NULL; - } - - if (m_pDataTarget != NULL) - { - m_pDataTarget.Clear(); - } - - // Note that once we release this handle, the DAC module can be unloaded and all calls - // into DAC could be invalid. - if (m_hDacModule != NULL) - { - m_hDacModule.Clear(); - } -} - -HRESULT InProcDac::DoRequest(ReadBuffer * pSend, WriteBuffer * pResult) -{ - HRESULT hr = S_OK; - - // Lazily initialize the DacDbiMarshalStub. - if (m_pDacDbi == NULL) - { - EX_TRY - { - Initialize(); - } - EX_CATCH_HRESULT(hr); - IfFailRet(hr); - } - - _ASSERTE(m_pDacDbi != NULL); - - /* - * @dbgtodo : We have to make sure to call Flush whenever runtime data structures may have changed. - * Eg: - * - after every IPC event - * - whenever we suspend the process - * For now we rely on the RS to tell us when to flush, just like the Windows runtime. It's a little riskier - * in this case because the target is actually running code. Since the cost of copying locally is fairly - * low, it is probably best to just flush at the beginning and/or end of all DD requests (i.e. here). - * Flushing more that necessary may be best for performance. - * Note however that this could in theory expose lateng bugs where we've been getting away with bleeding - * DAC state across DD calls on Windows. - */ - EX_TRY - { - m_pUnpacker->HandleDDMessage(pSend, pResult); - } - EX_CATCH_HRESULT(hr); - return hr; -} - -#ifndef DACCESS_COMPILE -IMDInternalImport * InProcDac::LookupMetaData(VMPTR_PEFile addressPEFile, bool &isILMetaDataForNGENImage) -{ - isILMetaDataForNGENImage = false; - PEFile* peFile = addressPEFile.GetRawPtr(); - return peFile->GetPersistentMDImport(); -} -#endif -//*************************************************************** -// InProcDataTarget implementation -//*************************************************************** - -// -// InProcDataTarget ctor -// -// Instantiate an InProcDataTarget -// -InProcDac::InProcDataTarget::InProcDataTarget() : - m_ref(0) -{ -} - -// -// InProcDataTarget dtor -// -// -InProcDac::InProcDataTarget::~InProcDataTarget() -{ -} - -// Standard impl of IUnknown::QueryInterface -HRESULT STDMETHODCALLTYPE -InProcDac::InProcDataTarget::QueryInterface( - REFIID InterfaceId, - PVOID* pInterface) -{ - if (InterfaceId == IID_IUnknown) - { - *pInterface = static_cast<IUnknown *>(static_cast<ICorDebugDataTarget *>(this)); - } - else if (InterfaceId == IID_ICorDebugDataTarget) - { - *pInterface = static_cast<ICorDebugDataTarget *>(this); - } - else if (InterfaceId == IID_ICorDebugMutableDataTarget) - { - *pInterface = static_cast<ICorDebugMutableDataTarget *>(this); - } - else - { - *pInterface = NULL; - return E_NOINTERFACE; - } - - AddRef(); - return S_OK; -} - -// Standard impl of IUnknown::AddRef -ULONG STDMETHODCALLTYPE -InProcDac::InProcDataTarget::AddRef() -{ - LONG ref = InterlockedIncrement(&m_ref); - return ref; -} - -// Standard impl of IUnknown::Release -ULONG STDMETHODCALLTYPE -InProcDac::InProcDataTarget::Release() -{ - LONG ref = InterlockedDecrement(&m_ref); - if (ref == 0) - { - delete this; - } - return ref; -} - -// impl of interface method ICorDebugDataTarget::GetPlatform -HRESULT STDMETHODCALLTYPE -InProcDac::InProcDataTarget::GetPlatform( - CorDebugPlatform * pPlatform) -{ -#if defined(_TARGET_X86_) - *pPlatform = CORDB_PLATFORM_WINDOWS_X86; -#elif defined(_TARGET_AMD64_) - *pPlatform = CORDB_PLATFORM_WINDOWS_AMD64; -#elif defined(_TARGET_ARM_) - *pPlatform = CORDB_PLATFORM_WINDOWS_ARM; -#else -#error Unknown Processor. -#endif // platform - - return S_OK; -} - -// impl of interface method ICorDebugDataTarget::ReadVirtual -HRESULT STDMETHODCALLTYPE -InProcDac::InProcDataTarget::ReadVirtual( - CORDB_ADDRESS address, - PBYTE pBuffer, - ULONG32 cbRequestSize, - ULONG32 * pcbRead) -{ - void * pSrc = reinterpret_cast<void*>(address); - memcpy(pBuffer, pSrc, cbRequestSize); - if (pcbRead != NULL) - { - *pcbRead = cbRequestSize; - } - return S_OK; -} - -// impl of interface method ICorDebugMutableDataTarget::WriteVirtual -HRESULT STDMETHODCALLTYPE -InProcDac::InProcDataTarget::WriteVirtual( - CORDB_ADDRESS address, - const BYTE * pBuffer, - ULONG32 cbRequestSize) -{ - void * pDst = reinterpret_cast<void*>(address); - memcpy(pDst, pBuffer, cbRequestSize); - return S_OK; -} - - -// impl of interface method ICorDebugDataTarget::GetThreadContext -HRESULT STDMETHODCALLTYPE -InProcDac::InProcDataTarget::GetThreadContext( - DWORD dwThreadID, - ULONG32 contextFlags, - ULONG32 contextSize, - PBYTE pContext) -{ - if (contextSize < sizeof(CONTEXT)) - { - return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); - } - - HandleHolder hThread = ::OpenThread(THREAD_GET_CONTEXT, FALSE, dwThreadID); - if (hThread == NULL) - { - return HRESULT_FROM_GetLastError(); - } - - // This assumes pContext is appropriately aligned. - CONTEXT * pCtx = reinterpret_cast<CONTEXT*>(pContext); - pCtx->ContextFlags = contextFlags; - if (!::GetThreadContext(hThread, pCtx)) - { - return HRESULT_FROM_GetLastError(); - } - - return S_OK; -} - -// impl of interface method ICorDebugMutableDataTarget::SetThreadContext -HRESULT STDMETHODCALLTYPE -InProcDac::InProcDataTarget::SetThreadContext( - DWORD dwThreadID, - ULONG32 contextSize, - const BYTE * pContext) -{ - if (contextSize < sizeof(CONTEXT)) - { - return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); - } - - HandleHolder hThread = ::OpenThread(THREAD_SET_CONTEXT, FALSE, dwThreadID); - if (hThread == NULL) - { - return HRESULT_FROM_GetLastError(); - } - - // This assumes pContext is appropriately aligned. - const CONTEXT * pCtx = reinterpret_cast<const CONTEXT*>(pContext); - if (!::SetThreadContext(hThread,pCtx)) - { - return HRESULT_FROM_GetLastError(); - } - - return S_OK; -} - -// implementation of ICorDebugMutableDataTarget::ContinueStatusChanged -HRESULT STDMETHODCALLTYPE -InProcDac::InProcDataTarget::ContinueStatusChanged( - DWORD dwThreadId, - CORDB_CONTINUE_STATUS continueStatus) -{ - return E_NOTIMPL; -} - -#ifndef DACCESS_COMPILE - -// Trivial implementation for IDacDbiInterface::IAllocator methods -void * InProcDac::Alloc(SIZE_T lenBytes) -{ - return new BYTE[lenBytes]; -} - -void InProcDac::Free(void * p) -{ - BYTE* pB = static_cast<BYTE*>(p); - delete[] pB; -} - -#endif //!DACCESS_COMPILE - -#endif //FEATURE_DBGIPC_TRANSPORT_VM |