## Installing dotnet-dump
-The first step is to install the dotnet-dump CLI global tool. This requires the 2.1 .NET Core SDK to be installed. If you see the error message `Tool 'dotnet-dump' is already installed`, you will need to uninstall the global tool (see below).
+The first step is to install the dotnet-dump CLI global tool. This requires at least the 2.1 or greater .NET Core SDK to be installed. If you see the error message `Tool 'dotnet-dump' is already installed`, you will need to uninstall the global tool (see below).
$ dotnet tool install -g dotnet-dump --version 1.0.3-preview5.19251.2
You can invoke the tool using the following command: dotnet-dump
Installing SOS on Linux and MacOS
=================================
-The first step is to install the dotnet-sos CLI global tool. This requires the 2.1 .NET Core SDK to be installed. If you see the error message `Tool 'dotnet-sos' is already installed`, you will need to uninstall the global tool (see below).
+The first step is to install the dotnet-sos CLI global tool. This requires at least the 2.1 or greater .NET Core SDK to be installed. If you see the error message `Tool 'dotnet-sos' is already installed`, you will need to uninstall the global tool (see below).
$ dotnet tool install -g dotnet-sos --version 1.0.3-preview5.19251.2
You can invoke the tool using the following command: dotnet-sos
/// <summary>
/// Used to enable app-local assembly unification.
/// </summary>
- internal static class AssemblyResolver
+ public static class AssemblyResolver
{
+ private static bool s_initialized = false;
+
/// <summary>
/// Call to enable the assembly resolver for the current AppDomain.
/// </summary>
public static void Enable()
{
- AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
+ if (!s_initialized)
+ {
+ s_initialized = true;
+ AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
+ }
}
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
public IntPtr ILLDBServices { get; }
- #region SOS.NETCore function delegates
-
- private delegate bool InitializeSymbolStoreDelegate(
- bool logging,
- bool msdl,
- bool symweb,
- string symbolServerPath,
- string symbolCachePath,
- string windowsSymbolPath);
-
- private delegate void DisplaySymbolStoreDelegate();
-
- private delegate void DisableSymbolStoreDelegate();
-
- private delegate void LoadNativeSymbolsDelegate(
- SymbolReader.SymbolFileCallback callback,
- IntPtr parameter,
- string tempDirectory,
- string moduleFilePath,
- ulong address,
- int size,
- SymbolReader.ReadMemoryDelegate readMemory);
-
- 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);
-
- #endregion
-
- /// <summary>
- /// Used by ISOSHostServices.GetSOSNETCoreCallbacks.
- /// </summary>
- [StructLayout(LayoutKind.Sequential)]
- struct SOSNetCoreCallbacks
- {
- public InitializeSymbolStoreDelegate InitializeSymbolStoreDelegate;
- public DisplaySymbolStoreDelegate DisplaySymbolStoreDelegate;
- public DisableSymbolStoreDelegate DisableSymbolStoreDelegate;
- public LoadNativeSymbolsDelegate LoadNativeSymbolsDelegate;
- public LoadSymbolsForModuleDelegate LoadSymbolsForModuleDelegate;
- public DisposeDelegate DisposeDelegate;
- public ResolveSequencePointDelegate ResolveSequencePointDelegate;
- public GetLineByILOffsetDelegate GetLineByILOffsetDelegate;
- public GetLocalVariableNameDelegate GetLocalVariableNameDelegate;
- public GetMetadataLocatorDelegate GetMetadataLocatorDelegate;
- }
-
- static SOSNetCoreCallbacks s_callbacks = new SOSNetCoreCallbacks {
- InitializeSymbolStoreDelegate = SymbolReader.InitializeSymbolStore,
- DisplaySymbolStoreDelegate = SymbolReader.DisplaySymbolStore,
- DisableSymbolStoreDelegate = SymbolReader.DisableSymbolStore,
- LoadNativeSymbolsDelegate = SymbolReader.LoadNativeSymbols,
- LoadSymbolsForModuleDelegate = SymbolReader.LoadSymbolsForModule,
- DisposeDelegate = SymbolReader.Dispose,
- ResolveSequencePointDelegate = SymbolReader.ResolveSequencePoint,
- GetLineByILOffsetDelegate = SymbolReader.GetLineByILOffset,
- GetLocalVariableNameDelegate = SymbolReader.GetLocalVariableName,
- GetMetadataLocatorDelegate = MetadataHelper.GetMetadataLocator
- };
-
static readonly string s_coreclrModuleName = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "coreclr" : "libcoreclr.so";
readonly SOSHost _sosHost;
builder.AddMethod(new AddModuleSymbolDelegate(AddModuleSymbol));
builder.Complete();
- builder = AddInterface(IID_SOSHostServices, validate: false);
- builder.AddMethod(new GetSOSNETCoreCallbacksDelegate(GetSOSNETCoreCallbacks));
- builder.Complete();
-
AddRef();
}
#endregion
- #region ISOSHostServices
-
- int GetSOSNETCoreCallbacks(
- IntPtr self,
- int version,
- IntPtr pCallbacks)
- {
- if (version < 1)
- {
- return E_FAIL;
- }
- try
- {
- Marshal.StructureToPtr(s_callbacks, pCallbacks, false);
- }
- catch (ArgumentException)
- {
- return E_FAIL;
- }
- return S_OK;
- }
-
- #endregion
-
#region ILLDBServices delegates
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
[MarshalAs(UnmanagedType.LPStr)] string symbolFilename);
#endregion
-
- #region ISOSHostServices delegates
-
- [UnmanagedFunctionPointer(CallingConvention.StdCall)]
- private delegate int GetSOSNETCoreCallbacksDelegate(
- IntPtr self,
- int version,
- IntPtr pCallbacks);
-
- #endregion
}
}
\ No newline at end of file
using Microsoft.Diagnostics.Runtime;
using System;
+using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
public sealed class SOSHost
{
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
- delegate int SOSCommandDelegate(IntPtr ILLDBServices, [In, MarshalAs(UnmanagedType.LPStr)] string args);
+ private delegate int SOSCommandDelegate(
+ IntPtr ILLDBServices,
+ [In, MarshalAs(UnmanagedType.LPStr)] string args);
+
+ [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+ private delegate int SOSInitializeDelegate(
+ [In, MarshalAs(UnmanagedType.Struct)] ref SOSNetCoreCallbacks callbacks,
+ int callbacksSize,
+ [In, MarshalAs(UnmanagedType.LPStr)] string tempDirectory,
+ [In, MarshalAs(UnmanagedType.LPStr)] string dacFilePath,
+ [In, MarshalAs(UnmanagedType.LPStr)] string dbiFilePath,
+ bool symbolStoreEnabled);
+
+ private const string SOSInitialize = "SOSInitializeByHost";
+
+ #region SOS.NETCore function delegates
+
+ private delegate bool InitializeSymbolStoreDelegate(
+ bool logging,
+ bool msdl,
+ bool symweb,
+ string symbolServerPath,
+ string symbolCachePath,
+ string windowsSymbolPath);
+
+ private delegate void DisplaySymbolStoreDelegate();
+
+ private delegate void DisableSymbolStoreDelegate();
+
+ private delegate void LoadNativeSymbolsDelegate(
+ SymbolReader.SymbolFileCallback callback,
+ IntPtr parameter,
+ string tempDirectory,
+ string moduleFilePath,
+ ulong address,
+ int size,
+ SymbolReader.ReadMemoryDelegate readMemory);
+
+ 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);
+
+ #endregion
+
+ /// <summary>
+ /// Pass to SOSInitializeByHost
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential)]
+ struct SOSNetCoreCallbacks
+ {
+ public InitializeSymbolStoreDelegate InitializeSymbolStoreDelegate;
+ public DisplaySymbolStoreDelegate DisplaySymbolStoreDelegate;
+ public DisableSymbolStoreDelegate DisableSymbolStoreDelegate;
+ public LoadNativeSymbolsDelegate LoadNativeSymbolsDelegate;
+ public LoadSymbolsForModuleDelegate LoadSymbolsForModuleDelegate;
+ public DisposeDelegate DisposeDelegate;
+ public ResolveSequencePointDelegate ResolveSequencePointDelegate;
+ public GetLineByILOffsetDelegate GetLineByILOffsetDelegate;
+ public GetLocalVariableNameDelegate GetLocalVariableNameDelegate;
+ public GetMetadataLocatorDelegate GetMetadataLocatorDelegate;
+ }
+
+ static SOSNetCoreCallbacks s_callbacks = new SOSNetCoreCallbacks {
+ InitializeSymbolStoreDelegate = SymbolReader.InitializeSymbolStore,
+ DisplaySymbolStoreDelegate = SymbolReader.DisplaySymbolStore,
+ DisableSymbolStoreDelegate = SymbolReader.DisableSymbolStore,
+ LoadNativeSymbolsDelegate = SymbolReader.LoadNativeSymbols,
+ LoadSymbolsForModuleDelegate = SymbolReader.LoadSymbolsForModule,
+ DisposeDelegate = SymbolReader.Dispose,
+ ResolveSequencePointDelegate = SymbolReader.ResolveSequencePoint,
+ GetLineByILOffsetDelegate = SymbolReader.GetLineByILOffset,
+ GetLocalVariableNameDelegate = SymbolReader.GetLocalVariableName,
+ GetMetadataLocatorDelegate = MetadataHelper.GetMetadataLocator
+ };
readonly LLDBServicesWrapper _wrapper;
IntPtr _sosLibrary = IntPtr.Zero;
_wrapper = new LLDBServicesWrapper(this, dataReader, context);
}
+ /// <summary>
+ /// Loads and initializes the SOS module.
+ /// </summary>
+ /// <param name="tempDirectory">Temporary directory created to download DAC module</param>
+ /// <param name="dacFilePath">The path to DAC that CLRMD loaded or downloaded or null</param>
+ /// <param name="dbiFilePath">The path to DBI (for future use) or null</param>
+ public void InitializeSOSHost(string tempDirectory, string dacFilePath, string dbiFilePath)
+ {
+ if (_sosLibrary == IntPtr.Zero)
+ {
+ string sosPath = Path.Combine(SOSPath, RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "sos.dll" : "libsos.so");
+ try
+ {
+ _sosLibrary = DataTarget.PlatformFunctions.LoadLibrary(sosPath);
+ }
+ catch (DllNotFoundException ex)
+ {
+ // This is a workaround for the Microsoft SDK docker images. Can fail when LoadLibrary uses libdl.so to load the SOS module.
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+ {
+ throw new DllNotFoundException("Problem loading SOS module. Try installing libc6-dev (apt-get install libc6-dev) to work around this problem.", ex);
+ }
+ else
+ {
+ throw;
+ }
+ }
+ if (_sosLibrary == IntPtr.Zero)
+ {
+ throw new FileNotFoundException($"SOS module {sosPath} not found");
+ }
+ IntPtr initializeAddress = DataTarget.PlatformFunctions.GetProcAddress(_sosLibrary, SOSInitialize);
+ if (initializeAddress == IntPtr.Zero)
+ {
+ throw new EntryPointNotFoundException($"Can not find SOS module initialization function: {SOSInitialize}");
+ }
+ var initializeFunc = (SOSInitializeDelegate)Marshal.GetDelegateForFunctionPointer(initializeAddress, typeof(SOSInitializeDelegate));
+
+ // SOS depends on that the temp directory ends with "/".
+ if (!string.IsNullOrEmpty(tempDirectory) && tempDirectory[tempDirectory.Length - 1] != Path.DirectorySeparatorChar)
+ {
+ tempDirectory = tempDirectory + Path.DirectorySeparatorChar;
+ }
+
+ int result = initializeFunc(
+ ref s_callbacks,
+ Marshal.SizeOf<SOSNetCoreCallbacks>(),
+ tempDirectory,
+ dacFilePath,
+ dbiFilePath,
+ SymbolReader.IsSymbolStoreEnabled());
+
+ if (result != 0)
+ {
+ throw new InvalidOperationException($"SOS initialization FAILED 0x{result:X8}");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Execute a SOS command.
+ /// </summary>
+ /// <param name="commandLine">command name and arguments</param>
public void ExecuteCommand(string commandLine)
{
string command = "Help";
ExecuteCommand(command, arguments);
}
+ /// <summary>
+ /// Execute a SOS command.
+ /// </summary>
+ /// <param name="command">just the command name</param>
+ /// <param name="arguments">the command arguments and options</param>
public void ExecuteCommand(string command, string arguments)
{
- if (_sosLibrary == IntPtr.Zero)
- {
- string sosPath = Path.Combine(SOSPath, RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "sos.dll" : "libsos.so");
- _sosLibrary = DataTarget.PlatformFunctions.LoadLibrary(sosPath);
- if (_sosLibrary == IntPtr.Zero)
- {
- throw new FileNotFoundException($"SOS module {sosPath} not found");
- }
- }
+ Debug.Assert(_sosLibrary != null);
+
IntPtr commandAddress = DataTarget.PlatformFunctions.GetProcAddress(_sosLibrary, command);
if (commandAddress == IntPtr.Zero)
{
/// </summary>
/// <param name="callback">called back for each symbol file loaded</param>
/// <param name="parameter">callback parameter</param>
+ /// <param name="tempDirectory">temp directory unique to this instance of SOS</param>
/// <param name="moduleFilePath">module path</param>
/// <param name="address">module base address</param>
/// <param name="size">module size</param>
// Don't download the sos binaries that come with the runtime
if (moduleFileName != "SOS.NETCore.dll" && !moduleFileName.StartsWith("libsos."))
{
- using (SymbolStoreFile file = GetSymbolStoreFile(key))
+ string downloadFilePath = GetSymbolFile(key, tempDirectory);
+ if (downloadFilePath != null)
{
- if (file != null)
- {
- try
- {
- string downloadFilePath = file.FileName;
-
- // If the downloaded doesn't already exists on disk in the cache, then write it to a temporary location.
- if (!File.Exists(downloadFilePath))
- {
- downloadFilePath = Path.Combine(tempDirectory, moduleFileName);
-
- using (Stream destinationStream = File.OpenWrite(downloadFilePath)) {
- file.Stream.CopyTo(destinationStream);
- }
- s_tracer.WriteLine("Downloaded symbol file {0}", key.FullPathName);
- }
- s_tracer.Information("{0}: {1}", moduleFileName, downloadFilePath);
- callback(parameter, moduleFileName, downloadFilePath);
- }
- catch (Exception ex) when (ex is UnauthorizedAccessException || ex is DirectoryNotFoundException)
- {
- s_tracer.Error("{0}", ex.Message);
- }
- }
+ s_tracer.Information("{0}: {1}", moduleFileName, downloadFilePath);
+ callback(parameter, moduleFileName, downloadFilePath);
}
}
}
}
catch (Exception ex) when (ex is BadInputFormatException || ex is InvalidVirtualAddressException)
{
- s_tracer.Error("Exception: {0}/{1}: {2:X16}", moduleFilePath, address);
+ s_tracer.Error("{0}/{1:X16}: {2}", moduleFilePath, address, ex.Message);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Download a symbol from the symbol stores/server.
+ /// </summary>
+ /// <param name="key">index of the file to download</param>
+ /// <param name="tempDirectory">temp directory to put the file. This directory is only created if
+ /// the file is NOT already in the cache and is downloaded.</param>
+ /// <returns>Path to the downloaded file either in the cache or in the temp directory</returns>
+ public static string GetSymbolFile(SymbolStoreKey key, string tempDirectory)
+ {
+ string downloadFilePath = null;
+
+ if (IsSymbolStoreEnabled())
+ {
+ using (SymbolStoreFile file = GetSymbolStoreFile(key))
+ {
+ if (file != null)
+ {
+ try
+ {
+ downloadFilePath = file.FileName;
+
+ // If the downloaded doesn't already exists on disk in the cache, then write it to a temporary location.
+ if (!File.Exists(downloadFilePath))
+ {
+ Directory.CreateDirectory(tempDirectory);
+ downloadFilePath = Path.Combine(tempDirectory, Path.GetFileName(key.FullPathName));
+
+ using (Stream destinationStream = File.OpenWrite(downloadFilePath)) {
+ file.Stream.CopyTo(destinationStream);
+ }
+ s_tracer.WriteLine("Downloaded symbol file {0}", key.FullPathName);
+ }
+ }
+ catch (Exception ex) when (ex is UnauthorizedAccessException || ex is DirectoryNotFoundException)
+ {
+ s_tracer.Error("{0}: {1}", file.FileName, ex.Message);
+ downloadFilePath = null;
+ }
+ }
}
}
+
+ return downloadFilePath;
}
/// <summary>
/// <summary>
/// Returns true if symbol download has been enabled.
/// </summary>
- internal static bool IsSymbolStoreEnabled()
+ public static bool IsSymbolStoreEnabled()
{
return s_symbolStore != null;
}
<ClInclude Include="ntinfo.h" />
<ClInclude Include="platformspecific.h" />
<ClInclude Include="sos.h" />
- <ClInclude Include="soshostservices.h" />
<ClInclude Include="sos_md.h" />
<ClInclude Include="sos_stacktrace.h" />
<ClInclude Include="strike.h" />
<Filter>inc</Filter>
</ClInclude>
<ClInclude Include="hostcoreclr.h" />
- <ClInclude Include="soshostservices.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Native.rc" />
return g_dbiFilePath;
}
+/**********************************************************************\
+ * Called when the managed SOS Host loads/initializes SOS.
+\**********************************************************************/
+extern "C" HRESULT SOSInitializeByHost(SOSNetCoreCallbacks* callbacks, int callbacksSize, LPCSTR tempDirectory, LPCSTR dacFilePath, LPCSTR dbiFilePath, bool symbolStoreEnabled)
+{
+ if (memcpy_s(&g_SOSNetCoreCallbacks, sizeof(g_SOSNetCoreCallbacks), callbacks, callbacksSize) != 0)
+ {
+ return E_INVALIDARG;
+ }
+ if (tempDirectory != nullptr)
+ {
+ g_tmpPath = _strdup(tempDirectory);
+ }
+ if (dacFilePath != nullptr)
+ {
+ g_dacFilePath = _strdup(dacFilePath);
+ }
+ if (dbiFilePath != nullptr)
+ {
+ g_dbiFilePath = _strdup(dbiFilePath);
+ }
+ g_symbolStoreInitialized = symbolStoreEnabled;
+ g_hostingInitialized = true;
+ return S_OK;
+}
+
/**********************************************************************\
* Returns true if the host runtime has already been initialized.
\**********************************************************************/
{
return S_OK;
}
-#ifdef FEATURE_PAL
- ToRelease<ISOSHostServices> hostServices(NULL);
- if (SUCCEEDED(g_ExtServices->QueryInterface(__uuidof(ISOSHostServices), (void**)&hostServices)))
- {
- if (SUCCEEDED(hostServices->GetSOSNETCoreCallbacks(SOSNetCoreCallbacksVersion, &g_SOSNetCoreCallbacks)))
- {
- g_hostingInitialized = true;
- return S_OK;
- }
- }
-#endif // FEATURE_PAL
coreclr_initialize_ptr initializeCoreCLR = nullptr;
coreclr_create_delegate_ptr createDelegate = nullptr;
std::string hostRuntimeDirectory;
#ifndef __hostcoreclr_h__
#define __hostcoreclr_h__
-#include <soshostservices.h>
+struct SymbolModuleInfo;
+
+typedef void (*OutputDelegate)(const char*);
+typedef int (*ReadMemoryDelegate)(ULONG64, uint8_t*, int);
+typedef void (*SymbolFileCallbackDelegate)(void*, const char* moduleFileName, const char* symbolFilePath);
+
+typedef BOOL (*InitializeSymbolStoreDelegate)(BOOL, BOOL, BOOL, const char*, const char*, const char*);
+typedef void (*DisplaySymbolStoreDelegate)();
+typedef void (*DisableSymbolStoreDelegate)();
+typedef void (*LoadNativeSymbolsDelegate)(SymbolFileCallbackDelegate, void*, const char*, const char*, ULONG64, int, ReadMemoryDelegate);
+typedef PVOID (*LoadSymbolsForModuleDelegate)(const char*, BOOL, ULONG64, int, ULONG64, int, ReadMemoryDelegate);
+typedef void (*DisposeDelegate)(PVOID);
+typedef BOOL (*ResolveSequencePointDelegate)(PVOID, const char*, unsigned int, unsigned int*, unsigned int*);
+typedef BOOL (*GetLocalVariableNameDelegate)(PVOID, int, int, BSTR*);
+typedef BOOL (*GetLineByILOffsetDelegate)(PVOID, mdMethodDef, ULONG64, ULONG *, BSTR*);
+
+typedef BOOL (*GetMetadataLocatorDelegate)(
+ LPCWSTR imagePath,
+ unsigned int imageTimestamp,
+ unsigned int imageSize,
+ GUID* mvid,
+ unsigned int mdRva,
+ unsigned int flags,
+ unsigned int bufferSize,
+ PVOID pMetadata,
+ unsigned int* pMetadataSize
+);
+
+struct SOSNetCoreCallbacks
+{
+ InitializeSymbolStoreDelegate InitializeSymbolStoreDelegate;
+ DisplaySymbolStoreDelegate DisplaySymbolStoreDelegate;
+ DisableSymbolStoreDelegate DisableSymbolStoreDelegate;
+ LoadNativeSymbolsDelegate LoadNativeSymbolsDelegate;
+ LoadSymbolsForModuleDelegate LoadSymbolsForModuleDelegate;
+ DisposeDelegate DisposeDelegate;
+ ResolveSequencePointDelegate ResolveSequencePointDelegate;
+ GetLineByILOffsetDelegate GetLineByILOffsetDelegate;
+ GetLocalVariableNameDelegate GetLocalVariableNameDelegate;
+ GetMetadataLocatorDelegate GetMetadataLocatorDelegate;
+};
static const char *SOSManagedDllName = "SOS.NETCore";
static const char *SymbolReaderClassName = "SOS.SymbolReader";
getCodeTypeFlags=GetCodeTypeFlags
TraceToCode
tracetocode=TraceToCode
-#endif
\ No newline at end of file
+#endif
+
+ SOSInitializeByHost
Token2EE
u
VerifyHeap
+
+SOSInitializeByHost
\ No newline at end of file
+++ /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.
-
-//----------------------------------------------------------------------------
-//
-// LLDB debugger services for sos
-//
-//----------------------------------------------------------------------------
-
-#ifndef __SOSHOSTSERVICES_H__
-#define __SOSHOSTSERVICES_H__
-
-#include <stdarg.h>
-#include <unknwn.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct SymbolModuleInfo;
-
-typedef void (*OutputDelegate)(const char*);
-typedef int (*ReadMemoryDelegate)(ULONG64, uint8_t*, int);
-typedef void (*SymbolFileCallbackDelegate)(void*, const char* moduleFileName, const char* symbolFilePath);
-
-typedef BOOL (*InitializeSymbolStoreDelegate)(BOOL, BOOL, BOOL, const char*, const char*, const char*);
-typedef void (*DisplaySymbolStoreDelegate)();
-typedef void (*DisableSymbolStoreDelegate)();
-typedef void (*LoadNativeSymbolsDelegate)(SymbolFileCallbackDelegate, void*, const char*, const char*, ULONG64, int, ReadMemoryDelegate);
-typedef PVOID (*LoadSymbolsForModuleDelegate)(const char*, BOOL, ULONG64, int, ULONG64, int, ReadMemoryDelegate);
-typedef void (*DisposeDelegate)(PVOID);
-typedef BOOL (*ResolveSequencePointDelegate)(PVOID, const char*, unsigned int, unsigned int*, unsigned int*);
-typedef BOOL (*GetLocalVariableNameDelegate)(PVOID, int, int, BSTR*);
-typedef BOOL (*GetLineByILOffsetDelegate)(PVOID, mdMethodDef, ULONG64, ULONG *, BSTR*);
-
-typedef BOOL (*GetMetadataLocatorDelegate)(
- LPCWSTR imagePath,
- unsigned int imageTimestamp,
- unsigned int imageSize,
- GUID* mvid,
- unsigned int mdRva,
- unsigned int flags,
- unsigned int bufferSize,
- PVOID pMetadata,
- unsigned int* pMetadataSize
-);
-
-#define SOSNetCoreCallbacksVersion 2
-
-struct SOSNetCoreCallbacks
-{
- InitializeSymbolStoreDelegate InitializeSymbolStoreDelegate;
- DisplaySymbolStoreDelegate DisplaySymbolStoreDelegate;
- DisableSymbolStoreDelegate DisableSymbolStoreDelegate;
- LoadNativeSymbolsDelegate LoadNativeSymbolsDelegate;
- LoadSymbolsForModuleDelegate LoadSymbolsForModuleDelegate;
- DisposeDelegate DisposeDelegate;
- ResolveSequencePointDelegate ResolveSequencePointDelegate;
- GetLineByILOffsetDelegate GetLineByILOffsetDelegate;
- GetLocalVariableNameDelegate GetLocalVariableNameDelegate;
- GetMetadataLocatorDelegate GetMetadataLocatorDelegate;
-};
-
-MIDL_INTERFACE("D13608FB-AD14-4B49-990A-80284F934C41")
-ISOSHostServices : public IUnknown
-{
-public:
- //----------------------------------------------------------------------------
- // ISOSHostServices
- //----------------------------------------------------------------------------
-
- virtual HRESULT GetSOSNETCoreCallbacks(
- int version,
- SOSNetCoreCallbacks* callbacks) = 0;
-};
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif // #ifndef __SOSHOSTSERVICES_H__
//
// --------------------------------------------------------------------
using Microsoft.Diagnostics.Runtime;
+using Microsoft.SymbolStore;
+using Microsoft.SymbolStore.KeyGenerators;
using SOS;
using System;
+using System.Collections.Generic;
using System.CommandLine;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
using System.Threading;
namespace Microsoft.Diagnostic.Tools.Dump
{
private readonly IConsole _console;
private ClrRuntime _runtime;
- private SOSHost _sosHost;
+
+ private static SOSHost s_sosHost;
+ private static string s_tempDirectory;
+ private static string s_dacFilePath;
public AnalyzeContext(IConsole console, DataTarget target)
{
if (Target.ClrVersions.Count != 1) {
throw new InvalidOperationException("More or less than 1 CLR version is present");
}
- _runtime = Target.ClrVersions[0].CreateRuntime();
+ ClrInfo clrInfo = Target.ClrVersions[0];
+ string dacFilePath = GetDacFile(clrInfo);
+ try
+ {
+ _runtime = clrInfo.CreateRuntime(dacFilePath);
+ }
+ catch (DllNotFoundException ex)
+ {
+ // This is a workaround for the Microsoft SDK docker images. Can fail when clrmd uses libdl.so
+ // to create a symlink to and load the DAC module.
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+ {
+ throw new DllNotFoundException("Problem initializing CLRMD. Try installing libc6-dev (apt-get install libc6-dev) to work around this problem.", ex);
+ }
+ else
+ {
+ throw;
+ }
+ }
}
return _runtime;
}
}
+ private string GetDacFile(ClrInfo clrInfo)
+ {
+ if (s_dacFilePath == null)
+ {
+ string dac = clrInfo.LocalMatchingDac;
+ if (dac != null && File.Exists(dac))
+ {
+ s_dacFilePath = dac;
+ }
+ else if (SymbolReader.IsSymbolStoreEnabled())
+ {
+ string dacFileName = Path.GetFileName(clrInfo.LocalMatchingDac);
+ SymbolStoreKey key = null;
+
+ if (clrInfo.ModuleInfo.BuildId != null)
+ {
+ IEnumerable<SymbolStoreKey> keys = ELFFileKeyGenerator.GetKeys(
+ KeyTypeFlags.ClrKeys, clrInfo.ModuleInfo.FileName, clrInfo.ModuleInfo.BuildId, symbolFile: false, symbolFileName: null);
+
+ key = keys.SingleOrDefault((k) => Path.GetFileName(k.FullPathName) == dacFileName);
+ }
+ else
+ {
+ // Use the coreclr.dll's id (timestamp/filesize) to download the the dac module.
+ key = PEFileKeyGenerator.GetKey(dacFileName, clrInfo.ModuleInfo.TimeStamp, clrInfo.ModuleInfo.FileSize);
+ }
+
+ if (key != null)
+ {
+ if (s_tempDirectory == null)
+ {
+ int processId = Process.GetCurrentProcess().Id;
+ s_tempDirectory = Path.Combine(Path.GetTempPath(), "analyze" + processId.ToString());
+ }
+ // Now download the DAC module from the symbol server
+ s_dacFilePath = SymbolReader.GetSymbolFile(key, s_tempDirectory);
+ }
+ }
+
+ if (s_dacFilePath == null)
+ {
+ throw new FileNotFoundException("Could not find matching DAC for this runtime: {0}", clrInfo.ModuleInfo.FileName);
+ }
+ }
+
+ return s_dacFilePath;
+ }
+
/// <summary>
/// Returns the SOS host instance
/// </summary>
{
get
{
- if (_sosHost == null) {
- _sosHost = new SOSHost(Target.DataReader, this);
+ if (s_sosHost == null) {
+ s_sosHost = new SOSHost(Target.DataReader, this);
+ s_sosHost.InitializeSOSHost(s_tempDirectory, s_dacFilePath, dbiFilePath: null);
}
- return _sosHost;
+ return s_sosHost;
}
}
- /// <summary>
- /// Delegate to invoke to exit repl
- /// </summary>
- public Action Exit { get; }
-
/// <summary>
/// Current OS thread Id
/// </summary>
using Microsoft.Diagnostic.Repl;
using Microsoft.Diagnostics.Runtime;
+using SOS;
using System;
using System.CommandLine;
using System.IO;
private readonly ConsoleProvider _consoleProvider;
private readonly CommandProcessor _commandProcessor;
+ /// <summary>
+ /// Enable the assembly resolver to get the right SOS.NETCore version (the one
+ /// in the same directory as this assembly).
+ /// </summary>
+ static Analyzer()
+ {
+ AssemblyResolver.Enable();
+ }
+
public Analyzer()
{
_consoleProvider = new ConsoleProvider();
target = DataTarget.LoadCoreDump(dump_path.FullName);
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
- //target = DataTarget.LoadCrashDump(dump_path.FullName, CrashDumpReader.ClrMD);
- throw new PlatformNotSupportedException("Preview build: This is not yet implemented on Windows");
+ target = DataTarget.LoadCrashDump(dump_path.FullName, CrashDumpReader.ClrMD);
}
else {
throw new PlatformNotSupportedException($"Unsupported operating system: {RuntimeInformation.OSDescription}");
_commandProcessor.AddService(analyzeContext);
// Automatically enable symbol server support on Linux and MacOS
- if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
- analyzeContext.SOSHost.ExecuteCommand("SetSymbolServer", "-ms");
+ //if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ SymbolReader.InitializeSymbolStore(logging: false, msdl: true, symweb: false, symbolServerPath: null, symbolCachePath: null, windowsSymbolPath: null);
}
// Run the commands from the dotnet-dump command line
--- /dev/null
+
+using Microsoft.Diagnostic.Repl;
+using Microsoft.Diagnostics.Runtime;
+using System.CommandLine;
+using System.Threading.Tasks;
+
+namespace Microsoft.Diagnostic.Tools.Dump
+{
+ [Command(Name = "clrmodules", Help = "Lists the managed modules in the process.")]
+ public class ClrModulesCommand : CommandBase
+ {
+ public AnalyzeContext AnalyzeContext { get; set; }
+
+ public override Task InvokeAsync()
+ {
+ foreach (ClrModule module in AnalyzeContext.Runtime.Modules)
+ {
+ WriteLine("{0:X16} {1}", module.Address, module.FileName);
+ }
+ return Task.CompletedTask;
+ }
+ }
+}
<ItemGroup>
<PackageReference Include="Microsoft.Diagnostics.Runtime" Version="$(MicrosoftDiagnosticsRuntimeVersion)" />
+ <PackageReference Include="Microsoft.SymbolStore" Version="$(MicrosoftSymbolStoreVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(MSBuildThisFileDirectory)..\..\Microsoft.Diagnostic.Repl\Microsoft.Diagnostic.Repl.csproj" />
- <ProjectReference Include="$(MSBuildThisFileDirectory)..\..\SOS\SOS.Hosting\SOS.Hosting.csproj" />
<ProjectReference Include="$(MSBuildThisFileDirectory)..\..\Microsoft.Diagnostics.Tools.RuntimeClient\Microsoft.Diagnostics.Tools.RuntimeClient.csproj" />
+ <ProjectReference Include="$(MSBuildThisFileDirectory)..\..\SOS\SOS.Hosting\SOS.Hosting.csproj" />
+ <ProjectReference Include="$(MSBuildThisFileDirectory)..\..\SOS\SOS.NETCore\SOS.NETCore.csproj" />
</ItemGroup>
<ItemGroup>