Fix bpmd on Windows and other changes (#622)
authorMike McLaughlin <mikem@microsoft.com>
Mon, 18 Nov 2019 22:59:18 +0000 (14:59 -0800)
committerGitHub <noreply@github.com>
Mon, 18 Nov 2019 22:59:18 +0000 (14:59 -0800)
Fix bpmd on Windows by implementing IDataTarget2 which allows the DAC to allocate a JIT notification
table which is empty on Windows. Issue https://github.com/dotnet/diagnostics/issues/584.

Add SetRuntimeLoadedCallback lldb service for bpmd

Allow bpmd to work before coreclr is loaded. Issue https://github.com/dotnet/diagnostics/issues/15

Upgrade to symstore 1.0.55801

Set/reset symbol server path anytime .sympath changes

Add lldb h files to plugin project

Add bpmd tests. Update readme and help docs

21 files changed:
README.md
eng/Versions.props
src/SOS/SOS.NETCore/SymbolReader.cs
src/SOS/SOS.UnitTests/Scripts/NestedExceptionTest.script
src/SOS/SOS.UnitTests/Scripts/OtherCommands.script
src/SOS/SOS.UnitTests/Scripts/StackAndOtherTests.script
src/SOS/Strike/EventCallbacks.cpp
src/SOS/Strike/datatarget.cpp
src/SOS/Strike/datatarget.h
src/SOS/Strike/dllsext.cpp
src/SOS/Strike/hostcoreclr.cpp
src/SOS/Strike/hostcoreclr.h
src/SOS/Strike/sosdocs.txt
src/SOS/Strike/sosdocsunix.txt
src/SOS/Strike/strike.cpp
src/SOS/Strike/util.h
src/SOS/lldbplugin/inc/lldbservices.h
src/SOS/lldbplugin/lldbplugin.vcxproj
src/SOS/lldbplugin/lldbplugin.vcxproj.filters
src/SOS/lldbplugin/services.cpp
src/SOS/lldbplugin/services.h

index 9d01f900cb16594ffb46fc1eacb7c810cd5529be..980c1b649a238b512452f3773b79d3f16b34faea 100644 (file)
--- a/README.md
+++ b/README.md
@@ -56,6 +56,14 @@ Getting a version of lldb that works for your platform can be a problem sometime
 
 ## New Features
 
+The `bpmd` command can now be used before the runtime is loaded. You can load SOS or the sos plugin on Linux and execute bpmd. Always add the module extension for the first parameter.
+
+    bpmd SymbolTestApp.dll SymbolTestApp.Program.Main
+
+You can set a source file/line number breakpoint like this (the fully qualified source file path is usually not necessary):
+
+    bpmd SymbolTestApp.cs:24
+
 Symbol server support - The `setsymbolserver` command enables downloading the symbol files (portable PDBs) for managed assemblies during commands like `clrstack`, etc. See `soshelp setsymbolserver` for more details.
 
     (lldb) setsymbolserver -ms
index 135ff4b6271c82fbaef46b6f7966962dfb0b5e76..a6a55b8b8dce2a8037cd894763cc22addc6c3fd4 100644 (file)
@@ -23,7 +23,7 @@
     <MicrosoftWin32PrimitivesVersion>4.3.0</MicrosoftWin32PrimitivesVersion>
 
     <!-- Other libs -->
-    <MicrosoftSymbolStoreVersion>1.0.50701</MicrosoftSymbolStoreVersion>
+    <MicrosoftSymbolStoreVersion>1.0.55801</MicrosoftSymbolStoreVersion>
     <MicrosoftDiagnosticsRuntimeVersion>1.1.46104</MicrosoftDiagnosticsRuntimeVersion>
     <MicrosoftDiaSymReaderNativePackageVersion>1.7.0</MicrosoftDiaSymReaderNativePackageVersion>
     <MicrosoftDiagnosticsTracingTraceEventVersion>2.0.44</MicrosoftDiagnosticsTracingTraceEventVersion>
index 29081401a688985ebd220fce2ac5020080c00a1e..dde3a65838f466129638c21a4589f9d872a2d0e0 100644 (file)
@@ -226,18 +226,7 @@ namespace SOS
             SymbolStore symbolStore = s_symbolStore;
             while (symbolStore != null)
             {
-                if (symbolStore is CacheSymbolStore cache) {
-                    writeLine($"Cache: {cache.CacheDirectory}");
-                }
-                else if (symbolStore is HttpSymbolStore http) {
-                    writeLine($"Server: {http.Uri}");
-                }
-                else if (symbolStore is DirectorySymbolStore directory) {
-                    writeLine($"Directory: {directory.Directory}");
-                }
-                else {
-                    writeLine("Unknown symbol store");
-                }
+                writeLine(symbolStore.ToString());
                 symbolStore = symbolStore.BackingStore;
             }
         }
@@ -1130,7 +1119,7 @@ namespace SOS
                     return false;
                 }
 
