How can I view the disassembly of optimised jitted .NET code?
Asked Answered
U

6

17

For one reason or another, I sometimes find it useful or just interesting to look at the optimised compiler output for a function.

For unmanaged C/C++ code, my favourite way to do this has been to compile in Release mode, stick a breakpoint in the function of interest, run, and view the disassembly in Visual Studio when it hits the breakpoint.

I recently tried this with a C# project and discovered that that technique doesn't work. Even in Release mode, the disassembly I see is obviously not optimised. I found and disabled (in Visual Studio 2010) the "Debug ... Options and Settings ... Debugging ... General ... Suppress JIT optimization on module load" option, which presumeably gets me closer to what I want, only now it warns me when I try to run it, and I then can't get it to stop on a breakpoint so that I can see the disassembly.

So, if I want to see the disassembled, optimised output of the CLR (4.0) jitter for a function, what's the best way to go about that? To be clear, I'd like to see the x86 (or preferably x86_64) disassembly, not just the IL disassembly (which you can see in Reflector).

Unyoke answered 6/8, 2010 at 12:3 Comment(0)
U
19

Of course, after half a day of searching for the answer on this one, I find the answer myself 5 minutes after I ask on SO.

I was close; the only missing step from what I had in the question was that "Enable Just My Code" must also be unchecked in the options.

The full guide is available here: <Link>

Unyoke answered 6/8, 2010 at 12:17 Comment(3)
Dont you love (and hate) it when that happens? :)Felon
@leppie: Pretty much. It was a case of needing to know the solution to know what phrase to search for to find the solution...Unyoke
the link is deadRodrick
H
3

I believe the JIT knows when you're running under a debugger, and generates more "debugger-friendly" x86 code, which would explain why the x86 code you saw was unoptimized.

You might try running the app standalone, executing the code you're interested in at least once (so it JITs without the debugger attached), then attach the debugger to the process and set your breakpoint.

Homo answered 6/8, 2010 at 12:21 Comment(0)
C
2

Breakpoints in optimized code don't work in functions which are inlined. If you want to view disassembly of an inline function, you can insert command System.Diagnostics.Debugger.Break(); into your source code.

Clutch answered 23/5, 2017 at 12:8 Comment(0)
F
0

You could try inspecting an NGEN'd assembly, but that would be quite hard as no metadata is present. But it could work :)

Felon answered 6/8, 2010 at 12:13 Comment(0)
U
0

To see optimized code in the disassembler for managed code in a Release build, configure the following in Options/Debugging/General:

  • Disable "Enable Just My Code"
  • Disable "Automatically suppress JIT optimizations for debugged methods"
  • Disable "Suppress JIT optimization on module load"
Unstrap answered 2/7 at 9:52 Comment(0)
L
-1

You can use https://sharplab.io/ for snippets of code. It will show IL as well as the JIT Optimized Assembly code.

If you want to see this while debugging, you can look in the Disassembly and Registers Windows under the Debug | Windows menu option (only available while debugging). Make sure you are in 'Release' configuration and your 'Release' configuration has 'Optimize Code' checked.

Some Debug Options you may want to configure when de depending on your case, would be:

  • Check 'Enable address-level debugging'
  • Check 'Show disassembly if source is not available'
  • Uncheck 'Enable Just My Code'
  • Uncheck 'Automatically suppress JIT optimizations for debugged methods'
  • Uncheck 'Suppress JIT Optimization on module load'

BTW, running under VisualStudio regardless of whether or not you're in Debug or Release mode will still run under the Debugger even though the application code may be optimized.

Laomedon answered 1/3, 2011 at 19:11 Comment(2)
Is that true? If so, then why can you attach a debugger to a process that was run independently of a debugger? Don't forget that VS can debug native apps too, but you only see disassembly (assembly instructions) instead of C# or IL, and you see registers instead of locals. I'm not sure if you can load SOS.dll to dig further into memory if you attach to a process that wasn't launched with a debugger. Note too that they changed some stuff around the native debugging/instrumentation APIs with .NET 4, iirc.Quigley
@DrewNoakes I didn't say you couldn't use VS to attach to an optimized assembly/executable. I previously said in this answer that "it doesn't work well with optimized code". This was slightly misleading and I've removed that statement. What I meant when I said that before was that debugging optimized code against source code can step over certain statements/methods since they may have been optimized away by the JIT compiler. It can also be difficult to see some of the variables, parameters, symbols, etc. for the same reason.Laomedon

© 2022 - 2024 — McMap. All rights reserved.