Code Gen flags while Debugging

I ranted here that Debuggers shouldn’t affect behavior. V1.1 had some fundamental violations of this regarding code-gen. We’ve fixed this in v2.0 ICorDebug. This includes:

1)       Ensuring that the mere presence of a debugger doesn’t affect codegen flags. Eg, in v1.1, if a debugger was attached, we’d jit the code differently (such as disabling optimizations) to make it more debugger-friendly. This can be nice, except that the different code-gen may mean different behavior under a debugger vs. not under a debugger.

2)       Debugging Ngen: Because of #1, it was very difficult to load optimized ngen images under a debugger. Issue #1 caused the debugger to specify debuggable code-gen flags, so it would look for a debuggable-ngen configuration, not find it, and thus not load the ngen images.  We’ve fixed this by fixing #1, and adding ngen-policy APIs onto the process via ICorDebugProcess2::SetDesiredNGENCompilerFlags.

3)       Always track jit maps. In v1.1, you had to fiddle with ini files to tell the jit to track jit-maps for debugging for an app that wasn’t launched under the debugger. In v2.0, the CLR will always track these maps. Fixing this required finding a performant way to track these maps. The challenge here was to store these maps in an efficient manner.

4)       Unifying the Launch and Attach case. You don’t want a different debugging experience based off whether you’ve launched an app (eg, debugging some local console app you wrote), or you attached to it at a later time (eg, debugging ASP.Net). With changes #1 + #3 above, the attach case behaves just like the launch case.


Comments (11)

  1. Matt Davis says:

    So, regarding #4- is the restriction about no Edit/Continue on "attached" processes purely imposed by VS (November CTP bits), or is there a more complex architectural restriction under the covers of the debugging stuff?

  2. Mike Stall says:

    Matt – the restriction that EnC is not supported on attach is imposed by ICorDebug. The issue is that we need to know if we’re doing EnC during startup because it requires special codegen and special setup.

    This isn’t ideal, but it greatly simplified our EnC implementation and we figured it was a good cost-benefit tradeoff.

    This is a similar reason to why you currently can’t have a clr profiler attach to an already running process either.

  3. Matt Davis says:

    Thanks- it’s good to know I shouldn’t expect it to work (though a little disappointing)…

    If I’m spinning up the CLR in the host process myself (which I am, in the case I *really* care about), is there any chance the mechanism could be documented to allow EnC to work with an attach (special flags to CorBindToRuntimeEx or extra calls on ICorRuntimeHost, whatever)? Or is it much more involved than that? I do a lot of hosted COM interop development, and the cycle times are really long to tear down the host app, recompile, and re-set everything up every time…

    Thanks for the quick response!

  4. Matt Davis says:

    Curled up with cordebug.idl last night- does this sound about right? :)


    Fire up my appdomain, have it load my managed debug shim (that implements ICorDebugManagedCallback)

    Get ICorDebug from CreateDebuggingInterfaceFromVersion(…)

    pass my ICorDebugManagedCallback instance to ICorDebug::SetManagedHandler

    My managed callback’s LoadModule method should call ICorDebugModule2::SetJITCompilerFlags to CorDebugJitCompilerFlags.CORDEBUG_JIT_ENABLE_ENC on every module load notification.

    If that’s it- does VS check the module flag before enabling/disabling EnC in the IDE, or does it just assume any process it didn’t launch is not EnC capable?

    I won’t keep bugging you about this, but I’m going to code this up today. Am I barking up the right tree, or is it just completely hopeless?


  5. Mike Stall says:

    Jonathan Keljo (Program Manager for the CLR’s EnC support) offers this:

    It was thought about, yes, but there are many more hurdles on the debugger side of the house than there are on the CLR side. The ASP.NET case is particularly problematic since the compilation is generally done by the server, not by the IDE—you can’t do EnC with ASP.NET at all.

    It wouldn’t be a big deal for the CLR to actually pay attention to the “EnC” bit on the DebuggableAttribute and gen EnC-able code from the get-go such that attach would work at the runtime level. The main technical hurdle is for the debugger—how does it know that the source files it’s looking at haven’t been changed since the particular version of the app you’re attached to was compiled? Nobody we know of is trying to clear that hurdle, so it’s not enabled at our level. (Keeping it simple.)

  6. Mike Stall says:

    Matt – it sounds like you’re trying to use the ICorDebug interfaces from within your host (the debuggee)? They’re meant to be used from the debugger process (from VS), so you can’t really override them from the host.

  7. Matt Davis says:

    Here’s the bigger question (perhaps the one I should’ve asked first): Should EnC work on unmanaged exe hosts (Excel) in the "launch" scenario, when the unmanaged host loads the CLR during startup? VS allows EnC behavior in this case, but the debugee fails with an ExecutionEngineException whenever I try to apply any code changes (filed a bug on this last week- FDBK20760). I’ve accepted that it won’t work in the "attach" scenario for this release, but I can get a long way if it’ll work for "launch".

    Seems like the VSTO gang would be clamoring for this to work, and maybe it does when using their loader shims (not included in Nov CTP bits, so I can’t try it).

    I’m trying to sell Whidbey as a replacement for our Excel VBA development, but w/o EnC, the VBA crew isn’t buying… So I’m trying anything and everything to make it work. :)

    Thanks for the dialogue…

  8. Question from the mail bag:

    I am trying to get some information on what I can do usefully with the…

  9. You can debug ngen (aka prejitted) code from VS2005 and also have the VS2005 IDE launch ngenned code.