-                if (!IsDuplicateSymbolStore<HttpSymbolStore >(store, (httpSymbolStore) => uri.Equals(httpSymbolStore.Uri)))
+                if (!IsDuplicateSymbolStore<HttpSymbolStore>(store, (httpSymbolStore) => uri.Equals(httpSymbolStore.Uri)))
                 {
                     // Create symbol server store
                     if (internalServer)
index d8e97d4484134b9365d65933231344395e810f8c..704a335bd25dea5a71ef2421254dad56372daacf 100644 (file)
@@ -4,9 +4,24 @@
 # 3) load sos
 # We are only verifying the main PrintException fields and for the stacktrace, source lines in the program.
 
+LOADSOS
+
+# Verify that bpmd works
+IFDEF:PROJECTK
+IFDEF:LIVE
+!IFDEF:MAJOR_RUNTIME_VERSION_1
+
+SOSCOMMAND:bpmd NestedExceptionTest.dll NestedExceptionTest.Program.Main
 CONTINUE
+SOSCOMMAND:ClrStack
+VERIFY:\s+<HEXVAL>\s+<HEXVAL>\s+NestedExceptionTest\.Program\.Main(\(.*\))?\s*
+VERIFY:\[.*[\\|/]Debuggees[\\|/](dotnet.+[\\|/])?[Nn]ested[Ee]xception[Tt]est[\\|/][Nn]ested[Ee]xception[Tt]est\.cs @ 8\s*\]\s*
 
-LOADSOS
+ENDIF:MAJOR_RUNTIME_VERSION_1
+ENDIF:LIVE
+ENDIF:PROJECTK
+
+CONTINUE
 
 # 4) Verifying that !pe gives us the right exception in the format above.
 SOSCOMMAND:PrintException
index 87fa292f701b743b0b5c2cd5207cb6f53c5c33b0..62620f314dad8c085fc813a025fb632ff7301643 100644 (file)
@@ -2,9 +2,45 @@
 # Tests the various SOS commands with the SymbolTestApp debuggee
 #
 
+LOADSOS
+
+# Verify that bpmd works
+IFDEF:PROJECTK
+IFDEF:LIVE
+!IFDEF:MAJOR_RUNTIME_VERSION_1
+
+SOSCOMMAND:bpmd SymbolTestApp.dll SymbolTestApp.Program.Main
 CONTINUE
+SOSCOMMAND:ClrStack
+VERIFY:\s+<HEXVAL>\s+<HEXVAL>\s+SymbolTestApp\.Program\.Main\(.*\)\s+\[(?i:.*[\\|/]SymbolTestApp\.cs) @ 16\]\s*
 
-LOADSOS
+SOSCOMMAND:bpmd SymbolTestApp.cs:29
+SOSCOMMAND:bpmd SymbolTestApp.dll SymbolTestApp.Program.Foo4
+
+CONTINUE
+SOSCOMMAND:ClrStack
+VERIFY:\s+<HEXVAL>\s+<HEXVAL>\s+SymbolTestApp\.Program\.Main\(.*\)\s+\[(?i:.*[\\|/]SymbolTestApp\.cs) @ 16\]\s*
+
+CONTINUE
+SOSCOMMAND:ClrStack
+VERIFY:\s+<HEXVAL>\s+<HEXVAL>\s+SymbolTestApp\.Program\.Foo2\(.*\)\s+\[(?i:.*[\\|/]SymbolTestApp\.cs) @ 28\]\s*
+
+CONTINUE
+SOSCOMMAND:ClrStack
+VERIFY:\s+<HEXVAL>\s+<HEXVAL>\s+SymbolTestApp\.Program\.Foo4\(.*\)\s+\[(?i:.*[\\|/]SymbolTestApp\.cs) @ 34\]\s*
+
+ENDIF:MAJOR_RUNTIME_VERSION_1
+ENDIF:LIVE
+ENDIF:PROJECTK
+
+CONTINUE
+
+IFDEF:PROJECTK
+SOSCOMMAND:SetSymbolServer -ms
+!IFDEF:DOTNETDUMP
+SOSCOMMAND:SetHostRuntime
+ENDIF:DOTNETDUMP
+ENDIF:PROJECTK
 
 IFDEF:DOTNETDUMP
 COMMAND:clrmodules
index 5a8931e5b582f701277f2466475ae068d8e78969..e3854844207b76b8e2989d34b76a12fd1bd182e9 100644 (file)
@@ -1,12 +1,48 @@
 #
 # Tests the various SOS stack and other commands with the Windows/Portable PDB debuggee
 #
-# Commands Verified: ClrStack, DumpStackObjects, DumpStack, EEStack, IP2MD, u, Name2EE, Threads (clrthreads) and others
+# Commands Verified: ClrStack, DumpStackObjects, DumpStack, EEStack, IP2MD, u, Name2EE, Threads (clrthreads), bpmd and others
 #
 
+LOADSOS
+
+# Verify that bpmd works
+IFDEF:PROJECTK
+IFDEF:LIVE
+!IFDEF:MAJOR_RUNTIME_VERSION_1
+
+SOSCOMMAND:bpmd SymbolTestApp.dll SymbolTestApp.Program.Main
 CONTINUE
+SOSCOMMAND:ClrStack
+VERIFY:\s+<HEXVAL>\s+<HEXVAL>\s+SymbolTestApp\.Program\.Main\(.*\)\s+\[(?i:.*[\\|/]SymbolTestApp\.cs) @ 16\]\s*
 
-LOADSOS
+SOSCOMMAND:bpmd SymbolTestApp.cs:29
+SOSCOMMAND:bpmd SymbolTestApp.dll SymbolTestApp.Program.Foo4
+
+CONTINUE
+SOSCOMMAND:ClrStack
+VERIFY:\s+<HEXVAL>\s+<HEXVAL>\s+SymbolTestApp\.Program\.Main\(.*\)\s+\[(?i:.*[\\|/]SymbolTestApp\.cs) @ 16\]\s*
+
+CONTINUE
+SOSCOMMAND:ClrStack
+VERIFY:\s+<HEXVAL>\s+<HEXVAL>\s+SymbolTestApp\.Program\.Foo2\(.*\)\s+\[(?i:.*[\\|/]SymbolTestApp\.cs) @ 28\]\s*
+
+CONTINUE
+SOSCOMMAND:ClrStack
+VERIFY:\s+<HEXVAL>\s+<HEXVAL>\s+SymbolTestApp\.Program\.Foo4\(.*\)\s+\[(?i:.*[\\|/]SymbolTestApp\.cs) @ 34\]\s*
+
+ENDIF:MAJOR_RUNTIME_VERSION_1
+ENDIF:LIVE
+ENDIF:PROJECTK
+
+CONTINUE
+
+IFDEF:PROJECTK
+SOSCOMMAND:SetSymbolServer -ms
+!IFDEF:DOTNETDUMP
+SOSCOMMAND:SetHostRuntime
+ENDIF:DOTNETDUMP
+ENDIF:PROJECTK
 
 # Verify that ClrStack with no options works
 SOSCOMMAND:SetSymbolServer -ms
index 0066dfa1e875de3f8a9feb1dde04a80386ccb1e5..1535b566789c47e46c94431d498becd93d0b3d29 100644 (file)
@@ -67,6 +67,13 @@ HRESULT __stdcall EventCallbacks::ChangeEngineState(ULONG Flags, ULONG64 Argumen
 }
 HRESULT __stdcall EventCallbacks::ChangeSymbolState(ULONG Flags, ULONG64 Argument)
 {
+    if (Flags == DEBUG_CSS_PATHS)
+    {
+        IDebugClient* client = m_pDebugClient;
+        INIT_API_EXT();
+        DisableSymbolStore();
+        InitializeSymbolStoreFromSymPath();
+    }
     return DEBUG_STATUS_NO_CHANGE;
 }
 HRESULT __stdcall EventCallbacks::CreateProcess(ULONG64 ImageFileHandle,
@@ -109,10 +116,12 @@ HRESULT __stdcall EventCallbacks::ExitThread(ULONG ExitCode)
 
 HRESULT __stdcall EventCallbacks::GetInterestMask(PULONG Mask)
 {
-    *Mask = DEBUG_EVENT_LOAD_MODULE | DEBUG_EVENT_EXIT_PROCESS;
+    *Mask = DEBUG_EVENT_LOAD_MODULE | DEBUG_EVENT_EXIT_PROCESS | DEBUG_EVENT_CHANGE_SYMBOL_STATE;
     return S_OK;
 }
 
+extern HRESULT HandleRuntimeLoadedNotification(IDebugClient* client);
+extern bool g_breakOnRuntimeModuleLoad;
 extern BOOL g_fAllowJitOptimization;
 
 HRESULT __stdcall EventCallbacks::LoadModule(ULONG64 ImageFileHandle,
@@ -124,23 +133,29 @@ HRESULT __stdcall EventCallbacks::LoadModule(ULONG64 ImageFileHandle,
     ULONG TimeDateStamp)
 {
     HRESULT handleEventStatus = DEBUG_STATUS_NO_CHANGE;
-    ExtQuery(m_pDebugClient);
 
     if (ModuleName != NULL && _stricmp(ModuleName, MAIN_CLR_MODULE_NAME_A) == 0)
     {
+        if (g_breakOnRuntimeModuleLoad)
+        {
+            g_breakOnRuntimeModuleLoad = false;
+            HandleRuntimeLoadedNotification(m_pDebugClient);
+        }
         // if we don't want the JIT to optimize, we should also disable optimized NGEN images
-        if(!g_fAllowJitOptimization)
+        if (!g_fAllowJitOptimization)
         {
-            // if we aren't succesful SetNGENCompilerFlags will print relevant error messages
+            ExtQuery(m_pDebugClient);
+
+            // If we aren't successful SetNGENCompilerFlags will print relevant error messages
             // and then we need to stop the debugger so the user can intervene if desired
-            if(FAILED(SetNGENCompilerFlags(CORDEBUG_JIT_DISABLE_OPTIMIZATION)))
+            if (FAILED(SetNGENCompilerFlags(CORDEBUG_JIT_DISABLE_OPTIMIZATION)))
             {
                 handleEventStatus = DEBUG_STATUS_BREAK;
             }
+            ExtRelease();
         }
     }
 
-    ExtRelease();
     return handleEventStatus;
 }
 
index e763d4aa87bfe657a1267ead0be3bce89fbee8e0..f76426a18710af356d321d7da9006ad93ae8abe6 100644 (file)
@@ -31,6 +31,12 @@ DataTarget::QueryInterface(
         AddRef();
         return S_OK;
     }
+    else if (InterfaceId == IID_ICLRDataTarget2)
+    {
+        *Interface = (ICLRDataTarget2*)this;
+        AddRef();
+        return S_OK;
+    }
     else if (InterfaceId == IID_ICorDebugDataTarget4)
     {
         *Interface = (ICorDebugDataTarget4*)this;
@@ -277,6 +283,52 @@ DataTarget::Request(
     return E_NOTIMPL;
 }
 
+// ICLRDataTarget2
+
+HRESULT STDMETHODCALLTYPE 
+DataTarget::AllocVirtual(
+    /* [in] */ CLRDATA_ADDRESS addr,
+    /* [in] */ ULONG32 size,
+    /* [in] */ ULONG32 typeFlags,
+    /* [in] */ ULONG32 protectFlags,
+    /* [out] */ CLRDATA_ADDRESS* virt)
+{
+#ifdef FEATURE_PAL
+    return E_NOTIMPL;
+#else
+    ULONG64 hProcess;
+    HRESULT hr = g_ExtSystem->GetCurrentProcessHandle(&hProcess);
+    if (FAILED(hr)) {
+        return hr;
+    }
+    LPVOID allocation = ::VirtualAllocEx((HANDLE)hProcess, (LPVOID)addr, size, typeFlags, protectFlags);
+    if (allocation == NULL) {
+        return HRESULT_FROM_WIN32(::GetLastError());
+    }
+    *virt = (CLRDATA_ADDRESS)allocation;
+    return S_OK;
+#endif
+}
+        
+HRESULT STDMETHODCALLTYPE 
+DataTarget::FreeVirtual(
+    /* [in] */ CLRDATA_ADDRESS addr,
+    /* [in] */ ULONG32 size,
+    /* [in] */ ULONG32 typeFlags)
+{
+#ifdef FEATURE_PAL
+    return E_NOTIMPL;
+#else
+    ULONG64 hProcess;
+    HRESULT hr = g_ExtSystem->GetCurrentProcessHandle(&hProcess);
+    if (FAILED(hr)) {
+        return hr;
+    }
+    ::VirtualFreeEx((HANDLE)hProcess, (LPVOID)addr, size, typeFlags);
+    return S_OK;
+#endif
+}
+
 // ICorDebugDataTarget4
 
 HRESULT STDMETHODCALLTYPE 
index f3ec9d14e8bdeae4ad05e632ae59604cca85dc79..fb266276dc20d3ba83f432c83b87d2ea0b7e58d4 100644 (file)
@@ -2,7 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
-class DataTarget : public ICLRDataTarget, ICorDebugDataTarget4, ICLRMetadataLocator
+class DataTarget : public ICLRDataTarget2, ICorDebugDataTarget4, ICLRMetadataLocator
 {
 private:
     LONG m_ref;                         // Reference count.
@@ -81,6 +81,20 @@ public:
         /* [in] */ ULONG32 outBufferSize,
         /* [size_is][out] */ BYTE *outBuffer);
 
+    // ICLRDataTarget2
+
+    virtual HRESULT STDMETHODCALLTYPE AllocVirtual( 
+            /* [in] */ CLRDATA_ADDRESS addr,
+            /* [in] */ ULONG32 size,
+            /* [in] */ ULONG32 typeFlags,
+            /* [in] */ ULONG32 protectFlags,
+            /* [out] */ CLRDATA_ADDRESS *virt);
+        
+    virtual HRESULT STDMETHODCALLTYPE FreeVirtual( 
+            /* [in] */ CLRDATA_ADDRESS addr,
+            /* [in] */ ULONG32 size,
+            /* [in] */ ULONG32 typeFlags);
+
     // ICorDebugDataTarget4
 
     virtual HRESULT STDMETHODCALLTYPE VirtualUnwind(
index 7517d739a1c9c7b89a95f3c4d027f0e69285b312..4d1742802d885f85b3368ea648e3454307db22a2 100644 (file)
@@ -12,6 +12,8 @@
 #include "util.h"
 #include "platformspecific.h"
 
+#ifndef FEATURE_PAL
+
 typedef struct _PRIVATE_LDR_DATA_TABLE_ENTRY {
     LIST_ENTRY InLoadOrderLinks;
     LIST_ENTRY InMemoryOrderLinks;
@@ -45,8 +47,6 @@ typedef struct _PRIVATE_LDR_DATA_TABLE_ENTRY {
     
 } PRIVATE_LDR_DATA_TABLE_ENTRY, *PRIVATE_PLDR_DATA_TABLE_ENTRY;
 
-
-#ifndef FEATURE_PAL
 static void DllsNameFromPeb(
     ULONG_PTR addrContaining,
     __out_ecount (MAX_LONGPATH) WCHAR *dllName
@@ -245,7 +245,6 @@ static void DllsNameFromPeb(
         return;
     }
 }
-#endif
 
 HRESULT
 DllsName(
@@ -271,11 +270,11 @@ DllsName(
         MultiByteToWideChar (CP_ACP,0,name,-1,dllName,MAX_LONGPATH);
     }
     
-#ifndef FEATURE_PAL
     if (_wcsrchr (dllName, '\\') == NULL) {
         DllsNameFromPeb (addrContaining,dllName);
     }
-#endif
 
     return hr;
 }
+
+#endif // FEATURE_PAL
\ No newline at end of file
index 3f1318d3c5adb74a068a465403a3ac5ac25241ef..92fc0900b18e66767b16e7ffcfd47442c951334e 100644 (file)
@@ -41,7 +41,6 @@
 
 static bool g_hostingInitialized = false;
 static bool g_symbolStoreInitialized = false;
-static bool g_windowsSymbolPathInitialized = false;
 LPCSTR g_hostRuntimeDirectory = nullptr;
 LPCSTR g_dacFilePath = nullptr;
 LPCSTR g_dbiFilePath = nullptr;
@@ -797,34 +796,48 @@ HRESULT InitializeSymbolStore(BOOL logging, BOOL msdl, BOOL symweb, const char*
     return S_OK;
 }
 
-
 /**********************************************************************\
  * Setup and initialize the symbol server support using the .sympath
 \**********************************************************************/
-void InitializeSymbolStore()
+HRESULT InitializeSymbolStore()
 {
-    _ASSERTE(g_SOSNetCoreCallbacks.InitializeSymbolStoreDelegate != nullptr);
+    if (!g_symbolStoreInitialized)
+    {
+        HRESULT hr = InitializeHosting();
+        if (FAILED(hr)) {
+            return hr;
+        }
+#ifndef FEATURE_PAL
+        InitializeSymbolStoreFromSymPath();
+#endif
+    }
+    return S_OK;
+}
 
 #ifndef FEATURE_PAL
-    if (!g_windowsSymbolPathInitialized)
+/**********************************************************************\
+ * Setup and initialize the symbol server support using the .sympath
+\**********************************************************************/
+void InitializeSymbolStoreFromSymPath()
+{
+    if (g_SOSNetCoreCallbacks.InitializeSymbolStoreDelegate != nullptr)
     {
         ArrayHolder<char> symbolPath = new char[MAX_LONGPATH];
         if (SUCCEEDED(g_ExtSymbols->GetSymbolPath(symbolPath, MAX_LONGPATH, nullptr)))
         {
             if (strlen(symbolPath) > 0)
-            {
+            {   
                 if (!g_SOSNetCoreCallbacks.InitializeSymbolStoreDelegate(false, false, false, GetTempDirectory(), nullptr, nullptr, nullptr, symbolPath))
                 {
                     ExtErr("Windows symbol path parsing FAILED\n");
                     return;
                 }
-                g_windowsSymbolPathInitialized = true;
                 g_symbolStoreInitialized = true;
             }
         }
     }
-#endif
 }
+#endif // FEATURE_PAL
 
 //
 // Symbol downloader callback
@@ -926,7 +939,6 @@ void DisableSymbolStore()
     if (g_symbolStoreInitialized)
     {
         g_symbolStoreInitialized = false;
-        g_windowsSymbolPathInitialized = false;
 
         _ASSERTE(g_SOSNetCoreCallbacks.DisableSymbolStoreDelegate != nullptr);
         g_SOSNetCoreCallbacks.DisableSymbolStoreDelegate();
@@ -947,11 +959,9 @@ HRESULT GetMetadataLocator(
     BYTE* buffer,
     ULONG32* dataSize)
 {
-    HRESULT hr = InitializeHosting();
-    if (FAILED(hr)) {
-        return hr;
-    }
-    InitializeSymbolStore();
+    HRESULT Status = S_OK;
+    IfFailRet(InitializeSymbolStore());
+
     _ASSERTE(g_SOSNetCoreCallbacks.GetMetadataLocatorDelegate != nullptr);
     return g_SOSNetCoreCallbacks.GetMetadataLocatorDelegate(imagePath, imageTimestamp, imageSize, mvid, mdRva, flags, bufferSize, buffer, dataSize);
 }
@@ -1206,10 +1216,7 @@ HRESULT SymbolReader::LoadSymbolsForPortablePDB(__in_z WCHAR* pModuleName, ___in
     ___in ULONG64 peAddress, ___in ULONG64 peSize, ___in ULONG64 inMemoryPdbAddress, ___in ULONG64 inMemoryPdbSize)
 {
     HRESULT Status = S_OK;
-
-    IfFailRet(InitializeHosting());
-    InitializeSymbolStore();
-
+    IfFailRet(InitializeSymbolStore());
     _ASSERTE(g_SOSNetCoreCallbacks.LoadSymbolsForModuleDelegate != nullptr);
 
     // The module name needs to be null for in-memory PE's.
index 075e4ed1fb2f5990c9319a595aacf08054a9e108..565028e822b38726ce41f74d85e0fdbe6529eeca 100644 (file)
@@ -72,7 +72,9 @@ extern LPCSTR GetDbiFilePath();
 extern BOOL IsHostingInitialized();
 extern HRESULT InitializeHosting();
 extern HRESULT InitializeSymbolStore(BOOL logging, BOOL msdl, BOOL symweb, const char* symbolServer, const char* cacheDirectory, const char* searchDirectory, const char* windowsSymbolPath);
-extern void InitializeSymbolStore();
+#ifndef FEATURE_PAL
+extern void InitializeSymbolStoreFromSymPath();
+#endif
 extern HRESULT LoadNativeSymbols(bool runtimeOnly = false);
 extern void DisplaySymbolStore();
 extern void DisableSymbolStore();
index ea9ef9924f4b56ec0599db4d68db7e103c725229..42aa38e34592a9cda28f6460e10a02f10542171d 100644 (file)
@@ -32,7 +32,7 @@ DumpHeap                           EEStack
 DumpVC                             CLRStack
 GCRoot                             GCInfo
 ObjSize                            EHInfo
-FinalizeQueue                      BPMD
+FinalizeQueue                      BPMD (bpmd)
 PrintException (pe)                COMState
 TraverseHeap                       
 
@@ -1138,12 +1138,12 @@ pointer if provided.
 \\
 
 COMMAND: bpmd.
-!BPMD [-nofuturemodule] <module name> <method name> [<il offset>]
-!BPMD <source file name>:<line number>
-!BPMD -md <MethodDesc>
-!BPMD -list
-!BPMD -clear <pending breakpoint number>
-!BPMD -clearall
+!bpmd [-nofuturemodule] <module name> <method name> [<il offset>]
+!bpmd <source file name>:<line number>
+!bpmd -md <MethodDesc>
+!bpmd -list
+!bpmd -clear <pending breakpoint number>
+!bpmd -clearall
 
 !BPMD provides managed breakpoint support. If it can resolve the method name
 to a loaded, jitted or ngen'd function it will create a breakpoint with "bp".
@@ -1154,34 +1154,25 @@ receive news of module loads and JITs, at which time it will try to resolve
 the function to a breakpoint. -nofuturemodule can be used to suppress 
 creating a breakpoint against a module that has not yet been loaded.
 
-Management of the list of pending breakpoints can be done via !BPMD -list,
-!BPMD -clear, and !BPMD -clearall commands. !BPMD -list generates a list of 
-all of the pending breakpoints. If the pending breakpoint has a non-zero 
-module id, then that pending breakpoint is specific to function in that 
+Management of the list of pending breakpoints can be done via !bpmd -list,
+!bpmd -clear, and !bpmd -clearall commands. !bpmd -list generates a list of
+all of the pending breakpoints. If the pending breakpoint has a non-zero
+module id, then that pending breakpoint is specific to function in that
 particular loaded module. If the pending breakpoint has a zero module id, then
 the breakpoint applies to modules that have not yet been loaded. Use 
-!BPMD -clear or !BPMD -clearall to remove pending breakpoints from the list.
+!bpmd -clear or !bpmd -clearall to remove pending breakpoints from the list.
+
+The !bpmd command can now be used before the runtime is loaded. You can execute
+!bpmd right after SOS is loaded. Always add the module extension for the module
+name parameter.
 
 This brings up a good question: "I want to set a breakpoint on the main
 method of my application. How can I do this?"
 
-  1) If you know the full path to SOS, use this command and skip to step 6
-       .load <the full path to sos.dll>
-
-  2) If you don't know the full path to sos, its usually next to coreclr.dll
-     You can wait for clr to load and then find it.
-     Start the debugger and type: 
-       sxe -c "" clrn
-  3) g
-  4) You'll get the following notification from the debugger:
-     "CLR notification: module 'mscorlib' loaded"
-  5) Now you can load SOS. Type
-       .loadby sos clr
-
-  6) Add the breakpoint with command such as:
+  1) Add the breakpoint with command such as:
        !bpmd myapp.exe MyApp.Main
-  7) g
-  8) You will stop at the start of MyApp.Main. If you type "bl" you will 
+  2) g
+  3) You will stop at the start of MyApp.Main. If you type "bl" you will 
      see the breakpoint listed.
 
 You can specify breakpoints by file and line number if:
