HistRoot SetSymbolServer (setsymbolserver)
HistObj FAQ
HistObjFind SOSFlush
- HistClear Help (soshelp)
+ HistClear SOSStatus (sosstatus)
+ FAQ
+ Help (soshelp)
## Commands
|**RCWCleanupList** \<*RCWCleanupList address*>|Displays the list of runtime callable wrappers at the specified address that are awaiting cleanup.|
|**SaveModule** \<*Base address*> \<*Filename*>|Writes an image, which is loaded in memory at the specified address, to the specified file.|
|**SOSFlush**|Flushes an internal SOS cache.|
+|**SOSStatus** [**-netfx**] [**-netcore**] [**-reset**]|Display internal SOS status, reset the internal cached state, or change between the desktop .NET framework or .NET Core runtimes when both are loaded in the process or dump.<br/><br/>-netfx - switch to the desktop .NET Framework runtime if loaded.<br/>-netcore - switch to the .NET Core runtime if loaded.<br/>-reset - reset all the cached internal SOS state.<br/><br/>|
+|**SetHostRuntime** [**-netcore**] [**-netfx**] [\<runtime-directory\>]|This command controls the runtime that is used to host the maanged code that runs as part of SOS in the debugger (cdb/windbg). The default is the desktop .NET Framework. The "-netcore" option allows the installed .NET Core runtime be used. The "-netfx" option allows switches back to the .NET Framework runtime.<br/><br/>Normally, SOS attempts to find an installed .NET Core runtime to run its managed code automatically but this command is available if it fails. The default is to use the same runtime (libcoreclr) being debugged. Use this command if the default runtime being debugged isn't working enough to run the SOS code or if the version is less than 2.1.0.<br/><br/>If you received the following error message when running a SOS command, use this command to set the path to 2.1.0 or greater .NET Core runtime. <br/><br/>`(lldb) clrstack`<br/>`Error: Fail to initialize CoreCLR 80004005 ClrStack failed`<br/><br/>`(lldb) sethostruntime /usr/share/dotnet/shared/Microsoft.NETCore.App/2.1.6`<br/><br/>You can use the "dotnet --info" in a command shell to find the path of an installed .NET Core runtime.|
|**StopOnException** [**-derived**] [**-create** | **-create2**] \<*Exception*> \<*Pseudo-register number*>|Causes the debugger to stop when the specified exception is thrown, but to continue running when other exceptions are thrown.<br /><br /> The **-derived** option catches the specified exception and every exception that derives from the specified exception.|
|**SyncBlk** [**-all** | \<*syncblk number*>]|Displays the specified `SyncBlock` structure or all `SyncBlock` structures. If you do not pass any arguments, the **SyncBlk** command displays the `SyncBlock` structure corresponding to objects that are owned by a thread.<br /><br /> A `SyncBlock` structure is a container for extra information that does not need to be created for every object. It can hold COM interop data, hash codes, and locking information for thread-safe operations.|
|**ThreadPool**|Displays information about the managed thread pool, including the number of work requests in the queue, the number of completion port threads, and the number of timers.|
----------------------------- -----------------------------
HistInit (histinit) SetHostRuntime (sethostruntime)
HistRoot (histroot) SetSymbolServer (setsymbolserver, loadsymbols)
- HistObj (histobj) FAQ
- HistObjFind (histobjfind) SOSFlush
- HistClear (histclear) Help (soshelp)
+ HistObj (histobj) SetClrPath (setclrpath)
+ HistObjFind (histobjfind) SOSFlush (sosflush)
+ HistClear (histclear) SOSStatus (sosstatus)
+ FAQ
+ Help (soshelp)
## Commands
|**PrintException** [**-nested**] [**-lines**] [\<*Exception object address*>]<br /><br /> -or-<br /><br /> **PE** [**-nested**] [\<*Exception object address*>]|Displays and formats fields of any object derived from the <xref:System.Exception> class at the specified address. If you do not specify an address, the **PrintException** command displays the last exception thrown on the current thread.<br /><br /> The **-nested** option displays details about nested exception objects.<br /><br /> The **-lines** option displays source information, if available.<br /><br /> You can use this command to format and view the `_stackTrace` field, which is a binary array.|
|**SyncBlk** [**-all** | \<*syncblk number*>]|Displays the specified `SyncBlock` structure or all `SyncBlock` structures. If you do not pass any arguments, the **SyncBlk** command displays the `SyncBlock` structure corresponding to objects that are owned by a thread.<br /><br /> A `SyncBlock` structure is a container for extra information that does not need to be created for every object. It can hold COM interop data, hash codes, and locking information for thread-safe operations.|
|**SOSFlush**|Flushes an internal SOS cache.|
+|**SOSStatus** [**-reset**]|Displays internal SOS status or reset the internal cached state.|
+|**SetHostRuntime** [\<runtime-directory\>]|This command sets the path to the .NET Core runtime to use to host the managed code that runs as part of SOS in the debugger (lldb). The runtime needs to be at least version 2.1.0 or greater. If there are spaces in directory, it needs to be single-quoted (').<br/><br/>Normally, SOS attempts to find an installed .NET Core runtime to run its managed code automatically but this command is available if it fails. The default is to use the same runtime (libcoreclr) being debugged. Use this command if the default runtime being debugged isn't working enough to run the SOS code or if the version is less than 2.1.0.<br/><br/>If you received the following error message when running a SOS command, use this command to set the path to 2.1.0 or greater .NET Core runtime. <br/><br/>`(lldb) clrstack`<br/>`Error: Fail to initialize CoreCLR 80004005 ClrStack failed`<br/><br/>`(lldb) sethostruntime /usr/share/dotnet/shared/Microsoft.NETCore.App/2.1.6`<br/><br/>You can use the "dotnet --info" in a command shell to find the path of an installed .NET Core runtime.|
|**SetSymbolServer** [**-ms**] [**-disable**] [**-log**] [**-loadsymbols**] [**-cache** \<cache-path>] [**-directory** \<search-directory>] [**-sympath** \<windows-symbol-path>] [\<symbol-server-URL>]|Enables the symbol server downloading support.<br/><br/>The **-ms** option enables downloading from the public Microsoft symbol server.<br/><br/>The **-disable** option turns on the symbol download support.<br/><br/>The **-cache** \<cache-path> option specifies a symbol cache directory. The default is $HOME/.dotnet/symbolcache if not specified.<br/><br/>The **-directory** option add a path to search for symbols. Can be more than one.<br/><br/>The **-sympath** option adds server, cache and directory paths in the Windows symbol path format.<br/><br/>The **-log** option enables symbol download logging.<br/><br/>The **-loadsymbols** option attempts to download the native .NET Core symbols for the runtime.|
|**Token2EE** \<*module name*> \<*token*>|Turns the specified metadata token in the specified module into a `MethodTable` structure or `MethodDesc` structure.<br /><br /> You can pass `*` for the module name parameter to find what that token maps to in every loaded managed module. You can also pass the debugger's name for a module, such as `mscorlib` or `image00400000`.|
|**Threads** (**clrthreads**) [**-live**] [**-special**]|Displays all managed threads in the process.<br /><br /> The **Threads** command displays the debugger shorthand ID, the CLR thread ID, and the operating system thread ID. Additionally, the **Threads** command displays a Domain column that indicates the application domain in which a thread is executing, an APT column that displays the COM apartment mode, and an Exception column that displays the last exception thrown in the thread.<br /><br /> The **-live** option displays threads associated with a live thread.<br /><br /> The **-special** option displays all special threads created by the CLR. Special threads include garbage collection threads (in concurrent and server garbage collection), debugger helper threads, finalizer threads, <xref:System.AppDomain> unload threads, and thread pool timer threads.|
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
private delegate int SOSInitializeDelegate(
- [In, MarshalAs(UnmanagedType.Struct)] ref SOSNetCoreCallbacks callbacks,
+ [In, MarshalAs(UnmanagedType.Struct)] ref SymbolReader.SOSNetCoreCallbacks callbacks,
int callbacksSize,
[In, MarshalAs(UnmanagedType.LPStr)] string tempDirectory,
[In, MarshalAs(UnmanagedType.LPStr)] string runtimeModulePath,
[In, MarshalAs(UnmanagedType.LPStr)] string dbiFilePath,
bool symbolStoreEnabled);
- [UnmanagedFunctionPointer(CallingConvention.Winapi)]
- private delegate UIntPtr GetExpressionDelegate(
- [In, MarshalAs(UnmanagedType.LPStr)] string expression);
-
private const string SOSInitialize = "SOSInitializeByHost";
- #region SOS.NETCore function delegates
-
- private delegate bool InitializeSymbolStoreDelegate(
- bool logging,
- bool msdl,
- bool symweb,
- string tempDirectory,
- string symbolServerPath,
- string authToken,
- int timeoutInMintues,
- string symbolCachePath,
- string symbolDirectoryPath,
- string windowsSymbolPath);
-
- private delegate void DisplaySymbolStoreDelegate(
- SymbolReader.WriteLine writeLine);
-
- private delegate void DisableSymbolStoreDelegate();
-
- private delegate void LoadNativeSymbolsDelegate(
- SymbolReader.SymbolFileCallback callback,
- IntPtr parameter,
- SymbolReader.RuntimeConfiguration config,
- string moduleFilePath,
- ulong address,
- int size,
- SymbolReader.ReadMemoryDelegate readMemory);
-
- private delegate void LoadNativeSymbolsFromIndexDelegate(
- SymbolReader.SymbolFileCallback callback,
- IntPtr parameter,
- SymbolReader.RuntimeConfiguration config,
- string moduleFilePath,
- bool specialKeys,
- int moduleIndexSize,
- IntPtr moduleIndex);
-
- private delegate IntPtr LoadSymbolsForModuleDelegate(
- string assemblyPath,
- bool isFileLayout,
- ulong loadedPeAddress,
- int loadedPeSize,
- ulong inMemoryPdbAddress,
- int inMemoryPdbSize,
- SymbolReader.ReadMemoryDelegate readMemory);
-
- private delegate void DisposeDelegate(IntPtr symbolReaderHandle);
-
- private delegate bool ResolveSequencePointDelegate(
- IntPtr symbolReaderHandle,
- string filePath,
- int lineNumber,
- out int methodToken,
- out int ilOffset);
-
- private delegate bool GetLineByILOffsetDelegate(
- IntPtr symbolReaderHandle,
- int methodToken,
- long ilOffset,
- out int lineNumber,
- out IntPtr fileName);
-
- private delegate bool GetLocalVariableNameDelegate(
- IntPtr symbolReaderHandle,
- int methodToken,
- int localIndex,
- out IntPtr localVarName);
-
- private delegate int GetMetadataLocatorDelegate(
- [MarshalAs(UnmanagedType.LPWStr)] string imagePath,
- uint imageTimestamp,
- uint imageSize,
- [MarshalAs(UnmanagedType.LPArray, SizeConst = 16)] byte[] mvid,
- uint mdRva,
- uint flags,
- uint bufferSize,
- IntPtr buffer,
- IntPtr dataSize);
-
- private delegate int GetICorDebugMetadataLocatorDelegate(
- [MarshalAs(UnmanagedType.LPWStr)] string imagePath,
- uint imageTimestamp,
- uint imageSize,
- uint pathBufferSize,
- IntPtr pPathBufferSize,
- IntPtr pPathBuffer);
-
- #endregion
-
- /// <summary>
- /// Pass to SOSInitializeByHost
- /// </summary>
- [StructLayout(LayoutKind.Sequential)]
- struct SOSNetCoreCallbacks
- {
- public InitializeSymbolStoreDelegate InitializeSymbolStoreDelegate;
- public DisplaySymbolStoreDelegate DisplaySymbolStoreDelegate;
- public DisableSymbolStoreDelegate DisableSymbolStoreDelegate;
- public LoadNativeSymbolsDelegate LoadNativeSymbolsDelegate;
- public LoadNativeSymbolsFromIndexDelegate LoadNativeSymbolsFromIndexDelegate;
- public LoadSymbolsForModuleDelegate LoadSymbolsForModuleDelegate;
- public DisposeDelegate DisposeDelegate;
- public ResolveSequencePointDelegate ResolveSequencePointDelegate;
- public GetLineByILOffsetDelegate GetLineByILOffsetDelegate;
- public GetLocalVariableNameDelegate GetLocalVariableNameDelegate;
- public GetMetadataLocatorDelegate GetMetadataLocatorDelegate;
- public GetExpressionDelegate GetExpressionDelegate;
- public GetICorDebugMetadataLocatorDelegate GetICorDebugMetadataLocatorDelegate;
- }
-
- static SOSNetCoreCallbacks s_callbacks = new SOSNetCoreCallbacks {
- InitializeSymbolStoreDelegate = SymbolReader.InitializeSymbolStore,
- DisplaySymbolStoreDelegate = SymbolReader.DisplaySymbolStore,
- DisableSymbolStoreDelegate = SymbolReader.DisableSymbolStore,
- LoadNativeSymbolsDelegate = SymbolReader.LoadNativeSymbols,
- LoadNativeSymbolsFromIndexDelegate = SymbolReader.LoadNativeSymbolsFromIndex,
- LoadSymbolsForModuleDelegate = SymbolReader.LoadSymbolsForModule,
- DisposeDelegate = SymbolReader.Dispose,
- ResolveSequencePointDelegate = SymbolReader.ResolveSequencePoint,
- GetLineByILOffsetDelegate = SymbolReader.GetLineByILOffset,
- GetLocalVariableNameDelegate = SymbolReader.GetLocalVariableName,
- GetMetadataLocatorDelegate = MetadataHelper.GetMetadataLocator,
- GetExpressionDelegate = SOSHost.GetExpression,
- GetICorDebugMetadataLocatorDelegate = MetadataHelper.GetICorDebugMetadataLocator
- };
-
const string DesktopRuntimeModuleName = "clr";
internal readonly IDataReader DataReader;
}
int result = initializeFunc(
- ref s_callbacks,
- Marshal.SizeOf<SOSNetCoreCallbacks>(),
+ ref SymbolReader.SymbolCallbacks,
+ Marshal.SizeOf<SymbolReader.SOSNetCoreCallbacks>(),
tempDirectory,
AnalyzeContext.RuntimeModuleDirectory,
isDesktop,
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection.Metadata;
const string MsdlSymbolServer = "http://msdl.microsoft.com/download/symbols/";
const string SymwebSymbolServer = "http://symweb.corp.microsoft.com/";
+ [DllImport("sos.dll")]
+ private static extern int InitializeBySymbolReader([In, MarshalAs(UnmanagedType.Struct)] ref SOSNetCoreCallbacks callbacks, int callbacksSize);
+
/// <summary>
/// Read memory callback
/// </summary>
/// <param name="symbolFileName">symbol file name and path</param>
public delegate void SymbolFileCallback(IntPtr parameter, [MarshalAs(UnmanagedType.LPStr)] string moduleFileName, [MarshalAs(UnmanagedType.LPStr)] string symbolFileName);
+ #region SOS.NETCore function delegates
+
+ public delegate bool InitializeSymbolStoreDelegate(
+ bool logging,
+ bool msdl,
+ bool symweb,
+ string tempDirectory,
+ string symbolServerPath,
+ string authToken,
+ int timeoutInMintues,
+ string symbolCachePath,
+ string symbolDirectoryPath,
+ string windowsSymbolPath);
+
+ public delegate void DisplaySymbolStoreDelegate(
+ SymbolReader.WriteLine writeLine);
+
+ public delegate void DisableSymbolStoreDelegate();
+
+ public delegate void LoadNativeSymbolsDelegate(
+ SymbolReader.SymbolFileCallback callback,
+ IntPtr parameter,
+ SymbolReader.RuntimeConfiguration config,
+ string moduleFilePath,
+ ulong address,
+ int size,
+ SymbolReader.ReadMemoryDelegate readMemory);
+
+ public delegate void LoadNativeSymbolsFromIndexDelegate(
+ SymbolReader.SymbolFileCallback callback,
+ IntPtr parameter,
+ SymbolReader.RuntimeConfiguration config,
+ string moduleFilePath,
+ bool specialKeys,
+ int moduleIndexSize,
+ IntPtr moduleIndex);
+
+ public delegate IntPtr LoadSymbolsForModuleDelegate(
+ string assemblyPath,
+ bool isFileLayout,
+ ulong loadedPeAddress,
+ int loadedPeSize,
+ ulong inMemoryPdbAddress,
+ int inMemoryPdbSize,
+ SymbolReader.ReadMemoryDelegate readMemory);
+
+ public delegate void DisposeDelegate(
+ IntPtr symbolReaderHandle);
+
+ public delegate bool ResolveSequencePointDelegate(
+ IntPtr symbolReaderHandle,
+ string filePath,
+ int lineNumber,
+ out int methodToken,
+ out int ilOffset);
+
+ public delegate bool GetLineByILOffsetDelegate(
+ IntPtr symbolReaderHandle,
+ int methodToken,
+ long ilOffset,
+ out int lineNumber,
+ out IntPtr fileName);
+
+ public delegate bool GetLocalVariableNameDelegate(
+ IntPtr symbolReaderHandle,
+ int methodToken,
+ int localIndex,
+ out IntPtr localVarName);
+
+ [UnmanagedFunctionPointer(CallingConvention.Winapi)]
+ public delegate UIntPtr GetExpressionDelegate(
+ [In, MarshalAs(UnmanagedType.LPStr)] string expression);
+
+ public delegate int GetMetadataLocatorDelegate(
+ [MarshalAs(UnmanagedType.LPWStr)] string imagePath,
+ uint imageTimestamp,
+ uint imageSize,
+ [MarshalAs(UnmanagedType.LPArray, SizeConst = 16)] byte[] mvid,
+ uint mdRva,
+ uint flags,
+ uint bufferSize,
+ IntPtr buffer,
+ IntPtr dataSize);
+
+ public delegate int GetICorDebugMetadataLocatorDelegate(
+ [MarshalAs(UnmanagedType.LPWStr)] string imagePath,
+ uint imageTimestamp,
+ uint imageSize,
+ uint pathBufferSize,
+ IntPtr pPathBufferSize,
+ IntPtr pPathBuffer);
+
+ #endregion
+
+ /// <summary>
+ /// Symbol service callback table
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential)]
+ public struct SOSNetCoreCallbacks
+ {
+ public InitializeSymbolStoreDelegate InitializeSymbolStoreDelegate;
+ public DisplaySymbolStoreDelegate DisplaySymbolStoreDelegate;
+ public DisableSymbolStoreDelegate DisableSymbolStoreDelegate;
+ public LoadNativeSymbolsDelegate LoadNativeSymbolsDelegate;
+ public LoadNativeSymbolsFromIndexDelegate LoadNativeSymbolsFromIndexDelegate;
+ public LoadSymbolsForModuleDelegate LoadSymbolsForModuleDelegate;
+ public DisposeDelegate DisposeDelegate;
+ public ResolveSequencePointDelegate ResolveSequencePointDelegate;
+ public GetLineByILOffsetDelegate GetLineByILOffsetDelegate;
+ public GetLocalVariableNameDelegate GetLocalVariableNameDelegate;
+ public GetMetadataLocatorDelegate GetMetadataLocatorDelegate;
+ public GetExpressionDelegate GetExpressionDelegate;
+ public GetICorDebugMetadataLocatorDelegate GetICorDebugMetadataLocatorDelegate;
+ }
+
+ public static SOSNetCoreCallbacks SymbolCallbacks = new SOSNetCoreCallbacks {
+ InitializeSymbolStoreDelegate = SymbolReader.InitializeSymbolStore,
+ DisplaySymbolStoreDelegate = SymbolReader.DisplaySymbolStore,
+ DisableSymbolStoreDelegate = SymbolReader.DisableSymbolStore,
+ LoadNativeSymbolsDelegate = SymbolReader.LoadNativeSymbols,
+ LoadNativeSymbolsFromIndexDelegate = SymbolReader.LoadNativeSymbolsFromIndex,
+ LoadSymbolsForModuleDelegate = SymbolReader.LoadSymbolsForModule,
+ DisposeDelegate = SymbolReader.Dispose,
+ ResolveSequencePointDelegate = SymbolReader.ResolveSequencePoint,
+ GetLineByILOffsetDelegate = SymbolReader.GetLineByILOffset,
+ GetLocalVariableNameDelegate = SymbolReader.GetLocalVariableName,
+ GetMetadataLocatorDelegate = MetadataHelper.GetMetadataLocator,
+ GetExpressionDelegate = SymbolReader.GetExpression,
+ GetICorDebugMetadataLocatorDelegate = MetadataHelper.GetICorDebugMetadataLocator
+ };
+
/// <summary>
/// Temporary directory for dac/symbols
/// </summary>
static readonly ITracer s_tracer = new Tracer();
static SymbolStore s_symbolStore = null;
+ /// <summary>
+ /// Entry point from the desktop hosting code.
+ /// </summary>
+ /// <param name="argument">SOS module path</param>
+ /// <returns>0 success, !0 failure</returns>
+ public static int InitializeSymbolReader(string argument)
+ {
+ return InitializeBySymbolReader(ref SymbolCallbacks, Marshal.SizeOf<SymbolReader.SOSNetCoreCallbacks>());
+ }
+
/// <summary>
/// Initializes symbol loading. Adds the symbol server and/or the cache path (if not null) to the list of
/// symbol servers. This API can be called more than once to add more servers to search.
}
}
+ /// <summary>
+ /// Get expression helper for native SOS.
+ /// </summary>
+ /// <param name="expression">hex number</param>
+ /// <returns>value</returns>
+ public static UIntPtr GetExpression(
+ string expression)
+ {
+ if (expression != null)
+ {
+ if (ulong.TryParse(expression.Replace("0x", ""), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out ulong result))
+ {
+ return new UIntPtr(result);
+ }
+ }
+ return UIntPtr.Zero;
+ }
+
/// <summary>
/// Returns method token and IL offset for given source line number.
/// </summary>
<BuildProjectFramework>netcoreapp2.1</BuildProjectFramework>
<RuntimeFrameworkVersion>$(RuntimeVersion21)</RuntimeFrameworkVersion>
<FrameworkVersion>$(AspNetCoreVersion21)</FrameworkVersion>
+ <!-- Do at least one test hosted on .NET Core. -->
+ <SOSHostRuntime>$(DotNetRoot)\shared\Microsoft.NETCore.App\$(RuntimeVersion21)</SOSHostRuntime>
</Option>
<!--
SOS.WebApp3 and SOS.DualRuntimes (runs on 3.1 and latest aspnetcore)
<FrameworkVersion Condition="'$(FrameworkVersion)' == ''">$(RuntimeFrameworkVersion)</FrameworkVersion>
<RuntimeSymbolsPath>$(DotNetRoot)\shared\Microsoft.NETCore.App\$(RuntimeFrameworkVersion)</RuntimeSymbolsPath>
- <SOSHostRuntime>$(DotNetRoot)\shared\Microsoft.NETCore.App\$(RuntimeFrameworkVersion)</SOSHostRuntime>
<HostExe>$(DotNetRoot)\dotnet.exe</HostExe>
<HostArgs>--fx-version $(FrameworkVersion)</HostArgs>
</Option>
<BuildProjectRuntime>win-$(TargetArchitecture)</BuildProjectRuntime>
<DebugType>full</DebugType>
<RuntimeSymbolsPath>$(DesktopFrameworkPath)</RuntimeSymbolsPath>
- <SOSHostRuntime>$(DotNetRoot)\shared\Microsoft.NETCore.App\$(RuntimeVersion21)</SOSHostRuntime>
</Option>
</Options>
SOSCOMMAND:setclrpath %DESKTOP_RUNTIME_PATH%
ENDIF:TRIAGE_DUMP
-SOSCOMMAND:SOSStatus -desktop
+SOSCOMMAND:SOSStatus -netfx
VERIFY:\s*Switched to desktop CLR runtime successfully\s+
# Currently not on a desktop CLR thread so using the -all option to dump it.
VERIFY:\s+MT\s+Count\s+TotalSize\s+Class Name\s+
VERIFY:\s*<HEXVAL>\s+<DECVAL>\s+<DECVAL>\s+.*
VERIFY:\s*Total\s+<DECVAL>\s+objects\s+
-!VERIFY:.*UNKNOWN.*
\ No newline at end of file
+!VERIFY:.*UNKNOWN.*
gchist.cpp
gcroot.cpp
hostcoreclr.cpp
+ hostdesktop.cpp
metadata.cpp
runtime.cpp
sigparser.cpp
advapi32.lib
psapi.lib
ntdll.lib
+ mscoree.lib
)
else(WIN32)
add_definitions(-DFEATURE_ENABLE_HARDWARE_EXCEPTIONS)
<ClCompile Include="exts.cpp" />
<ClCompile Include="gchist.cpp" />
<ClCompile Include="gcroot.cpp" />
+ <ClCompile Include="hostdesktop.cpp" />
<ClCompile Include="metadata.cpp" />
<ClCompile Include="runtime.cpp" />
<ClCompile Include="sildasm.cpp" />
<ClCompile Include="disasmARM64.cpp" />
<ClCompile Include="hostcoreclr.cpp" />
<ClCompile Include="runtime.cpp" />
+ <ClCompile Include="hostdesktop.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="data.h" />
#define IfFailRet(EXPR) do { Status = (EXPR); if(FAILED(Status)) { return (Status); } } while (0)
#endif
+#ifdef FEATURE_PAL
+#define TPALIST_SEPARATOR_STR_A ":"
+#else
+#define TPALIST_SEPARATOR_STR_A ";"
+#endif
+
+#ifndef FEATURE_PAL
+extern HRESULT InitializeDesktopClrHost();
+extern void UninitializeDesktopClrHost();
+#endif
+
bool g_dotnetDumpHost = false;
static bool g_hostingInitialized = false;
bool g_symbolStoreInitialized = false;
LPCSTR g_hostRuntimeDirectory = nullptr;
LPCSTR g_tmpPath = nullptr;
SOSNetCoreCallbacks g_SOSNetCoreCallbacks;
+
#ifndef FEATURE_PAL
+bool g_useDesktopClrHost = true;
HMODULE g_hmoduleSymBinder = nullptr;
ISymUnmanagedBinder3 *g_pSymBinder = nullptr;
#endif
-
-#ifdef FEATURE_PAL
-#define TPALIST_SEPARATOR_STR_A ":"
-#else
-#define TPALIST_SEPARATOR_STR_A ";"
-#endif
-
//
// Build the TPA list of assemblies for the runtime hosting api.
//
}
}
+#ifndef FEATURE_PAL
+
+/**********************************************************************\
+ * Called when the desktop clr is initialized on Windows
+\**********************************************************************/
+extern "C" HRESULT InitializeBySymbolReader(
+ SOSNetCoreCallbacks * callbacks,
+ int callbacksSize)
+{
+ if (memcpy_s(&g_SOSNetCoreCallbacks, sizeof(g_SOSNetCoreCallbacks), callbacks, callbacksSize) != 0)
+ {
+ return E_INVALIDARG;
+ }
+ return S_OK;
+}
+
+#endif
+
/**********************************************************************\
* Called when the managed SOS Host loads/initializes SOS.
\**********************************************************************/
{
return S_OK;
}
+ HRESULT Status;
+#ifndef FEATURE_PAL
+ if (g_useDesktopClrHost)
+ {
+ Status = InitializeDesktopClrHost();
+ if (SUCCEEDED(Status))
+ {
+ OnUnloadTask::Register(UninitializeDesktopClrHost);
+ g_hostingInitialized = true;
+ return Status;
+ }
+ }
+#endif
coreclr_initialize_ptr initializeCoreCLR = nullptr;
coreclr_create_delegate_ptr createDelegate = nullptr;
std::string hostRuntimeDirectory;
std::string sosModuleDirectory;
std::string coreClrPath;
- HRESULT Status = GetHostRuntime(coreClrPath, hostRuntimeDirectory);
+ Status = GetHostRuntime(coreClrPath, hostRuntimeDirectory);
if (FAILED(Status))
{
ExtDbgOut("Error: Failed to get host runtime directory\n");
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+// Windows Header Files
+#include <windows.h>
+#include <stdio.h>
+#include <metahost.h>
+#include <objbase.h>
+#include <mscoree.h>
+#include <tchar.h>
+#include <strsafe.h>
+#include <string>
+#include <holder.h>
+#include <arrayholder.h>
+
+#define CLR_VERSION L"v4.0.30319"
+#define ASSEMBLY_NAME L"SOS.NETCore.dll"
+#define CLASS_NAME L"SOS.SymbolReader"
+#define FUNCTION_NAME L"InitializeSymbolReader"
+
+extern HMODULE g_hInstance;
+extern void ExtErr(PCSTR Format, ...);
+
+void UninitializeDesktopClrHost();
+
+ICLRRuntimeHost* g_clrHost = nullptr;
+
+/// <summary>
+/// Loads and initializes the desktop CLR to host the SOS.NetCore.dll code.
+/// </summary>
+HRESULT InitializeDesktopClrHost()
+{
+ HRESULT hr = S_OK;
+ DWORD ret = 0;
+
+ if (g_clrHost != nullptr)
+ {
+ return S_OK;
+ }
+ ArrayHolder<WCHAR> wszSOSModulePath = new WCHAR[MAX_LONGPATH + 1];
+ if (GetModuleFileNameW(g_hInstance, wszSOSModulePath, MAX_LONGPATH) == 0)
+ {
+ ExtErr("Error: Failed to get SOS module directory\n");
+ return HRESULT_FROM_WIN32(GetLastError());
+ }
+ ArrayHolder<WCHAR> wszManagedModulePath = new WCHAR[MAX_LONGPATH + 1];
+ if (wcscpy_s(wszManagedModulePath.GetPtr(), MAX_LONGPATH, wszSOSModulePath.GetPtr()) != 0)
+ {
+ ExtErr("Error: Failed to copy module name\n");
+ return E_FAIL;
+ }
+ WCHAR* lastSlash = wcsrchr(wszManagedModulePath.GetPtr(), DIRECTORY_SEPARATOR_CHAR_W);
+ if (lastSlash != nullptr)
+ {
+ *++lastSlash = L'\0';
+ }
+ if (wcscat_s(wszManagedModulePath.GetPtr(), MAX_LONGPATH, ASSEMBLY_NAME) != 0)
+ {
+ ExtErr("Error: Failed to append SOS module name\n");
+ return E_FAIL;
+ }
+ hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+ if (FAILED(hr) && hr != RPC_E_CHANGED_MODE)
+ {
+ ExtErr("Error: CoInitializeEx failed. %08x\n", hr);
+ return hr;
+ }
+ // Loads the CLR and then initializes the managed debugger extensions.
+ ReleaseHolder<ICLRMetaHost> metaHost;
+ hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (PVOID*)&metaHost);
+ if (FAILED(hr) || metaHost == nullptr)
+ {
+ ExtErr("Error: CLRCreateInstance failed %08x\n", hr);
+ return hr;
+ }
+ ReleaseHolder<ICLRRuntimeInfo> runtimeInfo;
+ hr = metaHost->GetRuntime(CLR_VERSION, IID_ICLRRuntimeInfo, (PVOID*)&runtimeInfo);
+ if (FAILED(hr) || runtimeInfo == nullptr)
+ {
+ ExtErr("Error: ICLRMetaHost::GetRuntime failed %08x\n", hr);
+ return hr;
+ }
+ hr = runtimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (PVOID*)&g_clrHost);
+ if (FAILED(hr) || g_clrHost == nullptr)
+ {
+ ExtErr("Error: ICLRRuntimeInfo::GetInterface failed %08x\n", hr);
+ return hr;
+ }
+ hr = g_clrHost->Start();
+ if (FAILED(hr))
+ {
+ ExtErr("Error: ICLRRuntimeHost::Start failed %08x\n", hr);
+ UninitializeDesktopClrHost();
+ return hr;
+ }
+ // Initialize the managed code
+ hr = g_clrHost->ExecuteInDefaultAppDomain(wszManagedModulePath.GetPtr(), CLASS_NAME, FUNCTION_NAME, wszSOSModulePath.GetPtr(), (DWORD *)&ret);
+ if (FAILED(hr))
+ {
+ ExtErr("Error: ICLRRuntimeHost::ExecuteInDefaultAppDomain failed %08x\n", hr);
+ UninitializeDesktopClrHost();
+ return hr;
+ }
+ if (ret != 0)
+ {
+ ExtErr("Error: InitializeSymbolReader failed %08x\n", ret);
+ UninitializeDesktopClrHost();
+ return ret;
+ }
+ return S_OK;
+}
+
+/// <summary>
+/// Uninitializes and unloads the desktop CLR
+/// </summary>
+void UninitializeDesktopClrHost()
+{
+ if (g_clrHost != nullptr)
+ {
+ g_clrHost->Stop();
+ g_clrHost->Release();
+ g_clrHost = nullptr;
+ }
+}
#endif
SOSInitializeByHost
+ InitializeBySymbolReader
\\
COMMAND: sethostruntime.
-!SetHostRuntime <runtime-directory>
+!SetHostRuntime [-netcore] [-netfx] <runtime-directory>
-This command sets the path to the .NET Core runtime to use to host the managed
-code that runs as part of SOS in the debugger (cdb/windbg). The runtime needs
-to be at least version 2.0.0 or greater. If there are spaces in directory, it
-needs to be single-quoted (').
+-netcore - switch to hosting on the .NET Core runtime
+-netfx - switch to hosting on the desktop .NET Framework runtime if loaded.
+
+This command controls the runtime that is used to host the maanged code that
+runs as part of SOS in the debugger (cdb/windbg). The default is the desktop
+.NET Framework. The "-netcore" option allows the installed .NET Core runtime
+be used. The "-netfx" option allows switches back to the .NET Framework runtime.
+
+If a <runtime-directory> is given, the command assumes it is a path to a .NET
+Core runtime which needs to be at least version 2.1.0 or greater. If there are
+spaces in directory, it needs to be single-quoted (').
Normally, SOS attempts to find an installed .NET Core runtime to run its
managed code automatically but this command is available if it fails. The
default is to use the same runtime (coreclr.dll) being debugged. Use this
command if the default runtime being debugged isn't working enough to run
-the SOS code or if the version is less than 2.0.0.
+the SOS code or if the version is less than 2.1.0.
If you received the following error message when running a SOS command, use
this command to set the path to 2.0.0 or greater .NET Core runtime.
\\
COMMAND: sosstatus.
-!SOSStatus [-desktop] [-netcore] [-reset]
+!SOSStatus [-netfx] [-netcore] [-reset]
--desktop - switch to the desktop runtime if loaded.
+-netfx - switch to the desktop .NET Framework runtime if loaded.
-netcore - switch to the .NET Core runtime if loaded.
--reset - reset all the cached internal SOS state.
+-reset - reset all the cached internal SOS state.
-Display internal SOS status, reset the internal cached state, or change between desktop or
-netcore runtimes when both are loaded in the process or dump.
+Display internal SOS status, reset the internal cached state, or change between the desktop .NET framework
+or .NET Core runtimes when both are loaded in the process or dump.
0:000> !sosstatus
Target platform: 8664 Context size 04d0
This command sets the path to the .NET Core runtime to use to host the managed
code that runs as part of SOS in the debugger (lldb). The runtime needs
-to be at least version 2.0.0 or greater. If there are spaces in directory, it
+to be at least version 2.1.0 or greater. If there are spaces in directory, it
needs to be single-quoted (').
Normally, SOS attempts to find an installed .NET Core runtime to run its
managed code automatically but this command is available if it fails. The
default is to use the same runtime (libcoreclr) being debugged. Use this
command if the default runtime being debugged isn't working enough to run
-the SOS code or if the version is less than 2.0.0.
+the SOS code or if the version is less than 2.1.0.
If you received the following error message when running a SOS command, use
-this command to set the path to 2.0.0 or greater .NET Core runtime.
+this command to set the path to 2.1.0 or greater .NET Core runtime.
(lldb) clrstack
Error: Fail to initialize CoreCLR 80004005
WCHAR g_mdName[mdNameLen];
#ifndef FEATURE_PAL
+extern bool g_useDesktopClrHost;
HMODULE g_hInstance = NULL;
#endif // !FEATURE_PAL
CMDOption option[] =
{ // name, vptr, type, hasValue
#ifndef FEATURE_PAL
- {"-desktop", &bDesktop, COBOOL, FALSE},
+ {"-netfx", &bDesktop, COBOOL, FALSE},
{"-netcore", &bNetCore, COBOOL, FALSE},
#endif
{"-reset", &bReset, COBOOL, FALSE},
}
else
{
- ExtErr("The '-desktop' and '-netcore' options are only supported on Windows targets\n");
+ ExtErr("The '-netfx' and '-netcore' options are only supported on Windows targets\n");
return E_FAIL;
}
}
if (g_tmpPath != nullptr) {
ExtOut("Temp path: %s\n", g_tmpPath);
}
+#ifndef FEATURE_PAL
+ if (g_useDesktopClrHost) {
+ ExtOut("Using the desktop .NET Framework to host the managed SOS code\n");
+ }
+ else
+#endif
if (g_hostRuntimeDirectory != nullptr) {
ExtOut("Host runtime path: %s\n", g_hostRuntimeDirectory);
}
{
INIT_API_EXT();
+ BOOL bDesktop = FALSE;
+ BOOL bNetCore = FALSE;
+ CMDOption option[] =
+ { // name, vptr, type, hasValue
+#ifndef FEATURE_PAL
+ {"-netfx", &bDesktop, COBOOL, FALSE},
+ {"-netcore", &bNetCore, COBOOL, FALSE},
+#endif
+ };
StringHolder hostRuntimeDirectory;
CMDValue arg[] =
{
{&hostRuntimeDirectory.data, COSTRING},
};
size_t narg;
- if (!GetCMDOption(args, nullptr, 0, arg, _countof(arg), &narg))
+ if (!GetCMDOption(args, option, _countof(option), arg, _countof(arg), &narg))
{
return E_FAIL;
}
+#ifndef FEATURE_PAL
+ if (narg > 0 || bNetCore || bDesktop)
+#else
if (narg > 0)
+#endif
{
if (IsHostingInitialized())
{
- ExtErr("Runtime hosting already initialized %s\n", g_hostRuntimeDirectory);
+ ExtErr("Runtime hosting already initialized %s\n", g_hostRuntimeDirectory != nullptr ? g_hostRuntimeDirectory : "");
return E_FAIL;
}
+ }
+#ifndef FEATURE_PAL
+ if (bNetCore)
+ {
+ g_useDesktopClrHost = false;
+ }
+ else if (bDesktop)
+ {
+ g_useDesktopClrHost = true;
+ }
+#endif
+ if (narg > 0)
+ {
if (g_hostRuntimeDirectory != nullptr)
{
free((void*)g_hostRuntimeDirectory);
}
g_hostRuntimeDirectory = _strdup(hostRuntimeDirectory.data);
+#ifndef FEATURE_PAL
+ g_useDesktopClrHost = false;
+#endif
}
- if (g_hostRuntimeDirectory != nullptr)
+#ifndef FEATURE_PAL
+ if (g_useDesktopClrHost)
{
- ExtOut("Host runtime path: %s\n", g_hostRuntimeDirectory);
+ ExtOut("Using the desktop .NET Framework to host the managed SOS code\n");
+ }
+ else
+#endif
+ {
+ ExtOut("Using the .NET Core runtime to host the managed SOS code\n");
+ if (g_hostRuntimeDirectory != nullptr)
+ {
+ ExtOut("Host runtime path: %s\n", g_hostRuntimeDirectory);
+ }
}
return S_OK;
}