Обнаружил очередную приколку в .NET Profiling API - есть событие ObjectsAllocatedByClass, где в качестве одно из аргументов передается массив ClassID. Так вот, если вызвать GetClassIDInfo/GetClassIDInfo2 для этого массива, то можно получить ModuleID для которого тоже можно вызвать GetModuleInfo. Все будет хорошо до тех пор пока GC не произойдет во время выгрузки application domain. Вот тут-то и появится проблема - GetModuleInfo может вернуть CORPROF_E_DATAINCOMPLETE. Так в чем же дело?
В MSDN сказано, что при выгрузке домена все классы и функции этого домена становятся недействительными - мы уже знаем что это ложь: во время выгрузки происходят компиляции функций и выделения объектов из самого выгружаемого домена до получения первого ModuleUnloadStarted. Сбор же мусора начинается как раз после получения всех ModuleUnloadStarted. Соответственно объекты из уже выгруженных модулей попадают в статистику GC. Занавес!