Enable crash dump report generation in SOS tests (#2558)
authorMike McLaughlin <mikem@microsoft.com>
Thu, 9 Sep 2021 20:37:29 +0000 (13:37 -0700)
committerGitHub <noreply@github.com>
Thu, 9 Sep 2021 20:37:29 +0000 (13:37 -0700)
Enable crash dump report generation in SOS tests

Load crash report json file and check some common values.

Enable Windows triage and heap dump testing

Check for ctrl-c on console writelines

Fix arm32/x86 sign extensions problems in C++ data targets

Fix dotnet-dump collect dump type and the exception display in commands

Fix eeversion command when private build version like 42.42.42.42424

Add the directory of the dump to the symbol search path

Remove "ChangeEngineState" message on every stop in windbg.

Fix module relocations fixes. It was using the wrong rva. Needed the original rva not the
translated file layout one.

Better SOS module load failure message.

Remove System.Memory dependencies

20 files changed:
eng/Versions.props
src/Microsoft.Diagnostics.DebugServices.Implementation/ImageMappingMemoryService.cs
src/Microsoft.Diagnostics.DebugServices.Implementation/Module.cs
src/Microsoft.Diagnostics.DebugServices/CommandBase.cs
src/Microsoft.Diagnostics.DebugServices/Microsoft.Diagnostics.DebugServices.csproj
src/Microsoft.Diagnostics.ExtensionCommands/DumpConcurrentDictionaryCommand.cs
src/Microsoft.Diagnostics.ExtensionCommands/DumpGen.cs
src/Microsoft.Diagnostics.Repl/Command/CommandProcessor.cs
src/SOS/SOS.Hosting/SOSLibrary.cs
src/SOS/SOS.UnitTests/SOS.UnitTests.csproj
src/SOS/SOS.UnitTests/SOS.cs
src/SOS/SOS.UnitTests/SOSRunner.cs
src/SOS/Strike/dbgengservices.cpp
src/SOS/Strike/platform/cordebugdatatarget.h
src/SOS/Strike/platform/datatarget.cpp
src/SOS/Strike/util.h
src/Tools/dotnet-dump/Analyzer.cs
src/Tools/dotnet-dump/Dumper.Windows.cs
src/Tools/dotnet-dump/Dumper.cs
src/tests/dotnet-counters/DotnetCounters.UnitTests.csproj

index 399e46c7b322a09a7a08093b11b06b54dcfca94a..b3e54f963615610687e6d073a930b9e56ed8487d 100644 (file)
@@ -51,5 +51,6 @@
     <XUnitAbstractionsVersion>2.0.3</XUnitAbstractionsVersion>
     <MicrosoftDotNetRemoteExecutorVersion>7.0.0-beta.21453.2</MicrosoftDotNetRemoteExecutorVersion>
     <cdbsosversion>10.0.18362</cdbsosversion>
+    <NewtonSoftJsonVersion>12.0.2</NewtonSoftJsonVersion>
   </PropertyGroup>
 </Project>
index 8ceeb7605696ef39a6fd4d8e49edf5970c82389c..2c9015129134cf59b859710629161a15b2e1c1be 100644 (file)
@@ -151,7 +151,7 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
                                     if ((rva + size) <= block.Length)
                                     {
                                         data = block.GetReader(rva, size).ReadBytes(size);
-                                        ApplyRelocations(module, reader, rva, data);
+                                        ApplyRelocations(module, reader, (int)(address - module.ImageBase), data);
                                     }
                                     else
                                     {
@@ -182,7 +182,9 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
                                 Debug.Assert(rva >= 0);
                                 try
                                 {
+#if TRACE_VERBOSE
                                     Trace.TraceInformation($"ReadMemoryFromModule: address {address:X16} rva {rva:X16} size {bytesRequested:X8} in ELF or MachO file {module.FileName}");
+#endif
                                     byte[] data = new byte[bytesRequested];
                                     uint read = virtualAddressReader.Read(rva, data, 0, (uint)bytesRequested);
                                     if (read == 0)
index 71f1a1cee0eca2d343bd342d0d383a4dcc4caab8..2da9ac5eb83aea56cec03fe01854ed212af19ab6 100644 (file)
@@ -183,6 +183,11 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
                 if (versionString != null)
                 {
                     int spaceIndex = versionString.IndexOf(' ');
+                    if (spaceIndex < 0)
+                    {
+                        // It is probably a private build version that doesn't end with a space (no commit id after)
+                        spaceIndex = versionString.Length;
+                    }
                     if (spaceIndex > 0)
                     {
                         if (versionString[spaceIndex - 1] == '.')
index 3470680e4b5074a64c30e835627a8d49a242ee67..2898669a4a17c6a8c0fcaf1507fcd483e056b1ec 100644 (file)
@@ -38,6 +38,7 @@ namespace Microsoft.Diagnostics.DebugServices
         protected void WriteLine(string message)
         {
             Console.Write(message + Environment.NewLine);
+            Console.CancellationToken.ThrowIfCancellationRequested();
         }
 
         /// <summary>
@@ -48,6 +49,7 @@ namespace Microsoft.Diagnostics.DebugServices
         protected void WriteLine(string format, params object[] args)
         {
             Console.Write(string.Format(format, args) + Environment.NewLine);
+            Console.CancellationToken.ThrowIfCancellationRequested();
         }
 
         /// <summary>
@@ -58,6 +60,7 @@ namespace Microsoft.Diagnostics.DebugServices
         protected void WriteLineWarning(string format, params object[] args)
         {
             Console.WriteWarning(string.Format(format, args) + Environment.NewLine);
+            Console.CancellationToken.ThrowIfCancellationRequested();
         }
 
         /// <summary>
@@ -68,6 +71,7 @@ namespace Microsoft.Diagnostics.DebugServices
         protected void WriteLineError(string format, params object[] args)
         {
             Console.WriteError(string.Format(format, args) + Environment.NewLine);
+            Console.CancellationToken.ThrowIfCancellationRequested();
         }
 
         /// <summary>
index 08b9efdb04cb90b08a613b0039add0c167775815..2e64849144470ea3c3ca62d70cef415e9b915496 100644 (file)
@@ -13,7 +13,6 @@
   </PropertyGroup>
   
   <ItemGroup>
-    <PackageReference Include="System.Memory" Version="$(SystemMemoryVersion)" />
     <PackageReference Include="Microsoft.SymbolStore" Version="$(MicrosoftSymbolStoreVersion)" />
   </ItemGroup>
 </Project>
index f5b1d5e19587bc04007532067d701917a81351e7..b3c4af85ab401172e22145a40b348bce9c28cee9 100644 (file)
@@ -32,7 +32,7 @@ namespace Microsoft.Diagnostics.ExtensionCommands
 
             var heap = Runtime.Heap;
             var type = heap.GetObjectType(address);
-            if (type == null)
+            if (type?.Name is null)
             {
                 WriteLine($"{Address:x16} is not referencing an object...");
                 return;
index 9261b1c3afeaf9237ac2e80fd09d64c3d83662d8..7d341ee3a4780b9ed8bbb9190cf3e4bde69c6793 100644 (file)
@@ -49,7 +49,7 @@ namespace Microsoft.Diagnostics.ExtensionCommands
 
         private static bool IsTypeNameMatching(string typeName, string typeNameFilter)
         {
-            return typeName.IndexOf(typeNameFilter, StringComparison.OrdinalIgnoreCase) >= 0;
+            return typeName != null && typeName.IndexOf(typeNameFilter, StringComparison.OrdinalIgnoreCase) >= 0;
         }
     }
 }
index cddc21a071883d6f36a3a1c578ad9c933b8df468..cce0c9a8b869dad5efbba911753a280a696cbc40 100644 (file)
@@ -240,14 +240,20 @@ namespace Microsoft.Diagnostics.Repl
 
         private void OnException(Exception ex, InvocationContext context)
         {
+            if (ex is TargetInvocationException)
+            {
+                ex = ex.InnerException;
+            }
             if (ex is NullReferenceException || 
                 ex is ArgumentException || 
                 ex is ArgumentNullException || 
                 ex is ArgumentOutOfRangeException || 
-                ex is NotImplementedException) {
+                ex is NotImplementedException) 
+            {
                 context.Console.Error.WriteLine(ex.ToString());
             }
-            else {
+            else 
+            {
                 context.Console.Error.WriteLine(ex.Message);
             }
             Trace.TraceError(ex.ToString());
@@ -368,18 +374,11 @@ namespace Microsoft.Diagnostics.Repl
 
             private void Invoke(MethodInfo methodInfo, InvocationContext context, Parser parser, IServiceProvider services)
             {
-                try
-                {
-                    object instance = _factory(services);
-                    SetProperties(context, parser, services, instance);
+                object instance = _factory(services);
+                SetProperties(context, parser, services, instance);
 
-                    object[] arguments = BuildArguments(methodInfo, services);
-                    methodInfo.Invoke(instance, arguments);
-                }
-                catch (TargetInvocationException ex)
-                {
-                    throw ex.InnerException;
-                }
+                object[] arguments = BuildArguments(methodInfo, services);
+                methodInfo.Invoke(instance, arguments);
             }
 
             private void SetProperties(InvocationContext context, Parser parser, IServiceProvider services, object instance)
index 6d0ce843fa114596855bda60e1037a980baa4a36..10d45761bb3531be0777ab006e541b82d244c501 100644 (file)
@@ -107,11 +107,11 @@ namespace SOS.Hosting
                     // 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);
+                        throw new DllNotFoundException($"Problem loading SOS module from {sosPath}. Try installing libc6-dev (apt-get install libc6-dev) to work around this problem.", ex);
                     }
                     else
                     {
-                        throw;
+                        throw new DllNotFoundException($"Problem loading SOS module from {sosPath}", ex);
                     }
                 }
                 if (_sosLibrary == IntPtr.Zero)
index 80842426fe9dd9a1458616a444e6f9d237a8ddd6..b5c2c4b3115db00b821b245ac43676dea05724a0 100644 (file)
@@ -32,6 +32,7 @@
   </ItemGroup>
 
   <ItemGroup>
+    <PackageReference Include="NewtonSoft.Json" Version="$(NewtonSoftJsonVersion)" />
     <PackageReference Include="Microsoft.Win32.Primitives" Version="$(MicrosoftWin32PrimitivesVersion)" />
     <PackageReference Include="cdb-sos" Version="$(cdbsosversion)" Condition="'$(OS)' == 'Windows_NT'" />
   </ItemGroup>
index 1f3ad1689db9d475fb66d2ec1357083fa3a98e95..b9bb0c8ff503c625f6428b888ef1cca07cd89e84 100644 (file)
@@ -3,6 +3,7 @@
 // See the LICENSE file in the project root for more information.
 
 using Microsoft.Diagnostics.TestHelpers;
+using Newtonsoft.Json;
 using System;
 using System.Collections.Generic;
 using System.IO;
@@ -41,7 +42,6 @@ public class SOS
     {
         information.OutputHelper = Output;
 
-        // TODO: enable either when bpmd is fixed on Alpine or the bpmd tests are ifdef'ed out of the scripts for Alpine
         if (testLive)
         {
             // Live
@@ -53,13 +53,15 @@ public class SOS
 
         if (testDump)
         {
+            string dumpName = null;
+
             // Create and test dumps on OSX or Alpine only if the runtime is 6.0 or greater
             if (!(OS.Kind == OSKind.OSX || SOSRunner.IsAlpine()) || information.TestConfiguration.RuntimeFrameworkVersionMajor > 5)
             {
                 // Generate a crash dump.
                 if (information.TestConfiguration.DebuggeeDumpOutputRootDir() != null)
                 {
-                    await SOSRunner.CreateDump(information);
+                    dumpName = await SOSRunner.CreateDump(information);
                 }
 
                 // Test against a crash dump.
@@ -85,8 +87,64 @@ public class SOS
                         }
                     }
                 }
+
+                // Test the crash report json file
+                if (dumpName != null && information.TestCrashReport)
+                {
+                    TestCrashReport(dumpName, information);
+                }
+            }
+        }
+    }
+
+    private void TestCrashReport(string dumpName, SOSRunner.TestInformation information)
+    {
+        string crashReportPath = dumpName + ".crashreport.json";
+        TestRunner.OutputHelper outputHelper = TestRunner.ConfigureLogging(information.TestConfiguration, information.OutputHelper, information.TestName + ".CrashReportTest");
+        try
+        {
+            outputHelper.WriteLine("CrashReportTest for {0}", crashReportPath);
+            outputHelper.WriteLine("{");
+
+            AssertX.FileExists("CrashReport", crashReportPath, outputHelper.IndentedOutput);
+
+            dynamic crashReport = JsonConvert.DeserializeObject(File.ReadAllText(crashReportPath));
+            Assert.NotNull(crashReport);
+
+            dynamic payload = crashReport.payload;
+            Assert.NotNull(payload);
+            Version protocol_version = Version.Parse((string)payload.protocol_version);
+            Assert.True(protocol_version >= new Version("1.0.0"));
+            outputHelper.IndentedOutput.WriteLine($"protocol_version {protocol_version}");
+
+            string process_name = (string)payload.process_name;
+            Assert.NotNull(process_name);
+            outputHelper.IndentedOutput.WriteLine($"process_name {process_name}");
+
+            Assert.NotNull(payload.threads);
+            IEnumerable<dynamic> threads = payload.threads;
+            Assert.True(threads.Any());
+            outputHelper.IndentedOutput.WriteLine($"threads # {threads.Count()}");
+
+            if (OS.Kind == OSKind.OSX)
+            {
+                dynamic parameters = crashReport.parameters;
+                Assert.NotNull(parameters);
+                Assert.NotNull(parameters.ExceptionType);
+                Assert.NotNull(parameters.OSVersion);
+                Assert.Equal(parameters.SystemManufacturer, "apple");
             }
         }
+        catch (Exception ex)
+        {
+            // Log the exception
+            outputHelper.IndentedOutput.WriteLine(ex.ToString());
+        }
+        finally
+        {
+            outputHelper.WriteLine("}");
+            outputHelper.Dispose();
+        }
     }
 
     private async Task RunTest(TestConfiguration config, string debuggeeName, string scriptName, string testName = null, bool testLive = true, bool testDump = true, bool testTriage = false)
@@ -127,7 +185,7 @@ public class SOS
     [SkippableTheory, MemberData(nameof(Configurations))]
     public async Task GCPOHTests(TestConfiguration config)
     {
-        if (!config.IsNETCore || config.RuntimeFrameworkVersionMajor < 5)
+        if (config.IsDesktop || config.RuntimeFrameworkVersionMajor < 5)
         {
             throw new SkipTestException("This test validates POH behavior, which was introduced in .net 5");
         }
@@ -142,7 +200,7 @@ public class SOS
             TestConfiguration = config,
             DebuggeeName = "Overflow",
             // Generating the logging for overflow test causes so much output from createdump that it hangs/timesout the test run
-            DumpDiagnostics = false,
+            DumpDiagnostics = config.IsNETCore && config.RuntimeFrameworkVersionMajor >= 6,
             DumpGenerator = config.StackOverflowCreatesDump ? SOSRunner.DumpGenerator.CreateDump : SOSRunner.DumpGenerator.NativeDebugger
         });
     }
