Я получаю ошибку повреждения кучи в модуле библиотеки C#, который я вызываю через COM в приложении C++. Конкретная ошибка:
HEAP: Free Heap block 4b61bb8 modified at 4b61be8 after it was freed
...
This may be due to a corruption of the heap, and indicates a bug in [app].exe or any of the DLLs it has loaded.
Верх стека вызовов:
CustomMarshalers.dll!System.Runtime.InteropServices.CustomMarshalers.EnumeratorViewOfEnumVariant.MoveNext() + 0x168 bytes
Теперь я понял, что .NET должен был смягчать проблемы с памятью, а не делать больше проблем с памятью, которые невозможно было исправить. Тем не менее, я не могу придумать, что бы я делал, чтобы вызвать ошибку памяти, или как я мог бы попытаться исправить это. Конкретный модуль использует компоненты Microsoft.VisualStudio.VCProjectEngine .NET для итерации файлов проекта VC с довольно простыми итераторами. Он нарушает оператор foreach при итерации файлов в фильтре (папке) VCProject после успешного выполнения примерно 100 предыдущих вызовов. Фактический код, который ломается:
IVCCollection CollectionFiles = (IVCCollection)FolderInProject.Files;
foreach (VCFile File in CollectionFiles)
{
[...]
}
Как я могу отладить это?
Обновлять:
Когда я вызываю if из чистого консольного приложения C# (без использования COM или собственного кода), я получаю:
An unhandled exception of type 'System.AccessViolationException' occurred in [component].dll
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
По-прежнему не понимаю, как я могу это отладить. Очевидно, где-то происходит ошибка памяти ... но как я могу отследить ее в чистом управляемом коде, когда модель памяти даже не отображается?
Что такое PIA? Я создаю публичный интерфейс, если вы об этом спрашиваете. Раньше я успешно создавал и использовал COM-объекты, и этот работает, если я немедленно вернусь; он не работает только при использовании объектов VC .NET. Также см. Мое продолжение.
PIA: msdn.microsoft.com/en-us/library/aax7sdch(VS.80).aspx
Хороший момент по поводу ответа / редактирования, я соответствующим образом обновил исходный вопрос.





Похоже, ваш COM-интерфейс неправильно маршалирует переменную параметра / возврата, в результате чего либо сборщик мусора неожиданно освобождает управляемую память, либо неуправляемую память удаляют из-за неправильного маршалинга. Вы можете получить более тонкий контроль над COM-интерфейсом, создав свой собственный Первичная сборка взаимодействия для COM-компонента. Приложив немного усилий, вы можете изучить вызывающий нарушение метод на COM-объекте и убедиться, что все его параметры имеют правильные метаданные, чтобы гарантировать, что они правильно упорядочены.
Другая возможность заключается в том, что вы все правильно маршалируете, но не совсем правильно вызываете интерфейс, что проявляется в неправильном использовании параметра, который в конечном итоге приводит к уничтожению неуправляемой памяти. Их не так интересно отслеживать, особенно если у вас нет доступа к источнику COM.
Один из приемов состоит в том, чтобы позволить программе аварийно завершить работу вне вашего отладчика, нажмите кнопку «Отладка», после чего появится окно выбора JIT Debugger. Затем установите флажок «Выбрать механизм отладки» (или что-то в этом роде) и убедитесь, что установлены флажки «Управляемый» и «Собственный». Экземпляр VS, который появляется, должен быть поврежден в фактическом умершем коде, а не в самом близком к смерти управляемом коде.
Однако я не думаю, что это COM-часть; в моем тестовом использовании консольного приложения нет использования COM. Я подозреваю, что это как-то связано с классами автоматизации Visual Studio, но я понятия не имею, как это отлаживать.
Вы создали PIA для модуля COM или использовали предварительно созданный PIA?