Могут ли некорректные дескрипторы потоков в C# быть признаком неуправляемого повреждения памяти?
У нас есть служба C#, которая очень странно перестала работать с дескрипторами потоков. В частности, вызовы EventWaitHandle.Reset, ReaderWriterLock и другие аналогичные вызовы многопоточности произвольно переносятся с ошибками Invalid Handle глубоко в стеке. Это звонки, которые обязательно должны работать. Может ли это быть признаком повреждения памяти? Если это так, мы немного запутались, почему это единственный симптом, а не сбой. У нас есть COM-объекты с кодом C++, где мы делаем HeapFree, а также есть некоторый управляемый код, вызывающий FreeHGlobal, так что это подозрительно. Кто-нибудь сталкивался с чем-то подобным, когда проблемы проявлялись, казалось бы, в локализации потоков?
2 ответа
Оказывается, это была проблема PInvoke. Мы неправильно вызывали дескриптор потока в оболочке C# SafeFileHandle, что в условиях записи сделало бы недействительным дескриптор потока, который впоследствии был перераспределен другими потоками, и произошел гигантский беспорядок. В силу морали этой истории будьте очень осторожны, используя классы-оболочки.net Handle в P-Invoke.
Я не видел этот конкретный симптом. Но я думаю, вполне возможно, что причина, как вы подозреваете, - нет правила, которое говорит, что повреждение памяти должно вызывать сбои.
Представьте, что у вас была такая структура данных
buffer[100];
threadHandle;
И у вас была простая ошибка в коде, заполняющем буфер. Теперь ваш дескриптор нити неисправен, и, вероятно, вы получите симптом, который видите.
Я плохо знаю вашу среду (сейчас я Linux/Java), но может ли другая причина использовать threadHandle после завершения потока? Так ручка действительно больше не действительна? Какое-то состояние гонки в вашем коде завершения?