Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement SOS Hosting for Windows (dotnet-dump) #352

Merged
merged 4 commits into from Jun 22, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 0 additions & 12 deletions eng/Tools.props

This file was deleted.

2 changes: 1 addition & 1 deletion eng/Versions.props
Expand Up @@ -21,7 +21,7 @@
<MicrosoftWin32PrimitivesVersion>4.3.0</MicrosoftWin32PrimitivesVersion>

<!-- Other libs -->
<MicrosoftSymbolStoreVersion>1.0.0-dev-64016-01</MicrosoftSymbolStoreVersion>
<MicrosoftSymbolStoreVersion>1.0.0-dev-64131-02</MicrosoftSymbolStoreVersion>
<MicrosoftDiagnosticsRuntimeVersion>1.0.5</MicrosoftDiagnosticsRuntimeVersion>

<MicrosoftDiagnosticsTracingTraceEventVersion>2.0.41</MicrosoftDiagnosticsTracingTraceEventVersion>
Expand Down
131 changes: 77 additions & 54 deletions src/Microsoft.Diagnostic.Repl/Command/CommandProcessor.cs
Expand Up @@ -5,6 +5,7 @@
// --------------------------------------------------------------------

using System;
using System.Collections;
using System.Collections.Generic;
using System.CommandLine;
using System.CommandLine.Binding;
Expand All @@ -28,8 +29,9 @@ public class CommandProcessor
/// Create an instance of the command processor;
/// </summary>
/// <param name="console">console instance to use for commands</param>
/// <param name="assemblies">The list of assemblies to look for commands</param>
public CommandProcessor(IConsole console, IEnumerable<Assembly> assemblies)
/// <param name="assemblies">Optional list of assemblies to look for commands</param>
/// <param name="types">Optional list of types to look for commands</param>
public CommandProcessor(IConsole console, IEnumerable<Assembly> assemblies = null, IEnumerable<Type> types = null)
{
Debug.Assert(console != null);
Debug.Assert(assemblies != null);
Expand All @@ -43,7 +45,12 @@ public CommandProcessor(IConsole console, IEnumerable<Assembly> assemblies)
.UseSuggestDirective()
.UseParseErrorReporting()
.UseExceptionHandler();
BuildCommands(rootBuilder, assemblies);
if (assemblies != null) {
BuildCommands(rootBuilder, assemblies);
}
if (types != null) {
BuildCommands(rootBuilder, types);
}
_rootCommand = rootBuilder.Command;
_parser = rootBuilder.Build();
}
Expand Down Expand Up @@ -96,73 +103,89 @@ public Command GetCommand(string name)

private void BuildCommands(CommandLineBuilder rootBuilder, IEnumerable<Assembly> assemblies)
{
foreach (Type type in assemblies.SelectMany((assembly) => assembly.GetExportedTypes()))
BuildCommands(rootBuilder, assemblies.SelectMany((assembly) => assembly.GetExportedTypes()));
}

private void BuildCommands(CommandLineBuilder rootBuilder, IEnumerable<Type> types)
{
foreach (Type type in types)
{
Command command = null;
for (Type baseType = type; baseType != null; baseType = baseType.BaseType)
{
if (baseType == typeof(CommandBase)) {
break;
}
BuildCommands(rootBuilder, baseType);
}
}
}

private void BuildCommands(CommandLineBuilder rootBuilder, Type type)
{
Command command = null;

var baseAttributes = (BaseAttribute[])type.GetCustomAttributes(typeof(BaseAttribute), inherit: false);
foreach (BaseAttribute baseAttribute in baseAttributes)
var baseAttributes = (BaseAttribute[])type.GetCustomAttributes(typeof(BaseAttribute), inherit: false);
foreach (BaseAttribute baseAttribute in baseAttributes)
{
if (baseAttribute is CommandAttribute commandAttribute)
{
if (baseAttribute is CommandAttribute commandAttribute)
{
command = new Command(commandAttribute.Name, commandAttribute.Help);
var properties = new List<(PropertyInfo, Option)>();
PropertyInfo argument = null;
command = new Command(commandAttribute.Name, commandAttribute.Help);
var properties = new List<(PropertyInfo, Option)>();
PropertyInfo argument = null;

foreach (PropertyInfo property in type.GetProperties().Where(p => p.CanWrite))
foreach (PropertyInfo property in type.GetProperties().Where(p => p.CanWrite))
{
var argumentAttribute = (ArgumentAttribute)property.GetCustomAttributes(typeof(ArgumentAttribute), inherit: false).SingleOrDefault();
if (argumentAttribute != null)
{
var argumentAttribute = (ArgumentAttribute)property.GetCustomAttributes(typeof(ArgumentAttribute), inherit: false).SingleOrDefault();
if (argumentAttribute != null)
if (argument != null) {
throw new ArgumentException($"More than one ArgumentAttribute in command class: {type.Name}");
}
IArgumentArity arity = property.PropertyType.IsArray ? ArgumentArity.ZeroOrMore : ArgumentArity.ZeroOrOne;

command.Argument = new Argument {
Name = argumentAttribute.Name ?? property.Name.ToLowerInvariant(),
Description = argumentAttribute.Help,
ArgumentType = property.PropertyType,
Arity = arity
};
argument = property;
}
else
{
var optionAttribute = (OptionAttribute)property.GetCustomAttributes(typeof(OptionAttribute), inherit: false).SingleOrDefault();
if (optionAttribute != null)
{
if (argument != null) {
throw new ArgumentException($"More than one ArgumentAttribute in command class: {type.Name}");
var option = new Option(optionAttribute.Name ?? BuildAlias(property.Name), optionAttribute.Help, new Argument { ArgumentType = property.PropertyType });
command.AddOption(option);
properties.Add((property, option));

foreach (var optionAliasAttribute in (OptionAliasAttribute[])property.GetCustomAttributes(typeof(OptionAliasAttribute), inherit: false))
{
option.AddAlias(optionAliasAttribute.Name);
}
IArgumentArity arity = property.PropertyType.IsArray ? ArgumentArity.ZeroOrMore : ArgumentArity.ZeroOrOne;

command.Argument = new Argument {
Name = argumentAttribute.Name ?? property.Name.ToLowerInvariant(),
Description = argumentAttribute.Help,
ArgumentType = property.PropertyType,
Arity = arity
};
argument = property;
}
else
{
var optionAttribute = (OptionAttribute)property.GetCustomAttributes(typeof(OptionAttribute), inherit: false).SingleOrDefault();
if (optionAttribute != null)
{
var option = new Option(optionAttribute.Name ?? BuildAlias(property.Name), optionAttribute.Help, new Argument { ArgumentType = property.PropertyType });
command.AddOption(option);
properties.Add((property, option));

foreach (var optionAliasAttribute in (OptionAliasAttribute[])property.GetCustomAttributes(typeof(OptionAliasAttribute), inherit: false))
{
option.AddAlias(optionAliasAttribute.Name);
}
}
else
{
// If not an option, add as just a settable properties
properties.Add((property, null));
}
// If not an option, add as just a settable properties
properties.Add((property, null));
}
}
}

var handler = new Handler(this, commandAttribute.AliasExpansion, argument, properties, type);
_commandHandlers.Add(command.Name, handler);
command.Handler = handler;
var handler = new Handler(this, commandAttribute.AliasExpansion, argument, properties, type);
_commandHandlers.Add(command.Name, handler);
command.Handler = handler;

rootBuilder.AddCommand(command);
}
rootBuilder.AddCommand(command);
}

if (baseAttribute is CommandAliasAttribute commandAliasAttribute)
{
if (command == null) {
throw new ArgumentException($"No previous CommandAttribute for this CommandAliasAttribute: {type.Name}");
}
command.AddAlias(commandAliasAttribute.Name);
if (baseAttribute is CommandAliasAttribute commandAliasAttribute)
{
if (command == null) {
throw new ArgumentException($"No previous CommandAttribute for this CommandAliasAttribute: {type.Name}");
}
command.AddAlias(commandAliasAttribute.Name);
}
}
}
Expand Down
14 changes: 8 additions & 6 deletions src/SOS/SOS.Hosting/Amd64Context.cs
Expand Up @@ -29,19 +29,21 @@ internal struct AMD64Context
public int MxCsr;

[FieldOffset(0x38)]
public short SegCs;
public short Cs;
[FieldOffset(0x3a)]
public short SegDs;
public short Ds;
[FieldOffset(0x3c)]
public short SegEs;
public short Es;
[FieldOffset(0x3e)]
public short SegFs;
public short Fs;
[FieldOffset(0x40)]
public short SegGs;
public short Gs;
[FieldOffset(0x42)]
public short SegSs;
public short Ss;
[FieldOffset(0x44)]
public int EFlags;
[FieldOffset(0x44)]
public ulong RFlags;
mikem8361 marked this conversation as resolved.
Show resolved Hide resolved

[FieldOffset(0x48)]
public ulong Dr0;
Expand Down