MDbg, Managed-debugging, and 64 bit

V2 CLR added support for 64-bit (amd64 and ia64), and that includes managed-debugging support. So a 64-bit MDbg can debug a 64-bit managed app. But what about cross-platform stuff when your debugger and debuggee are different platforms? Here's how MDbg and managed-debugging work across the 32/64 bit divide. 

The quick story is that Mdbg is pure IL and thus could be built platform neutral. However, the implementation of ICorDebug (mscordbi.dll) is native code, and thus platform specific (ICorDebug is the underlying managed-debugging interfaces). The problem is how does Mdbg know which mscordbi to invoke when MDbg instantiates an ICorDebug object?  Answering that question means Mdbg takes a subtle dependency on the platform. Thus we actually compile MDbg with a specific bitness (using /platform), even though it is pure IL. There are bit-specific versions of the framework, and so each version gets the corresponding bit-specific version of MDbg.

About 64-bit and other platforms:
On 64-bit machines, both the 32-bit and 64-bit CLR may be installed on the machine in separate directories. A pure-IL managed app can thus run in either 64-bit or 32-bit mode. In 32-bit mode, it loads the 32-bit CLR, and pinvokes to system dlls will resolve against the 32-bit version of those dlls. In 64-bit mode, it's a 64-bit pipeline.  If you run an assembly as 32-bit on a 64-bit machine, it will run in the WOW susbsystem.   Josh Williams has more details here.

When compiling a C# assembly, you can set the bitness with the /platform compiler flag to CSC. Or you can use CorFlags to change the bitness on an already-compiled assembly.

How does Mdbg instantiate ICorDebug?
Mscordbi.dll is loaded via a pinvoke call to mscoree!CreateDebuggingInterfaceFromVersion. If MDbg is running in 32-bit mode, it will pinvoke into the 32-bit version of mscoree and thus instantiate the 32-bit version of mscordbi. If Mdbg is running in 64-bit mode, by the same reasoning it will instantiate the 64-bit version of mscordbi. This is why that even though Mdbg is pure-IL, it compiles with platform affinity.

Debugging across 32/64 bit boundaries
At the ICD level, all managed debugging is local (what VS calls "remote-debugging", CLR calls "remote UI"). This also includes not debugging across the 32/64-bit boundary. So a 32-bit ICorDebug can't attach to a 64-bit debuggee, and vice-versa. Trying to cross this boundary gives a CORDBG_E_UNCOMPATIBLE_PLATFORMS hresult..  This means that if you want to debug 32-bit processes, you must spawn the 32-bit version of Mdbg.

What about platform specific code in Mdbg?
Almost all of  MDbg is platform neutral because ICD absorbs the platform specific stuff. A few platform-specific things (like dumping registers, native-disassembly) are in a platform-specific satellite dll, MdbgDis.dll. Here's the platform dependencies for the different parts of the SDK-version of Mdbg:

dll language platform specific? description
mscordbi.dll native C++ Yes Part of CLR redist for the platform specific implementation of ICorDebug
Mdbg.exe, MdbgCore.dll pure ILC#, IL No Bulk of Mdbg's functionality, including shell, all UI, and all commands.
MDbgDis.dll MC++  Yes Platform specific code for an Mdbg extension dll to provide native disassembly functions in the SDK version of MDbg.  MC++ helps it bridge the C++ disassembly functions to the managed Mdbg extension model. This is optional functioanlity.

What about EnC / Interop-debugging?
Edit-And-Continue (EnC) is only supported for x86. Thus to do EnC when developing on Mdbg on a 64-bit machine, you must be running it as a 32-bit app.  I believe the sample currently builds Mdbg in x86 mode, partly so that EnC is on by-default. Interop-debugging is also only supported on x86.

The bottom line:
If you want to debug a 32-bit app, you must launch a 32-bit MDbg. Ditto for 64-bit. This also means that a single MDbg instance can't debug processes from different architectures.

That may be annoying to the end-user to have to pick which version of the tool to launch in order to know what to debug. There are games you can play to get around that. For example, only your debug-engine needs to have the right platform-affinity. You could have a proxy, platform neutral shell, which then launched a separate process for the debug-engine in the proper bitness. The shell and debug-engine would need to communicate across processes.  That's all more complicated, but it would have a nicer end-user experience. I believe VS does some things like this.