egorbo / disasmo Goto Github PK
View Code? Open in Web Editor NEWVS2022 Add-in. Click on any method or class to see what .NET Core's JIT generates for them (ASM).
License: MIT License
VS2022 Add-in. Click on any method or class to see what .NET Core's JIT generates for them (ASM).
License: MIT License
Since the dotnet build
cmdline now includes /p:DefineConstants=DISASMO
, this value is taken instead of any value defined in the csproj.
I like being able to detect Disasmo runs from my project and/or code, but maybe an alternate property would be better. We could then bridge that into DefineConstants
ourselves if we want that.
Could we make this also as a .NET CLI tool so we can use it on none-Windows platforms?
I tried to look into the code but it's a bit hard for me to understand how it works.
Visual Studio 2019 Preview 3.0
.NET Core 3.0 Console Application
Code to reproduce:
using System;
using System.Runtime.Intrinsics.X86;
namespace ConsoleApp1
{
class Program
{
static unsafe void Main(string[] args)
{
Console.WriteLine("Hello World!");
DoTest();
Console.WriteLine($"Is sup: {Sse42.IsSupported}");
}
static unsafe void DoTest()
{
var srcBuf = stackalloc[] { (byte)0xF0, (byte)0xF0, (byte)0xF0, (byte)0xF0 };
var dstBuf = stackalloc[] { (byte)0xF0, (byte)0xF0, (byte)0xF0, (byte)0xF0 };
var cvrBuf = stackalloc[] { (byte)0xF0, (byte)0xF0, (byte)0xF0, (byte)0xF0 };
var alphaBuf = stackalloc[] { (byte)0xF0, (byte)0xF0, (byte)0xF0, (byte)0xF0 };
var csmBuf = stackalloc[]
{
(byte)0x00,
(byte)0xFF,
(byte)0xFF,
(byte)0xFF,
(byte)0x01,
(byte)0xFF,
(byte)0xFF,
(byte)0xFF,
(byte)0x02,
(byte)0xFF,
(byte)0xFF,
(byte)0xFF,
(byte)0x03,
(byte)0xFF,
(byte)0xFF,
(byte)0xFF
};
var onesBuf = stackalloc[]
{
(byte)0x01,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x01,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x01,
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x01,
(byte)0x00,
(byte)0x00,
(byte)0x00,
};
var length = 4;
var rCvr = Sse42.LoadVector128(cvrBuf);
var rSrc = Sse42.LoadVector128(srcBuf);
for (int i = 0; i < length; i++)
{
rCvr = Sse42.Shuffle(rCvr, Sse42.LoadVector128(csmBuf));
rCvr = Sse42.Add(rCvr, Sse42.LoadVector128(onesBuf));
}
}
}
}
"Disasm 'DoTest' method" fails with:
Unhandled Exception: System.TypeLoadException: Could not load type 'Internal.Runtime.Augments.EnvironmentAugments' from assembly 'System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'.
at System.Environment.get_CurrentManagedThreadId()
at System.Linq.Enumerable.Where[TSource](IEnumerable`1 source, Func`2 predicate)
at ConsoleApp1.Program.Main(String[] args)
Could bin\Disasmo be used instead of DisasmoBin?
I'm trying to Disasm any .NET Core 3.1 based method as shown in the example (including the example method: InefficientJoin), but I'm getting 0x80004005 error.
I'd like to use this extension since it seems to be helpful is some scenarios, however, I haven't figured out how to make it actually work. I've spent almost two days trying to make it work.
It seems that Disasmo does not support projects with multiple TargetFrameworks.
Can this be fixed?
I have a test app that runs DotNetBenchmark when building with Release, and some testing when ran in DEBUG.
I'd also really like Disasmo to run the debug case, but without actually compiling debug. I think this can be done by having Disamo adding a new define, so i can do:
#if DEBUG || DISASMO
//a
#else
//b
#endif
Local version of latest master brach dotNET runtime is built (with both .\build.cmd Clr+Libs -c Release -rc Checked
and .\build.cmd Clr -c Checked
). Upon start, compilation is done but fails with an error about .NET 6.0 (even though my app is targeting .NET 5.0 and Settings->Reload Strategy is set to dotnet publish
):
System.InvalidOperationException: ERROR: 'dotnet build' did not produce expected binaries ('C:\Users\uberhalit\AppData\Local\Temp\DisasmoLoader3\4.0.4_5.0.402\out\DisasmoLoader3.dll' and 'C:\Users\uberhalit\AppData\Local\Temp\DisasmoLoader3\4.0.4_5.0.402\out\DisasmoLoader3.runtimeconfig.json'):
Microsoft (R)-Build-Engine, Version 16.11.1+3e40a09f8 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.
C:\Program Files\dotnet\sdk\5.0.402\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.TargetFrameworkInference.targets(141,5): error NETSDK1045: The current .NET SDK does not support .NET 6.0 as target. [C:\Users\uberhalit\AppData\Local\Temp\DisasmoLoader3\4.0.4_5.0.402\DisasmoLoader3.csproj]
0 Warnings
1 Error
at Disasmo.Utils.LoaderAppManager.<InitLoaderAndCopyTo>d__2.MoveNext()
--- ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at Disasmo.MainViewModel.<RunFinalExe>d__61.MoveNext()
Hi,
Trying to install on Vs2019 enterprise 16.10.4, setup is always complaning about VSIXInstaller.NoApplicableSKUsException
Am I missing something ? Thanks.
dd_VSIXInstaller_20210807145614_0c34.log
This line will crash VS if network is not connected:
When looking for optimizations it's useful to see if a change may have reduced the overall bytes of a method. Currently I have to scroll down to see if it contains less instructions than before. This becomes a pain when a method is long (several hundreds of instructions).
It would be nice if disasmo could show the number of instructions / bytes at the top header.
<entry>
<record>698</record>
<time>2020/02/09 19:41:59.921</time>
<type>Error</type>
<source>Editor or Editor Extension</source>
<description>System.InvalidOperationException: Can only compare ISuggestedActionCategories defined with SuggestedActionCategoryRegistryService
 at Microsoft.VisualStudio.Language.Intellisense.Implementation.SuggestedActionCategoryComparer.Compare(String x, String y)
 at System.Linq.EnumerableSorter`2.CompareKeys(Int32 index1, Int32 index2)
 at System.Linq.EnumerableSorter`1.QuickSort(Int32[] map, Int32 left, Int32 right)
 at System.Linq.EnumerableSorter`1.Sort(TElement[] elements, Int32 count)
 at System.Linq.OrderedEnumerable`1.<GetEnumerator>d__1.MoveNext()
 at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
 at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
 at Microsoft.VisualStudio.Language.Intellisense.Implementation.DefaultLightBulbPresenterDefaultIconUIElementProvider.GetUIElement(ISuggestedActionCategorySet itemToRender, ILightBulbSession context, UIElementType elementType)
 at Microsoft.VisualStudio.Language.Intellisense.Implementation.LightBulb..ctor(LightBulbSession session, LightBulbPresenterStyleFactory presenterStyleFactory)
 at Microsoft.VisualStudio.Language.Intellisense.Implementation.LightBulbTagger.<Microsoft.VisualStudio.Text.Tagging.ITagger<Microsoft.VisualStudio.Language.Intellisense.Implementation.LightBulbTag>.GetTags>b__10_1()
 at Microsoft.VisualStudio.Language.Intellisense.Implementation.LightBulbTag.get_Glyph()
 at Microsoft.VisualStudio.Language.Intellisense.Implementation.LightBulbGlyphFactory.GenerateGlyph(IWpfTextViewLine line, ISuggestionTag tag)
 at Microsoft.VisualStudio.Text.Editor.Implementation.CanvasAndGlyphFactory`1.GenerateGlyph(IWpfTextViewLine line, ITag tag)
 at Microsoft.VisualStudio.Text.Editor.Implementation.GlyphMarginVisualManager`1.AddGlyph(TGlyphTag tag, SnapshotSpan span)
 at Microsoft.VisualStudio.Text.Editor.Implementation.GlyphMargin`1.RefreshGlyphsOver(ITextViewLine textViewLine)
 at Microsoft.VisualStudio.Text.Editor.Implementation.GlyphMargin`1.OnBatchedTagsChanged(Object sender, BatchedTagsChangedEventArgs e)
 at Microsoft.VisualStudio.Text.Utilities.GuardedOperations.RaiseEvent[TArgs](Object sender, EventHandler`1 eventHandlers, TArgs args)
--- End of stack trace from previous location where exception was thrown ---
 at Microsoft.VisualStudio.Telemetry.WindowsErrorReporting.WatsonReport.GetClrWatsonExceptionInfo(Exception exceptionObject)</description>
</entry>
I'm using VS2019 16.5 P2, but it used to happen with P1 as well. Can't confirm if it happened before. It appears that this only happens when Alt+Enter (or Ctrl + .) is pressed; this also does not happen with Disasmo disabled / uninstalled.
21619e8 removed the option "prefer checked runtime" and now disassembly is always done using checked runtime which unfortunately means that various runtime asserts and extra validations are also left in and thus the disassembly isn't always accurate. Only JIT dll needs to be from checked/debug build.
I tried disasmo but I get following failure in the disasmo window. Any idea?
Microsoft (R) Build Engine version 16.9.0-preview-20611-06+5abf1ff7b for .NET
Copyright (C) Microsoft Corporation. All rights reserved.
Determining projects to restore...
All projects are up-to-date for restore.
C:\Program Files\dotnet\sdk\5.0.200-preview.20614.14\Current\SolutionFile\ImportAfter\Microsoft.NET.Sdk.Solution.targets(27,5): error NETSDK1134: Building a solution with a specific RuntimeIdentifier is not supported. If you would like to publish for a single RID, specifiy the RID at the individual project level instead. [e:\ConsoleApp1.sln]
Build FAILED.
C:\Program Files\dotnet\sdk\5.0.200-preview.20614.14\Current\SolutionFile\ImportAfter\Microsoft.NET.Sdk.Solution.targets(27,5): error NETSDK1134: Building a solution with a specific RuntimeIdentifier is not supported. If you would like to publish for a single RID, specifiy the RID at the individual project level instead. [e:\ConsoleApp1.sln]
0 Warning(s)
1 Error(s)
Time Elapsed 00:00:00.13
Here is the output of dotnet --info
dotnet --info
.NET SDK (reflecting any global.json):
Version: 5.0.200-preview.20614.14
Commit: 863605c8c3
Runtime Environment:
OS Name: Windows
OS Version: 10.0.19042
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\5.0.200-preview.20614.14\
Host (useful for support):
Version: 5.0.1
Commit: b02e13abab
.NET SDKs installed:
3.1.400-preview-015151 [C:\Program Files\dotnet\sdk]
5.0.101 [C:\Program Files\dotnet\sdk]
5.0.200-preview.20614.14 [C:\Program Files\dotnet\sdk]
My Console1.csproj
looks like:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
</Project>
I noticed the RID is win-x64
and not sure if that is accurate.
This looks amazing, and I don't know why I've never seen it done before.
Unfortunately, I'm stuck in ancient history with Visual Studio 2017.
Is 2017 support possible, and if so would you be willing to add support? I'd be willing to recompile it myself, but I'm willing to bet there's others who would appreciate it too.
I hit this when trying to disasm a method in a plain (only shared framework dependencies) net5.0
library. It was failing with could not load System.Runtime Version=5.0.0
. After some investigation I determined that the cause of the error is the fact that Disasmo is now using dotnet build
(presumably, for its higher performance) instead of dotnet publish
to get the project's artifacts.
This does not work for libraries, as they, apparently, are built without the framework dependencies being copied to the output. Then CoreRun fails to find them and things do no work as expected.
The "easy" workaround would be to switch back to dotnet publish --self-contained true
(note that plain publish
does not work for libraries). I suspect, however, that the switch was deliberate and that would be a regression. Maybe CoreRun has some options for probing (I am not an expert in this area)?
Right now I am using a workaround of running a target that would publish my library to the Disasmo's folder after build. FWIW, it works, but it is not pretty.
I've been trying to get 'where Roslyn tells Disasmo the entrypoint is' to match up with 'where the entry point actually is' with a disappointingly low success rate....
class Program
{/*disasmo{*/System.Linq.Enumerable.ToList(System.Linq.Enumerable.Where(typeof(TestHarness.IndexOfTesting.InvertedIndexOfAdder).GetMethods(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic), w => w.DeclaringType == typeof(TestHarness.IndexOfTesting.InvertedIndexOfAdder))).ForEach(m => System.Runtime.CompilerServices.RuntimeHelpers.PrepareMethod(m.MethodHandle));System.Console.WriteLine(" ");System.Console.ReadLine();System.Environment.Exit(0);/*}disasmo*/
static void Main(string[] args)
{
class Program
{
static void Main(string[] args)
{
//for (int i = 0; i < 1000; i++)
//{/*disasmo{*/System.Linq.Enumerable.ToList(System.Linq.Enumerable.Where(typeof(TestHarness.IndexOfTesting.InvertedIndexOfAdder).GetMethods(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic), w => w.DeclaringType == typeof(TestHarness.IndexOfTesting.InvertedIndexOfAdder))).ForEach(m => System.Runtime.CompilerServices.RuntimeHelpers.PrepareMethod(m.MethodHandle));System.Console.WriteLine(" ");System.Console.ReadLine();System.Environment.Exit(0);/*}disasmo*/
Perhaps Mono.Cecil to add a module initializer, or hijacking the entrypoint to a different file, might be more reliable?
Hello,
Thanks for this awesome extension, this is something I've wanted for a long time.
One issue I've encountered is the following:
Unhandled exception. System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types.
Could not load file or assembly 'Vortice.Win32, Version=1.9.14.0, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.
Could not load file or assembly 'Vortice.Win32, Version=1.9.14.0, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.
at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
at System.Reflection.Assembly.GetTypes()
at DisasmoLoader.PrecompileAllMethodsInType(String[] args)
at DisasmoLoader.Main(String[] args)
Switching to "dotnet publish" mode, I now get this error:
C:\Program Files\dotnet\sdk\7.0.202\Sdks\Microsoft.DotNet.ILCompiler\build\Microsoft.NETCore.Native.Publish.targets(53,5):
error : PublishTrimmed is implied by native compilation and cannot be disabled. [pathtomy.csproj]
Disabling AOT by changing this option to false the ProperyGroup of my csproj:
<PublishAot>false</PublishAot>
Fixes the issue, and now Disasmo works in "dotnet publish" mode, however I then need to re-enable this option for other debugging and tests. Is there any way to get Disasmo working in an AOT project?
Thanks!
This is expected from the way how it works now (injecting some code to Main method and then running the executable).
I propose having simple "runner" executable (distributed along side with Disasmo) which would accept arguments telling it which dll/exe to load and which type/methods to prepare (=be JITed). Then there would be no need for code injection used now and it would be possible to disasm even methods from dlls.
It would also solve #3.
I can prepare pull request if you agree.
I would love to be able to see also methods and types IL. Maybe it should not be too difficult. I would just use ILSpy (though I've never used it programmatically).
Are you open to such extensions of Disasmo? I could have a look at it..
When create new application for .NET 6 it is missing Main method, and I have to create new method to find that Disasmo opens using autocomplete.
Sometimes when I open up VS anew and want to disassemble the method I can encounter this strange exception:
System.ArgumentException: The path is not of a legal form.
at System.IO.Path.NormalizePath(String path, Boolean fullCheck, Int32 maxPathLength, Boolean expandShortPaths)
at System.IO.Path.InternalGetDirectoryName(String path)
at Disasmo.MainViewModel.<RunOperationAsync>d__80.MoveNext()
It fixes up itself eventually but I don't understand how I get to see this problem self-fixed at all and I have no clear reasoning what's wrong about it.
BTW I have tried to try this with local dotnet/runtime build, turned all the switches on/off but it still doesn't work
It is Vector128<byte> Create (byte value)
but parsing of GitHub fails for me. Maybe Vector128 shoud be added to parsing logic too?
After reviewing data submitted by a user in Executing View.QuickActions often throws an exception, I found it's possible for a NullReferenceException
to be thrown in ObjectLayoutSuggestedAction.GetSymbol
, which eventually propagates to CommonSuggestedActionsSource.HasSuggestedActionsAsync
. This unhandled exception causes the lightbulb to misbehave. The following screenshot shows the problematic call stack:
It should just reference dlls and allow the roslyn host to load them. Right now, the extension (along with some others) cause my VS to not show quick info. :D
I'm interesting in NativeAOT, and usually works with debug versions instead of Checked, so I would like that this version woud be also picked up.
@EgorBo trying to use Disasmo with .NET 8.0 preview 7 but this appears to not work.
Unhandled exception. System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types.
Could not load file or assembly 'System.Runtime, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.
Project has
<TargetFrameworks>net7.0;net8.0</TargetFrameworks>
There's a TODO
in the code for this:
Disasmo/src/Vsix/ViewModels/MainViewModel.cs
Line 169 in 38e26cd
This affects me with Paint.NET because all of the assembly names are prefixed with PaintDotNet
, but the project names are not, e.g. Primitives.csproj
/ PaintDotNet.Primitives.dll
Disasmo/src/Vsix/ViewModels/MainViewModel.cs
Line 266 in 093e938
net5.0
TargetFramework
and prevents Disasmo from working.I think it would be practical to have settings to live in the default VS Options dialog. At least that's make things a it easier to discover during first time use.
Repro:
There is an easy workaround of copying the text out to something like notepad++, but it would be nice for this to work with the built-in search functionality, particularly for JitDump
This is a feature request to add a dropdown box where I can select which dll I want to disassemble. This would not change the disassembler used, but it would instead just change which dll it uses, for example I could select net6.0 and it would decompile my net6.0 dll with the .NET 7.0 disassembler.
This would be very useful to me as I often write very multi-tfm code, with lots of #if
s. It would be most useful to quickly check my net6.0 dll probably actually produces good vectorised code, since in .NET 7+ I am using the new operations on the vector types mostly, therefore this part of my code shares very few similarities between .NET 7 and .NET 6.
Another use would be if the library doesn't support .NET 7 directly, but you want to check what the codegen would be on .NET 7 to see if it should be specialised.
Thanks for making a great extension btw!
Instructions are already highlighted and it would be nice if they contain tooltips with some description or/and be clickable with URL to some documentation.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.