diff --git a/eng/Versions.props b/eng/Versions.props
index 73b7b137bb..407a6f1743 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -28,12 +28,12 @@
- 3.1.25
+ 3.1.28
$(MicrosoftNETCoreApp31Version)
- 6.0.6
+ 6.0.8
$(MicrosoftNETCoreApp60Version)
- 6.0.6
+ 6.0.8
7.0.0-rc.1.22403.8
diff --git a/src/Microsoft.Diagnostics.DebugServices.Implementation/CommandService.cs b/src/Microsoft.Diagnostics.DebugServices.Implementation/CommandService.cs
index bfb2bc5720..7585f33b90 100644
--- a/src/Microsoft.Diagnostics.DebugServices.Implementation/CommandService.cs
+++ b/src/Microsoft.Diagnostics.DebugServices.Implementation/CommandService.cs
@@ -42,8 +42,8 @@ public CommandService(string commandPrompt = null)
///
/// command line text
/// services for the command
- /// exit code
- public int Execute(string commandLine, IServiceProvider services)
+ /// true success, false failure
+ public bool Execute(string commandLine, IServiceProvider services)
{
// Parse the command line and invoke the command
ParseResult parseResult = Parser.Parse(commandLine);
@@ -70,7 +70,7 @@ public int Execute(string commandLine, IServiceProvider services)
{
context.Console.Error.WriteLine($"Command '{command.Name}' needs a target");
}
- return 1;
+ return false;
}
try
{
@@ -78,14 +78,27 @@ public int Execute(string commandLine, IServiceProvider services)
}
catch (Exception ex)
{
- OnException(ex, context);
+ if (ex is NullReferenceException ||
+ ex is ArgumentException ||
+ ex is ArgumentNullException ||
+ ex is ArgumentOutOfRangeException ||
+ ex is NotImplementedException)
+ {
+ context.Console.Error.WriteLine(ex.ToString());
+ }
+ else
+ {
+ context.Console.Error.WriteLine(ex.Message);
+ }
+ Trace.TraceError(ex.ToString());
+ return false;
}
}
}
}
context.InvocationResult?.Apply(context);
- return context.ResultCode;
+ return context.ResultCode == 0;
}
///
@@ -137,6 +150,13 @@ public bool DisplayHelp(string commandName, IServiceProvider services)
return true;
}
+ ///
+ /// Does this command or alias exists?
+ ///
+ /// command or alias name
+ /// true if command exists
+ public bool IsCommand(string commandName) => _rootBuilder.Command.Children.Contains(commandName);
+
///
/// Enumerates all the command's name and help
///
@@ -149,28 +169,31 @@ public bool DisplayHelp(string commandName, IServiceProvider services)
/// function to create command instance
public void AddCommands(Type type, Func factory)
{
- for (Type baseType = type; baseType != null; baseType = baseType.BaseType)
+ if (type.IsClass)
{
- if (baseType == typeof(CommandBase)) {
- break;
- }
- var commandAttributes = (CommandAttribute[])baseType.GetCustomAttributes(typeof(CommandAttribute), inherit: false);
- foreach (CommandAttribute commandAttribute in commandAttributes)
+ for (Type baseType = type; baseType != null; baseType = baseType.BaseType)
{
- if (factory == null)
+ if (baseType == typeof(CommandBase))
{
- // Assumes zero parameter constructor
- ConstructorInfo constructor = type.GetConstructors().SingleOrDefault((info) => info.GetParameters().Length == 0) ??
- throw new ArgumentException($"No eligible constructor found in {type}");
-
- factory = (services) => constructor.Invoke(Array.Empty
internal bool IsValidPlatform(ITarget target)
{
- if ((_commandAttribute.Platform & CommandPlatform.Global) != 0)
+ if ((_commandAttribute.Flags & CommandFlags.Global) != 0)
{
return true;
}
@@ -327,15 +329,15 @@ internal bool IsValidPlatform(ITarget target)
{
if (target.OperatingSystem == OSPlatform.Windows)
{
- return (_commandAttribute.Platform & CommandPlatform.Windows) != 0;
+ return (_commandAttribute.Flags & CommandFlags.Windows) != 0;
}
if (target.OperatingSystem == OSPlatform.Linux)
{
- return (_commandAttribute.Platform & CommandPlatform.Linux) != 0;
+ return (_commandAttribute.Flags & CommandFlags.Linux) != 0;
}
if (target.OperatingSystem == OSPlatform.OSX)
{
- return (_commandAttribute.Platform & CommandPlatform.OSX) != 0;
+ return (_commandAttribute.Flags & CommandFlags.OSX) != 0;
}
}
return false;
@@ -372,9 +374,7 @@ private void Invoke(MethodInfo methodInfo, InvocationContext context, Parser par
{
object instance = _factory(services);
SetProperties(context, parser, services, instance);
-
- object[] arguments = BuildArguments(methodInfo, services);
- methodInfo.Invoke(instance, arguments);
+ Utilities.Invoke(methodInfo, instance, services, optional: true);
}
private void SetProperties(InvocationContext context, Parser parser, IServiceProvider services, object instance)
@@ -461,21 +461,6 @@ private void SetProperties(InvocationContext context, Parser parser, IServicePro
argument.Property.SetValue(instance, array != null ? array.ToArray() : value);
}
}
-
- private object[] BuildArguments(MethodBase methodBase, IServiceProvider services)
- {
- ParameterInfo[] parameters = methodBase.GetParameters();
- object[] arguments = new object[parameters.Length];
- for (int i = 0; i < parameters.Length; i++)
- {
- Type parameterType = parameters[i].ParameterType;
-
- // The parameter will passed as null to allow for "optional" services. The invoked
- // method needs to check for possible null parameters.
- arguments[i] = services.GetService(parameterType);
- }
- return arguments;
- }
}
///
diff --git a/src/Microsoft.Diagnostics.DebugServices.Implementation/Utilities.cs b/src/Microsoft.Diagnostics.DebugServices.Implementation/Utilities.cs
index d1d71c81e1..0876574724 100644
--- a/src/Microsoft.Diagnostics.DebugServices.Implementation/Utilities.cs
+++ b/src/Microsoft.Diagnostics.DebugServices.Implementation/Utilities.cs
@@ -8,6 +8,7 @@
using System.Diagnostics;
using System.IO;
using System.Linq;
+using System.Reflection;
using System.Reflection.PortableExecutable;
namespace Microsoft.Diagnostics.DebugServices.Implementation
@@ -107,5 +108,65 @@ public static Stream TryOpenFile(string path)
return null;
}
+
+ ///
+ /// Call the constructor of the type and return the instance binding any
+ /// services in the constructor parameters.
+ ///
+ /// type to create
+ /// services
+ /// if true, the service is not required
+ /// type instance
+ public static object InvokeConstructor(Type type, IServiceProvider provider, bool optional)
+ {
+ ConstructorInfo constructor = type.GetConstructors().Single();
+ object[] arguments = BuildArguments(constructor, provider, optional);
+ try
+ {
+ return constructor.Invoke(arguments);
+ }
+ catch (TargetInvocationException ex)
+ {
+ throw ex.InnerException;
+ }
+ }
+
+ ///
+ /// Call the method and bind any services in the constructor parameters.
+ ///
+ /// method to invoke
+ /// class instance or null if static
+ /// services
+ /// if true, the service is not required
+ /// method return value
+ public static object Invoke(MethodBase method, object instance, IServiceProvider provider, bool optional)
+ {
+ object[] arguments = BuildArguments(method, provider, optional);
+ try
+ {
+ return method.Invoke(instance, arguments);
+ }
+ catch (TargetInvocationException ex)
+ {
+ throw ex.InnerException;
+ }
+ }
+
+ private static object[] BuildArguments(MethodBase methodBase, IServiceProvider services, bool optional)
+ {
+ ParameterInfo[] parameters = methodBase.GetParameters();
+ object[] arguments = new object[parameters.Length];
+ for (int i = 0; i < parameters.Length; i++)
+ {
+ // The parameter will passed as null to allow for "optional" services. The invoked
+ // method needs to check for possible null parameters.
+ arguments[i] = services.GetService(parameters[i].ParameterType);
+ if (arguments[i] is null && !optional)
+ {
+ throw new DiagnosticsException($"The {parameters[i].ParameterType} service is required by the {parameters[i].Name} parameter");
+ }
+ }
+ return arguments;
+ }
}
}
diff --git a/src/Microsoft.Diagnostics.DebugServices/CommandAttributes.cs b/src/Microsoft.Diagnostics.DebugServices/CommandAttributes.cs
index a02161eb70..a41d076712 100644
--- a/src/Microsoft.Diagnostics.DebugServices/CommandAttributes.cs
+++ b/src/Microsoft.Diagnostics.DebugServices/CommandAttributes.cs
@@ -7,10 +7,10 @@
namespace Microsoft.Diagnostics.DebugServices
{
///
- /// OS Platforms to add command
+ /// Command flags to filter by OS Platforms, control scope and how the command is registered.
///
[Flags]
- public enum CommandPlatform : byte
+ public enum CommandFlags : byte
{
Windows = 0x01,
Linux = 0x02,
@@ -21,6 +21,11 @@ public enum CommandPlatform : byte
///
Global = 0x08,
+ ///
+ /// Command is not added through reflection, but manually with command service API.
+ ///
+ Manual = 0x10,
+
///
/// Default. All operating system, but target is required
///
@@ -49,9 +54,9 @@ public class CommandAttribute : Attribute
public string[] Aliases = Array.Empty();
///
- /// Optional OS platform for the command
+ /// Command flags to filter by OS Platforms, control scope and how the command is registered.
///
- public CommandPlatform Platform = CommandPlatform.Default;
+ public CommandFlags Flags = CommandFlags.Default;
///
/// A string of options that are parsed before the command line options
diff --git a/src/Microsoft.Diagnostics.ExtensionCommands/DumpAsyncCommand.cs b/src/Microsoft.Diagnostics.ExtensionCommands/DumpAsyncCommand.cs
index b5d2c54556..8f1bb430e7 100644
--- a/src/Microsoft.Diagnostics.ExtensionCommands/DumpAsyncCommand.cs
+++ b/src/Microsoft.Diagnostics.ExtensionCommands/DumpAsyncCommand.cs
@@ -13,7 +13,7 @@
namespace Microsoft.Diagnostics.ExtensionCommands
{
- [Command(Name = CommandName, Help = "Displays information about async \"stacks\" on the garbage-collected heap.")]
+ [Command(Name = CommandName, Aliases = new string[] { "DumpAsync" }, Help = "Displays information about async \"stacks\" on the garbage-collected heap.")]
public sealed class DumpAsyncCommand : ExtensionCommandBase
{
/// The name of the command.
diff --git a/src/Microsoft.Diagnostics.ExtensionCommands/Host/LoggingCommand.cs b/src/Microsoft.Diagnostics.ExtensionCommands/Host/LoggingCommand.cs
index 10ec2d68d1..974a796816 100644
--- a/src/Microsoft.Diagnostics.ExtensionCommands/Host/LoggingCommand.cs
+++ b/src/Microsoft.Diagnostics.ExtensionCommands/Host/LoggingCommand.cs
@@ -8,7 +8,7 @@
namespace Microsoft.Diagnostics.ExtensionCommands
{
- [Command(Name = "logging", Help = "Enable/disable internal logging", Platform = CommandPlatform.Global)]
+ [Command(Name = "logging", Help = "Enable/disable internal logging", Flags = CommandFlags.Global)]
public class LoggingCommand : CommandBase
{
[Option(Name = "enable", Help = "Enable internal logging.")]
diff --git a/src/Microsoft.Diagnostics.ExtensionCommands/Host/SetSymbolServerCommand.cs b/src/Microsoft.Diagnostics.ExtensionCommands/Host/SetSymbolServerCommand.cs
index 756b302c00..eaf0797af8 100644
--- a/src/Microsoft.Diagnostics.ExtensionCommands/Host/SetSymbolServerCommand.cs
+++ b/src/Microsoft.Diagnostics.ExtensionCommands/Host/SetSymbolServerCommand.cs
@@ -10,7 +10,12 @@ namespace Microsoft.Diagnostics.ExtensionCommands
Name = "setsymbolserver",
Aliases = new string[] { "SetSymbolServer" },
Help = "Enable and set symbol server support for symbols and module download",
- Platform = CommandPlatform.Global)]
+ Flags = CommandFlags.Global)]
+ [Command(
+ Name = "loadsymbols",
+ DefaultOptions = "--loadsymbols",
+ Help = "Load symbols for all modules",
+ Flags = CommandFlags.Global)]
public class SetSymbolServerCommand : CommandBase
{
public ISymbolService SymbolService { get; set; }
diff --git a/src/Microsoft.Diagnostics.Repl/ExitCommand.cs b/src/Microsoft.Diagnostics.Repl/ExitCommand.cs
index c7678c3f1f..4d4eb4eee1 100644
--- a/src/Microsoft.Diagnostics.Repl/ExitCommand.cs
+++ b/src/Microsoft.Diagnostics.Repl/ExitCommand.cs
@@ -7,7 +7,7 @@
namespace Microsoft.Diagnostics.Repl
{
- [Command(Name = "exit", Aliases = new string[] { "quit", "q" }, Help = "Exit interactive mode.", Platform = CommandPlatform.Global)]
+ [Command(Name = "exit", Aliases = new string[] { "quit", "q" }, Help = "Exit interactive mode.", Flags = CommandFlags.Global | CommandFlags.Manual)]
public class ExitCommand : CommandBase
{
private readonly Action _exit;
diff --git a/src/Microsoft.Diagnostics.Repl/HelpCommand.cs b/src/Microsoft.Diagnostics.Repl/HelpCommand.cs
index cbf3699f4f..b4153706f4 100644
--- a/src/Microsoft.Diagnostics.Repl/HelpCommand.cs
+++ b/src/Microsoft.Diagnostics.Repl/HelpCommand.cs
@@ -7,7 +7,7 @@
namespace Microsoft.Diagnostics.Repl
{
- [Command(Name = "help", Help = "Display help for a command.", Platform = CommandPlatform.Global)]
+ [Command(Name = "help", Help = "Display help for a command.", Flags = CommandFlags.Global | CommandFlags.Manual)]
public class HelpCommand : CommandBase
{
[Argument(Help = "Command to find help.")]
diff --git a/src/SOS/SOS.Extensions/HostServices.cs b/src/SOS/SOS.Extensions/HostServices.cs
index 41b9947ac8..91308b8945 100644
--- a/src/SOS/SOS.Extensions/HostServices.cs
+++ b/src/SOS/SOS.Extensions/HostServices.cs
@@ -13,6 +13,7 @@
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
+using System.Text;
namespace SOS.Extensions
{
@@ -128,7 +129,7 @@ private HostServices()
builder.AddMethod(new FlushTargetDelegate(FlushTarget));
builder.AddMethod(new DestroyTargetDelegate(DestroyTarget));
builder.AddMethod(new DispatchCommandDelegate(DispatchCommand));
- builder.AddMethod(new DispatchCommandDelegate(DisplayHelp));
+ builder.AddMethod(new DisplayHelpDelegate(DisplayHelp));
builder.AddMethod(new UninitializeDelegate(Uninitialize));
IHostServices = builder.Complete();
@@ -325,15 +326,30 @@ private void DestroyTarget(
private HResult DispatchCommand(
IntPtr self,
- string commandLine)
+ string commandName,
+ string commandArguments)
{
- if (commandLine == null)
+ if (string.IsNullOrWhiteSpace(commandName))
{
return HResult.E_INVALIDARG;
}
+ if (!_commandService.IsCommand(commandName))
+ {
+ return HResult.E_NOTIMPL;
+ }
try
{
- return _commandService.Execute(commandLine, _contextService.Services);
+ StringBuilder sb = new();
+ sb.Append(commandName);
+ if (!string.IsNullOrWhiteSpace(commandArguments))
+ {
+ sb.Append(' ');
+ sb.Append(commandArguments);
+ }
+ if (_commandService.Execute(sb.ToString(), _contextService.Services))
+ {
+ return HResult.S_OK;
+ }
}
catch (Exception ex)
{
@@ -344,11 +360,11 @@ private HResult DispatchCommand(
private HResult DisplayHelp(
IntPtr self,
- string command)
+ string commandName)
{
try
{
- if (!_commandService.DisplayHelp(command, _contextService.Services))
+ if (!_commandService.DisplayHelp(commandName, _contextService.Services))
{
return HResult.E_INVALIDARG;
}
@@ -424,12 +440,13 @@ private delegate void DestroyTargetDelegate(
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
private delegate HResult DispatchCommandDelegate(
[In] IntPtr self,
- [In, MarshalAs(UnmanagedType.LPStr)] string commandLine);
+ [In, MarshalAs(UnmanagedType.LPStr)] string commandName,
+ [In, MarshalAs(UnmanagedType.LPStr)] string commandArguments);
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
private delegate HResult DisplayHelpDelegate(
[In] IntPtr self,
- [In, MarshalAs(UnmanagedType.LPStr)] string command);
+ [In, MarshalAs(UnmanagedType.LPStr)] string commandName);
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
private delegate void UninitializeDelegate(
diff --git a/src/SOS/SOS.Hosting/Commands/SOSCommand.cs b/src/SOS/SOS.Hosting/Commands/SOSCommand.cs
index c37b4f7b1e..d4e5f38570 100644
--- a/src/SOS/SOS.Hosting/Commands/SOSCommand.cs
+++ b/src/SOS/SOS.Hosting/Commands/SOSCommand.cs
@@ -60,13 +60,13 @@ namespace SOS.Hosting
[Command(Name = "threadpool", DefaultOptions = "ThreadPool", Help = "Lists basic information about the thread pool.")]
[Command(Name = "verifyheap", DefaultOptions = "VerifyHeap", Help = "Checks the GC heap for signs of corruption.")]
[Command(Name = "verifyobj", DefaultOptions = "VerifyObj", Help = "Checks the object for signs of corruption.")]
- [Command(Name = "dumprcw", DefaultOptions = "DumpRCW", Platform = CommandPlatform.Windows, Help = "Displays information about a Runtime Callable Wrapper.")]
- [Command(Name = "dumpccw", DefaultOptions = "DumpCCW", Platform = CommandPlatform.Windows, Help = "Displays information about a COM Callable Wrapper.")]
- [Command(Name = "dumppermissionset",DefaultOptions = "DumpPermissionSet", Platform = CommandPlatform.Windows, Help = "Displays a PermissionSet object (debug build only).")]
- [Command(Name = "traverseheap", DefaultOptions = "TraverseHeap", Platform = CommandPlatform.Windows, Help = "Writes out a file in a format understood by the CLR Profiler.")]
- [Command(Name = "watsonbuckets", DefaultOptions = "WatsonBuckets", Platform = CommandPlatform.Windows, Help = "Displays the Watson buckets.")]
- [Command(Name = "comstate", DefaultOptions = "COMState", Platform = CommandPlatform.Windows, Help = "Lists the COM apartment model for each thread.")]
- [Command(Name = "gchandleleaks", DefaultOptions = "GCHandleLeaks", Platform = CommandPlatform.Windows, Help = "Helps in tracking down GCHandle leaks")]
+ [Command(Name = "comstate", DefaultOptions = "COMState", Flags = CommandFlags.Windows, Help = "Lists the COM apartment model for each thread.")]
+ [Command(Name = "dumprcw", DefaultOptions = "DumpRCW", Flags = CommandFlags.Windows, Help = "Displays information about a Runtime Callable Wrapper.")]
+ [Command(Name = "dumpccw", DefaultOptions = "DumpCCW", Flags = CommandFlags.Windows, Help = "Displays information about a COM Callable Wrapper.")]
+ [Command(Name = "dumppermissionset",DefaultOptions = "DumpPermissionSet", Flags = CommandFlags.Windows, Help = "Displays a PermissionSet object (debug build only).")]
+ [Command(Name = "gchandleleaks", DefaultOptions = "GCHandleLeaks", Flags = CommandFlags.Windows, Help = "Helps in tracking down GCHandle leaks")]
+ [Command(Name = "traverseheap", DefaultOptions = "TraverseHeap", Flags = CommandFlags.Windows, Help = "Writes out a file in a format understood by the CLR Profiler.")]
+ [Command(Name = "watsonbuckets", DefaultOptions = "WatsonBuckets", Flags = CommandFlags.Windows, Help = "Displays the Watson buckets.")]
public class SOSCommand : CommandBase
{
[Argument(Name = "arguments", Help = "Arguments to SOS command.")]
@@ -78,7 +78,7 @@ public override void Invoke()
{
try {
Debug.Assert(Arguments != null && Arguments.Length > 0);
- string arguments = string.Concat(Arguments.Skip(1).Select((arg) => arg + " "));
+ string arguments = string.Concat(Arguments.Skip(1).Select((arg) => arg + " ")).Trim();
SOSHost.ExecuteCommand(Arguments[0], arguments);
}
catch (Exception ex) when (ex is FileNotFoundException || ex is EntryPointNotFoundException || ex is InvalidOperationException) {
diff --git a/src/SOS/SOS.Hosting/CorDebugDataTargetWrapper.cs b/src/SOS/SOS.Hosting/CorDebugDataTargetWrapper.cs
index 0954470bc5..058cdb4dfb 100644
--- a/src/SOS/SOS.Hosting/CorDebugDataTargetWrapper.cs
+++ b/src/SOS/SOS.Hosting/CorDebugDataTargetWrapper.cs
@@ -125,13 +125,17 @@ private unsafe int ReadVirtual(
uint bytesRequested,
uint* pbytesRead)
{
- address &= _ignoreAddressBitsMask;
- if (!_memoryService.ReadMemory(address, buffer, unchecked((int)bytesRequested), out int bytesRead))
+ int read = 0;
+ if (bytesRequested > 0)
{
- Trace.TraceError("CorDebugDataTargetWrappter.ReadVirtual FAILED address {0:X16} size {1:X8}", address, bytesRequested);
- return HResult.E_FAIL;
+ address &= _ignoreAddressBitsMask;
+ if (!_memoryService.ReadMemory(address, buffer, unchecked((int)bytesRequested), out read))
+ {
+ Trace.TraceError("CorDebugDataTargetWrappter.ReadVirtual FAILED address {0:X16} size {1:X8}", address, bytesRequested);
+ return HResult.E_FAIL;
+ }
}
- SOSHost.Write(pbytesRead, (uint)bytesRead);
+ SOSHost.Write(pbytesRead, (uint)read);
return HResult.S_OK;
}
diff --git a/src/SOS/SOS.Hosting/DataTargetWrapper.cs b/src/SOS/SOS.Hosting/DataTargetWrapper.cs
index 826143d224..a5a9d4992e 100644
--- a/src/SOS/SOS.Hosting/DataTargetWrapper.cs
+++ b/src/SOS/SOS.Hosting/DataTargetWrapper.cs
@@ -149,17 +149,21 @@ private int ReadVirtual(
ulong address,
IntPtr buffer,
uint bytesRequested,
- uint* bytesRead)
+ uint* pbytesRead)
{
Debug.Assert(address != MagicCallbackConstant);
- address &= _ignoreAddressBitsMask;
- if (!_memoryService.ReadMemory(address, buffer, unchecked((int)bytesRequested), out int read))
+ int read = 0;
+ if (bytesRequested > 0)
{
- Trace.TraceError("DataTargetWrapper.ReadVirtual FAILED address {0:X16} size {1:X8}", address, bytesRequested);
- SOSHost.Write(bytesRead);
- return HResult.E_FAIL;
+ address &= _ignoreAddressBitsMask;
+ if (!_memoryService.ReadMemory(address, buffer, unchecked((int)bytesRequested), out read))
+ {
+ Trace.TraceError("DataTargetWrapper.ReadVirtual FAILED address {0:X16} size {1:X8}", address, bytesRequested);
+ SOSHost.Write(pbytesRead);
+ return HResult.E_FAIL;
+ }
}
- SOSHost.Write(bytesRead, (uint)read);
+ SOSHost.Write(pbytesRead, (uint)read);
return HResult.S_OK;
}
diff --git a/src/SOS/SOS.Hosting/SOSLibrary.cs b/src/SOS/SOS.Hosting/SOSLibrary.cs
index 1009e5a7be..a43683f7c3 100644
--- a/src/SOS/SOS.Hosting/SOSLibrary.cs
+++ b/src/SOS/SOS.Hosting/SOSLibrary.cs
@@ -159,7 +159,7 @@ public void ExecuteCommand(IntPtr client, string command, string arguments)
var commandFunc = SOSHost.GetDelegateFunction(_sosLibrary, command);
if (commandFunc == null)
{
- throw new EntryPointNotFoundException($"Can not find SOS command: {command}");
+ throw new DiagnosticsException($"SOS command not found: {command}");
}
int result = commandFunc(client, arguments ?? "");
if (result != HResult.S_OK)
diff --git a/src/SOS/SOS.UnitTests/SOSRunner.cs b/src/SOS/SOS.UnitTests/SOSRunner.cs
index 2b6c697e17..616733bfae 100644
--- a/src/SOS/SOS.UnitTests/SOSRunner.cs
+++ b/src/SOS/SOS.UnitTests/SOSRunner.cs
@@ -924,6 +924,8 @@ public async Task LoadSosExtension()
{
commands.Add($"sethostruntime {setHostRuntime}");
}
+ // Disabled until https://github.com/dotnet/diagnostics/issues/3265 is fixed.
+#if DISABLED
// If a single-file app, add the path to runtime so SOS can find DAC/DBI locally.
if (_config.PublishSingleFile)
{
@@ -932,6 +934,7 @@ public async Task LoadSosExtension()
commands.Add($"setclrpath {runtimeSymbolsPath}");
}
}
+#endif
if (!isHostRuntimeNone && !string.IsNullOrEmpty(setSymbolServer))
{
commands.Add($"setsymbolserver {setSymbolServer}");
@@ -1015,7 +1018,7 @@ public async Task RunSosCommand(string command, bool extensionCommand = fa
case NativeDebugger.Cdb:
if (extensionCommand)
{
- command = "!ext " + command;
+ command = "!sos " + command;
}
else
{
@@ -1023,20 +1026,26 @@ public async Task RunSosCommand(string command, bool extensionCommand = fa
}
break;
case NativeDebugger.Lldb:
- if (!extensionCommand)
- {
- command = "sos " + command;
- }
+ command = "sos " + command;
break;
case NativeDebugger.DotNetDump:
- int index = command.IndexOf(' ');
- if (index != -1) {
- // lowercase just the command name not the rest of the command line
- command = command.Substring(0, index).ToLowerInvariant() + command.Substring(index);
+ if (extensionCommand)
+ {
+ command = "sos " + command;
}
- else {
- // it is only the command name
- command = command.ToLowerInvariant();
+ else
+ {
+ int index = command.IndexOf(' ');
+ if (index != -1)
+ {
+ // lowercase just the command name not the rest of the command line
+ command = command.Substring(0, index).ToLowerInvariant() + command.Substring(index);
+ }
+ else
+ {
+ // it is only the command name
+ command = command.ToLowerInvariant();
+ }
}
break;
default:
diff --git a/src/SOS/SOS.UnitTests/Scripts/OtherCommands.script b/src/SOS/SOS.UnitTests/Scripts/OtherCommands.script
index 76470093ed..32fb62b9eb 100644
--- a/src/SOS/SOS.UnitTests/Scripts/OtherCommands.script
+++ b/src/SOS/SOS.UnitTests/Scripts/OtherCommands.script
@@ -68,9 +68,11 @@ VERIFY:\s*\s+0x\s+\(\)\s+
EXTCOMMAND:registers
VERIFY:\s*([r|e]ip|pc) = 0x\s+
-SOSCOMMAND:ThreadPool
+EXTCOMMAND:ClrStack
-SOSCOMMAND:VerifyHeap
+EXTCOMMAND:ThreadPool
+
+EXTCOMMAND:VerifyHeap
SOSCOMMAND:DumpHeap
VERIFY:\s+Address\s+MT\s+Size\s+
diff --git a/src/SOS/SOS.UnitTests/Scripts/StackAndOtherTests.script b/src/SOS/SOS.UnitTests/Scripts/StackAndOtherTests.script
index e4afc5c497..3cf92dd763 100644
--- a/src/SOS/SOS.UnitTests/Scripts/StackAndOtherTests.script
+++ b/src/SOS/SOS.UnitTests/Scripts/StackAndOtherTests.script
@@ -197,7 +197,6 @@ VERIFY:.*\s+\s+\s+System\.String\[\].*
ENDIF:NETCORE_OR_DOTNETDUMP
# Issue: https://github.com/dotnet/diagnostics/issues/2947
-!IFDEF:MAJOR_RUNTIME_VERSION_GE_7
!IFDEF:DOTNETDUMP
!IFDEF:ARM
@@ -220,7 +219,6 @@ VERIFY:(.*\s+\s+\s+\(MethodDesc\s+\s+(\+\s*0x\s+
ENDIF:ARM
ENDIF:DOTNETDUMP
-ENDIF:MAJOR_RUNTIME_VERSION_GE_7
# Verify that IP2MD works (uses IP from ClrStack)
SOSCOMMAND:ClrStack
diff --git a/src/SOS/SOS.UnitTests/Scripts/StackTests.script b/src/SOS/SOS.UnitTests/Scripts/StackTests.script
index e7bb519a48..d140295527 100644
--- a/src/SOS/SOS.UnitTests/Scripts/StackTests.script
+++ b/src/SOS/SOS.UnitTests/Scripts/StackTests.script
@@ -151,7 +151,6 @@ VERIFY:.*\s+\s+\s+System\.InvalidOperationException\s+
VERIFY:.*\s+\s+\s+System\.String.*
# Issue: https://github.com/dotnet/diagnostics/issues/2947
-!IFDEF:MAJOR_RUNTIME_VERSION_GE_7
!IFDEF:DOTNETDUMP
!IFDEF:ARM
@@ -174,4 +173,3 @@ VERIFY:.*\s+\s+\s+\(MethodDesc\s+\s+\+\s*0x\s+Ne
ENDIF:ARM
ENDIF:DOTNETDUMP
-ENDIF:MAJOR_RUNTIME_VERSION_GE_7
diff --git a/src/SOS/SOS.UnitTests/Scripts/WebApp.script b/src/SOS/SOS.UnitTests/Scripts/WebApp.script
index f5e7e5eef7..ffa91ff7e9 100644
--- a/src/SOS/SOS.UnitTests/Scripts/WebApp.script
+++ b/src/SOS/SOS.UnitTests/Scripts/WebApp.script
@@ -34,11 +34,19 @@ EXTCOMMAND:parallelstacks
EXTCOMMAND:timerinfo
VERIFY:\s*\s*timers\s*
+SOSCOMMAND:runtimes
+
+EXTCOMMAND:runtimes
+
# Verify that ClrStack with no options works
SOSCOMMAND:ClrStack
VERIFY:.*OS Thread Id:\s+0x\s+.*
VERIFY:\s+Child\s+SP\s+IP\s+Call Site\s+
+EXTCOMMAND:ClrStack
+VERIFY:.*OS Thread Id:\s+0x\s+.*
+VERIFY:\s+Child\s+SP\s+IP\s+Call Site\s+
+
# Verify that ClrStack for all threads works
SOSCOMMAND:ClrStack -all
diff --git a/src/SOS/Strike/Strike.vcxproj b/src/SOS/Strike/Strike.vcxproj
index b8ec9fe5bc..be63febcfb 100644
--- a/src/SOS/Strike/Strike.vcxproj
+++ b/src/SOS/Strike/Strike.vcxproj
@@ -265,7 +265,7 @@
true
Level3
true
- NDEBUG;URTBLDENV_FRIENDLY=Retail;_AMD64_;_WIN64;AMD64;BIT64=1;_TARGET_64BIT_=1;_TARGET_AMD64_=1;DBG_TARGET_64BIT=1;DBG_TARGET_AMD64=1;DBG_TARGET_WIN64=1;WIN32;_WIN32;WINVER=0x0602;_WIN32_WINNT=0x0602;WIN32_LEAN_AND_MEAN=1;_CRT_SECURE_NO_WARNINGS;;FEATURE_COMINTEROP;FEATURE_HIJACK;_SECURE_SCL=0;_TARGET_WIN64_=1;SOS_TARGET_AMD64=1;SOS_TARGET_ARM64=1;STRIKE;USE_STL;FX_VER_INTERNALNAME_STR=SOS.dll;CMAKE_INTDIR="Release";sos_EXPORTS;%(PreprocessorDefinitions)
+ HOST_WINDOWS;NDEBUG;URTBLDENV_FRIENDLY=Retail;_AMD64_;_WIN64;AMD64;BIT64=1;_TARGET_64BIT_=1;_TARGET_AMD64_=1;DBG_TARGET_64BIT=1;DBG_TARGET_AMD64=1;DBG_TARGET_WIN64=1;WIN32;_WIN32;WINVER=0x0602;_WIN32_WINNT=0x0602;WIN32_LEAN_AND_MEAN=1;_CRT_SECURE_NO_WARNINGS;FEATURE_COMINTEROP;FEATURE_HIJACK;_SECURE_SCL=0;_TARGET_WIN64_=1;SOS_TARGET_AMD64=1;SOS_TARGET_ARM64=1;STRIKE;USE_STL;FX_VER_INTERNALNAME_STR=SOS.dll;CMAKE_INTDIR="Release";sos_EXPORTS;%(PreprocessorDefinitions)
$(IntDir)
diff --git a/src/SOS/Strike/sos.def b/src/SOS/Strike/sos.def
index e548eac314..6dec87fd17 100644
--- a/src/SOS/Strike/sos.def
+++ b/src/SOS/Strike/sos.def
@@ -74,7 +74,9 @@ EXPORTS
EHInfo
ehinfo=EHInfo
Ehinfo=EHInfo
+ enummemory
ext
+ sos=ext
FinalizeQueue
finalizequeue=FinalizeQueue
fq=FinalizeQueue
diff --git a/src/SOS/Strike/sos_unixexports.src b/src/SOS/Strike/sos_unixexports.src
index 35bd51fa0c..9ac9f71d9a 100644
--- a/src/SOS/Strike/sos_unixexports.src
+++ b/src/SOS/Strike/sos_unixexports.src
@@ -4,13 +4,11 @@
AnalyzeOOM
bpmd
-clrmodules
ClrStack
dbgout
DumpALC
DumpArray
DumpAssembly
-DumpAsync
DumpClass
DumpDelegate
DumpDomain
@@ -32,7 +30,7 @@ EEHeap
EEVersion
EEStack
EHInfo
-ext
+enummemory
FinalizeQueue
FindAppDomain
FindRoots
@@ -50,7 +48,6 @@ HistRoot
HistStats
IP2MD
ListNearObj
-logging
Name2EE
ObjSize
PrintException
@@ -58,9 +55,9 @@ PathTo
runtimes
StopOnCatch
SetClrPath
-SetSymbolServer
SOSFlush
SOSStatus
+runtimes
SuppressJitOptimization
SyncBlk
Threads
diff --git a/src/SOS/Strike/sosdocsunix.txt b/src/SOS/Strike/sosdocsunix.txt
index 6eb004882b..00127b9d5a 100644
--- a/src/SOS/Strike/sosdocsunix.txt
+++ b/src/SOS/Strike/sosdocsunix.txt
@@ -2227,8 +2227,7 @@ You can use the "dotnet --info" in a command shell to find the path of an instal
COMMAND: setsymbolserver.
COMMAND: loadsymbols.
-COMMAND: sympath.
-SetSymbolServer [-ms] [-disable] [-log] [-loadsymbols] [-cache ] [-directory ] [-timeout ] [-pat ] [-sympath ] []
+SetSymbolServer [-ms] [-disable] [-log] [-loadsymbols] [-cache ] [-directory ] [-timeout ] [-pat ] []
-ms - Use the public Microsoft symbol server.
-disable - Disable symbol download support.
@@ -2236,7 +2235,6 @@ SetSymbolServer [-ms] [-disable] [-log] [-loadsymbols] [-cache ] [-
-timeout - Specify the symbol server timeout in minutes
-pat - Access token to the authenticated server.
-cache - Specific a symbol cache directory. The default is $HOME/.dotnet/symbolcache if not specified.
--sympath - Add server, cache and directory paths in the Windows symbol path format.
-loadsymbols - Attempts to download the native .NET Core symbols for the runtime
- Symbol server URL.
@@ -2260,10 +2258,6 @@ To add a directory to search for symbols:
This command can be used so the module/symbol file structure does not have to match the machine
file structure that the core dump was generated.
-The "sympath" option/command alias allows Windows symbol paths to be parsed:
-
- (lldb) sympath "/home/mikem/localsymbols;srv*/home/mikem/symbolcache*https://msdl.microsoft.com/download/symbols".
-
To clear the default cache run "rm -r $HOME/.dotnet/symbolcache" in a command shell.
If you receive an error like the one below on a core dump, you need to set the .NET Core
diff --git a/src/SOS/Strike/strike.cpp b/src/SOS/Strike/strike.cpp
index dd5177e95b..e974e1684c 100644
--- a/src/SOS/Strike/strike.cpp
+++ b/src/SOS/Strike/strike.cpp
@@ -105,6 +105,7 @@
#include "cordebug.h"
#include "dacprivate.h"
#include "corexcep.h"
+#include
#define CORHANDLE_MASK 0x1
#define SWITCHED_OUT_FIBER_OSID 0xbaadf00d;
@@ -10357,9 +10358,7 @@ DECLARE_API(SOSStatus)
IHostServices* hostServices = GetHostServices();
if (hostServices != nullptr)
{
- std::string command("sosstatus ");
- command.append(args);
- Status = hostServices->DispatchCommand(command.c_str());
+ Status = hostServices->DispatchCommand("sosstatus", args);
}
else
{
@@ -15697,6 +15696,108 @@ DECLARE_API(StopOnCatch)
return S_OK;
}
+class EnumMemoryCallback : public ICLRDataEnumMemoryRegionsCallback, ICLRDataEnumMemoryRegionsLoggingCallback
+{
+private:
+ LONG m_ref;
+ bool m_log;
+
+public:
+ EnumMemoryCallback(bool log) :
+ m_ref(1),
+ m_log(log)
+ {
+ }
+
+ virtual ~EnumMemoryCallback()
+ {
+ }
+
+ STDMETHODIMP QueryInterface(
+ ___in REFIID InterfaceId,
+ ___out PVOID* Interface)
+ {
+ if (InterfaceId == IID_IUnknown ||
+ InterfaceId == IID_ICLRDataEnumMemoryRegionsCallback)
+ {
+ *Interface = (ICLRDataEnumMemoryRegionsCallback*)this;
+ AddRef();
+ return S_OK;
+ }
+ else if (InterfaceId == IID_ICLRDataEnumMemoryRegionsLoggingCallback)
+ {
+ *Interface = (ICLRDataEnumMemoryRegionsLoggingCallback*)this;
+ AddRef();
+ return S_OK;
+ }
+ else
+ {
+ *Interface = nullptr;
+ return E_NOINTERFACE;
+ }
+ }
+
+ STDMETHODIMP_(ULONG) AddRef()
+ {
+ LONG ref = InterlockedIncrement(&m_ref);
+ return ref;
+ }
+
+ STDMETHODIMP_(ULONG) Release()
+ {
+ LONG ref = InterlockedDecrement(&m_ref);
+ if (ref == 0)
+ {
+ delete this;
+ }
+ return ref;
+ }
+
+ HRESULT STDMETHODCALLTYPE EnumMemoryRegion(
+ /* [in] */ CLRDATA_ADDRESS address,
+ /* [in] */ ULONG32 size)
+ {
+ if (m_log)
+ {
+ ExtOut("%016llx %08x\n", address, size);
+ }
+ return S_OK;
+ }
+
+ HRESULT STDMETHODCALLTYPE LogMessage(
+ /* [in] */ LPCSTR message)
+ {
+ ExtOut("%s", message);
+ return S_OK;
+ }
+};
+
+DECLARE_API(enummemory)
+{
+ INIT_API();
+
+ ToRelease enumMemoryRegions;
+ Status = g_clrData->QueryInterface(__uuidof(ICLRDataEnumMemoryRegions), (void**)&enumMemoryRegions);
+ if (SUCCEEDED(Status))
+ {
+ ToRelease callback = new EnumMemoryCallback(false);
+ ULONG32 minidumpType =
+ (MiniDumpWithPrivateReadWriteMemory |
+ MiniDumpWithDataSegs |
+ MiniDumpWithHandleData |
+ MiniDumpWithUnloadedModules |
+ MiniDumpWithFullMemoryInfo |
+ MiniDumpWithThreadInfo |
+ MiniDumpWithTokenInformation);
+ Status = enumMemoryRegions->EnumMemoryRegions(callback, minidumpType, CLRDataEnumMemoryFlags::CLRDATA_ENUM_MEM_DEFAULT);
+ if (FAILED(Status))
+ {
+ ExtErr("EnumMemoryRegions FAILED %08x\n", Status);
+ }
+ }
+ return Status;
+}
+
#ifndef FEATURE_PAL
// This is an undocumented SOS extension command intended to help test SOS
@@ -16008,9 +16109,7 @@ DECLARE_API(SetClrPath)
IHostServices* hostServices = GetHostServices();
if (hostServices != nullptr)
{
- std::string command("setclrpath ");
- command.append(args);
- return hostServices->DispatchCommand(command.c_str());
+ return hostServices->DispatchCommand("setclrpath", args);
}
else
{
@@ -16054,9 +16153,7 @@ DECLARE_API(runtimes)
IHostServices* hostServices = GetHostServices();
if (hostServices != nullptr)
{
- std::string command("runtimes ");
- command.append(args);
- Status = hostServices->DispatchCommand(command.c_str());
+ Status = hostServices->DispatchCommand("runtimes", args);
}
else
{
@@ -16099,31 +16196,22 @@ DECLARE_API(runtimes)
return Status;
}
+#ifdef HOST_WINDOWS
+
//
// Executes managed extension commands
//
-HRESULT ExecuteCommand(PCSTR command, PCSTR args)
+HRESULT ExecuteCommand(PCSTR commandName, PCSTR args)
{
IHostServices* hostServices = GetHostServices();
if (hostServices != nullptr)
{
- std::string commandLine(command);
- if (args != nullptr && strlen(args) > 0)
- {
- commandLine.append(" ");
- commandLine.append(args);
- }
- if (!commandLine.empty())
+ if (commandName != nullptr && strlen(commandName) > 0)
{
- return hostServices->DispatchCommand(commandLine.c_str());
+ return hostServices->DispatchCommand(commandName, args);
}
}
- else
- {
- ExtErr("Command not loaded\n");
- return E_FAIL;
- }
- return S_OK;
+ return E_NOTIMPL;
}
//
@@ -16162,15 +16250,44 @@ DECLARE_API(logging)
return ExecuteCommand("logging", args);
}
+typedef HRESULT (*PFN_COMMAND)(PDEBUG_CLIENT client, PCSTR args);
+
//
// Executes managed extension commands
//
DECLARE_API(ext)
{
INIT_API_EXT();
- return ExecuteCommand("", args);
+
+ if (args == nullptr || strlen(args) <= 0)
+ {
+ args = "Help";
+ }
+ std::string arguments(args);
+ size_t pos = arguments.find(' ');
+ std::string commandName = arguments.substr(0, pos);
+ if (pos != std::string::npos)
+ {
+ arguments = arguments.substr(pos + 1);
+ }
+ else
+ {
+ arguments.clear();
+ }
+ Status = ExecuteCommand(commandName.c_str(), arguments.c_str());
+ if (Status == E_NOTIMPL)
+ {
+ PFN_COMMAND commandFunc = (PFN_COMMAND)GetProcAddress(g_hInstance, commandName.c_str());
+ if (commandFunc != nullptr)
+ {
+ Status = (*commandFunc)(client, arguments.c_str());
+ }
+ }
+ return Status;
}
+#endif // HOST_WINDOWS
+
void PrintHelp (__in_z LPCSTR pszCmdName)
{
static LPSTR pText = NULL;
diff --git a/src/SOS/inc/hostservices.h b/src/SOS/inc/hostservices.h
index 6b7c19eb6f..bf4403845f 100644
--- a/src/SOS/inc/hostservices.h
+++ b/src/SOS/inc/hostservices.h
@@ -76,18 +76,20 @@ IHostServices : public IUnknown
///
/// Dispatches the command line to managed extension
///
- /// full command line
+ /// command name
+ /// command arguments
/// error code
virtual HRESULT STDMETHODCALLTYPE DispatchCommand(
- PCSTR commandLine) = 0;
+ PCSTR commandName,
+ PCSTR arguments) = 0;
///
/// Displays the help for a managed extension command
///
- ///
+ ///
/// error code
virtual HRESULT STDMETHODCALLTYPE DisplayHelp(
- PCSTR command) = 0;
+ PCSTR commandName) = 0;
///
/// Uninitialize the extension infrastructure
diff --git a/src/SOS/lldbplugin/services.cpp b/src/SOS/lldbplugin/services.cpp
index c278558289..fde35e73f8 100644
--- a/src/SOS/lldbplugin/services.cpp
+++ b/src/SOS/lldbplugin/services.cpp
@@ -2113,19 +2113,17 @@ class ExtensionCommand : public lldb::SBCommandPluginInterface
result.SetStatus(lldb::eReturnStatusFailed);
return false;
}
- std::string commandLine;
- commandLine.append(m_commandName);
- commandLine.append(" ");
+ std::string commandArguments;
if (arguments != nullptr)
{
- for (const char* arg = *arguments; arg; arg = *(++arguments))
+ for (const char* arg = *arguments; arg != nullptr; arg = *(++arguments))
{
- commandLine.append(arg);
- commandLine.append(" ");
+ commandArguments.append(arg);
+ commandArguments.append(" ");
}
}
g_services->FlushCheck();
- HRESULT hr = hostservices->DispatchCommand(commandLine.c_str());
+ HRESULT hr = hostservices->DispatchCommand(m_commandName, commandArguments.c_str());
if (hr != S_OK)
{
result.SetStatus(lldb::eReturnStatusFailed);
@@ -2784,6 +2782,66 @@ LLDBServices::AddCommand(
return command;
}
+void
+LLDBServices::AddManagedCommand(
+ const char* name,
+ const char* help)
+{
+ HRESULT hr = AddCommand(name, help, nullptr, 0);
+ if (FAILED(hr))
+ {
+ Output(DEBUG_OUTPUT_ERROR, "AddManagedCommand FAILED %08x\n", hr);
+ }
+}
+
+bool
+LLDBServices::ExecuteCommand(
+ const char* commandName,
+ char** arguments,
+ lldb::SBCommandReturnObject &result)
+{
+ // Build all the possible arguments into a string
+ std::string commandArguments;
+ for (const char* arg = *arguments; arg != nullptr; arg = *(++arguments))
+ {
+ commandArguments.append(arg);
+ commandArguments.append(" ");
+ }
+ // Load and initialize the managed extensions and commands before we check the m_commands list.
+ IHostServices* hostservices = GetHostServices();
+
+ // If the command is a native SOS or managed extension command execute it through the lldb command added.
+ if (m_commands.find(commandName) != m_commands.end())
+ {
+ std::string commandLine;
+ commandLine.append(commandName);
+ if (!commandArguments.empty())
+ {
+ commandLine.append(" ");
+ commandLine.append(commandArguments);
+ }
+ lldb::ReturnStatus status = m_interpreter.HandleCommand(commandLine.c_str(), result);
+ result.SetStatus(status);
+ return true;
+ }
+
+ // Fallback to dispatch it as a managed command for those commands that couldn't be added
+ // directly to the lldb interpreter because of existing commands or aliases.
+ if (hostservices != nullptr)
+ {
+ g_services->FlushCheck();
+ HRESULT hr = hostservices->DispatchCommand(commandName, commandArguments.c_str());
+ if (hr != E_NOTIMPL)
+ {
+ result.SetStatus(hr == S_OK ? lldb::eReturnStatusSuccessFinishResult : lldb::eReturnStatusFailed);
+ return true;
+ }
+ }
+
+ // Command not found; attempt dispatch to native SOS module
+ return false;
+}
+
HRESULT
LLDBServices::InternalOutputVaList(
ULONG mask,
diff --git a/src/SOS/lldbplugin/services.h b/src/SOS/lldbplugin/services.h
index 558f30d856..d741ed51eb 100644
--- a/src/SOS/lldbplugin/services.h
+++ b/src/SOS/lldbplugin/services.h
@@ -414,5 +414,9 @@ class LLDBServices : public ILLDBServices, public ILLDBServices2, public IDebugg
lldb::SBCommand AddCommand(const char *name, lldb::SBCommandPluginInterface *impl, const char *help);
+ void AddManagedCommand(const char* name, const char* help);
+
+ bool ExecuteCommand( const char* commandName, char** arguments, lldb::SBCommandReturnObject &result);
+
HRESULT InternalOutputVaList(ULONG mask, PCSTR format, va_list args);
};
diff --git a/src/SOS/lldbplugin/soscommand.cpp b/src/SOS/lldbplugin/soscommand.cpp
index 2ed9a26cf1..d9bee0214f 100644
--- a/src/SOS/lldbplugin/soscommand.cpp
+++ b/src/SOS/lldbplugin/soscommand.cpp
@@ -38,21 +38,27 @@ class sosCommand : public lldb::SBCommandPluginInterface
{
result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
- LoadSos();
-
- if (g_sosHandle != nullptr)
+ const char* sosCommand = m_command;
+ if (sosCommand == nullptr)
{
- const char* sosCommand = m_command;
- if (sosCommand == nullptr)
+ if (arguments == nullptr || *arguments == nullptr)
{
- if (arguments == nullptr || *arguments == nullptr) {
- sosCommand = "Help";
- }
- else
+ sosCommand = "Help";
+ }
+ else
+ {
+ sosCommand = *arguments++;
+ if (g_services->ExecuteCommand(sosCommand, arguments, result))
{
- sosCommand = *arguments++;
+ return result.Succeeded();
}
}
+ }
+
+ LoadSos();
+
+ if (g_sosHandle != nullptr)
+ {
CommandFunc commandFunc = (CommandFunc)dlsym(g_sosHandle, sosCommand);
if (commandFunc)
{
@@ -149,16 +155,16 @@ bool
sosCommandInitialize(lldb::SBDebugger debugger)
{
g_services->AddCommand("sos", new sosCommand(nullptr), "Various .NET Core debugging commands. See 'soshelp' for more details. sos ");
- g_services->AddCommand("ext", new sosCommand("ext"), "Execute extension command. See 'soshelp' for more details. ext ");
+ g_services->AddCommand("ext", new sosCommand(nullptr), "Various .NET Core debugging commands. See 'soshelp' for more details. ext ");
g_services->AddCommand("bpmd", new sosCommand("bpmd"), "Creates a breakpoint at the specified managed method in the specified module.");
- g_services->AddCommand("clrmodules", new sosCommand("clrmodules"), "Lists the managed modules in the process.");
+ g_services->AddManagedCommand("clrmodules", "Lists the managed modules in the process.");
g_services->AddCommand("clrstack", new sosCommand("ClrStack"), "Provides a stack trace of managed code only.");
g_services->AddCommand("clrthreads", new sosCommand("Threads"), "List the managed threads running.");
g_services->AddCommand("clru", new sosCommand("u"), "Displays an annotated disassembly of a managed method.");
g_services->AddCommand("dbgout", new sosCommand("dbgout"), "Enable/disable (-off) internal SOS logging.");
g_services->AddCommand("dumpalc", new sosCommand("DumpALC"), "Displays details about a collectible AssemblyLoadContext to which the specified object is loaded.");
g_services->AddCommand("dumparray", new sosCommand("DumpArray"), "Displays details about a managed array.");
- g_services->AddCommand("dumpasync", new sosCommand("DumpAsync"), "Displays information about async \"stacks\" on the garbage-collected heap.");
+ g_services->AddManagedCommand("dumpasync", "Displays information about async \"stacks\" on the garbage-collected heap.");
g_services->AddCommand("dumpassembly", new sosCommand("DumpAssembly"), "Displays details about an assembly.");
g_services->AddCommand("dumpclass", new sosCommand("DumpClass"), "Displays information about a EE class structure at the specified address.");
g_services->AddCommand("dumpdelegate", new sosCommand("DumpDelegate"), "Displays information about a delegate.");
@@ -198,20 +204,20 @@ sosCommandInitialize(lldb::SBDebugger debugger)
g_services->AddCommand("histstats", new sosCommand("HistStats"), "Displays stress log stats.");
g_services->AddCommand("ip2md", new sosCommand("IP2MD"), "Displays the MethodDesc structure at the specified address in code that has been JIT-compiled.");
g_services->AddCommand("listnearobj", new sosCommand("ListNearObj"), "displays the object preceeding and succeeding the address passed.");
- g_services->AddCommand("loadsymbols", new sosCommand("SetSymbolServer", "-loadsymbols"), "Load the .NET Core native module symbols.");
- g_services->AddCommand("logging", new sosCommand("logging"), "Enable/disable internal SOS logging.");
+ g_services->AddManagedCommand("loadsymbols", "Load the .NET Core native module symbols.");
+ g_services->AddManagedCommand("logging", "Enable/disable internal SOS logging.");
g_services->AddCommand("name2ee", new sosCommand("Name2EE"), "Displays the MethodTable structure and EEClass structure for the specified type or method in the specified module.");
g_services->AddCommand("objsize", new sosCommand("ObjSize"), "Displays the size of the specified object.");
- g_services->AddCommand("pe", new sosCommand("PrintException"), "Displays and formats fields of any object derived from the Exception class at the specified address.");
g_services->AddCommand("pathto", new sosCommand("PathTo"), "Displays the GC path from to .");
+ g_services->AddCommand("pe", new sosCommand("PrintException"), "Displays and formats fields of any object derived from the Exception class at the specified address.");
+ g_services->AddCommand("printexception", new sosCommand("PrintException"), "Displays and formats fields of any object derived from the Exception class at the specified address.");
g_services->AddCommand("runtimes", new sosCommand("runtimes"), "List the runtimes in the target or change the default runtime.");
g_services->AddCommand("stoponcatch", new sosCommand("StopOnCatch"), "Debuggee will break the next time a managed exception is caught during execution");
g_services->AddCommand("setclrpath", new sosCommand("SetClrPath"), "Set the path to load the runtime DAC/DBI files.");
- g_services->AddCommand("setsymbolserver", new sosCommand("SetSymbolServer"), "Enables the symbol server support ");
- g_services->AddCommand("sympath", new sosCommand("SetSymbolServer", "-sympath"), "Add server, cache and directory paths in the Windows symbol path format.");
+ g_services->AddManagedCommand("setsymbolserver", "Enables the symbol server support ");
g_services->AddCommand("soshelp", new sosCommand("Help"), "Displays all available commands when no parameter is specified, or displays detailed help information about the specified command. soshelp ");
- g_services->AddCommand("sosflush", new sosCommand("SOSFlush"), "Flushes the DAC caches.");
g_services->AddCommand("sosstatus", new sosCommand("SOSStatus"), "Displays the global SOS status.");
+ g_services->AddCommand("sosflush", new sosCommand("SOSFlush"), "Flushes the DAC caches.");
g_services->AddCommand("syncblk", new sosCommand("SyncBlk"), "Displays the SyncBlock holder info.");
g_services->AddCommand("threadpool", new sosCommand("ThreadPool"), "Displays info about the runtime thread pool.");
g_services->AddCommand("threadstate", new sosCommand("ThreadState"), "Pretty prints the meaning of a threads state.");
diff --git a/src/Tools/dotnet-dump/Analyzer.cs b/src/Tools/dotnet-dump/Analyzer.cs
index 7532b870df..069e3af3bf 100644
--- a/src/Tools/dotnet-dump/Analyzer.cs
+++ b/src/Tools/dotnet-dump/Analyzer.cs
@@ -58,6 +58,7 @@ public Analyzer()
_commandService.AddCommands(new Assembly[] { typeof(SOSHost).Assembly });
_commandService.AddCommands(typeof(HelpCommand), (services) => new HelpCommand(_commandService, services));
_commandService.AddCommands(typeof(ExitCommand), (services) => new ExitCommand(_consoleProvider.Stop));
+ _commandService.AddCommands(typeof(SOSCommand), (services) => new SOSCommand(_commandService, services));
}
public Task Analyze(FileInfo dump_path, string[] command)
diff --git a/src/Tools/dotnet-dump/Commands/ReadMemoryCommand.cs b/src/Tools/dotnet-dump/Commands/ReadMemoryCommand.cs
index a6f7a25c90..6cf6ec614b 100644
--- a/src/Tools/dotnet-dump/Commands/ReadMemoryCommand.cs
+++ b/src/Tools/dotnet-dump/Commands/ReadMemoryCommand.cs
@@ -6,7 +6,7 @@
using System;
using System.Text;
-namespace Microsoft.Diagnostics.ExtensionCommands
+namespace Microsoft.Diagnostics.Tools.Dump
{
[Command(Name = "readmemory", Aliases = new string[] { "d" }, Help = "Dump memory contents.")]
[Command(Name = "db", DefaultOptions = "--ascii:true --unicode:false --ascii-string:false --unicode-string:false -c:128 -l:1 -w:16", Help = "Dump memory as bytes.")]
diff --git a/src/Tools/dotnet-dump/Commands/SOSCommand.cs b/src/Tools/dotnet-dump/Commands/SOSCommand.cs
new file mode 100644
index 0000000000..4d3a2f4a8f
--- /dev/null
+++ b/src/Tools/dotnet-dump/Commands/SOSCommand.cs
@@ -0,0 +1,60 @@
+// 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 Microsoft.Diagnostics.DebugServices;
+using Microsoft.Diagnostics.DebugServices.Implementation;
+using SOS.Hosting;
+using System;
+using System.Linq;
+
+namespace Microsoft.Diagnostics.Tools.Dump
+{
+ [Command(Name = "sos", Aliases = new string[] { "ext" }, Help = "Run SOS command", Flags = CommandFlags.Global | CommandFlags.Manual)]
+ public class SOSCommand : CommandBase
+ {
+ private readonly CommandService _commandService;
+ private readonly IServiceProvider _services;
+ private SOSHost _sosHost;
+
+ [Argument(Name = "arguments", Help = "SOS command and arguments.")]
+ public string[] Arguments { get; set; }
+
+ public SOSCommand(CommandService commandService, IServiceProvider services)
+ {
+ _commandService = commandService;
+ _services = services;
+ }
+
+ public override void Invoke()
+ {
+ string commandLine;
+ string commandName;
+ if (Arguments != null && Arguments.Length > 0)
+ {
+ commandLine = string.Concat(Arguments.Select((arg) => arg + " ")).Trim();
+ commandName = Arguments[0];
+ }
+ else
+ {
+ commandLine = commandName = "help";
+ }
+ if (_commandService.IsCommand(commandName))
+ {
+ _commandService.Execute(commandLine, _services);
+ }
+ else
+ {
+ if (_sosHost is null)
+ {
+ _sosHost = _services.GetService();
+ if (_sosHost is null)
+ {
+ throw new DiagnosticsException($"'{commandName}' command not found");
+ }
+ }
+ _sosHost.ExecuteCommand(commandLine);
+ }
+ }
+ }
+}
diff --git a/src/shared/inc/clrdata.idl b/src/shared/inc/clrdata.idl
index 0ce58c6fa7..4252dc6409 100644
--- a/src/shared/inc/clrdata.idl
+++ b/src/shared/inc/clrdata.idl
@@ -25,6 +25,7 @@ import "unknwn.idl";
interface ICLRDataEnumMemoryRegions;
interface ICLRDataEnumMemoryRegionsCallback;
interface ICLRDataEnumMemoryRegionsCallback2;
+interface ICLRDataEnumMemoryRegionsCallback3;
interface ICLRDataTarget;
interface ICLRDataTarget2;
interface ICLRMetadataLocator;
@@ -287,6 +288,20 @@ interface ICLRDataEnumMemoryRegionsCallback2 : ICLRDataEnumMemoryRegionsCallback
[in, size_is(bufferSize)] BYTE* buffer);
}
+/*
+ * Optional callback interface for logging EnumMemoryRegions operations and errors.
+ */
+[
+ object,
+ local,
+ uuid(F315248D-8B79-49DB-B184-37426559F703)
+]
+interface ICLRDataEnumMemoryRegionsLoggingCallback : IUnknown
+{
+ HRESULT LogMessage(
+ [in] LPCSTR message);
+}
+
/*
* Flags for controlling which memory regions are enumerated.
*/
diff --git a/src/shared/inc/dumpcommon.h b/src/shared/inc/dumpcommon.h
new file mode 100644
index 0000000000..83a0f447c4
--- /dev/null
+++ b/src/shared/inc/dumpcommon.h
@@ -0,0 +1,136 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#ifndef DEBUGGER_DUMPCOMMON_H
+#define DEBUGGER_DUMPCOMMON_H
+
+#ifdef HOST_UNIX
+typedef enum _MINIDUMP_TYPE {
+ 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,
+ MiniDumpWithAvxXStateContext = 0x00200000,
+ MiniDumpValidTypeFlags = 0x003fffff,
+} MINIDUMP_TYPE;
+#endif // HOST_UNIX
+
+#if defined(DACCESS_COMPILE) || defined(RIGHT_SIDE_COMPILE)
+
+// When debugging against minidumps, we frequently need to ignore errors
+// due to the dump not having memory content.
+// You should be VERY careful using these macros. Because our code does not
+// distinguish target types, when you allow memory to be missing because a dump
+// target may not have that memory content by-design you are also implicitly
+// allowing that same data to be missing from a live debugging target.
+// Also, be aware that these macros exist in code under vm\. You must be careful to
+// only allow them to change execution for DAC and DBI.
+// Be careful state is such that execution can continue if the target is missing
+// memory.
+// In general, there are two solutions to this problem:
+// a) add the memory to all minidumps
+// b) stop forcing the memory to always be present
+// All decisions between a & b focus on cost. For a, cost is adding the memory & a complete
+// path to locate it to the dump, both in terms of dump generation time and most
+// especially in terms of dump size (we cannot make MiniDumpNormal many MB for trivial
+// apps).
+// For b, cost is that we lose some of our validation when we have to turn off asserts
+// and other checks for targets that should always have the missing memory present
+// because we have no concept of allowing it to be missing only from a dump.
+
+// This seemingly awkward try block starting tag is so that when the macro is used over
+// multiple source lines we don't create a useless try/catch block. This is important
+// when using the macros in vm\ code.
+#define EX_TRY_ALLOW_DATATARGET_MISSING_MEMORY EX_TRY
+#define EX_END_CATCH_ALLOW_DATATARGET_MISSING_MEMORY \
+ EX_CATCH \
+ { \
+ if ((GET_EXCEPTION()->GetHR() != HRESULT_FROM_WIN32(ERROR_PARTIAL_COPY)) && \
+ (GET_EXCEPTION()->GetHR() != CORDBG_E_READVIRTUAL_FAILURE) ) \
+ { \
+ EX_RETHROW; \
+ } \
+ } \
+ EX_END_CATCH(SwallowAllExceptions)
+
+#define EX_TRY_ALLOW_DATATARGET_MISSING_MEMORY_WITH_HANDLER EX_TRY
+#define EX_CATCH_ALLOW_DATATARGET_MISSING_MEMORY_WITH_HANDLER \
+ EX_CATCH \
+ { \
+ if ((GET_EXCEPTION()->GetHR() != HRESULT_FROM_WIN32(ERROR_PARTIAL_COPY)) && \
+ (GET_EXCEPTION()->GetHR() != CORDBG_E_READVIRTUAL_FAILURE) ) \
+ { \
+ EX_RETHROW; \
+ } \
+ else \
+
+#define EX_TRY_ALLOW_DATATARGET_MISSING_OR_INCONSISTENT_MEMORY EX_TRY
+#define EX_END_CATCH_ALLOW_DATATARGET_MISSING_OR_INCONSISTENT_MEMORY \
+ EX_CATCH \
+ { \
+ if ((GET_EXCEPTION()->GetHR() != HRESULT_FROM_WIN32(ERROR_PARTIAL_COPY)) && \
+ (GET_EXCEPTION()->GetHR() != CORDBG_E_READVIRTUAL_FAILURE) && \
+ (GET_EXCEPTION()->GetHR() != CORDBG_E_TARGET_INCONSISTENT)) \
+ { \
+ EX_RETHROW; \
+ } \
+ } \
+ EX_END_CATCH(SwallowAllExceptions)
+
+
+#define EX_END_CATCH_ALLOW_DATATARGET_MISSING_MEMORY_WITH_HANDLER \
+ } \
+ EX_END_CATCH(SwallowAllExceptions)
+
+// Only use this version for wrapping single source lines, or you'll make debugging
+// painful.
+#define ALLOW_DATATARGET_MISSING_MEMORY(sourceCode) \
+ EX_TRY \
+ { \
+ sourceCode \
+ } \
+ EX_END_CATCH_ALLOW_DATATARGET_MISSING_MEMORY
+
+#define ALLOW_DATATARGET_MISSING_OR_INCONSISTENT_MEMORY(sourceCode) \
+ EX_TRY \
+ { \
+ sourceCode \
+ } \
+ EX_END_CATCH_ALLOW_DATATARGET_MISSING_OR_INCONSISTENT_MEMORY
+
+#else
+#define EX_TRY_ALLOW_DATATARGET_MISSING_MEMORY
+#define EX_END_CATCH_ALLOW_DATATARGET_MISSING_MEMORY
+#define EX_TRY_ALLOW_DATATARGET_MISSING_MEMORY_WITH_HANDLER \
+ #error This macro is only intended for use in DAC code!
+#define EX_CATCH_ALLOW_DATATARGET_MISSING_MEMORY_WITH_HANDLER \
+ #error This macro is only intended for use in DAC code!
+#define EX_END_CATCH_ALLOW_DATATARGET_MISSING_MEMORY_WITH_HANDLER \
+ #error This macro is only intended for use in DAC code!
+
+
+#define ALLOW_DATATARGET_MISSING_MEMORY(sourceCode) \
+ sourceCode
+
+#endif // defined(DACCESS_COMPILE) || defined(RIGHT_SIDE_COMPILE)
+
+
+#endif //DEBUGGER_DUMPCOMMON_H
diff --git a/src/shared/pal/prebuilt/idl/clrdata_i.cpp b/src/shared/pal/prebuilt/idl/clrdata_i.cpp
index 7d6b61a14f..872841a0d9 100644
--- a/src/shared/pal/prebuilt/idl/clrdata_i.cpp
+++ b/src/shared/pal/prebuilt/idl/clrdata_i.cpp
@@ -1,16 +1,13 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
+
/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */
/* link this file in with the server and any clients */
- /* File created by MIDL compiler version 8.01.0622 */
-/* at Mon Jan 18 19:14:07 2038
- */
-/* Compiler settings for C:/ssd/runtime/src/coreclr/inc/clrdata.idl:
- Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.01.0622
+ /* File created by MIDL compiler version 8.01.0626 */
+/* Compiler settings for clrdata.idl:
+ Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.01.0626
protocol : dce , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
@@ -89,6 +86,9 @@ MIDL_DEFINE_GUID(IID, IID_ICLRDataEnumMemoryRegionsCallback,0xBCDD6908,0xBA2D,0x
MIDL_DEFINE_GUID(IID, IID_ICLRDataEnumMemoryRegionsCallback2,0x3721A26F,0x8B91,0x4D98,0xA3,0x88,0xDB,0x17,0xB3,0x56,0xFA,0xDB);
+MIDL_DEFINE_GUID(IID, IID_ICLRDataEnumMemoryRegionsLoggingCallback,0xF315248D,0x8B79,0x49DB,0xB1,0x84,0x37,0x42,0x65,0x59,0xF7,0x03);
+
+
MIDL_DEFINE_GUID(IID, IID_ICLRDataEnumMemoryRegions,0x471c35b4,0x7c2f,0x4ef0,0xa9,0x45,0x00,0xf8,0xc3,0x80,0x56,0xf1);
#undef MIDL_DEFINE_GUID
diff --git a/src/shared/pal/prebuilt/inc/clrdata.h b/src/shared/pal/prebuilt/inc/clrdata.h
index 29f72974c5..3999908b26 100644
--- a/src/shared/pal/prebuilt/inc/clrdata.h
+++ b/src/shared/pal/prebuilt/inc/clrdata.h
@@ -1,14 +1,11 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
+
/* this ALWAYS GENERATED file contains the definitions for the interfaces */
- /* File created by MIDL compiler version 8.01.0622 */
-/* at Mon Jan 18 19:14:07 2038
- */
-/* Compiler settings for C:/ssd/runtime/src/coreclr/inc/clrdata.idl:
- Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.01.0622
+ /* File created by MIDL compiler version 8.01.0626 */
+/* Compiler settings for clrdata.idl:
+ Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.01.0626
protocol : dce , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
@@ -44,6 +41,14 @@
#pragma once
#endif
+#ifndef DECLSPEC_XFGVIRT
+#if _CONTROL_FLOW_GUARD_XFG
+#define DECLSPEC_XFGVIRT(base, func) __declspec(xfg_virtual(base, func))
+#else
+#define DECLSPEC_XFGVIRT(base, func)
+#endif
+#endif
+
/* Forward Declarations */
#ifndef __ICLRDataTarget_FWD_DEFINED__
@@ -95,6 +100,13 @@ typedef interface ICLRDataEnumMemoryRegionsCallback2 ICLRDataEnumMemoryRegionsCa
#endif /* __ICLRDataEnumMemoryRegionsCallback2_FWD_DEFINED__ */
+#ifndef __ICLRDataEnumMemoryRegionsLoggingCallback_FWD_DEFINED__
+#define __ICLRDataEnumMemoryRegionsLoggingCallback_FWD_DEFINED__
+typedef interface ICLRDataEnumMemoryRegionsLoggingCallback ICLRDataEnumMemoryRegionsLoggingCallback;
+
+#endif /* __ICLRDataEnumMemoryRegionsLoggingCallback_FWD_DEFINED__ */
+
+
#ifndef __ICLRDataEnumMemoryRegions_FWD_DEFINED__
#define __ICLRDataEnumMemoryRegions_FWD_DEFINED__
typedef interface ICLRDataEnumMemoryRegions ICLRDataEnumMemoryRegions;
@@ -119,6 +131,7 @@ extern "C"{
+
typedef ULONG64 CLRDATA_ADDRESS;
STDAPI CLRDataCreateInstance(REFIID iid, ICLRDataTarget* target, void** iface);
@@ -205,31 +218,38 @@ EXTERN_C const IID IID_ICLRDataTarget;
{
BEGIN_INTERFACE
+ DECLSPEC_XFGVIRT(IUnknown, QueryInterface)
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
ICLRDataTarget * This,
/* [in] */ REFIID riid,
/* [annotation][iid_is][out] */
_COM_Outptr_ void **ppvObject);
+ DECLSPEC_XFGVIRT(IUnknown, AddRef)
ULONG ( STDMETHODCALLTYPE *AddRef )(
ICLRDataTarget * This);
+ DECLSPEC_XFGVIRT(IUnknown, Release)
ULONG ( STDMETHODCALLTYPE *Release )(
ICLRDataTarget * This);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, GetMachineType)
HRESULT ( STDMETHODCALLTYPE *GetMachineType )(
ICLRDataTarget * This,
/* [out] */ ULONG32 *machineType);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, GetPointerSize)
HRESULT ( STDMETHODCALLTYPE *GetPointerSize )(
ICLRDataTarget * This,
/* [out] */ ULONG32 *pointerSize);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, GetImageBase)
HRESULT ( STDMETHODCALLTYPE *GetImageBase )(
ICLRDataTarget * This,
/* [string][in] */ LPCWSTR imagePath,
/* [out] */ CLRDATA_ADDRESS *baseAddress);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, ReadVirtual)
HRESULT ( STDMETHODCALLTYPE *ReadVirtual )(
ICLRDataTarget * This,
/* [in] */ CLRDATA_ADDRESS address,
@@ -237,6 +257,7 @@ EXTERN_C const IID IID_ICLRDataTarget;
/* [in] */ ULONG32 bytesRequested,
/* [out] */ ULONG32 *bytesRead);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, WriteVirtual)
HRESULT ( STDMETHODCALLTYPE *WriteVirtual )(
ICLRDataTarget * This,
/* [in] */ CLRDATA_ADDRESS address,
@@ -244,22 +265,26 @@ EXTERN_C const IID IID_ICLRDataTarget;
/* [in] */ ULONG32 bytesRequested,
/* [out] */ ULONG32 *bytesWritten);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, GetTLSValue)
HRESULT ( STDMETHODCALLTYPE *GetTLSValue )(
ICLRDataTarget * This,
/* [in] */ ULONG32 threadID,
/* [in] */ ULONG32 index,
/* [out] */ CLRDATA_ADDRESS *value);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, SetTLSValue)
HRESULT ( STDMETHODCALLTYPE *SetTLSValue )(
ICLRDataTarget * This,
/* [in] */ ULONG32 threadID,
/* [in] */ ULONG32 index,
/* [in] */ CLRDATA_ADDRESS value);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, GetCurrentThreadID)
HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )(
ICLRDataTarget * This,
/* [out] */ ULONG32 *threadID);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, GetThreadContext)
HRESULT ( STDMETHODCALLTYPE *GetThreadContext )(
ICLRDataTarget * This,
/* [in] */ ULONG32 threadID,
@@ -267,12 +292,14 @@ EXTERN_C const IID IID_ICLRDataTarget;
/* [in] */ ULONG32 contextSize,
/* [size_is][out] */ BYTE *context);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, SetThreadContext)
HRESULT ( STDMETHODCALLTYPE *SetThreadContext )(
ICLRDataTarget * This,
/* [in] */ ULONG32 threadID,
/* [in] */ ULONG32 contextSize,
/* [size_is][in] */ BYTE *context);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, Request)
HRESULT ( STDMETHODCALLTYPE *Request )(
ICLRDataTarget * This,
/* [in] */ ULONG32 reqCode,
@@ -384,31 +411,38 @@ EXTERN_C const IID IID_ICLRDataTarget2;
{
BEGIN_INTERFACE
+ DECLSPEC_XFGVIRT(IUnknown, QueryInterface)
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
ICLRDataTarget2 * This,
/* [in] */ REFIID riid,
/* [annotation][iid_is][out] */
_COM_Outptr_ void **ppvObject);
+ DECLSPEC_XFGVIRT(IUnknown, AddRef)
ULONG ( STDMETHODCALLTYPE *AddRef )(
ICLRDataTarget2 * This);
+ DECLSPEC_XFGVIRT(IUnknown, Release)
ULONG ( STDMETHODCALLTYPE *Release )(
ICLRDataTarget2 * This);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, GetMachineType)
HRESULT ( STDMETHODCALLTYPE *GetMachineType )(
ICLRDataTarget2 * This,
/* [out] */ ULONG32 *machineType);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, GetPointerSize)
HRESULT ( STDMETHODCALLTYPE *GetPointerSize )(
ICLRDataTarget2 * This,
/* [out] */ ULONG32 *pointerSize);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, GetImageBase)
HRESULT ( STDMETHODCALLTYPE *GetImageBase )(
ICLRDataTarget2 * This,
/* [string][in] */ LPCWSTR imagePath,
/* [out] */ CLRDATA_ADDRESS *baseAddress);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, ReadVirtual)
HRESULT ( STDMETHODCALLTYPE *ReadVirtual )(
ICLRDataTarget2 * This,
/* [in] */ CLRDATA_ADDRESS address,
@@ -416,6 +450,7 @@ EXTERN_C const IID IID_ICLRDataTarget2;
/* [in] */ ULONG32 bytesRequested,
/* [out] */ ULONG32 *bytesRead);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, WriteVirtual)
HRESULT ( STDMETHODCALLTYPE *WriteVirtual )(
ICLRDataTarget2 * This,
/* [in] */ CLRDATA_ADDRESS address,
@@ -423,22 +458,26 @@ EXTERN_C const IID IID_ICLRDataTarget2;
/* [in] */ ULONG32 bytesRequested,
/* [out] */ ULONG32 *bytesWritten);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, GetTLSValue)
HRESULT ( STDMETHODCALLTYPE *GetTLSValue )(
ICLRDataTarget2 * This,
/* [in] */ ULONG32 threadID,
/* [in] */ ULONG32 index,
/* [out] */ CLRDATA_ADDRESS *value);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, SetTLSValue)
HRESULT ( STDMETHODCALLTYPE *SetTLSValue )(
ICLRDataTarget2 * This,
/* [in] */ ULONG32 threadID,
/* [in] */ ULONG32 index,
/* [in] */ CLRDATA_ADDRESS value);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, GetCurrentThreadID)
HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )(
ICLRDataTarget2 * This,
/* [out] */ ULONG32 *threadID);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, GetThreadContext)
HRESULT ( STDMETHODCALLTYPE *GetThreadContext )(
ICLRDataTarget2 * This,
/* [in] */ ULONG32 threadID,
@@ -446,12 +485,14 @@ EXTERN_C const IID IID_ICLRDataTarget2;
/* [in] */ ULONG32 contextSize,
/* [size_is][out] */ BYTE *context);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, SetThreadContext)
HRESULT ( STDMETHODCALLTYPE *SetThreadContext )(
ICLRDataTarget2 * This,
/* [in] */ ULONG32 threadID,
/* [in] */ ULONG32 contextSize,
/* [size_is][in] */ BYTE *context);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, Request)
HRESULT ( STDMETHODCALLTYPE *Request )(
ICLRDataTarget2 * This,
/* [in] */ ULONG32 reqCode,
@@ -460,6 +501,7 @@ EXTERN_C const IID IID_ICLRDataTarget2;
/* [in] */ ULONG32 outBufferSize,
/* [size_is][out] */ BYTE *outBuffer);
+ DECLSPEC_XFGVIRT(ICLRDataTarget2, AllocVirtual)
HRESULT ( STDMETHODCALLTYPE *AllocVirtual )(
ICLRDataTarget2 * This,
/* [in] */ CLRDATA_ADDRESS addr,
@@ -468,6 +510,7 @@ EXTERN_C const IID IID_ICLRDataTarget2;
/* [in] */ ULONG32 protectFlags,
/* [out] */ CLRDATA_ADDRESS *virt);
+ DECLSPEC_XFGVIRT(ICLRDataTarget2, FreeVirtual)
HRESULT ( STDMETHODCALLTYPE *FreeVirtual )(
ICLRDataTarget2 * This,
/* [in] */ CLRDATA_ADDRESS addr,
@@ -585,31 +628,38 @@ EXTERN_C const IID IID_ICLRDataTarget3;
{
BEGIN_INTERFACE
+ DECLSPEC_XFGVIRT(IUnknown, QueryInterface)
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
ICLRDataTarget3 * This,
/* [in] */ REFIID riid,
/* [annotation][iid_is][out] */
_COM_Outptr_ void **ppvObject);
+ DECLSPEC_XFGVIRT(IUnknown, AddRef)
ULONG ( STDMETHODCALLTYPE *AddRef )(
ICLRDataTarget3 * This);
+ DECLSPEC_XFGVIRT(IUnknown, Release)
ULONG ( STDMETHODCALLTYPE *Release )(
ICLRDataTarget3 * This);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, GetMachineType)
HRESULT ( STDMETHODCALLTYPE *GetMachineType )(
ICLRDataTarget3 * This,
/* [out] */ ULONG32 *machineType);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, GetPointerSize)
HRESULT ( STDMETHODCALLTYPE *GetPointerSize )(
ICLRDataTarget3 * This,
/* [out] */ ULONG32 *pointerSize);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, GetImageBase)
HRESULT ( STDMETHODCALLTYPE *GetImageBase )(
ICLRDataTarget3 * This,
/* [string][in] */ LPCWSTR imagePath,
/* [out] */ CLRDATA_ADDRESS *baseAddress);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, ReadVirtual)
HRESULT ( STDMETHODCALLTYPE *ReadVirtual )(
ICLRDataTarget3 * This,
/* [in] */ CLRDATA_ADDRESS address,
@@ -617,6 +667,7 @@ EXTERN_C const IID IID_ICLRDataTarget3;
/* [in] */ ULONG32 bytesRequested,
/* [out] */ ULONG32 *bytesRead);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, WriteVirtual)
HRESULT ( STDMETHODCALLTYPE *WriteVirtual )(
ICLRDataTarget3 * This,
/* [in] */ CLRDATA_ADDRESS address,
@@ -624,22 +675,26 @@ EXTERN_C const IID IID_ICLRDataTarget3;
/* [in] */ ULONG32 bytesRequested,
/* [out] */ ULONG32 *bytesWritten);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, GetTLSValue)
HRESULT ( STDMETHODCALLTYPE *GetTLSValue )(
ICLRDataTarget3 * This,
/* [in] */ ULONG32 threadID,
/* [in] */ ULONG32 index,
/* [out] */ CLRDATA_ADDRESS *value);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, SetTLSValue)
HRESULT ( STDMETHODCALLTYPE *SetTLSValue )(
ICLRDataTarget3 * This,
/* [in] */ ULONG32 threadID,
/* [in] */ ULONG32 index,
/* [in] */ CLRDATA_ADDRESS value);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, GetCurrentThreadID)
HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )(
ICLRDataTarget3 * This,
/* [out] */ ULONG32 *threadID);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, GetThreadContext)
HRESULT ( STDMETHODCALLTYPE *GetThreadContext )(
ICLRDataTarget3 * This,
/* [in] */ ULONG32 threadID,
@@ -647,12 +702,14 @@ EXTERN_C const IID IID_ICLRDataTarget3;
/* [in] */ ULONG32 contextSize,
/* [size_is][out] */ BYTE *context);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, SetThreadContext)
HRESULT ( STDMETHODCALLTYPE *SetThreadContext )(
ICLRDataTarget3 * This,
/* [in] */ ULONG32 threadID,
/* [in] */ ULONG32 contextSize,
/* [size_is][in] */ BYTE *context);
+ DECLSPEC_XFGVIRT(ICLRDataTarget, Request)
HRESULT ( STDMETHODCALLTYPE *Request )(
ICLRDataTarget3 * This,
/* [in] */ ULONG32 reqCode,
@@ -661,6 +718,7 @@ EXTERN_C const IID IID_ICLRDataTarget3;
/* [in] */ ULONG32 outBufferSize,
/* [size_is][out] */ BYTE *outBuffer);
+ DECLSPEC_XFGVIRT(ICLRDataTarget2, AllocVirtual)
HRESULT ( STDMETHODCALLTYPE *AllocVirtual )(
ICLRDataTarget3 * This,
/* [in] */ CLRDATA_ADDRESS addr,
@@ -669,24 +727,28 @@ EXTERN_C const IID IID_ICLRDataTarget3;
/* [in] */ ULONG32 protectFlags,
/* [out] */ CLRDATA_ADDRESS *virt);
+ DECLSPEC_XFGVIRT(ICLRDataTarget2, FreeVirtual)
HRESULT ( STDMETHODCALLTYPE *FreeVirtual )(
ICLRDataTarget3 * This,
/* [in] */ CLRDATA_ADDRESS addr,
/* [in] */ ULONG32 size,
/* [in] */ ULONG32 typeFlags);
+ DECLSPEC_XFGVIRT(ICLRDataTarget3, GetExceptionRecord)
HRESULT ( STDMETHODCALLTYPE *GetExceptionRecord )(
ICLRDataTarget3 * This,
/* [in] */ ULONG32 bufferSize,
/* [out] */ ULONG32 *bufferUsed,
/* [size_is][out] */ BYTE *buffer);
+ DECLSPEC_XFGVIRT(ICLRDataTarget3, GetExceptionContextRecord)
HRESULT ( STDMETHODCALLTYPE *GetExceptionContextRecord )(
ICLRDataTarget3 * This,
/* [in] */ ULONG32 bufferSize,
/* [out] */ ULONG32 *bufferUsed,
/* [size_is][out] */ BYTE *buffer);
+ DECLSPEC_XFGVIRT(ICLRDataTarget3, GetExceptionThreadID)
HRESULT ( STDMETHODCALLTYPE *GetExceptionThreadID )(
ICLRDataTarget3 * This,
/* [out] */ ULONG32 *threadID);
@@ -802,18 +864,22 @@ EXTERN_C const IID IID_ICLRRuntimeLocator;
{
BEGIN_INTERFACE
+ DECLSPEC_XFGVIRT(IUnknown, QueryInterface)
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
ICLRRuntimeLocator * This,
/* [in] */ REFIID riid,
/* [annotation][iid_is][out] */
_COM_Outptr_ void **ppvObject);
+ DECLSPEC_XFGVIRT(IUnknown, AddRef)
ULONG ( STDMETHODCALLTYPE *AddRef )(
ICLRRuntimeLocator * This);
+ DECLSPEC_XFGVIRT(IUnknown, Release)
ULONG ( STDMETHODCALLTYPE *Release )(
ICLRRuntimeLocator * This);
+ DECLSPEC_XFGVIRT(ICLRRuntimeLocator, GetRuntimeBase)
HRESULT ( STDMETHODCALLTYPE *GetRuntimeBase )(
ICLRRuntimeLocator * This,
/* [out] */ CLRDATA_ADDRESS *baseAddress);
@@ -890,18 +956,22 @@ EXTERN_C const IID IID_ICLRMetadataLocator;
{
BEGIN_INTERFACE
+ DECLSPEC_XFGVIRT(IUnknown, QueryInterface)
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
ICLRMetadataLocator * This,
/* [in] */ REFIID riid,
/* [annotation][iid_is][out] */
_COM_Outptr_ void **ppvObject);
+ DECLSPEC_XFGVIRT(IUnknown, AddRef)
ULONG ( STDMETHODCALLTYPE *AddRef )(
ICLRMetadataLocator * This);
+ DECLSPEC_XFGVIRT(IUnknown, Release)
ULONG ( STDMETHODCALLTYPE *Release )(
ICLRMetadataLocator * This);
+ DECLSPEC_XFGVIRT(ICLRMetadataLocator, GetMetadata)
HRESULT ( STDMETHODCALLTYPE *GetMetadata )(
ICLRMetadataLocator * This,
/* [in] */ LPCWSTR imagePath,
@@ -979,18 +1049,22 @@ EXTERN_C const IID IID_ICLRDataEnumMemoryRegionsCallback;
{
BEGIN_INTERFACE
+ DECLSPEC_XFGVIRT(IUnknown, QueryInterface)
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
ICLRDataEnumMemoryRegionsCallback * This,
/* [in] */ REFIID riid,
/* [annotation][iid_is][out] */
_COM_Outptr_ void **ppvObject);
+ DECLSPEC_XFGVIRT(IUnknown, AddRef)
ULONG ( STDMETHODCALLTYPE *AddRef )(
ICLRDataEnumMemoryRegionsCallback * This);
+ DECLSPEC_XFGVIRT(IUnknown, Release)
ULONG ( STDMETHODCALLTYPE *Release )(
ICLRDataEnumMemoryRegionsCallback * This);
+ DECLSPEC_XFGVIRT(ICLRDataEnumMemoryRegionsCallback, EnumMemoryRegion)
HRESULT ( STDMETHODCALLTYPE *EnumMemoryRegion )(
ICLRDataEnumMemoryRegionsCallback * This,
/* [in] */ CLRDATA_ADDRESS address,
@@ -1062,23 +1136,28 @@ EXTERN_C const IID IID_ICLRDataEnumMemoryRegionsCallback2;
{
BEGIN_INTERFACE
+ DECLSPEC_XFGVIRT(IUnknown, QueryInterface)
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
ICLRDataEnumMemoryRegionsCallback2 * This,
/* [in] */ REFIID riid,
/* [annotation][iid_is][out] */
_COM_Outptr_ void **ppvObject);
+ DECLSPEC_XFGVIRT(IUnknown, AddRef)
ULONG ( STDMETHODCALLTYPE *AddRef )(
ICLRDataEnumMemoryRegionsCallback2 * This);
+ DECLSPEC_XFGVIRT(IUnknown, Release)
ULONG ( STDMETHODCALLTYPE *Release )(
ICLRDataEnumMemoryRegionsCallback2 * This);
+ DECLSPEC_XFGVIRT(ICLRDataEnumMemoryRegionsCallback, EnumMemoryRegion)
HRESULT ( STDMETHODCALLTYPE *EnumMemoryRegion )(
ICLRDataEnumMemoryRegionsCallback2 * This,
/* [in] */ CLRDATA_ADDRESS address,
/* [in] */ ULONG32 size);
+ DECLSPEC_XFGVIRT(ICLRDataEnumMemoryRegionsCallback2, UpdateMemoryRegion)
HRESULT ( STDMETHODCALLTYPE *UpdateMemoryRegion )(
ICLRDataEnumMemoryRegionsCallback2 * This,
/* [in] */ CLRDATA_ADDRESS address,
@@ -1126,7 +1205,91 @@ EXTERN_C const IID IID_ICLRDataEnumMemoryRegionsCallback2;
#endif /* __ICLRDataEnumMemoryRegionsCallback2_INTERFACE_DEFINED__ */
-/* interface __MIDL_itf_clrdata_0000_0007 */
+#ifndef __ICLRDataEnumMemoryRegionsLoggingCallback_INTERFACE_DEFINED__
+#define __ICLRDataEnumMemoryRegionsLoggingCallback_INTERFACE_DEFINED__
+
+/* interface ICLRDataEnumMemoryRegionsLoggingCallback */
+/* [uuid][local][object] */
+
+
+EXTERN_C const IID IID_ICLRDataEnumMemoryRegionsLoggingCallback;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("F315248D-8B79-49DB-B184-37426559F703")
+ ICLRDataEnumMemoryRegionsLoggingCallback : public IUnknown
+ {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE LogMessage(
+ /* [in] */ LPCSTR message) = 0;
+
+ };
+
+
+#else /* C style interface */
+
+ typedef struct ICLRDataEnumMemoryRegionsLoggingCallbackVtbl
+ {
+ BEGIN_INTERFACE
+
+ DECLSPEC_XFGVIRT(IUnknown, QueryInterface)
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ ICLRDataEnumMemoryRegionsLoggingCallback * This,
+ /* [in] */ REFIID riid,
+ /* [annotation][iid_is][out] */
+ _COM_Outptr_ void **ppvObject);
+
+ DECLSPEC_XFGVIRT(IUnknown, AddRef)
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ ICLRDataEnumMemoryRegionsLoggingCallback * This);
+
+ DECLSPEC_XFGVIRT(IUnknown, Release)
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ ICLRDataEnumMemoryRegionsLoggingCallback * This);
+
+ DECLSPEC_XFGVIRT(ICLRDataEnumMemoryRegionsLoggingCallback, LogMessage)
+ HRESULT ( STDMETHODCALLTYPE *LogMessage )(
+ ICLRDataEnumMemoryRegionsLoggingCallback * This,
+ /* [in] */ LPCSTR message);
+
+ END_INTERFACE
+ } ICLRDataEnumMemoryRegionsLoggingCallbackVtbl;
+
+ interface ICLRDataEnumMemoryRegionsLoggingCallback
+ {
+ CONST_VTBL struct ICLRDataEnumMemoryRegionsLoggingCallbackVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define ICLRDataEnumMemoryRegionsLoggingCallback_QueryInterface(This,riid,ppvObject) \
+ ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
+
+#define ICLRDataEnumMemoryRegionsLoggingCallback_AddRef(This) \
+ ( (This)->lpVtbl -> AddRef(This) )
+
+#define ICLRDataEnumMemoryRegionsLoggingCallback_Release(This) \
+ ( (This)->lpVtbl -> Release(This) )
+
+
+#define ICLRDataEnumMemoryRegionsLoggingCallback_LogMessage(This,message) \
+ ( (This)->lpVtbl -> LogMessage(This,message) )
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+
+#endif /* __ICLRDataEnumMemoryRegionsLoggingCallback_INTERFACE_DEFINED__ */
+
+
+/* interface __MIDL_itf_clrdata_0000_0008 */
/* [local] */
typedef
@@ -1140,8 +1303,8 @@ enum CLRDataEnumMemoryFlags
-extern RPC_IF_HANDLE __MIDL_itf_clrdata_0000_0007_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_clrdata_0000_0007_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_clrdata_0000_0008_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_clrdata_0000_0008_v0_0_s_ifspec;
#ifndef __ICLRDataEnumMemoryRegions_INTERFACE_DEFINED__
#define __ICLRDataEnumMemoryRegions_INTERFACE_DEFINED__
@@ -1172,18 +1335,22 @@ EXTERN_C const IID IID_ICLRDataEnumMemoryRegions;
{
BEGIN_INTERFACE
+ DECLSPEC_XFGVIRT(IUnknown, QueryInterface)
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
ICLRDataEnumMemoryRegions * This,
/* [in] */ REFIID riid,
/* [annotation][iid_is][out] */
_COM_Outptr_ void **ppvObject);
+ DECLSPEC_XFGVIRT(IUnknown, AddRef)
ULONG ( STDMETHODCALLTYPE *AddRef )(
ICLRDataEnumMemoryRegions * This);
+ DECLSPEC_XFGVIRT(IUnknown, Release)
ULONG ( STDMETHODCALLTYPE *Release )(
ICLRDataEnumMemoryRegions * This);
+ DECLSPEC_XFGVIRT(ICLRDataEnumMemoryRegions, EnumMemoryRegions)
HRESULT ( STDMETHODCALLTYPE *EnumMemoryRegions )(
ICLRDataEnumMemoryRegions * This,
/* [in] */ ICLRDataEnumMemoryRegionsCallback *callback,