Ratio between Managed and Native Modules
There is not always a 1:1 correlation between Managed modules and native modules. For example,
- Sometimes it's (managed:unmanaged) 1:1. (Normal file-based modules) This is the common case, so people tend to assume it's always true. Regular file-based managed modules are implemented on top of native modules. So if you load C# module foo.dll, the process is loading a native module foo.dll which shows up in the native module lists.
- Sometimes it's 1:0. (In-memory modules) However, the CLR can have managed modules that don't have a native module counterpart. For example, the CLR supports purely in-memory modules (Assembly.Load(Byte []). Also, ref.Emit (and services built on that like CodeDom) can create pure in-memory modules too. These don't have any associated native module.
- Sometimes it's 1:2. (Ngen) Ngen images are implemented on top of native modules, so a managed foo.dll may show up as foo.ni.dll (see debugging ngen code for more details). Thus a single managed dll (foo.dll) may correspond to 2 native dlls (foo.dll, foo.ni.dll)
- Sometimes it's n:1. (Domain-neutral Sharing). As an optimization, the CLR can share certain modules (such as mscorlib) across multiple appdomains. So there will be 1 native module loaded under the hood for the entire process, but it will appear as 1 managed module in each appdomain.
There are probably more combos I'm missing.
Other trivia:
- Windows has some nice APIs for viewing native module lists, like kernel32!CreateToolHelp32Snapshot. There are nice tools too, like listdlls.exe.
- Viewing the native-modules is a rough approximation for the managed modules, and is often good enough. But the only correct way to view all managed modules is via the ICorDebug, the managed debugging API. Here's a sample to view managed modules.
- The System.Diagnostics.ProcessModule class represents native modules, because it's just a wrapper around the APIs for enumerating native modules. So don't think that just because it's a C# API, that it only aplies to C# constructs!
- When interop-debugging, the module window will show both managed and native modules (and it will tell you which is which). Since some managed modules are built on native modules, you'll see 2 entires in the module window. One will be managed, and one will be native.
Comments
Anonymous
February 22, 2007
AppDomain.GetAssemblies() seems like better alternative than ICorDebug (where that is applicable, of course).Anonymous
February 23, 2007
Mihailik - you're right. Reflection also lets you get the managed modules. I was focusing on out-of-process tool APIs and forgot about the in-process reflection options.