@@ -1192,7 +1183,6 @@ You can specify breakpoints by file and line number if:
 This is often easier than module and method name syntax. For example:
    !bpmd Demo.cs:15
 
-
 To correctly specify explicitly implemented methods make sure to retrieve the
 method name from the metadata, or from the output of the "!dumpmt -md" command. 
 For example:
@@ -1211,7 +1201,7 @@ For example:
        !bpmd myapp.exe ExplicitItfImpl.I1.M1
 
 
-!BPMD works equally well with generic types. Adding a breakpoint on a generic 
+!bpmd works equally well with generic types. Adding a breakpoint on a generic 
 type sets breakpoints on all already JIT-ted generic methods and sets a pending 
 breakpoint for any instantiation that will be JIT-ted in the future.
 
@@ -1267,7 +1257,7 @@ Additional examples:
 
        !bpmd bpmd.exe NS.Outer+ExplicitItfImpl`1.NS.Outer.IT1<U>.M1
 
-!BPMD does not accept offsets nor parameters in the method name. You can add
+!bpmd does not accept offsets nor parameters in the method name. You can add
 an IL offset as an optional parameter seperate from the name. If there are overloaded
 methods, !bpmd will set a breakpoint for all of them.
 
index c1dcbe8db4479d739bc73537b7bbc3168ee57c09..b6dff6278601b4eb3c82be42e4ea36e683b48046 100644 (file)
@@ -911,10 +911,10 @@ bpmd provides managed breakpoint support. If it can resolve the method name
 to a loaded, jitted or ngen'd function it will create a breakpoint with "bp".
 If not then either the module that contains the method hasn't been loaded yet
 or the module is loaded, but the function is not jitted yet. In these cases,
-bpmd asks the Windows Debugger to receive CLR Notifications, and waits to
-receive news of module loads and JITs, at which time it will try to resolve 
-the function to a breakpoint. -nofuturemodule can be used to suppress 
-creating a breakpoint against a module that has not yet been loaded.
+bpmd asks the Debugger to receive CLR Notifications, and waits to receive news 
+of module loads and JITs, at which time it will try to resolve the function to
+a breakpoint. -nofuturemodule can be used to suppress creating a breakpoint 
+against a module that has not yet been loaded.
 
 Management of the list of pending breakpoints can be done via bpmd -list,
 bpmd -clear, and bpmd -clearall commands. bpmd -list generates a list of 
@@ -924,15 +924,17 @@ particular loaded module. If the pending breakpoint has a zero module id, then
 the breakpoint applies to modules that have not yet been loaded. Use 
 bpmd -clear or bpmd -clearall to remove pending breakpoints from the list.
 
+The bpmd command can now be used before the runtime is loaded. You can execute
+bpmd right after the SOS plug-in is loaded. Always add the module extension for
+the module name parameter.
+
 This brings up a good question: "I want to set a breakpoint on the main
 method of my application. How can I do this?"
 
-  1) Stop after coreclr is loaded - TBD
-
-  2) Add the breakpoint with command such as:
-       bpmd myapp.exe MyApp.Main
-  3) g
-  4) You will stop at the start of MyApp.Main. If you type "bl" you will 
+  1) Add the breakpoint with command such as:
+       bpmd myapp.dll MyApp.Main
+  2) g
+  3) You will stop at the start of MyApp.Main. If you type "bl" you will 
      see the breakpoint listed.
 
 To correctly specify explicitly implemented methods make sure to retrieve the
@@ -950,7 +952,7 @@ For example:
            { ... }
        }
 
-       bpmd myapp.exe ExplicitItfImpl.I1.M1
+       bpmd myapp.dll ExplicitItfImpl.I1.M1
 
 
 bpmd works equally well with generic types. Adding a breakpoint on a generic 
@@ -973,11 +975,11 @@ Example for generics:
                { ... }
        }
 
-       One would issue the following commands to set breapoints on G3.F() and 
+       One would issue the following commands to set breakpoints on G3.F() and 
        G1.G():
 
-       bpmd myapp.exe G3`3.F
-       bpmd myapp.exe G1`1.G
+       bpmd myapp.dll G3`3.F
+       bpmd myapp.dll G1`1.G
 
 And for explicitly implemented methods on generic interfaces:
        public interface IT1<T>
@@ -992,7 +994,7 @@ And for explicitly implemented methods on generic interfaces:
            { ... }
        }
 
-       bpmd bpmd.exe ExplicitItfImpl`1.IT1<U>.M1
+       bpmd bpmd.dll ExplicitItfImpl`1.IT1<U>.M1
 
 Additional examples:
        If IT1 and ExplicitItfImpl are types declared inside another class, 
@@ -1007,10 +1009,10 @@ Additional examples:
        Furthermore, if the Outer class resides in a namespace, NS, the bpmd 
        command to use becomes:
 
-       bpmd bpmd.exe NS.Outer+ExplicitItfImpl`1.NS.Outer.IT1<U>.M1
+       bpmd bpmd.dll NS.Outer+ExplicitItfImpl`1.NS.Outer.IT1<U>.M1
 
 bpmd does not accept offsets nor parameters in the method name. You can add
-an IL offset as an optional parameter seperate from the name. If there are overloaded
+an IL offset as an optional parameter separate from the name. If there are overloaded
 methods, bpmd will set a breakpoint for all of them.
 
 In the case of hosted environments such as SQL, the module name may be 
index d286f75a549e549ef13964a4a1cea5d3aa5d7505..868febf6d5d066e9f11e0b50816efb1e6d91f300 100644 (file)
@@ -7470,7 +7470,7 @@ private:
         // This function only works with pending breakpoints that are not module bound.
         if (pCur->pModule == NULL)
         {
-            if(pCur->szModuleName[0] != L'\0')
+            if (pCur->szModuleName[0] != L'\0')
             {
                 return ResolvePendingNonModuleBoundBreakpoint(pCur->szModuleName, pCur->szFunctionName, mod, pCur->ilOffset);
             }
@@ -7517,6 +7517,11 @@ private:
 
 Breakpoints g_bpoints;
 
+// If true, call the HandleRuntimeLoadedNotification function to enable the assembly load and JIT exceptions
+#ifndef FEATURE_PAL
+bool g_breakOnRuntimeModuleLoad = true;
+#endif
+
 // Controls whether optimizations are disabled on module load and whether NGEN can be used
 BOOL g_fAllowJitOptimization = TRUE;
 
@@ -7642,20 +7647,20 @@ public:
             g_bpoints.Update(TO_TADDR(dgma.ModulePtr), TRUE);
         }
 
-        if(!g_fAllowJitOptimization)
+        if (!g_fAllowJitOptimization)
         {
             HRESULT hr;
             ToRelease<IXCLRDataModule2> mod2;
-            if(FAILED(mod->QueryInterface(__uuidof(IXCLRDataModule2), (void**) &mod2)))
+            if (FAILED(mod->QueryInterface(__uuidof(IXCLRDataModule2), (void**) &mod2)))
             {
                 ExtOut("SOS: warning, optimizations for this module could not be suppressed because this CLR version doesn't support the functionality\n");
             }
             else if(FAILED(hr = mod2->SetJITCompilerFlags(CORDEBUG_JIT_DISABLE_OPTIMIZATION)))
             {
                 if(hr == CORDBG_E_CANT_CHANGE_JIT_SETTING_FOR_ZAP_MODULE)
-                    ExtOut("SOS: warning, optimizations for this module could not be surpressed because an optimized prejitted image was loaded\n");
+                    ExtOut("SOS: warning, optimizations for this module could not be suppressed because an optimized prejitted image was loaded\n");
                 else
-                    ExtOut("SOS: warning, optimizations for this module could not be surpressed hr=0x%x\n", hr);
+                    ExtOut("SOS: warning, optimizations for this module could not be suppressed hr=0x%x\n", hr);
             }
         }
         
@@ -7864,16 +7869,32 @@ HRESULT HandleCLRNotificationEvent()
     return S_OK;
 }
 
+void EnableModuleLoadUnloadCallbacks()
+{
+    _ASSERTE(g_clrData != nullptr);
+
+    ULONG32 flags = 0;
+    g_clrData->GetOtherNotificationFlags(&flags);
+    flags |= (CLRDATA_NOTIFY_ON_MODULE_LOAD | CLRDATA_NOTIFY_ON_MODULE_UNLOAD);
+    g_clrData->SetOtherNotificationFlags(flags);
+}
+
 #ifndef FEATURE_PAL
 
 DECLARE_API(HandleCLRN)
 {
     INIT_API();    
     MINIDUMP_NOT_SUPPORTED();    
-
     return HandleCLRNotificationEvent();
 }
 
+HRESULT HandleRuntimeLoadedNotification(IDebugClient* client)
+{
+    INIT_API();
+    EnableModuleLoadUnloadCallbacks();
+    return g_ExtControl->Execute(DEBUG_EXECUTE_NOT_LOGGED, "sxe -c \"!HandleCLRN\" clrn", 0);
+}
+
 #else // FEATURE_PAL
 
 HRESULT HandleExceptionNotification(ILLDBServices *client)
@@ -7882,6 +7903,13 @@ HRESULT HandleExceptionNotification(ILLDBServices *client)
     return HandleCLRNotificationEvent();
 }
 
+HRESULT HandleRuntimeLoadedNotification(ILLDBServices *client)
+{
+    INIT_API();
+    EnableModuleLoadUnloadCallbacks();
+    return g_ExtServices->SetExceptionCallback(HandleExceptionNotification);
+}
+
 #endif // FEATURE_PAL
 
 DECLARE_API(bpmd)
@@ -7973,11 +8001,6 @@ DECLARE_API(bpmd)
         // did we get dll and type name or file:line#? Search for a colon in the first arg
         // to see if it is in fact a file:line#
         CHAR* pColon = strchr(DllName.data, ':');
-        if (FAILED(GetRuntimeModuleInfo(NULL, NULL))) {
-           ExtOut("%s not loaded yet\n", MAIN_CLR_DLL_NAME_A);
-           return Status;
-        }
-
         if(NULL != pColon)
         {
             fIsFilename = true;
@@ -8084,8 +8107,10 @@ DECLARE_API(bpmd)
         // If LoadClrDebugDll() succeeded make sure we release g_clrData
         ToRelease<IXCLRDataProcess> spIDP(g_clrData);
         ToRelease<ISOSDacInterface> spISD(g_sos);
-        ResetGlobals();
-        
+        if (g_sos != nullptr)
+        {
+            ResetGlobals();
+        }
         // we can get here with EE not loaded => 0 modules
         //                      EE is loaded => 0 or more modules
         ArrayHolder<DWORD_PTR> pMDs = NULL;
@@ -8174,12 +8199,19 @@ DECLARE_API(bpmd)
             {
                 g_bpoints.Add(Filename, lineNumber, NULL);
             }
-            bNeedNotificationExceptions = TRUE;
-
-            ULONG32 flags = 0;
-            g_clrData->GetOtherNotificationFlags(&flags);
-            flags |= (CLRDATA_NOTIFY_ON_MODULE_LOAD | CLRDATA_NOTIFY_ON_MODULE_UNLOAD);
-            g_clrData->SetOtherNotificationFlags(flags);
+            if (g_clrData != nullptr)
+            {
+                bNeedNotificationExceptions = TRUE;
+                EnableModuleLoadUnloadCallbacks();
+            }
+            else 
+            {
+#ifdef FEATURE_PAL
+                Status = g_ExtServices2->SetRuntimeLoadedCallback(HandleRuntimeLoadedNotification);
+#else
+                g_breakOnRuntimeModuleLoad = true;
+#endif
+            }
         }
     }
     else /* We were given a MethodDesc already */
@@ -8251,8 +8283,7 @@ DECLARE_API(bpmd)
     {
         ExtOut("Adding pending breakpoints...\n");
 #ifndef FEATURE_PAL
-        sprintf_s(buffer, _countof(buffer), "sxe -c \"!HandleCLRN\" clrn");
-        Status = g_ExtControl->Execute(DEBUG_EXECUTE_NOT_LOGGED, buffer, 0);        
+        Status = g_ExtControl->Execute(DEBUG_EXECUTE_NOT_LOGGED, "sxe -c \"!HandleCLRN\" clrn", 0);
 #else
         Status = g_ExtServices->SetExceptionCallback(HandleExceptionNotification);
 #endif // FEATURE_PAL
@@ -15410,16 +15441,18 @@ DECLARE_API(SuppressJitOptimization)
         return E_FAIL;
     }
 
-    if(nArg == 1 && (_stricmp(onOff.data, "On") == 0))
+    if (nArg == 1 && (_stricmp(onOff.data, "On") == 0))
     {
         // if CLR is already loaded, try to change the flags now
-        if(CheckEEDll() == S_OK)
+        if (CheckEEDll() == S_OK)
         {
             SetNGENCompilerFlags(CORDEBUG_JIT_DISABLE_OPTIMIZATION);
         }
 
-        if(!g_fAllowJitOptimization)
+        if (!g_fAllowJitOptimization)
+        {
             ExtOut("JIT optimization is already suppressed\n");
+        }
         else
         {
             g_fAllowJitOptimization = FALSE;
index d1a811572d266e81be14184d94696c9aabb2b0df..a8f0f405b7884eceb04ff12dd64f06136c841949 100644 (file)
@@ -1440,11 +1440,13 @@ int bitidx(SCALAR bitflag)
     return -1;
 }
 
+#ifndef FEATURE_PAL
 HRESULT
 DllsName(
     ULONG_PTR addrContaining,
     __out_ecount (MAX_LONGPATH) WCHAR *dllName
     );
+#endif
 
 inline
 BOOL IsElementValueType (CorElementType cet)
index a8bd87bd695317373cdc6f56807fc36bb0c1f7cf..d96aaa818f173affcaaad3b9a2558987f991c99e 100644 (file)
@@ -231,6 +231,7 @@ typedef struct _DEBUG_STACK_FRAME_EX
 
 interface ILLDBServices;
 typedef HRESULT (*PFN_EXCEPTION_CALLBACK)(ILLDBServices *services);
+typedef HRESULT (*PFN_RUNTIME_LOADED_CALLBACK)(ILLDBServices *services);
 
 //----------------------------------------------------------------------------
 // ILLDBServices
@@ -575,6 +576,9 @@ public:
         PVOID buffer,
         ULONG bufferSize,
         PULONG versionInfoSize) = 0;
+
+    virtual HRESULT SetRuntimeLoadedCallback(
+        PFN_RUNTIME_LOADED_CALLBACK callback) = 0;
 };
 
 #ifdef __cplusplus
index 42644ea5d3de7041fdb4439fb140e56e298cd4cc..c9a75821d837645364531d3c4139681b0f3aee2a 100644 (file)
     <ClInclude Include="mstypes.h" />
     <ClInclude Include="services.h" />
     <ClInclude Include="sosplugin.h" />
+    <ClInclude Include="swift-4.0\lldb\API\LLDB.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBAddress.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBAttachInfo.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBBlock.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBBreakpoint.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBBreakpointLocation.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBBroadcaster.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBCommandInterpreter.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBCommandReturnObject.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBCommunication.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBCompileUnit.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBData.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBDebugger.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBDeclaration.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBDefines.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBError.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBEvent.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBExecutionContext.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBExpressionOptions.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBFileSpec.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBFileSpecList.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBFrame.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBFunction.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBHostOS.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBInstruction.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBInstructionList.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBLanguageRuntime.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBLaunchInfo.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBLineEntry.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBListener.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBMemoryRegionInfo.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBMemoryRegionInfoList.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBModule.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBModuleSpec.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBPlatform.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBProcess.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBQueue.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBQueueItem.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBSection.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBSourceManager.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBStream.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBStringList.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBStructuredData.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBSymbol.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBSymbolContext.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBSymbolContextList.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBTarget.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBThread.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBThreadCollection.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBThreadPlan.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBType.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBTypeCategory.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBTypeEnumMember.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBTypeFilter.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBTypeFormat.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBTypeNameSpecifier.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBTypeSummary.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBTypeSynthetic.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBUnixSignals.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBValue.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBValueList.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBVariablesOptions.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SBWatchpoint.h" />
+    <ClInclude Include="swift-4.0\lldb\API\SystemInitializerFull.h" />
+    <ClInclude Include="swift-4.0\lldb\lldb-defines.h" />
+    <ClInclude Include="swift-4.0\lldb\lldb-enumerations.h" />
+    <ClInclude Include="swift-4.0\lldb\lldb-forward.h" />
+    <ClInclude Include="swift-4.0\lldb\lldb-private-defines.h" />
+    <ClInclude Include="swift-4.0\lldb\lldb-private-enumerations.h" />
+    <ClInclude Include="swift-4.0\lldb\lldb-private-forward.h" />
+    <ClInclude Include="swift-4.0\lldb\lldb-private-interfaces.h" />
+    <ClInclude Include="swift-4.0\lldb\lldb-private-types.h" />
+    <ClInclude Include="swift-4.0\lldb\lldb-private.h" />
+    <ClInclude Include="swift-4.0\lldb\lldb-public.h" />
+    <ClInclude Include="swift-4.0\lldb\lldb-types.h" />
+    <ClInclude Include="swift-4.0\lldb\lldb-versioning.h" />
+    <ClInclude Include="swift-4.0\lldb\Utility\AnsiTerminal.h" />
+    <ClInclude Include="swift-4.0\lldb\Utility\CleanUp.h" />
+    <ClInclude Include="swift-4.0\lldb\Utility\ConvertEnum.h" />
+    <ClInclude Include="swift-4.0\lldb\Utility\Either.h" />
+    <ClInclude Include="swift-4.0\lldb\Utility\Iterable.h" />
+    <ClInclude Include="swift-4.0\lldb\Utility\JSON.h" />
+    <ClInclude Include="swift-4.0\lldb\Utility\LLDBAssert.h" />
+    <ClInclude Include="swift-4.0\lldb\Utility\NameMatches.h" />
+    <ClInclude Include="swift-4.0\lldb\Utility\PriorityPointerPair.h" />
+    <ClInclude Include="swift-4.0\lldb\Utility\ProcessStructReader.h" />
+    <ClInclude Include="swift-4.0\lldb\Utility\PseudoTerminal.h" />
+    <ClInclude Include="swift-4.0\lldb\Utility\Range.h" />
+    <ClInclude Include="swift-4.0\lldb\Utility\RegisterNumber.h" />
+    <ClInclude Include="swift-4.0\lldb\Utility\SafeMachO.h" />
+    <ClInclude Include="swift-4.0\lldb\Utility\SelectHelper.h" />
+    <ClInclude Include="swift-4.0\lldb\Utility\SharedCluster.h" />
+    <ClInclude Include="swift-4.0\lldb\Utility\SharingPtr.h" />
+    <ClInclude Include="swift-4.0\lldb\Utility\StringExtractor.h" />
+    <ClInclude Include="swift-4.0\lldb\Utility\StringLexer.h" />
+    <ClInclude Include="swift-4.0\lldb\Utility\TaskPool.h" />
+    <ClInclude Include="swift-4.0\lldb\Utility\Timeout.h" />
+    <ClInclude Include="swift-4.0\lldb\Utility\Utils.h" />
   </ItemGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>$(SolutionDir)src\pal\prebuilt\inc;$(SolutionDir)src\inc;$(SolutionDir)src\pal\inc;$(SolutionDir)src\pal\inc\rt;$(SolutionDir)src\SOS\lldbplugin\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(SolutionDir)src\pal\prebuilt\inc;$(SolutionDir)src\inc;$(SolutionDir)src\pal\inc;$(SolutionDir)src\pal\inc\rt;$(SolutionDir)src\SOS\lldbplugin\inc;$(SolutionDir)src\SOS\lldbplugin\swift-4.0;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
   </ItemDefinitionGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
index e42fbc5dd66f2454e78af6fe0346ad539bcea3cc..b1e7b11756420920a5f2ec87ed1efbdaecc844db 100644 (file)
     <ClInclude Include="inc\lldbservices.h">
       <Filter>inc</Filter>
     </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\lldb-defines.h">
+      <Filter>swift-4.0\lldb</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\lldb-enumerations.h">
+      <Filter>swift-4.0\lldb</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\lldb-forward.h">
+      <Filter>swift-4.0\lldb</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\lldb-private.h">
+      <Filter>swift-4.0\lldb</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\lldb-private-defines.h">
+      <Filter>swift-4.0\lldb</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\lldb-private-enumerations.h">
+      <Filter>swift-4.0\lldb</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\lldb-private-forward.h">
+      <Filter>swift-4.0\lldb</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\lldb-private-interfaces.h">
+      <Filter>swift-4.0\lldb</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\lldb-private-types.h">
+      <Filter>swift-4.0\lldb</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\lldb-public.h">
+      <Filter>swift-4.0\lldb</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\lldb-types.h">
+      <Filter>swift-4.0\lldb</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\lldb-versioning.h">
+      <Filter>swift-4.0\lldb</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\LLDB.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBAddress.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBAttachInfo.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBBlock.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBBreakpoint.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBBreakpointLocation.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBBroadcaster.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBCommandInterpreter.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBCommandReturnObject.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBCommunication.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBCompileUnit.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBData.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBDebugger.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBDeclaration.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBDefines.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBError.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBEvent.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBExecutionContext.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBExpressionOptions.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBFileSpec.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBFileSpecList.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBFrame.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBFunction.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBHostOS.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBInstruction.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBInstructionList.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBLanguageRuntime.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBLaunchInfo.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBLineEntry.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBListener.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBMemoryRegionInfo.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBMemoryRegionInfoList.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBModule.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBModuleSpec.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBPlatform.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBProcess.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBQueue.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBQueueItem.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBSection.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBSourceManager.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBStream.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBStringList.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBStructuredData.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBSymbol.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBSymbolContext.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBSymbolContextList.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBTarget.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBThread.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBThreadCollection.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBThreadPlan.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBType.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBTypeCategory.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBTypeEnumMember.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBTypeFilter.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBTypeFormat.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBTypeNameSpecifier.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBTypeSummary.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBTypeSynthetic.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBUnixSignals.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBValue.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBValueList.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBVariablesOptions.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SBWatchpoint.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\API\SystemInitializerFull.h">
+      <Filter>swift-4.0\lldb\API</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\Utility\AnsiTerminal.h">
+      <Filter>swift-4.0\lldb\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\Utility\CleanUp.h">
+      <Filter>swift-4.0\lldb\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\Utility\ConvertEnum.h">
+      <Filter>swift-4.0\lldb\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\Utility\Either.h">
+      <Filter>swift-4.0\lldb\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\Utility\Iterable.h">
+      <Filter>swift-4.0\lldb\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\Utility\JSON.h">
+      <Filter>swift-4.0\lldb\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\Utility\LLDBAssert.h">
+      <Filter>swift-4.0\lldb\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\Utility\NameMatches.h">
+      <Filter>swift-4.0\lldb\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\Utility\PriorityPointerPair.h">
+      <Filter>swift-4.0\lldb\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\Utility\ProcessStructReader.h">
+      <Filter>swift-4.0\lldb\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\Utility\PseudoTerminal.h">
+      <Filter>swift-4.0\lldb\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\Utility\Range.h">
+      <Filter>swift-4.0\lldb\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\Utility\RegisterNumber.h">
+      <Filter>swift-4.0\lldb\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\Utility\SafeMachO.h">
+      <Filter>swift-4.0\lldb\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\Utility\SelectHelper.h">
+      <Filter>swift-4.0\lldb\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\Utility\SharedCluster.h">
+      <Filter>swift-4.0\lldb\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\Utility\SharingPtr.h">
+      <Filter>swift-4.0\lldb\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\Utility\StringExtractor.h">
+      <Filter>swift-4.0\lldb\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\Utility\StringLexer.h">
+      <Filter>swift-4.0\lldb\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\Utility\TaskPool.h">
+      <Filter>swift-4.0\lldb\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\Utility\Timeout.h">
+      <Filter>swift-4.0\lldb\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="swift-4.0\lldb\Utility\Utils.h">
+      <Filter>swift-4.0\lldb\Utility</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <Filter Include="inc">
       <UniqueIdentifier>{32c8e536-f88f-4485-a168-9f9e9fab5822}</UniqueIdentifier>
     </Filter>
+    <Filter Include="swift-4.0">
+      <UniqueIdentifier>{218787e9-5d31-4db1-bc35-232897746e27}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="swift-4.0\lldb">
+      <UniqueIdentifier>{351934db-c5e0-4f1a-aeef-e882535040d3}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="swift-4.0\lldb\API">
+      <UniqueIdentifier>{2b88af64-c488-40e3-8617-50dc26f41547}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="swift-4.0\lldb\Utility">
+      <UniqueIdentifier>{ffdcee4c-ef55-4963-9791-6f0784ba4151}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
 </Project>
\ No newline at end of file
index 0cbeacc88f7091f696b2415edd88967f3cf06163..a2340bdd3b27e9d23673c08836a1bd3534dc5525 100644 (file)
@@ -259,13 +259,12 @@ ExceptionBreakpointCallback(
 
     // Send the normal and error output to stdout/stderr since we
     // don't have a return object from the command interpreter.
-    lldb::SBCommandReturnObject result;
-    result.SetImmediateOutputFile(stdout);
-    result.SetImmediateErrorFile(stderr);
+    lldb::SBCommandReturnObject returnObject;
+    returnObject.SetImmediateOutputFile(stdout);
+    returnObject.SetImmediateErrorFile(stderr);
 
-    // Save the process and thread to be used by the current process/thread 
-    // helper functions.
-    LLDBServices* client = new LLDBServices(debugger, result, &process, &thread);
+    // Save the process and thread to be used by the current process/thread helper functions.
+    LLDBServices* client = new LLDBServices(debugger, returnObject, &process, &thread);
     return ((PFN_EXCEPTION_CALLBACK)baton)(client) == S_OK;
 }
 
@@ -1981,6 +1980,69 @@ LLDBServices::GetModuleVersionInformation(
     return S_OK;
 }
 
+lldb::SBBreakpoint g_runtimeLoadedBp;
+
+bool 
+RuntimeLoadedBreakpointCallback(
+    void *baton, 
+    lldb::SBProcess &process,
+    lldb::SBThread &thread, 
+    lldb::SBBreakpointLocation &location)
+{
+    lldb::SBDebugger debugger = process.GetTarget().GetDebugger();
+
+    // Send the normal and error output to stdout/stderr since we
+    // don't have a return object from the command interpreter.
+    lldb::SBCommandReturnObject returnObject;
+    returnObject.SetImmediateOutputFile(stdout);
+    returnObject.SetImmediateErrorFile(stderr);
+
+    // Save the process and thread to be used by the current process/thread helper functions.
+    LLDBServices* client = new LLDBServices(debugger, returnObject, &process, &thread);
+    bool result = ((PFN_RUNTIME_LOADED_CALLBACK)baton)(client) == S_OK;
+
+    // Clear the breakpoint
+    if (g_runtimeLoadedBp.IsValid())
+    {
+        process.GetTarget().BreakpointDelete(g_runtimeLoadedBp.GetID());
+        g_runtimeLoadedBp = lldb::SBBreakpoint();
+    }
+
+    // Continue the process
+    if (result)
+    {
+        lldb::SBError error = process.Continue();
+        result = error.Success();
+    }
+    return result;
+}
+
+HRESULT 
+LLDBServices::SetRuntimeLoadedCallback(
+    PFN_RUNTIME_LOADED_CALLBACK callback)
+{
+    if (!g_runtimeLoadedBp.IsValid())
+    {
+        lldb::SBTarget target = m_debugger.GetSelectedTarget();
+        if (!target.IsValid())
+        {
+            return E_FAIL;
+        }
+        // By the time the host calls coreclr_execute_assembly, the coreclr DAC table should be initialized so DAC can be loaded.
+        lldb::SBBreakpoint runtimeLoadedBp = target.BreakpointCreateByName("coreclr_execute_assembly", MAKEDLLNAME_A("coreclr"));
+        if (!runtimeLoadedBp.IsValid())
+        {
+            return E_FAIL;
+        }
+#ifdef FLAGS_ANONYMOUS_ENUM
+        runtimeLoadedBp.AddName("DoNotDeleteOrDisable");
+#endif
+        runtimeLoadedBp.SetCallback(RuntimeLoadedBreakpointCallback, (void *)callback);
+        g_runtimeLoadedBp = runtimeLoadedBp;
+    }
+    return S_OK;
+}
+
 //----------------------------------------------------------------------------
 // Helper functions
 //----------------------------------------------------------------------------
index ff06c9e25ab0a2737bb5062c4362660fb1468a2a..947c31bce044b5fdc76a65e03fa38a936c8a2e39 100644 (file)
@@ -308,6 +308,9 @@ public:
         ULONG bufferSize,
         PULONG versionInfoSize);
 
+    HRESULT SetRuntimeLoadedCallback(
+        PFN_RUNTIME_LOADED_CALLBACK callback);
+
     //----------------------------------------------------------------------------
     // LLDBServices (internal)
     //----------------------------------------------------------------------------