8
8
using System . Linq ;
9
9
using System . Text . RegularExpressions ;
10
10
using BenchmarkDotNet . Portability ;
11
+ using BenchmarkDotNet . Helpers ;
11
12
12
13
namespace BenchmarkDotNet . Disassemblers
13
14
{
14
15
// This Disassembler uses ClrMd v2x. Please keep it in sync with ClrMdV1Disassembler (if possible).
15
16
internal abstract class ClrMdV2Disassembler
16
17
{
18
+ private static readonly ulong MinValidAddress = GetMinValidAddress ( ) ;
19
+
20
+ private static ulong GetMinValidAddress ( )
21
+ {
22
+ // https://github.com/dotnet/BenchmarkDotNet/pull/2413#issuecomment-1688100117
23
+ if ( RuntimeInformation . IsWindows ( ) )
24
+ return 65536 ;
25
+ if ( RuntimeInformation . IsMacOS ( ) )
26
+ return RuntimeInformation . GetCurrentPlatform ( ) switch
27
+ {
28
+ Environments . Platform . X86 or Environments . Platform . X64 => 4096 ,
29
+ Environments . Platform . Arm64 => 0x100000000 ,
30
+ _ => throw new NotSupportedException ( $ "{ RuntimeInformation . GetCurrentPlatform ( ) } is not supported")
31
+ } ;
32
+ if ( RuntimeInformation . IsLinux ( ) )
33
+ {
34
+ string ? minAddrResult = ProcessHelper . RunAndReadOutput ( "/bin/bash" , "sudo cat /proc/sys/vm/mmap_min_addr" ) ;
35
+ ulong . TryParse ( minAddrResult , out ulong minAddress ) ;
36
+ return minAddress ;
37
+ }
38
+ throw new NotSupportedException ( $ "{ System . Runtime . InteropServices . RuntimeInformation . OSDescription } is not supported") ;
39
+ }
40
+
17
41
internal DisassemblyResult AttachAndDisassemble ( Settings settings )
18
42
{
19
43
using ( var dataTarget = DataTarget . AttachToProcess (
@@ -242,8 +266,10 @@ protected static bool TryReadNativeCodeAddresses(ClrRuntime runtime, ClrMethod m
242
266
243
267
protected void TryTranslateAddressToName ( ulong address , bool isAddressPrecodeMD , State state , bool isIndirectCallOrJump , int depth , ClrMethod currentMethod )
244
268
{
245
- // 0 or -1 (ulong.MaxValue) addresses are invalid, and will crash the runtime in older runtimes. https://github.com/dotnet/runtime/pull/90794
246
- if ( address == 0 || address == ulong . MaxValue )
269
+ // -1 (ulong.MaxValue) address is invalid, and will crash the runtime in older runtimes. https://github.com/dotnet/runtime/pull/90794
270
+ // 0 is NULL and therefore never valid.
271
+ // Addresses less than the minimum virtual address are also invalid.
272
+ if ( address == ulong . MaxValue || address == 0 || address < MinValidAddress )
247
273
return ;
248
274
249
275
if ( state . AddressToNameMapping . ContainsKey ( address ) )
@@ -259,7 +285,7 @@ protected void TryTranslateAddressToName(ulong address, bool isAddressPrecodeMD,
259
285
}
260
286
261
287
var method = runtime . GetMethodByInstructionPointer ( address ) ;
262
- if ( method is null && ( address & ( ( uint ) runtime . DataTarget . DataReader . PointerSize - 1 ) ) == 0 )
288
+ if ( method is null && ( address & ( ( uint ) runtime . DataTarget . DataReader . PointerSize - 1 ) ) == 0 )
263
289
{
264
290
if ( runtime . DataTarget . DataReader . ReadPointer ( address , out ulong newAddress ) && newAddress > ushort . MaxValue )
265
291
{
@@ -275,28 +301,24 @@ protected void TryTranslateAddressToName(ulong address, bool isAddressPrecodeMD,
275
301
276
302
if ( method is null )
277
303
{
278
- if ( isAddressPrecodeMD )
304
+ var methodDescriptor = runtime . GetMethodByHandle ( address ) ;
305
+ if ( methodDescriptor is not null )
279
306
{
280
- var methodDescriptor = runtime . GetMethodByHandle ( address ) ;
281
- if ( ! ( methodDescriptor is null ) )
307
+ if ( isAddressPrecodeMD )
282
308
{
283
- if ( isAddressPrecodeMD )
284
- {
285
- state . AddressToNameMapping . Add ( address , $ "Precode of { methodDescriptor . Signature } ") ;
286
- }
287
- else
288
- {
289
- state . AddressToNameMapping . Add ( address , $ "MD_{ methodDescriptor . Signature } ") ;
290
- }
291
- return ;
309
+ state . AddressToNameMapping . Add ( address , $ "Precode of { methodDescriptor . Signature } ") ;
292
310
}
311
+ else
312
+ {
313
+ state . AddressToNameMapping . Add ( address , $ "MD_{ methodDescriptor . Signature } ") ;
314
+ }
315
+ return ;
293
316
}
294
317
295
318
var methodTableName = runtime . DacLibrary . SOSDacInterface . GetMethodTableName ( address ) ;
296
319
if ( ! string . IsNullOrEmpty ( methodTableName ) )
297
320
{
298
321
state . AddressToNameMapping . Add ( address , $ "MT_{ methodTableName } ") ;
299
- return ;
300
322
}
301
323
return ;
302
324
}
0 commit comments