-
Notifications
You must be signed in to change notification settings - Fork 401
Expand file tree
/
Copy pathProgram.cs
More file actions
122 lines (104 loc) · 5.25 KB
/
Copy pathProgram.cs
File metadata and controls
122 lines (104 loc) · 5.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.CommandLine;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Internal.Common;
using Microsoft.Internal.Common.Commands;
namespace Microsoft.Diagnostics.Tools.Dump
{
internal static class Program
{
public static int Main(string[] args)
{
RootCommand rootCommand = new()
{
CollectCommand(),
AnalyzeCommand(),
ProcessStatusCommandHandler.ProcessStatusCommand("Lists the dotnet processes that dumps can be collected from.")
};
return rootCommand.Parse(args).Invoke();
}
private static Command CollectCommand()
{
Command command = new(name: "collect", description: "Capture dumps from a process")
{
ProcessIdOption, OutputOption, DiagnosticLoggingOption, CrashReportOption, TypeOption, ProcessNameOption, DiagnosticPortOption
};
command.SetAction((parseResult) => new Dumper().Collect(
stdOutput: parseResult.Configuration.Output,
stdError: parseResult.Configuration.Error,
processId: parseResult.GetValue(ProcessIdOption),
output: parseResult.GetValue(OutputOption),
diag: parseResult.GetValue(DiagnosticLoggingOption),
crashreport: parseResult.GetValue(CrashReportOption),
type: parseResult.GetValue(TypeOption),
name: parseResult.GetValue(ProcessNameOption),
diagnosticPort: parseResult.GetValue(DiagnosticPortOption)));
return command;
}
private static readonly Option<int> ProcessIdOption =
new("--process-id", "-p")
{
Description = "The process id to collect a memory dump."
};
private static readonly Option<string> ProcessNameOption =
new("--name", "-n")
{
Description = "The name of the process to collect a memory dump."
};
private static readonly Option<string> OutputOption =
new("--output", "-o")
{
Description = @"The path where collected dumps should be written. Defaults to '.\dump_YYYYMMDD_HHMMSS.dmp' on Windows and './core_YYYYMMDD_HHMMSS'
on Linux where YYYYMMDD is Year/Month/Day and HHMMSS is Hour/Minute/Second. Otherwise, it is the full path and file name of the dump."
};
private static readonly Option<bool> DiagnosticLoggingOption =
new("--diag")
{
Description = "Enable dump collection diagnostic logging."
};
private static readonly Option<bool> CrashReportOption =
new("--crashreport")
{
Description = "Enable crash report generation."
};
private static readonly Option<Dumper.DumpTypeOption> TypeOption =
new("--type")
{
Description = @"The dump type determines the kinds of information that are collected from the process. There are several types: Full - The largest dump containing all memory including the module images. Heap - A large and relatively comprehensive dump containing module lists, thread lists, all 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 PII removed.",
DefaultValueFactory = _ => Dumper.DumpTypeOption.Full
};
private static readonly Option<string> DiagnosticPortOption =
new("--diagnostic-port", "--dport")
{
Description = "The path to a diagnostic port to be used. Must be a runtime connect port."
};
private static Command AnalyzeCommand()
{
Command command = new(
name: "analyze",
description: "Starts an interactive shell with debugging commands to explore a dump")
{
DumpPath,
RunCommand
};
command.SetAction((parseResult) => new Analyzer().Analyze(
parseResult.GetValue(DumpPath),
parseResult.GetValue(RunCommand) ?? Array.Empty<string>()));
return command;
}
private static readonly Argument<FileInfo> DumpPath =
new Argument<FileInfo>(name: "dump_path")
{
Description = "Name of the dump file to analyze."
}.AcceptExistingOnly();
private static readonly Option<string[]> RunCommand =
new("--command", "-c")
{
Description = "Runs the command on start. Multiple instances of this parameter can be used in an invocation to chain commands. Commands will get run in the order that they are provided on the command line. If you want dotnet dump to exit after the commands, your last command should be 'exit'.",
Arity = ArgumentArity.ZeroOrMore
};
}
}