31

How can I have a trace of native code generated by the JIT-Compiler ?

Thanks

David Klempfner
  • 8,700
  • 20
  • 73
  • 153
Thomas
  • 313
  • 3
  • 4

5 Answers5

20

In Visual Studio place a breakpoint in the code and start debugging. When it breaks, open the Disassembly window (Debug > Windows > Disassembly or Alt+Ctrl+D).

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • Is there a way to dump it into a file ? – Thomas Mar 09 '10 at 15:37
  • 4
    Select All, Copy, open Notepad, Paste and Save. – Guffa Mar 09 '10 at 15:40
  • Why the downvote? If you don't explain what it is that you think is wrong, it can't improve the answer. – Guffa Feb 27 '15 at 12:58
  • Release mode does not automatically imlpy JITted code. – Dan Byström Jun 02 '15 at 12:38
  • @DanByström: What do you mean? – Guffa Jun 02 '15 at 13:10
  • 3
    By default JITting is turned off when you run within Visual Studio. Normally there's a huge performance diffference when running code directly from Visual Studio (built for Release mode), compared to running the EXE-file. You change that under Tools, Options, Debugging, "Supress JIT optimization during module load". See also this Q/A: http://stackoverflow.com/questions/4043821/performance-differences-between-debug-and-release-builds – Dan Byström Jun 02 '15 at 14:14
  • @DanByström: It's only *JIT optimizing* that is turned off, not the JIT compiler. The language compiler (C# or VB) can't produce machine code, it's always the JIT compiler that does that. – Guffa Jun 02 '15 at 17:07
  • 1
    You are of course correct, I have phrased myself sloppy. My point was that by neglecting to view the optimized code, you get a false picture of what will be executed "for real". – Dan Byström Jun 02 '15 at 17:28
  • 1
    @DanByström Thanks for pointing this out. Guffa's comment to Mutel's answer was wrong, his later response above to your comment about JIT optimizing turned off is correct. Most people looking at the generated JIT code would be interested in performance, in which case it is crucial for optimizations to be enabled. – Evgeniy Berezovsky Jun 16 '15 at 02:33
  • @EugeneBeresovsky: No, my comment to Mutel's answer is not wrong. Please get your facts straight before claming anything like that. – Guffa Jun 16 '15 at 07:29
  • @Guffa Straight facts added in a response to your comment over at Mutel's answer. – Evgeniy Berezovsky Jun 17 '15 at 00:55
19

If you just use Debug->Windows->Disassembly on a standard Debug or Release exe, without modifying Visual Studio Debugging options, you will just see a version of non optimized .NET code.

Have a look at this article "How to see the Assembly code generated by the JIT using Visual Studio". It explains how to inspect generated JIT optimized code.

One relevant quote from the article:

  1. Configure the Debugging Options in Visual Studio to allow the JIT to generate optimized code and to allow you to debug the optimized code.

Go to Tools => Options => Debugging => General · Make sure that box labeled ‘Suppress JIT optimization on module load’ is Unchecked.

· Make sure that the box labeled ‘Enable Just My Code’ is Unchecked.

Evgeniy Berezovsky
  • 18,571
  • 13
  • 82
  • 156
Alexandre Mutel
  • 467
  • 4
  • 4
  • That's not correct. In release mode you will see the optimised code. The article is talking about debug mode. – Guffa Feb 27 '15 at 13:01
  • 1
    @Guffa I copied a relevant piece of the article into this answer, but something that more specifically refutes your claim above: `Ideally you would have wanted it to be the case that simply changing the configuration in the Solution Configuration window to ‘Release’ would be sufficient.` – Evgeniy Berezovsky Jun 16 '15 at 02:29
  • @EugeneBeresovsky: Sorry, you got that mixed up. What the article is talking about in the passage that you quoted is not generating optimised code, but generating debug information. You don't need debug information to see the optimised code. – Guffa Jun 16 '15 at 07:27
  • 1
    @Guffa Release mode *by itself* will NOT let you see optimized code when you debug, as stated btw in the quote in my comment above. Just read the 3 necessary steps after `settings that you will need to change in order for you to see the Optimized code generated by the JIT compiler.` Changing to Release mode is but the first step, the others being `Set Generate debug info to pdb-only` and the last one is about unchecking *Suppress JIT optimization on module load* and *Enable Just My Code*. – Evgeniy Berezovsky Jun 17 '15 at 00:21
  • 1
    @Guffa It is also spelt out quite unambiguously: `Whenever you launch a managed program under Visual Studio using (Start-Debugging or F5), it will by default, force the JIT to create Debug code. This is true even when you have selected the 'Release' configuration. The reason for this is to improve the debugging experience, but it also makes it impossible to see the Optimized code that you will get whenever your program is not running under the Visual Studio debugger.` – Evgeniy Berezovsky Jun 17 '15 at 00:37
  • @Guffa You are incorrect. With the VS debugger attached (which it will be when running the code from VS), the JIT does not generate optimized code, even in Release mode, unless you uncheck those two options. – BlueRaja - Danny Pflughoeft Sep 14 '16 at 21:31
  • The link is broken. – David Klempfner Nov 20 '20 at 12:50
5

You can even use Sharplab to see generated code => https://sharplab.io/ . In this, you can quickly see the generated code based on what C# code you write in both Debug and Release configuration.

Recently popular compiler explorer also started supporting .NET languages. Here is the example => https://godbolt.org/z/P49Y6Ejh6 It's not fast as SharpLab, but still it's a viable option to look for.

4

You should look for the files output from the NGen tool. NGen compiles and stores pre-jitted versions of assemblies in the Global Assembly Cache.

Peter Lillevold
  • 33,668
  • 7
  • 97
  • 131
1

There's a more cross-platform, cross-architecture, local-only and open source approach possible with recent versions of .NET. This also allows you to build/modify the JIT itself and see the results. The complete steps are described at:

https://github.com/dotnet/runtime/blob/main/docs/design/coreclr/jit/viewing-jit-dumps.md

The downside is that it's not as "simple" or easy to use out of the box.

It boils down to:

  • Build your application and publish it. Something like this:

    dotnet publish -c Release -r linux-x64

    But replace linux-x64 with the appropriate OS/architecture combo, like win-x64 or osx-arm64 as appropriate.

  • Build a Debug build of the clrjit:

    git clone https://github.com/dotnet/runtime cd runtime ./build clr -c Debug

  • Replace your application's clrjit with the one you built

    cp /path/to/dotnet/runtime/artifacts/bin/coreclr/Linux.x64.Debug/* bin/Release/net6.0/linux-x64/publish/

    Adjust Linux.x64, net6.0 and linux-x64 as appropriate.

  • Set the COMPlus_JitDump=<Method> environment variable and run the application to dump the JIT output to the standard output.

    COMPlus_JitDump=Main ./bin/Release/net6.0/linux-x64/publish/Application

omajid
  • 14,165
  • 4
  • 47
  • 64