Skip to content

Commit 604d561

Browse files
committed
Fix ClrMD attach to self process in non-windows.
1 parent b5386bd commit 604d561

File tree

1 file changed

+31
-32
lines changed

1 file changed

+31
-32
lines changed

src/BenchmarkDotNet/Disassemblers/ClrMdDisassembler.cs

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -73,45 +73,44 @@ private static bool IsValidAddress(ulong address)
7373

7474
internal DisassemblyResult AttachAndDisassemble(ClrMdArgs settings)
7575
{
76-
using (var dataTarget = DataTarget.AttachToProcess(
77-
settings.ProcessId,
78-
suspend: false))
79-
{
80-
var runtime = dataTarget.ClrVersions.Single().CreateRuntime();
76+
using var dataTarget = settings.ProcessId == System.Diagnostics.Process.GetCurrentProcess().Id
77+
? DataTarget.CreateSnapshotAndAttach(settings.ProcessId)
78+
: DataTarget.AttachToProcess(settings.ProcessId, suspend: false);
8179

82-
ConfigureSymbols(dataTarget);
80+
var runtime = dataTarget.ClrVersions.Single().CreateRuntime();
8381

84-
var state = new State(runtime, settings.TargetFrameworkMoniker);
82+
ConfigureSymbols(dataTarget);
8583

86-
if (settings.Filters.Length > 0)
87-
{
88-
FilterAndEnqueue(state, settings);
89-
}
90-
else
91-
{
92-
ClrType typeWithBenchmark = state.Runtime.EnumerateModules().Select(module => module.GetTypeByName(settings.TypeName)).First(type => type != null);
84+
var state = new State(runtime, settings.TargetFrameworkMoniker);
9385

94-
state.Todo.Enqueue(
95-
new MethodInfo(
96-
// the Disassembler Entry Method is always parameterless, so check by name is enough
97-
typeWithBenchmark.Methods.Single(method => method.Attributes.HasFlag(System.Reflection.MethodAttributes.Public) && method.Name == settings.MethodName),
98-
0));
99-
}
86+
if (settings.Filters.Length > 0)
87+
{
88+
FilterAndEnqueue(state, settings);
89+
}
90+
else
91+
{
92+
ClrType typeWithBenchmark = state.Runtime.EnumerateModules().Select(module => module.GetTypeByName(settings.TypeName)).First(type => type != null);
10093

101-
var disassembledMethods = Disassemble(settings, state);
94+
state.Todo.Enqueue(
95+
new MethodInfo(
96+
// the Disassembler Entry Method is always parameterless, so check by name is enough
97+
typeWithBenchmark.Methods.Single(method => method.Attributes.HasFlag(System.Reflection.MethodAttributes.Public) && method.Name == settings.MethodName),
98+
0));
99+
}
102100

103-
// we don't want to export the disassembler entry point method which is just an artificial method added to get generic types working
104-
var filteredMethods = disassembledMethods.Length == 1
105-
? disassembledMethods // if there is only one method we want to return it (most probably benchmark got inlined)
106-
: disassembledMethods.Where(method => !method.Name.Contains(DisassemblerConstants.DisassemblerEntryMethodName)).ToArray();
101+
var disassembledMethods = Disassemble(settings, state);
107102

108-
return new DisassemblyResult
109-
{
110-
Methods = filteredMethods,
111-
SerializedAddressToNameMapping = state.AddressToNameMapping.Select(x => new DisassemblyResult.MutablePair { Key = x.Key, Value = x.Value }).ToArray(),
112-
PointerSize = (uint)IntPtr.Size
113-
};
114-
}
103+
// we don't want to export the disassembler entry point method which is just an artificial method added to get generic types working
104+
var filteredMethods = disassembledMethods.Length == 1
105+
? disassembledMethods // if there is only one method we want to return it (most probably benchmark got inlined)
106+
: disassembledMethods.Where(method => !method.Name.Contains(DisassemblerConstants.DisassemblerEntryMethodName)).ToArray();
107+
108+
return new DisassemblyResult
109+
{
110+
Methods = filteredMethods,
111+
SerializedAddressToNameMapping = state.AddressToNameMapping.Select(x => new DisassemblyResult.MutablePair { Key = x.Key, Value = x.Value }).ToArray(),
112+
PointerSize = (uint) IntPtr.Size
113+
};
115114
}
116115

117116
private static void ConfigureSymbols(DataTarget dataTarget)

0 commit comments

Comments
 (0)