Fix Runtime::GetRuntime*Name() for cross-dac (#930)
authorSteve MacLean <Steve.MacLean@microsoft.com>
Mon, 23 Mar 2020 19:04:17 +0000 (15:04 -0400)
committerGitHub <noreply@github.com>
Mon, 23 Mar 2020 19:04:17 +0000 (15:04 -0400)
* Fix Runtime::GetRuntime*Name() for cross-dac

* Refactor GetRuntime*Name()

Add IRuntime::RuntimeConfiguration
Add IRuntime::GetRuntimeConfiguration()
Remove IRuntime::IsDesktop()
Remove NETCORE_RUNTIME*
Remove DESKTOP_RUNTIME*

src/SOS/SOS.UnitTests/Scripts/DualRuntimes.script
src/SOS/Strike/EventCallbacks.cpp
src/SOS/Strike/exts.h
src/SOS/Strike/hostcoreclr.cpp
src/SOS/Strike/runtime.cpp
src/SOS/Strike/runtime.h
src/SOS/Strike/strike.cpp

index 954d5fea3d86aa8fb3204a4dd1ac5ea14c398d77..32368122f2d04a1913d6f5cbd36873e6a0e10a0b 100644 (file)
@@ -69,7 +69,7 @@ VERIFY:\s*Total\s+<DECVAL>\s+objects\s+
 #
 
 SOSCOMMAND:SOSStatus
-VERIFY:.*\.NET Core runtime at.*\s+
+VERIFY:.*\.NET Core .*runtime at.*\s+
 
 IFDEF:TRIAGE_DUMP
 SOSCOMMAND:setclrpath %DESKTOP_RUNTIME_PATH%
index bdef2f9e65eeca4be931fe7db7f91e601ed949c4..2c5813af577b5e3cfeb009a8537fe3a0ac58e5ff 100644 (file)
@@ -135,12 +135,19 @@ HRESULT __stdcall EventCallbacks::LoadModule(ULONG64 ImageFileHandle,
 {
     HRESULT handleEventStatus = DEBUG_STATUS_NO_CHANGE;
 
-    if (ModuleName != NULL) 
+    if (ModuleName != NULL)
     {
-        bool isNetCore = _stricmp(ModuleName, NETCORE_RUNTIME_MODULE_NAME_A) == 0;
-        bool isDesktop = _stricmp(ModuleName, DESKTOP_RUNTIME_MODULE_NAME_A) == 0;
+        bool isRuntimeModule = false;
+        for (int runtime = 0; runtime < IRuntime::ConfigurationEnd; ++runtime)
+        {
+            if (_stricmp(ModuleName, GetRuntimeModuleName((IRuntime::RuntimeConfiguration)runtime)) == 0)
+            {
+                isRuntimeModule = true;
+                break;
+            }
+        }
 
-        if (isNetCore || isDesktop)
+        if (isRuntimeModule)
         {
             if (g_breakOnRuntimeModuleLoad)
             {
index 2d630b87bdf596968e466aa91434ef8100c47c7a..d109637a16e6c4de1ed1727956c0795f282db72f 100644 (file)
@@ -197,9 +197,9 @@ public:
 inline void EENotLoadedMessage(HRESULT Status)
 {
 #ifdef FEATURE_PAL
-    ExtOut("Failed to find runtime module (%s), 0x%08x\n", NETCORE_RUNTIME_DLL_NAME_A, Status);
+    ExtOut("Failed to find runtime module (%s), 0x%08x\n", GetRuntimeDllName(IRuntime::Core), Status);
 #else
-    ExtOut("Failed to find runtime module (%s or %s), 0x%08x\n", NETCORE_RUNTIME_DLL_NAME_A, DESKTOP_RUNTIME_DLL_NAME_A, Status);
+    ExtOut("Failed to find runtime module (%s or %s or %s), 0x%08x\n", GetRuntimeDllName(IRuntime::Core), GetRuntimeDllName(IRuntime::WindowsDesktop), GetRuntimeDllName(IRuntime::UnixCore), Status);
 #endif
     ExtOut("Extension commands need it in order to have something to do.\n");
 }
index 731401a481691e95fc31ab14c38473e246c39526..1e791369cb99d0b0f8685f160f17387eaef020ae 100644 (file)
@@ -368,7 +368,7 @@ static HRESULT GetHostRuntime(std::string& coreClrPath, std::string& hostRuntime
                                 return hr;
                             }
                             // Don't use the desktop runtime to host
-                            if (g_pRuntime->IsDesktop())
+                            if (g_pRuntime->GetRuntimeConfiguration() == IRuntime::WindowsDesktop)
                             {
                                 return E_FAIL;
                             }
@@ -391,7 +391,7 @@ static HRESULT GetHostRuntime(std::string& coreClrPath, std::string& hostRuntime
     hostRuntimeDirectory.assign(g_hostRuntimeDirectory);
     coreClrPath.assign(g_hostRuntimeDirectory);
     coreClrPath.append(DIRECTORY_SEPARATOR_STR_A);
-    coreClrPath.append(NETCORE_RUNTIME_DLL_NAME_A);
+    coreClrPath.append(GetRuntimeDllName(IRuntime::Core));
     return S_OK;
 }
 
@@ -732,7 +732,7 @@ void InitializeSymbolStoreFromSymPath()
 //
 static void SymbolFileCallback(void* param, const char* moduleFileName, const char* symbolFilePath)
 {
-    if (strcmp(moduleFileName, NETCORE_RUNTIME_DLL_NAME_A) == 0) {
+    if (strcmp(moduleFileName, GetRuntimeDllName(IRuntime::Core)) == 0) {
         return;
     }
     if (strcmp(moduleFileName, NETCORE_DAC_DLL_NAME_A) == 0) {
index a84ea2fad6dae45f7dd61a97adc7e6f522c6734c..60004e8e12b3b5c11ff054f2ed9a87536934d048 100644 (file)
@@ -33,7 +33,7 @@ Runtime* Runtime::s_desktop = nullptr;
 #endif
 
 // Used to initialize the runtime instance with values from the host when under dotnet-dump
-bool Runtime::s_isDesktop = false;
+IRuntime::RuntimeConfiguration Runtime::s_configuration = IRuntime::Core;
 LPCSTR Runtime::s_dacFilePath = nullptr;
 LPCSTR Runtime::s_dbiFilePath = nullptr;
 
@@ -46,9 +46,9 @@ IRuntime* g_pRuntime = nullptr;
 /**********************************************************************\
  * Creates a desktop or .NET Core instance of the runtime class
 \**********************************************************************/
-HRESULT Runtime::CreateInstance(bool isDesktop, Runtime **ppRuntime)
+HRESULT Runtime::CreateInstance(RuntimeConfiguration configuration, Runtime **ppRuntime)
 {
-    PCSTR runtimeModuleName = isDesktop ? DESKTOP_RUNTIME_MODULE_NAME_A : NETCORE_RUNTIME_MODULE_NAME_A;
+    PCSTR runtimeModuleName = GetRuntimeModuleName(configuration);
     ULONG moduleIndex = 0;
     ULONG64 moduleAddress = 0;
     ULONG64 moduleSize = 0;
@@ -57,15 +57,6 @@ HRESULT Runtime::CreateInstance(bool isDesktop, Runtime **ppRuntime)
     if (*ppRuntime == nullptr)
     {
         hr = g_ExtSymbols->GetModuleByModuleName(runtimeModuleName, 0, &moduleIndex, &moduleAddress);
-#ifndef FEATURE_PAL
-        // On Windows, support loading a Linux core dump by checking for NETCORE_RUNTIME_MODULE_NAME_UNIX_A too
-        if (!SUCCEEDED(hr) && !isDesktop)
-        {
-            runtimeModuleName = NETCORE_RUNTIME_MODULE_NAME_UNIX_A;
-
-            hr = g_ExtSymbols->GetModuleByModuleName(runtimeModuleName, 0, &moduleIndex, &moduleAddress);
-        }
-#endif // !FEATURE_PAL
         if (SUCCEEDED(hr))
         {
 #ifdef FEATURE_PAL
@@ -99,7 +90,7 @@ HRESULT Runtime::CreateInstance(bool isDesktop, Runtime **ppRuntime)
         {
             if (moduleSize > 0) 
             {
-                *ppRuntime = new Runtime(isDesktop, moduleIndex, moduleAddress, moduleSize);
+                *ppRuntime = new Runtime(configuration, moduleIndex, moduleAddress, moduleSize);
                 OnUnloadTask::Register(CleanupRuntimes);
             }
             else 
@@ -124,13 +115,17 @@ HRESULT Runtime::CreateInstance()
     HRESULT hr = S_OK;
     if (g_pRuntime == nullptr)
     {
-        hr = CreateInstance(false, &s_netcore);
+        hr = CreateInstance(IRuntime::Core, &s_netcore);
 #ifdef FEATURE_PAL
         g_pRuntime = s_netcore;
 #else
         if (FAILED(hr))
         {
-            hr = CreateInstance(true, &s_desktop);
+            hr = CreateInstance(IRuntime::UnixCore, &s_netcore);
+        }
+        if (FAILED(hr))
+        {
+            hr = CreateInstance(IRuntime::WindowsDesktop, &s_desktop);
         }
         g_pRuntime = s_netcore != nullptr ? s_netcore : s_desktop;
 #endif
@@ -146,7 +141,7 @@ HRESULT Runtime::CreateInstance()
 bool Runtime::SwitchRuntime(bool desktop)
 {
     if (desktop) {
-        CreateInstance(true, &s_desktop);
+        CreateInstance(IRuntime::WindowsDesktop, &s_desktop);
     }
     IRuntime* runtime = desktop ? s_desktop : s_netcore;
     if (runtime == nullptr) {
@@ -477,7 +472,7 @@ HRESULT Runtime::GetCorDebugInterface(ICorDebugProcess** ppCorDebugProcess)
     GUID skuId = CLR_ID_CORECLR;
 #endif
 #ifndef FEATURE_PAL
-    if (IsDesktop())
+    if (GetRuntimeConfiguration() == IRuntime::WindowsDesktop)
     {
         skuId = CLR_ID_V4_DESKTOP;
     }
@@ -530,7 +525,7 @@ HRESULT Runtime::GetCorDebugInterface(ICorDebugProcess** ppCorDebugProcess)
 \**********************************************************************/
 void Runtime::DisplayStatus()
 {
-    ExtOut("%s runtime at %p (%08x)\n", m_isDesktop ? "Desktop" : ".NET Core", m_address, m_size);
+    ExtOut("%s runtime at %p (%08x)\n", GetRuntimeConfigurationName(GetRuntimeConfiguration()), m_address, m_size);
     if (m_runtimeDirectory != nullptr) {
         ExtOut("Runtime directory: %s\n", m_runtimeDirectory);
     }
index fdae98432b7b979c375a2aed9927dc814419a76f..561b9416d6b09464b65ec20a63354c3b6021aea8 100644 (file)
@@ -7,11 +7,6 @@
 
 #ifdef FEATURE_PAL
 
-#define NETCORE_RUNTIME_MODULE_NAME_W   MAKEDLLNAME_W(W("coreclr"))
-#define NETCORE_RUNTIME_MODULE_NAME_A   MAKEDLLNAME_A("coreclr")
-#define NETCORE_RUNTIME_DLL_NAME_W      NETCORE_RUNTIME_MODULE_NAME_W
-#define NETCORE_RUNTIME_DLL_NAME_A      NETCORE_RUNTIME_MODULE_NAME_A
-
 #define NETCORE_DAC_MODULE_NAME_W       MAKEDLLNAME_W(W("mscordaccore"))
 #define NETCORE_DAC_MODULE_NAME_A       MAKEDLLNAME_A("mscordaccore")
 #define NETCORE_DAC_DLL_NAME_W          NETCORE_DAC_MODULE_NAME_W
 
 #else
 
-#define NETCORE_RUNTIME_MODULE_NAME_UNIX_A "libcoreclr"
-
-#define NETCORE_RUNTIME_MODULE_NAME_W   W("coreclr")
-#define NETCORE_RUNTIME_MODULE_NAME_A   "coreclr"
-#define NETCORE_RUNTIME_DLL_NAME_W      MAKEDLLNAME_W(NETCORE_RUNTIME_MODULE_NAME_W)
-#define NETCORE_RUNTIME_DLL_NAME_A      MAKEDLLNAME_A(NETCORE_RUNTIME_MODULE_NAME_A)
-
 #define NETCORE_DAC_MODULE_NAME_W       W("mscordaccore")
 #define NETCORE_DAC_MODULE_NAME_A       "mscordaccore"
 #define NETCORE_DAC_DLL_NAME_W          MAKEDLLNAME_W(NETCORE_DAC_MODULE_NAME_W)
 
 #endif // FEATURE_PAL
 
-#define DESKTOP_RUNTIME_MODULE_NAME_W   W("clr")
-#define DESKTOP_RUNTIME_MODULE_NAME_A   "clr"
-#define DESKTOP_RUNTIME_DLL_NAME_W      MAKEDLLNAME_W(DESKTOP_RUNTIME_MODULE_NAME_W)
-#define DESKTOP_RUNTIME_DLL_NAME_A      MAKEDLLNAME_A(DESKTOP_RUNTIME_MODULE_NAME_A)
-
 #define DESKTOP_DAC_MODULE_NAME_W       W("mscordacwks")
 #define DESKTOP_DAC_MODULE_NAME_A       "mscordacwks"
 #define DESKTOP_DAC_DLL_NAME_W          MAKEDLLNAME_W(W("mscordacwks"))
 class IRuntime
 {
 public:
-    // Returns true if desktop CLR; false if .NET Core
-    virtual bool IsDesktop() const = 0;
+    enum RuntimeConfiguration
+    {
+        WindowsDesktop,
+        WindowsCore,
+        UnixCore,
+        OSXCore,
+        ConfigurationEnd,
+#ifdef FEATURE_PAL
+#ifdef __APPLE__
+        Core = OSXCore
+#else
+        Core = UnixCore
+#endif
+#else
+        Core = WindowsCore
+#endif
+    };
+
+    // Returns the runtime configuration
+    virtual RuntimeConfiguration GetRuntimeConfiguration() const = 0;
 
     // Returns the runtime module index
     virtual ULONG GetModuleIndex() const = 0;
@@ -90,6 +91,47 @@ public:
     virtual void DisplayStatus() = 0;
 };
 
+// Returns the runtime configuration as a string
+inline static const char* GetRuntimeConfigurationName(IRuntime::RuntimeConfiguration config)
+{
+    static const char* name[IRuntime::ConfigurationEnd] = {
+        "Desktop",
+        ".NET Core (Windows)",
+        ".NET Core (Unix)",
+        ".NET Core (Mac)"
+    };
+    return (config < IRuntime::ConfigurationEnd) ? name[config] : nullptr;
+}
+
+// Returns the runtime module DLL name (clr.dll, coreclr.dll, libcoreclr.so, libcoreclr.dylib)
+inline static const char* GetRuntimeDllName(IRuntime::RuntimeConfiguration config)
+{
+    static const char* name[IRuntime::ConfigurationEnd] = {
+        "clr.dll",
+        "coreclr.dll",
+        "libcoreclr.so",
+        "libcoreclr.dylib"
+    };
+    return (config < IRuntime::ConfigurationEnd) ? name[config] : nullptr;
+}
+
+// Returns the runtime module name (clr, coreclr, libcoreclr.so, libcoreclr.dylib).
+inline static const char* GetRuntimeModuleName(IRuntime::RuntimeConfiguration config)
+{
+#ifdef FEATURE_PAL
+    return GetRuntimeDllName(config);
+#else
+    // On a windows host the module name does not include the extension.
+    static const char* name[IRuntime::ConfigurationEnd] = {
+        "clr",
+        "coreclr",
+        "libcoreclr",
+        "libcoreclr"
+    };
+    return (config < IRuntime::ConfigurationEnd) ? name[config] : nullptr;
+#endif
+}
+
 extern LPCSTR g_runtimeModulePath;
 extern IRuntime* g_pRuntime;
 
@@ -99,7 +141,7 @@ extern IRuntime* g_pRuntime;
 class Runtime : public IRuntime
 {
 private:
-    bool m_isDesktop;
+    RuntimeConfiguration m_configuration;
     ULONG m_index;
     ULONG64 m_address;
     ULONG64 m_size;
@@ -113,12 +155,12 @@ private:
 #ifndef FEATURE_PAL
     static Runtime* s_desktop;
 #endif
-    static bool s_isDesktop;
+    static RuntimeConfiguration s_configuration;
     static LPCSTR s_dacFilePath;
     static LPCSTR s_dbiFilePath;
 
-    Runtime(bool isDesktop, ULONG index, ULONG64 address, ULONG64 size) : 
-        m_isDesktop(isDesktop),
+    Runtime(RuntimeConfiguration configuration,ULONG index, ULONG64 address, ULONG64 size) :
+        m_configuration(configuration),
         m_index(index),
         m_address(address),
         m_size(size),
@@ -131,7 +173,7 @@ private:
         _ASSERTE(index != -1);
         _ASSERTE(address != 0);
         _ASSERTE(size != 0);
-        if (isDesktop == s_isDesktop) {
+        if (configuration == s_configuration) {
             SetDacFilePath(s_dacFilePath);
             SetDbiFilePath(s_dbiFilePath);
         }
@@ -139,7 +181,7 @@ private:
 
     virtual Runtime::~Runtime();
 
-    static HRESULT CreateInstance(bool isDesktop, Runtime** ppRuntime);
+    static HRESULT CreateInstance(RuntimeConfiguration configuration, Runtime** ppRuntime);
 
     HRESULT GetRuntimeDirectory(std::string& runtimeDirectory);
 
@@ -177,7 +219,7 @@ public:
 
     static void SetDacDbiPath(bool isDesktop, LPCSTR dacFilePath, LPCSTR dbiFilePath)
     {
-        s_isDesktop = isDesktop;
+        s_configuration = isDesktop ? IRuntime::WindowsDesktop : IRuntime::Core;
         if (dacFilePath != nullptr) {
             s_dacFilePath = _strdup(dacFilePath);
         }
@@ -188,7 +230,7 @@ public:
 
     static void Flush();
 
-    virtual bool IsDesktop() const { return m_isDesktop; }
+    virtual RuntimeConfiguration GetRuntimeConfiguration() const { return m_configuration; }
 
     virtual ULONG GetModuleIndex() const { return m_index; }
 
@@ -211,50 +253,50 @@ public:
     // Returns the runtime module DLL name (clr.dll, coreclr.dll, libcoreclr.so, libcoreclr.dylib)
     inline const char* GetRuntimeDllName() const
     {
-        return IsDesktop() ? DESKTOP_RUNTIME_DLL_NAME_A : NETCORE_RUNTIME_DLL_NAME_A;
+        return ::GetRuntimeDllName(GetRuntimeConfiguration());
     }
 
     // Returns the DAC module name (mscordacwks.dll, mscordaccore.dll, libmscordaccore.so, libmscordaccore.dylib) 
     inline const char* GetDacDllName() const
     {
-        return IsDesktop() ? DESKTOP_DAC_DLL_NAME_A : NETCORE_DAC_DLL_NAME_A;
+        return (GetRuntimeConfiguration() == IRuntime::WindowsDesktop) ? DESKTOP_DAC_DLL_NAME_A : NETCORE_DAC_DLL_NAME_A;
     }
 
     // Returns the DAC module name (mscordacwks, mscordaccore, libmscordaccore.so, libmscordaccore.dylib) 
     inline const WCHAR* GetDacModuleNameW() const
     {
-        return IsDesktop() ? DESKTOP_DAC_MODULE_NAME_W : NETCORE_DAC_MODULE_NAME_W;
+        return (GetRuntimeConfiguration() == IRuntime::WindowsDesktop) ? DESKTOP_DAC_MODULE_NAME_W : NETCORE_DAC_MODULE_NAME_W;
     }
 
     // Returns the DAC module name (mscordacwks.dll, mscordaccore.dll, libmscordaccore.so, libmscordaccore.dylib) 
     inline const WCHAR* GetDacDllNameW() const
     {
-        return IsDesktop() ? DESKTOP_DAC_DLL_NAME_W : NETCORE_DAC_DLL_NAME_W;
+        return (GetRuntimeConfiguration() == IRuntime::WindowsDesktop) ? DESKTOP_DAC_DLL_NAME_W : NETCORE_DAC_DLL_NAME_W;
     }
 };
 
 // Returns the runtime module name (clr, coreclr, libcoreclr.so, libcoreclr.dylib).
 inline const char* GetRuntimeModuleName()
 {
-    return g_pRuntime->IsDesktop() ? DESKTOP_RUNTIME_MODULE_NAME_A : NETCORE_RUNTIME_MODULE_NAME_A;
+    return GetRuntimeModuleName(g_pRuntime->GetRuntimeConfiguration());
 }
 
 // Returns the runtime module DLL name (clr.dll, coreclr.dll, libcoreclr.so, libcoreclr.dylib)
 inline const char* GetRuntimeDllName()
 {
-    return g_pRuntime->IsDesktop() ? DESKTOP_RUNTIME_DLL_NAME_A : NETCORE_RUNTIME_DLL_NAME_A;
+    return GetRuntimeDllName(g_pRuntime->GetRuntimeConfiguration());
 }
 
 // Returns the DAC module name (mscordacwks, mscordaccore, libmscordaccore.so, libmscordaccore.dylib) 
 inline const char* GetDacModuleName()
 {
-    return g_pRuntime->IsDesktop() ? DESKTOP_DAC_MODULE_NAME_A : NETCORE_DAC_MODULE_NAME_A;
+    return (g_pRuntime->GetRuntimeConfiguration() == IRuntime::WindowsDesktop) ? DESKTOP_DAC_MODULE_NAME_A : NETCORE_DAC_MODULE_NAME_A;
 }
 
 // Returns the DAC module name (mscordacwks.dll, mscordaccore.dll, libmscordaccore.so, libmscordaccore.dylib) 
 inline const char* GetDacDllName()
 {
-    return g_pRuntime->IsDesktop() ? DESKTOP_DAC_DLL_NAME_A : NETCORE_DAC_DLL_NAME_A;
+    return (g_pRuntime->GetRuntimeConfiguration() == IRuntime::WindowsDesktop) ? DESKTOP_DAC_DLL_NAME_A : NETCORE_DAC_DLL_NAME_A;
 }
 
 #endif // __runtime_h__
index 8e18d42c25ac3464c252cef472fcc2f5c5d8b21d..fb44ec32afe4b65c763ec37ede6807e87fc28617 100644 (file)
@@ -7624,7 +7624,7 @@ public:
 
         // This is only needed for desktop runtime because OnCodeGenerated2
         // isn't supported by the desktop DAC.
-        if (g_pRuntime->IsDesktop())
+        if (g_pRuntime->GetRuntimeConfiguration() == IRuntime::WindowsDesktop)
         {
             // Some method has been generated, make a breakpoint and remove it.
             ULONG32 len = mdNameLen;
@@ -9872,7 +9872,7 @@ DECLARE_API(DumpLog)
     _ASSERTE(g_pRuntime != nullptr);
 
     // Not supported on desktop runtime
-    if (g_pRuntime->IsDesktop())
+    if (g_pRuntime->GetRuntimeConfiguration() == IRuntime::WindowsDesktop)
     {
         ExtErr("DumpLog not supported on desktop runtime\n");
         return E_FAIL;