dotnet / BenchmarkDotNet

Powerful .NET library for benchmarking
https://benchmarkdotnet.org
MIT License
10.55k stars 969 forks source link

NativeAOT disassembly #2062

Open MichalPetryka opened 2 years ago

MichalPetryka commented 2 years ago

BenchmarkDotNet 0.13.1.1835 from the nightlies currently errors out when DisassemblyDiagnoser is used with a NativeAOT job with this exception:

Failed to disassemble with following exception:
Sequence contains no elements.
   in System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
   in BenchmarkDotNet.Disassemblers.ClrMdV1Disassembler.AttachAndDisassemble(Settings settings)
   in BenchmarkDotNet.Disassemblers.Program.Main(String[] args)

BDN should at least provide a message saying that NativeAOT disassembly is not supported, or properly support it.

adamsitnik commented 2 years ago

@MichalPetryka You are right, we should at least print a nice error. And ideally implement the support.

@MichalStrehovsky @jkotas Do you know if there is any existing .NET library that supports parsing native assemblies? Or anything else that could help us with implementing this feature?

jkotas commented 2 years ago

I am not aware of any library like that. I think that the best path to enable this would be to enhance clrmd to understand NativeAOT.

MichalPetryka commented 2 years ago

Would it maybe be possible to add a flag to NativeAOT that'd dump the assembly to a file while building?

jkotas commented 2 years ago

There are tools for dumping binaries disassembly: dumpbin on Windows and objdump on Unix. I do not think we would want to the AOT compiler to carry the disassembler with it - it does not carry one today.

MichalPetryka commented 2 years ago

Couldn't the disassembler that the JIT uses with JitDump be used here?

jkotas commented 2 years ago

JitDump is not available in shipping JIT binary.

MichalStrehovsky commented 2 years ago

If JitDump support ever starts shipping in Release builds, we could easily add that to the compiler.

When using an external disassembler, the main problem would be matching the mangled names to the managed methods. We could potentially have a compiler switch to dump the decoder ring into a file (mapping type and method names and tokens to the mangled representation) if there's interest.

jkotas commented 2 years ago

We could potentially have a compiler switch to dump the decoder ring into a file

FWIW, we will need to do something like this if we get serious about good diagnostic experience for NativeAOT.

MichalPetryka commented 2 years ago

If JitDump support ever starts shipping in Release builds, we could easily add that to the compiler.

For reference: https://github.com/dotnet/runtime/pull/73365

MichalStrehovsky commented 2 years ago

If JitDump support ever starts shipping in Release builds, we could easily add that to the compiler.

For reference: dotnet/runtime#73365

To make it meaningfully useful for NativeAOT/R2R, one needs to pass --parallelism:1 to the AOT compiler. The compiler is heavily multithreaded and the output wouldn't make sense otherwise.

We could potentially have a compiler switch to dump the decoder ring into a file

FWIW, we will need to do something like this if we get serious about good diagnostic experience for NativeAOT.

I'm adding something usable for this purpose in https://github.com/dotnet/runtime/pull/73913. Besides the sizes of things, it also has a mapping from IL entities to the mangled names. If I can get someone to sign off on this and merge it before Monday 4 PM Pacific time, it will be part of .NET 7.