Skip to content

Commit

Permalink
Add mini dump support on Windows to RemoteExecutor
Browse files Browse the repository at this point in the history
  • Loading branch information
stephentoub committed Oct 9, 2019
1 parent 3256926 commit f9c85ca
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 0 deletions.
80 changes: 80 additions & 0 deletions src/Microsoft.DotNet.RemoteExecutor/src/MiniDump.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// 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.

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;

namespace Microsoft.DotNet.RemoteExecutor
{
internal static class MiniDump
{
public static void Create(Process process, string destinationPath)
{
if (process is null)
{
throw new ArgumentNullException(nameof(process));
}
if (destinationPath is null)
{
throw new ArgumentNullException(nameof(destinationPath));
}

int result, lastError;
using (FileStream fs = File.Create(destinationPath))
{
const MINIDUMP_TYPE MiniDumpType =
MINIDUMP_TYPE.MiniDumpWithFullMemory |
MINIDUMP_TYPE.MiniDumpIgnoreInaccessibleMemory;

result = MiniDumpWriteDump(process.SafeHandle, process.Id, fs.SafeFileHandle, MiniDumpType, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
lastError = Marshal.GetLastWin32Error();
}

if (result == 0)
{
throw new Win32Exception(lastError);
}
}

[DllImport("DbgHelp.dll", SetLastError = true)]
private static extern int MiniDumpWriteDump(
SafeHandle hProcess,
int ProcessId,
SafeHandle hFile,
MINIDUMP_TYPE DumpType,
IntPtr ExceptionParam,
IntPtr UserStreamParam,
IntPtr CallbackParam);

private enum MINIDUMP_TYPE : int
{
MiniDumpNormal = 0x00000000,
MiniDumpWithDataSegs = 0x00000001,
MiniDumpWithFullMemory = 0x00000002,
MiniDumpWithHandleData = 0x00000004,
MiniDumpFilterMemory = 0x00000008,
MiniDumpScanMemory = 0x00000010,
MiniDumpWithUnloadedModules = 0x00000020,
MiniDumpWithIndirectlyReferencedMemory = 0x00000040,
MiniDumpFilterModulePaths = 0x00000080,
MiniDumpWithProcessThreadData = 0x00000100,
MiniDumpWithPrivateReadWriteMemory = 0x00000200,
MiniDumpWithoutOptionalData = 0x00000400,
MiniDumpWithFullMemoryInfo = 0x00000800,
MiniDumpWithThreadInfo = 0x00001000,
MiniDumpWithCodeSegs = 0x00002000,
MiniDumpWithoutAuxiliaryState = 0x00004000,
MiniDumpWithFullAuxiliaryState = 0x00008000,
MiniDumpWithPrivateWriteCopyMemory = 0x00010000,
MiniDumpIgnoreInaccessibleMemory = 0x00020000,
MiniDumpWithTokenInformation = 0x00040000,
MiniDumpWithModuleHeaders = 0x00080000,
MiniDumpFilterTriage = 0x00100000,
MiniDumpValidTypeFlags = 0x001fffff
}
}
}
21 changes: 21 additions & 0 deletions src/Microsoft.DotNet.RemoteExecutor/src/RemoteInvokeHandle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,27 @@ private void Dispose(bool disposing)
{
var description = new StringBuilder();
description.AppendLine($"Timed out at {DateTime.Now} after {Options.TimeOut}ms waiting for remote process.");

// Create a dump if possible
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
string uploadPath = Environment.GetEnvironmentVariable("HELIX_WORKITEM_UPLOAD_ROOT");
if (!string.IsNullOrWhiteSpace(uploadPath))
{
try
{
string miniDmpPath = Path.Combine(uploadPath, $"{Process.Id}.{Path.GetRandomFileName()}.dmp");
MiniDump.Create(Process, miniDmpPath);
description.AppendLine($"Wrote mini dump to: {miniDmpPath}");
}
catch (Exception exc)
{
description.AppendLine($"Failed to create mini dump: {exc.Message}");
}
}
}

// Gather additional details about the process if possible
try
{
description.AppendLine($"\tProcess ID: {Process.Id}");
Expand Down

0 comments on commit f9c85ca

Please sign in to comment.