Search code examples
clrcoreclrmscorwks.dll

Where is COMDynamicWrite.SavePEFile implemented?


I am debugging an issue saving a dynamic assembly to disk, and I want to see what exceptions can be thrown when saving an assembly PE file to disk. The save code eventually calls down to AssemblyBuilder.Save which eventually calls the internal method ModuleBuilder.SavePEFile. This method is an internal QCall and the target method is declared in a class called COMDynamicWrite. However, the entire repository doesn't seem to have an implementation for this method.

Where, and how, is COMDynamicWrite::SavePEFile implemented?


Solution

  • Let's get this answered, there's a relevant detail that anybody that looks at the CoreCLR project should be aware of. I am 90% sure that the .NETCore and the full version of the CLR were built from the same codebase. Things that should not be the core version were disabled with #ifndef FEATURE_CORECLR. You'll for example find AppDomain support back, a feature that is not in .NETCore and isn't planned to ever be in there.

    They took a big step on Feb 10th 2017 that permanently divorces the CoreCLR codebase from its roots. They aggressively deleted code that is always disabled when FEATURE_CORECLR is not in effect. Probably to make the porting effort a bit more manageable, I imagine they got a lot of patches to this code.

    That also deleted COMDynamicWrite::SavePEFile(). A typical porting problem since Unix does not use the PE32 executable file format. It is still there in the previous version.

    I recommend in general to use the first checked-in version of CoreCLR for this kind of exploration. It has the least amount of patches and therefore most likely to accurately represent desktop CLR behavior. Likewise, be wary of changes to the CLR after the split. Very hard to see of course. While it is largely in maintenance mode, I do know for example that they tinkered with the GC to make it able to better deal with giant multi-gigabyte heap sizes. Only because it caused a nasty bug in 4.6, fixed in 4.6.1