You can’t attach 2 debuggers to 1 process


For both managed-only and native-only debugging, you can only attach 1 debugger to a process.

 

Why?

The native debugger steals debug events from underneath the managed debugger. This confuses the managed-debugger and will cause it to crash. The native debugger has no way of coordinating with the managed-debugger here.

 

Troubles enforcing this:

In windows, the OS enforces that only 1 native debugger can be attached to a debuggee at a time (DebugActiveProcess to an already-debugged process will fail).

The Managed-only debugging services have similar checks to enforce that only 1 managed debugger can attach to a debuggee at a time.

 

Managed-only debugging is actually separate from native-only debugging. (This is related to using a helper-thread). If a process is being managed-only debugged, the OS does not view it as being native-only debugged.

 

This allows the loophole to attach 1 managed and 1 native debugger to an app at the same time. That would circumvent the checks.

 

To make matters worse, we can’t fully detect this scenario. The native debug APIs know nothing of managed-debugging, and so can’t enforce this. The inprocess-portion of the managed-debugging APIs could call IsDebuggerPresent to check if a native-debugger is attached, but the native-debugger could attach between such calls. There’s also not a good way for the managed debugger to respond even once it detects this situation.

 

Why would anybody want to do this?

There are actually a few scenarios to motivate attaching multiple debuggers to an app.

1)      Getting more functionality – A native-only debugger can only debug the native portions of the app. Likewise, A managed-only debugger can only debug the managed-only portions of the app. So what if you want to debug a mixed app with both managed and native code?  One solution would be to attach both debuggers and use them simultaneously. (I think this is what you’d have to do in other similar scenarios; such as debugging VB6 calling native COM objects). We developed interop-debugging (aka “mixed-mode”) to explicitly enable this scenario. It allows a single debugger to debug both the managed and native portions of the app. Visual Studio supports mixed-mode debugging.

2)      Debugging servers. Some server apps (like ASP.Net + SQL) may run code on behalf of multiple users. Ideally, each user could just attach a debugger simultaneously and debug their portion of the code running on the server.  We hope to support these scenarios in a future CLR version via per-appdomain debugging (instead of just per-process debugging).
 

Comments (12)

  1. Stephane Rodriguez says:

    But this doesn’t allow a managed library t o be debugged if it’s started by an unmanaged app, does it? Case in point : debugging Google deskbar add-ons (hosted by explorer.exe), which are based on .NET assemblies.

    Any workaround?

  2. Mike Stall says:

    Sure it does. ICorDebug can attach a managed debugger to a native-app. It will just be very uninteresting until the app actually loads native code. (Eg, spawn notepad.exe from Cordbg/Mdbg.exe).

    However, I think Visual Studio may explicitly disallow this in v1.1 – though I thought they added support for it in v2.0 (I’d better check…)

  3. Chango V. says:

    The managed VS debugger doesn’t let you attach to a process that doesn’t run managed code (yet), but you can start any executable with it. It does some assembly loading interception and activates breakpoints defined in a source file as soon as a matching assembly is loaded. Neat.

  4. Dmitriy Zaslavskiy says:

    I had a scenario where attaching another debugger (windbg) is usefull.

    Mixed mode is somewhat painfull and managed debugger doesn’t allow browse objects. So just add windbg/sos to the mix. And yes it confuses VS on occasion so just attach in non-invasive mode and remember to "g" after you done in windbg

  5. Mike Stall says:

    Chango – thanks for the confirmation about VS. One trivia – it’s actually the module-load (not assembly-load) event to check for new source files.

    Dmitriy – we use Windbg to debug the in-process portion of the managed-debugging services all the time. Windbg’s "gn" vs. "g" commands let us ensure that the native exceptions all get delegated properly.

    Unfortunately, VS doesn’t offer quite that granularity (nor does it offer non-invasive debugging).

  6. Anonymous says:

    Chris talks about how Borland’s debugger approaches mixed mode debugging.

  7. I wrote a simple tool to take a snapshot of a running managed process and dump the output as an XML file….

  8. Don’t have your non-debugger app use the debugging services just to get some cool functionality. The

  9. We are trying to unravel and get to the bottom of the above limitation, not allowing us to perform code