Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

--disasm switch on ARM64 throws Exception #1422

Closed
kunalspathak opened this issue Apr 13, 2020 · 4 comments · Fixed by #2127
Closed

--disasm switch on ARM64 throws Exception #1422

kunalspathak opened this issue Apr 13, 2020 · 4 comments · Fixed by #2127

Comments

@kunalspathak
Copy link
Member

I get following exception when using --disasm on ARM64.

// AfterAll
Unhandled exception. System.InvalidOperationException: There is an error in XML document (0, 0).
 ---> System.Xml.XmlException: Root element is missing.
   at System.Xml.XmlTextReaderImpl.Throw(Exception e)
   at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
   at System.Xml.XmlTextReaderImpl.Read()
   at System.Xml.XmlReader.MoveToContent()
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderDisassemblyResult.Read9_DisassemblyResult()
   --- End of inner exception stack trace ---
   at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
   at BenchmarkDotNet.Diagnosers.WindowsDisassembler.Disassemble(DiagnoserActionParameters parameters)
   at BenchmarkDotNet.Diagnosers.DisassemblyDiagnoser.Handle(HostSignal signal, DiagnoserActionParameters parameters)
   at BenchmarkDotNet.Diagnosers.CompositeDiagnoser.Handle(HostSignal signal, DiagnoserActionParameters parameters)
   at BenchmarkDotNet.Loggers.SynchronousProcessOutputLoggerWithDiagnoser.ProcessInput()
   at BenchmarkDotNet.Toolchains.DotNetCli.DotNetCliExecutor.Execute(BenchmarkCase benchmarkCase, BenchmarkId benchmarkId, ILogger logger, ArtifactsPaths artifactsPaths, IDiagnoser diagnoser, String executableName, IResolver resolver)
   at BenchmarkDotNet.Toolchains.DotNetCli.DotNetCliExecutor.Execute(ExecuteParameters executeParameters)
   at BenchmarkDotNet.Running.BenchmarkRunnerClean.Execute(ILogger logger, BenchmarkCase benchmarkCase, BenchmarkId benchmarkId, IToolchain toolchain, BuildResult buildResult, IResolver resolver)
   at BenchmarkDotNet.Running.BenchmarkRunnerClean.RunCore(BenchmarkCase benchmarkCase, BenchmarkId benchmarkId, ILogger logger, IResolver resolver, BuildResult buildResult)
   at BenchmarkDotNet.Running.BenchmarkRunnerClean.Run(BenchmarkRunInfo benchmarkRunInfo, Dictionary`2 buildResults, IResolver resolver, ILogger logger, List`1 artifactsToCleanup, String resultsFolderPath, String logFilePath, StartedClock& runChronometer)
   at BenchmarkDotNet.Running.BenchmarkRunnerClean.Run(BenchmarkRunInfo[] benchmarkRunInfos)
   at BenchmarkDotNet.Running.BenchmarkSwitcher.RunWithDirtyAssemblyResolveHelper(String[] args, IConfig config)
   at BenchmarkDotNet.Running.BenchmarkSwitcher.Run(String[] args, IConfig config)
   at MicroBenchmarks.Program.Main(String[] args) in D:\Users\dotnet-bot\kpathak\git\performance\src\benchmarks\micro\Program.cs:line 35
@kunalspathak
Copy link
Member Author

@adamsitnik

@adamsitnik
Copy link
Member

The disassembler does not work on ARM & ARM64 due to the fact that we are internally using Iced which does not support it yet.

As soon as https://github.com/0xd4d/iced/issues/79 and https://github.com/0xd4d/iced/issues/80 get implemented, we are going to update Iced on our side and add the support. I don't know when it's going to happen.

@adamsitnik
Copy link
Member

adamsitnik commented Sep 16, 2022

Currently we can implement it in following ways:

DOTNET_JitDisasm

Use DOTNET_JitDisasm exposed recently by dotnet/runtime#73365 and parse the disassembly from standard output. In #2092 I've extended ExecuteResult with new StandardOutput that contains all the lines printed by the benchmark process to standard output.

public IReadOnlyList<string> StandardOutput { get; }

Advantages:

  • if we add any new architectures in the future, it should work OOTB
  • no new dependencies
  • some users are already used to this format of output

Disadvantages:

capstone

The current x64/x86 disassembler uses ClrMD to get disassembly as byte[] and Iced to decode the instructions and format them. Iced does not support arm yet: icedland/iced#72 (the issue is closed, but there is no support).

For arm64/arm we could use https://github.com/capstone-engine/capstone which supports .NET and arm. The .NET library has recently added support for linux and macOS (so far it supported only Windows): 9ee1/Capstone.NET#32, but a new NuGet package version was not published to nuget.org yet. However, a fork of it has published the package: https://www.nuget.org/packages/js6pak.Gee.External.Capstone

Advantages:

  • should work with all .NET versions

Disadvantages:

Iced

We could contribute to Iced and implement arm64 support. This would require us to establish new abstractions (so far everything assumed x64) and also implement arm64/arm decoding. IMO this would be a lot of work, but I might be wrong.

@adamsitnik adamsitnik self-assigned this Sep 16, 2022
@adamsitnik
Copy link
Member

@janvorli I've done two experiments:

  1. I've tried ClrMD on Arm64: it works on Linux, it throws on Windows
  2. I've tried Capstone and it works nice on Linux. I was able to decode all methods (using --disasmFilter *) and it did not throw.

Branch that I've been using: https://github.com/dotnet/BenchmarkDotNet/tree/arm64Disasm

Demo:

; BenchmarkDotNet.Samples.IntroDisassembly.SumField()
       stp x29, x30, [sp, #-0x10]!
       mov x29, sp
       mov w1, wzr
       mov w2, wzr
       ldr x0, [x0, #8]
       ldr w3, [x0, #8]
       cmp w3, #0
       b.le #0x1044
       mov x3, x0
       ldr w4, [x3, #8]
       cmp w2, w4
       b.hs #0x1040
       sxtw x4, w2
       lsl x4, x4, #2
       add x4, x4, #0x10
       ldr w3, [x3, x4]
       add w1, w3, w1
       add w2, w2, #1
       ldr w3, [x0, #8]
       cmp w3, w2
       b.gt #0xfd8
       mov w0, w1
       ldp x29, x30, [sp], #0x10
       ret
       bl #0xffffffffff8a39b0
       brk #0
; Total bytes of code 104

@adamsitnik adamsitnik added this to the v0.13.3 milestone Sep 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants