@@ -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