#c# #visual-studio #debugging #memory #interop
Вопрос:
Я получаю ошибку повреждения кучи в модуле библиотеки C#, который я вызываю через COM в приложении C . Конкретная ошибка заключается в:
КУЧА: Свободный блок кучи 4b61bb8 изменен в 4b61be8 после его освобождения
…
Это может быть связано с повреждением кучи и указывает на ошибку в [app].exe или любой из загруженных библиотек DLL.
Верхняя часть стека вызовов находится:
CustomMarshalers.dll!System.Runtime.InteropServices.CustomMarshalers.EnumeratorViewOfEnumVariant.MoveNext() 0x168 bytes
Теперь я понял, что это так .Предполагалось, что NET смягчит проблемы с памятью, а не сделает так, чтобы больше проблем с памятью было невозможно исправить. Тем не менее, я не могу придумать ничего, что я мог бы сделать, чтобы вызвать ошибку в памяти, или как я мог бы попытаться ее исправить. Конкретный модуль использует Microsoft.VisualStudio.Проект VC .СЕТЕВЫЕ компоненты для итерации файлов проекта VC с помощью довольно простых итераторов. Это нарушает инструкцию foreach при повторении файлов в фильтре (папке) VCProject после успешного выполнения предыдущих примерно 100 вызовов. Фактический код, который нарушается, — это:
IVCCollection CollectionFiles = (IVCCollection)FolderInProject.Files;
foreach (VCFile File in CollectionFiles)
{
[...]
}
Как я могу приступить к отладке этого?
Обновить:
Когда я звоню, если из чистого консольного приложения C# (без участия COM или собственного кода), я получаю:
Необработанное исключение типа » Система.Исключение AccessViolationException’ произошло в [компоненте].dll
Дополнительная информация: Попытка чтения или записи защищенной памяти. Это часто указывает на то, что другая память повреждена.
Все еще понятия не имею, как я мог бы заняться отладкой этого. Очевидно, где-то произошла ошибка в памяти… но как я могу отследить это в чистом управляемом коде, где модель памяти даже не раскрывается?
Комментарии:
1. Вы создали PIA для COM-модуля или использовали предварительно созданный PIA?
2. Что такое PIA? Я создаю общедоступный интерфейс, если вы об этом спрашиваете. Я уже создавал и успешно использовал COM-объекты раньше, и этот работает, если я немедленно вернусь; он выходит из строя только при использовании объектов VC .NET. Кроме того, ознакомьтесь с моими последующими действиями.
3. PIA: msdn.microsoft.com/en-us/library/aax7sdch(ПРОТИВ 80).aspx
4. Хороший момент в вопросе об ответе/редактировании, я соответствующим образом обновил исходный вопрос.
Ответ №1:
Похоже, что ваш COM-интерфейс неправильно маршалирует переменную параметра/возврата, в результате чего либо управляемая память неожиданно освобождается GC, либо неуправляемая память уничтожается из-за неправильного маршалинга. Вы можете получить более точный контроль над интерфейсом COM, созданным путем создания собственной основной сборки взаимодействия для компонента COM. Немного поработав, вы можете изучить метод-нарушитель на COM-объекте и убедиться, что все его параметры имеют правильные метаданные, чтобы убедиться, что они правильно упорядочены.
Теперь другая возможность заключается в том, что вы все правильно упорядочиваете, но не совсем правильно вызываете интерфейс, что проявляется в неправильном использовании параметра, который в конечном итоге уничтожает неуправляемую память. Их менее интересно отслеживать, особенно если у вас нет доступа к источнику COM.
Один из трюков состоит в том, чтобы разрешить программе аварийно завершать работу за пределами вашего отладчика, нажмите кнопку Отладка, в результате чего откроется окно отладчика pick JIT. Затем установите флажок «Выбрать механизм отладки» (или что-то в этом роде) и убедитесь, что установлены флажки «Управляемый» и «Собственный». Экземпляр VS, который появляется, должен быть разбит в фактическом коде, который умер, а не в ближайшем управляемом коде к смерти.
Комментарии:
1. Однако я не думаю, что это часть COM; в моем приложении для тестовой консоли нет использования COM. Я подозреваю, что это как-то связано с классами автоматизации Visual Studio, но я понятия не имею, как это отладить.