index c8566c98ee87d838e4e1807b41993ef7fe23dfea..056c12bcd27ab37d6f8413ae09c275d32b514cfe 100644 (file)
@@ -67,6 +67,8 @@ public class SOSRunner : IDisposable
     public class TestInformation
     {
         private string _testName;
+        private bool _testCrashReport = true;
+        private DumpGenerator _dumpGenerator = DumpGenerator.CreateDump; 
 
         public TestConfiguration TestConfiguration { get; set; }
 
@@ -82,7 +84,21 @@ public class SOSRunner : IDisposable
 
         public string DebuggeeArguments { get; set; }
 
-        public DumpGenerator DumpGenerator { get; set; } = DumpGenerator.CreateDump;
+        public DumpGenerator DumpGenerator
+        {
+            get {
+                DumpGenerator dumpGeneration = _dumpGenerator;
+                if (dumpGeneration == DumpGenerator.CreateDump)
+                {
+                    if (!TestConfiguration.CreateDumpExists || TestConfiguration.GenerateDumpWithLLDB() || TestConfiguration.GenerateDumpWithGDB())
+                    {
+                        dumpGeneration = DumpGenerator.NativeDebugger;
+                    }
+                }
+                return dumpGeneration;
+            }
+            set { _dumpGenerator = value; }
+        }
 
         public DumpType DumpType { get; set; } = DumpType.Heap;
 
@@ -92,6 +108,12 @@ public class SOSRunner : IDisposable
 
         public string DumpNameSuffix { get; set; }
 
+        public bool TestCrashReport
+        {
+            get { return _testCrashReport && DumpGenerator == DumpGenerator.CreateDump && OS.Kind != OSKind.Windows && TestConfiguration.RuntimeFrameworkVersionMajor >= 6; }
+            set { _testCrashReport = value; }
+        }
+
         public bool IsValid()
         {
             return TestConfiguration != null && OutputHelper != null && DebuggeeName != null;
@@ -134,24 +156,18 @@ public class SOSRunner : IDisposable
     /// Run a debuggee and create a dump.
     /// </summary>
     /// <param name="information">test info</param>
-    public static async Task CreateDump(TestInformation information)
+    /// <returns>full dump name</returns>
+    public static async Task<string> CreateDump(TestInformation information)
     {
         if (!information.IsValid()) {
             throw new ArgumentException("Invalid TestInformation");
         }
         TestConfiguration config = information.TestConfiguration;
         DumpGenerator dumpGeneration = information.DumpGenerator;
+        string dumpName = null;
 
         Directory.CreateDirectory(config.DebuggeeDumpOutputRootDir());
 
-        if (dumpGeneration == DumpGenerator.CreateDump)
-        {
-            if (!config.CreateDumpExists || config.GenerateDumpWithLLDB() || config.GenerateDumpWithGDB())
-            {
-                dumpGeneration = DumpGenerator.NativeDebugger;
-            }
-        }
-
         if (dumpGeneration == DumpGenerator.NativeDebugger)
         {
             // Force the dump type to full for .NET Core 1.1 because the heap dumps are broken (can't read ThreadStore).
@@ -160,6 +176,7 @@ public class SOSRunner : IDisposable
                 information.DumpType = DumpType.Full;
             }
             using SOSRunner runner = await SOSRunner.StartDebugger(information, DebuggerAction.GenerateDump);
+            dumpName = runner.ReplaceVariables("%DUMP_NAME%");
             try
             {
                 await runner.LoadSosExtension();
@@ -215,6 +232,7 @@ public class SOSRunner : IDisposable
                 // source directory name has been lowercased by the build system.
                 DebuggeeConfiguration debuggeeConfig = await DebuggeeCompiler.Execute(config, information.DebuggeeName, outputHelper);
                 Dictionary<string, string> variables = GenerateVariables(information, debuggeeConfig, DebuggerAction.GenerateDump);
+                dumpName = ReplaceVariables(variables, "%DUMP_NAME%");
 
                 outputHelper.WriteLine("Starting {0}", information.TestName);
                 outputHelper.WriteLine("{");
@@ -264,14 +282,19 @@ public class SOSRunner : IDisposable
                     // Run the debuggee with the createdump environment variables set to generate a coredump on unhandled exception
                     processRunner.
                         WithEnvironmentVariable("COMPlus_DbgEnableMiniDump", "1").
-                        WithEnvironmentVariable("COMPlus_DbgMiniDumpName", ReplaceVariables(variables, "%DUMP_NAME%"));
+                        WithEnvironmentVariable("COMPlus_DbgMiniDumpName", dumpName);
 
                     if (information.DumpDiagnostics)
                     {
                         processRunner.WithEnvironmentVariable("COMPlus_CreateDumpDiagnostics", "1");
                     }
-
-                    // TODO: temporary hack to disable using createdump for triage type until the failures can be fixed
+                    if (information.TestCrashReport)
+                    {
+                        processRunner.WithEnvironmentVariable("COMPlus_EnableCrashReport", "1");
+                    }
+                    // Windows createdump's triage MiniDumpWriteDump flags for .NET 5.0 are broken
+                    // Disable testing triage dumps on 6.0 until the DAC signing issue is resolved - issue https://github.com/dotnet/diagnostics/issues/2542
+                    // if (OS.Kind == OSKind.Windows && dumpType == DumpType.Triage && config.IsNETCore && config.RuntimeFrameworkVersionMajor < 6)
                     DumpType dumpType = information.DumpType;
                     if (OS.Kind == OSKind.Windows && dumpType == DumpType.Triage)
                     {
@@ -315,9 +338,14 @@ public class SOSRunner : IDisposable
                         }
 
                         // Start dotnet-dump collect
+                        DumpType dumpType = information.DumpType;
+                        if (config.IsDesktop || config.RuntimeFrameworkVersionMajor <  6)
+                        {
+                            dumpType = DumpType.Full;
+                        }
                         var dotnetDumpArguments = new StringBuilder();
                         dotnetDumpArguments.Append(config.DotNetDumpPath());
-                        dotnetDumpArguments.AppendFormat(" collect --process-id {0} --output %DUMP_NAME%", processRunner.ProcessId);
+                        dotnetDumpArguments.AppendFormat($" collect --process-id {processRunner.ProcessId} --output {dumpName} --type {dumpType}");
                         if (information.DumpDiagnostics)
                         {
                             dotnetDumpArguments.Append(" --diag");
@@ -362,6 +390,7 @@ public class SOSRunner : IDisposable
                 pipeServer?.Dispose();
             }
         }
+        return dumpName;
     }
 
     /// <summary>
@@ -809,6 +838,15 @@ public class SOSRunner : IDisposable
                 {
                     commands.Add($"!SetHostRuntime {setHostRuntime}");
                 }
+                // Add the path to runtime so SOS can find DAC/DBI for triage dumps
+                if (_dumpType.HasValue && _dumpType == DumpType.Triage)
+                {
+                    string runtimeSymbolsPath = _config.RuntimeSymbolsPath;
+                    if (runtimeSymbolsPath != null)
+                    {
+                        commands.Add("!SetClrPath " + runtimeSymbolsPath);
+                    }
+                }
                 break;
             case NativeDebugger.Lldb:
                 commands.Add($"plugin load {sosPath}");
index 3b1c47b1057e7d7ef016db6b39f21b4b9b00267d..adbd7e5d5833533e60125b533ba7aad16a8fc51c 100644 (file)
@@ -502,8 +502,6 @@ HRESULT DbgEngServices::ChangeEngineState(
     {
         if (((Argument & DEBUG_STATUS_MASK) == DEBUG_STATUS_BREAK) && ((Argument & DEBUG_STATUS_INSIDE_WAIT) == 0))
         {
-            m_control->Output(DEBUG_OUTPUT_NORMAL, "ChangeEngineState\n");
-
             // Flush the target when the debugger target breaks
             Extensions::GetInstance()->FlushTarget();
         }
index 27a7b0eb9b8377c34425b4d3cc7de0be10dd9762..94ee03a6cc44c96f559149e9f0a2bc005279ae85 100644 (file)
@@ -114,6 +114,7 @@ public:
         {
             return E_UNEXPECTED;
         }
+        address = CONVERT_FROM_SIGN_EXTENDED(address);
 #ifdef FEATURE_PAL
         if (g_sos != nullptr)
         {
index 7e21a89d01f4cb4016a43489eed95f36694bc18e..9c9dc2e48e1adc79fd9f41bf9286720c2872683a 100644 (file)
@@ -148,6 +148,7 @@ DataTarget::ReadVirtual(
     {
         return E_UNEXPECTED;
     }
+    address = CONVERT_FROM_SIGN_EXTENDED(address);
 #ifdef FEATURE_PAL
     if (g_sos != nullptr)
     {
index 51c3da0c648792077a53378a5f9fe0281ed32c09..6f68cafb275d73a4ccc48e21769f9b9f8ea53a0f 100644 (file)
@@ -7,6 +7,8 @@
 
 #define LIMITED_METHOD_CONTRACT
 
+#define CONVERT_FROM_SIGN_EXTENDED(offset) ((ULONG_PTR)(offset))
+
 // So we can use the PAL_TRY_NAKED family of macros without dependencies on utilcode.
 inline void RestoreSOToleranceState() {}
 
index d6b7be75f645ca009e0097f63f5dcc82884a0743..8ec88179ad7a0561d8544c0b8104be964aa303e5 100644 (file)
@@ -98,9 +98,10 @@ namespace Microsoft.Diagnostics.Tools.Dump
 
                 _target.ServiceProvider.AddServiceFactory<SOSHost>(() => new SOSHost(_contextService.Services));
 
-                // Automatically enable symbol server support
+                // Automatically enable symbol server support, default cache and search for symbols in the dump directory
                 _symbolService.AddSymbolServer(msdl: true, symweb: false, symbolServerPath: null, authToken: null, timeoutInMinutes: 0);
                 _symbolService.AddCachePath(_symbolService.DefaultSymbolCache);
+                _symbolService.AddDirectoryPath(Path.GetDirectoryName(dump_path.FullName));
 
                 // Run the commands from the dotnet-dump command line
                 if (command != null)
index dda341879ee40ef99c7d2c841ca9197b66b8fab1..3f8b5d19a60949c8df0327470d997f0c5674cc38 100644 (file)
@@ -42,7 +42,20 @@ namespace Microsoft.Diagnostics.Tools.Dump
                                        NativeMethods.MINIDUMP_TYPE.MiniDumpWithTokenInformation;
                             break;
                         case DumpTypeOption.Mini:
-                            dumpType = NativeMethods.MINIDUMP_TYPE.MiniDumpWithThreadInfo;
+                            dumpType = NativeMethods.MINIDUMP_TYPE.MiniDumpNormal |
+                                       NativeMethods.MINIDUMP_TYPE.MiniDumpWithDataSegs |
+                                       NativeMethods.MINIDUMP_TYPE.MiniDumpWithHandleData |
+                                       NativeMethods.MINIDUMP_TYPE.MiniDumpWithThreadInfo;
+                            break;
+                        case DumpTypeOption.Triage:
+                            dumpType = NativeMethods.MINIDUMP_TYPE.MiniDumpFilterTriage |
+                                       NativeMethods.MINIDUMP_TYPE.MiniDumpIgnoreInaccessibleMemory |
+                                       NativeMethods.MINIDUMP_TYPE.MiniDumpWithoutOptionalData |
+                                       NativeMethods.MINIDUMP_TYPE.MiniDumpWithProcessThreadData |
+                                       NativeMethods.MINIDUMP_TYPE.MiniDumpFilterModulePaths |
+                                       NativeMethods.MINIDUMP_TYPE.MiniDumpWithUnloadedModules |
+                                       NativeMethods.MINIDUMP_TYPE.MiniDumpFilterMemory |
+                                       NativeMethods.MINIDUMP_TYPE.MiniDumpWithHandleData;
                             break;
                     }
 
index efe81a8368dc2e75b0d8c558a4945d15022a12c6..8d9140a96d87af18a1da4f49756eead1645980ee 100644 (file)
@@ -26,6 +26,8 @@ namespace Microsoft.Diagnostics.Tools.Dump
                         // stacks, exception information, handle information, and all memory except for mapped images.
 
             Mini,       // A small dump containing module lists, thread lists, exception information and all stacks.
+
+            Triage      // A small dump containing module lists, thread lists, exception information, all stacks and PMI removed.
         }
 
         public Dumper()
@@ -105,6 +107,9 @@ namespace Microsoft.Diagnostics.Tools.Dump
                         case DumpTypeOption.Mini:
                             dumpType = DumpType.Normal;
                             break;
+                        case DumpTypeOption.Triage:
+                            dumpType = DumpType.Triage;
+                            break;
                     }
 
                     // Send the command to the runtime to initiate the core dump
index 822d483b362444d88c32119d86041044cc6721a1..3e891e2a458be5ec1fa0b08cecd4bdef57131352 100644 (file)
@@ -9,7 +9,7 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="NewtonSoft.Json" Version="12.0.2" />
+    <PackageReference Include="NewtonSoft.Json" Version="$(NewtonSoftJsonVersion)" />
   </ItemGroup>
 
 </Project>