#include <tlhelp32.h>
#include <cor.h>
#include <sstring.h>
+#ifndef FEATURE_PAL
#include <securityutil.h>
+#endif
#include <ex.h>
#include <cordebug.h> // for Version nunmbers
//-----------------------------------------------------------------------------
#define StartupNotifyEventNamePrefix W("TelestoStartupEvent_")
const int cchEventNameBufferSize = sizeof(StartupNotifyEventNamePrefix)/sizeof(WCHAR) + 8; // + hex DWORD (8). NULL terminator is included in sizeof(StartupNotifyEventNamePrefix)
+
HRESULT GetStartupNotificationEvent(DWORD debuggeePID,
__out HANDLE* phStartupEvent)
{
PUBLIC_CONTRACT;
- HRESULT hr;
if (phStartupEvent == NULL)
return E_INVALIDARG;
+#ifndef FEATURE_PAL
+ HRESULT hr;
+
// Note this event name doesn't have a Global prefix, and so debugging across sessions will not work.
WCHAR szEventName[cchEventNameBufferSize];
swprintf_s(szEventName, cchEventNameBufferSize, StartupNotifyEventNamePrefix W("%08x"), debuggeePID);
}
*phStartupEvent = startupEvent;
+#else
+ *phStartupEvent = NULL;
+#endif // FEATURE_PAL
return S_OK;
}
-HRESULT GetContinueStartupEvent(DWORD debuggeePID,
- LPCWSTR szTelestoFullPath,
- __out HANDLE* phContinueStartupEvent);
-
//-----------------------------------------------------------------------------
// Public API.
//
if (pHandleArray == NULL)
return S_OK;
+#ifndef FEATURE_PAL
for (DWORD i = 0; i < dwArrayLength; i++)
{
HANDLE hTemp = pHandleArray[i];
CloseHandle(hTemp);
}
}
+#endif // FEATURE_PAL
delete[] pHandleArray;
return S_OK;
}
+#ifndef FEATURE_PAL
+
+HRESULT GetContinueStartupEvent(DWORD debuggeePID,
+ LPCWSTR szTelestoFullPath,
+ __out HANDLE* phContinueStartupEvent);
+
// Refer to clr\src\mscoree\mscorwks_ntdef.src.
const WORD kOrdinalForMetrics = 2;
return false;
}
+#endif // !FEATURE_PAL
+
//-----------------------------------------------------------------------------
// Public API.
//
if ((ppHandleArrayOut == NULL) || (ppStringArrayOut == NULL) || (pdwArrayLengthOut == NULL))
return E_INVALIDARG;
+#ifndef FEATURE_PAL
HandleHolder hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, debuggeePID);
if (NULL == hProcess)
ThrowHR(E_FAIL);
}
}
-
// If we didn't find anything, no point in continuing.
if (count == 0)
{
*ppStringArrayOut = NULL;
*pdwArrayLengthOut = 0;
- return S_OK;
+ return S_OK;
}
+#else
+ DWORD count = 1;
+#endif // FEATURE_PAL
size_t cbEventArrayData = sizeof(HANDLE) * count; // event array data
size_t cbStringArrayData = sizeof(LPWSTR) * count; // string array data
HANDLE* pEventArray = (HANDLE*) &pOutBuffer[0];
LPWSTR* pStringArray = (LPWSTR*) &pOutBuffer[cbEventArrayData];
WCHAR* pStringData = (WCHAR*) &pOutBuffer[cbEventArrayData + cbStringArrayData];
+ DWORD idx = 0;
+#ifndef FEATURE_PAL
+ // There's no guarantee that another coreclr hasn't loaded already anyhow,
+ // so if we get the corner case that the second time through we enumerate
+ // more coreclrs, just ignore the extras.
+ // This mismatch could happen when
+ // a) take module shapshot
+ // b) underlying file is opened for exclusive access/deleted/moved/ACL'd etc so we can't open it
+ // c) count is determined
+ // d) file is closed/copied/moved/ACL'd etc so we can find/open it again
+ // e) this loop runs
+ // Thus the loop checks idx < count
- // There's no guarantee that another coreclr hasn't loaded already anyhow,
- // so if we get the corner case that the second time through we enumerate
- // more coreclrs, just ignore the extras.
- // This mismatch could happen when
- // a) take module shapshot
- // b) underlying file is opened for exclusive access/deleted/moved/ACL'd etc so we can't open it
- // c) count is determined
- // d) file is closed/copied/moved/ACL'd etc so we can find/open it again
- // e) this loop runs
- // Thus the loop checks idx < count
-
- DWORD idx = 0;
for(DWORD i = 0; i < countModules && idx < count; i++)
{
if (IsCoreClrWithGoodHeader(hProcess, modules[i]))
// Strings themselves don't need moved.
}
+#else
+ pStringArray[idx] = &pStringData[idx * MAX_PATH];
+ wcscpy_s(pStringArray[idx], MAX_PATH, MAKEDLLNAME_W(W("coreclr")));
+ idx++;
+#endif // FEATURE_PAL
*ppHandleArrayOut = pEventArray;
*ppStringArrayOut = pStringArray;
return S_OK;
}
+#ifndef FEATURE_PAL
+
//-----------------------------------------------------------------------------
// Get the base address of a module from the remote process.
//
return NULL;
}
+#endif // FEATURE_PAL
+
// DBI version: max 8 hex chars
// SEMICOLON: 1
// PID: max 8 hex chars
}
else if (pBuffer != NULL)
{
+#ifndef FEATURE_PAL
HRESULT hr = S_OK;
EX_TRY
{
}
EX_CATCH_HRESULT(hr);
return hr;
+#else
+ swprintf_s(pBuffer, cchBuffer, W("%08x"), pidDebuggee);
+#endif // FEATURE_PAL
}
return S_OK;
}
+#ifndef FEATURE_PAL
+
// Functions that we'll look for in the loaded Mscordbi module.
typedef HRESULT (STDAPICALLTYPE *FPCoreCLRCreateCordbObject)(
int iDebuggerVersion,
}
}
+#else
+
+// Functions that we'll look for in the loaded Mscordbi module.
+typedef HRESULT (STDAPICALLTYPE *FPCreateCordbObject)(
+ int iDebuggerVersion,
+ IUnknown ** ppCordb);
+
+#endif // FEATURE_PAL
+
//-----------------------------------------------------------------------------
// Public API.
// Given a version string, create the matching mscordbi.dll for it.
//-----------------------------------------------------------------------------
HRESULT CreateDebuggingInterfaceFromVersionEx(
int iDebuggerVersion,
- LPCWSTR szDebuggeeVersion,
+ LPCWSTR szDebuggeeVersion,
IUnknown ** ppCordb
-)
+ )
{
PUBLIC_CONTRACT;
- HRESULT hrIgnore; // ignored HResult
+ HRESULT hrIgnore = S_OK; // ignored HResult
HRESULT hr = S_OK;
HMODULE hMod = NULL;
IUnknown * pCordb = NULL;
-
- SString szFullDbiPath;
- SString szFullCoreClrPath;
-
LOG((LF_CORDB, LL_EVERYTHING, "Calling CreateDebuggerInterfaceFromVersion, ver=%S\n", szDebuggeeVersion));
if ((szDebuggeeVersion == NULL) || (ppCordb == NULL))
*ppCordb = NULL;
+#ifndef FEATURE_PAL
//
// Step 1: Parse version information into internal data structures
//
-
+
CorDebugInterfaceVersion iTargetVersion; // the CorDebugInterfaceVersion (CorDebugVersion_2_0)
DWORD pidDebuggee; // OS process ID of the debuggee
HMODULE hmodTargetCLR; // module of Telesto in target (the clrInstanceId)
if (FAILED(hr))
goto Exit;
-
//
// Step 2: Find the proper Dbi module (mscordbi.dll) and load it.
//
// This will be very common for internal developer setups, but not common in end-user setups.
EX_TRY
{
+ SString szFullDbiPath;
+ SString szFullCoreClrPath;
+
GetDbiFilenameNextToRuntime(pidDebuggee, hmodTargetCLR, szFullDbiPath, szFullCoreClrPath);
if (!CheckDbiAndRuntimeVersion(szFullDbiPath, szFullCoreClrPath))
// We calculated where dbi would be, but haven't yet verified if it's there.
// Try to load it. We're using this to check for file existence.
- // Issue:951525: coreclr mscordbi load fails on downlevel OS since LoadLibraryEx can't find
- // dependent forwarder DLLs. Force LoadLibrary to look for dependencies in szFullDbiPath plus the default
- // search paths.
- hMod = WszLoadLibraryEx(szFullDbiPath, NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
+ // Issue:951525: coreclr mscordbi load fails on downlevel OS since LoadLibraryEx can't find
+ // dependent forwarder DLLs. Force LoadLibrary to look for dependencies in szFullDbiPath plus the default
+ // search paths.
+ hMod = WszLoadLibraryEx(szFullDbiPath, NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
}
EX_CATCH_HRESULT(hrIgnore); // failure leaves hMod null
//
// Step 3: Now that module is loaded, instantiate an ICorDebug.
//
-
- FPCoreCLRCreateCordbObject fpCreate2 = (FPCoreCLRCreateCordbObject) GetProcAddress(hMod, "CoreCLRCreateCordbObject");
+ FPCoreCLRCreateCordbObject fpCreate2 = (FPCoreCLRCreateCordbObject)GetProcAddress(hMod, "CoreCLRCreateCordbObject");
if (fpCreate2 == NULL)
{
// New-style creation API didn't exist - this DBI must be the wrong version, for the Mix07 protocol
hr = CORDBG_E_INCOMPATIBLE_PROTOCOL;
goto Exit;
}
-
+
// Invoke to instantiate an ICorDebug. This export was introduced after the Mix'07 release.
hr = fpCreate2(iDebuggerVersion, pidDebuggee, hmodTargetCLR, &pCordb);
+#else
+ {
+ hMod = LoadLibraryExW(MAKEDLLNAME_W(W("mscordbi")), NULL, 0);
+ if (NULL == hMod)
+ {
+ hr = CORDBG_E_DEBUG_COMPONENT_MISSING;
+ goto Exit;
+ }
+ FPCreateCordbObject fpCreate = (FPCreateCordbObject)GetProcAddress(hMod, "CreateCordbObject");
+ if (fpCreate == NULL)
+ {
+ hr = CORDBG_E_INCOMPATIBLE_PROTOCOL;
+ goto Exit;
+ }
+ hr = fpCreate(iDebuggerVersion, &pCordb);
+ }
+#endif // FEATURE_PAL
_ASSERTE((pCordb == NULL) == FAILED(hr));
-
-
-
Exit:
if (FAILED(hr))
ppCordb);
}
+#ifndef FEATURE_PAL
//------------------------------------------------------------------------------
// Manually retrieves the "continue startup" event from the correct CLR instance
return hr;
}
+#endif // !FEATURE_PAL
#if defined(FEATURE_CORESYSTEM) && defined(_TARGET_X86_)
#include "debugshim.h"
#endif
}
+#ifdef FEATURE_PAL
+EXTERN_C BOOL WINAPI
+DllMain(HANDLE instance, DWORD reason, LPVOID reserved)
+{
+ int err = 0;
+ switch (reason)
+ {
+ case DLL_PROCESS_ATTACH:
+ {
+ err = PAL_InitializeDLL();
+ break;
+ }
+
+ case DLL_THREAD_ATTACH:
+ err = PAL_EnterTop();
+ break;
+ }
+
+ if (err != 0)
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+#endif // FEATURE_PAL