Caveats about managed JIT-debugging

I received some questions in the mailbag about what Debugger.Launch actually does. Debugger.Launch the same mechanism as JIT-attach when you get an unhandled managed exception. Here are some random caveats about the jit-launch mechanism:

  1. Jit-launch calls kernel32!CreateProcess on the string set by the DbgManagedDebugger registry key to create a debugger process. Registry settings are described here in more detail. The string has printf format specifiers that (described more here).  These are different than the native JIT-debugging registry settings (with AeDebug). See here for other managed/native API differences.
  2. The newly spawned debugger then attaches to the target app. With .NET 2.0, managed debugging requires an in-process helper-thread, and so attaching means there must be some inter-process communication between the debugger and debuggee.
  3. When you install VS, VS will register itself as the JIT-debugger. More specifically, VS registers a stub process (like VS7Jit.exe), which prompts up a dialog that eventually launches the real version of VS. This can be useful if there are multiple versions of VS installed. It can also let you use an existing instance of VS or a new instance.  (If a .Net 1.0 app crashed, you can debug it with either VS2002, VS2003, VS2005. See here for details.) It could also ensure the security settings of the debugger are correct.
  4. Pre .NET 2.0, the CLR used cordbg as the default JIT-debugger if no other was registered. This is problematic. Cordbg lives in the SDK, which is likely not installed for most end-users people (and even if it was, a managed app doesn't know where it was installed), and that would cause errors like "cordbg.exe !a 0x123" failed.