У меня есть процесс мониторинга изменений каталогов, который считывает обновления из файлов в наборе каталогов. У меня есть другой процесс, который выполняет небольшие записи во многие файлы в эти каталоги (тестовая программа). Рисунок около 100 каталогов с 10 файлами в каждом и около 500 файлов, изменяемых в секунду.
Через некоторое время процесс мониторинга каталогов зависает при вызове fclose()
в методе, который в основном отслеживает файл. В этом методе я fopen()
файл, проверяю правильность дескриптора, выполняю несколько операций поиска и чтения и затем вызываю fclose()
. Все эти чтения выполняются одним и тем же потоком в процессе. После зависания нить никогда не прогрессирует.
Я не смог найти хорошую информацию о том, почему fclose()
может зайти в тупик вместо того, чтобы возвращать какой-то код ошибки. В документации упоминается _fclose_nolock()
, но она мне недоступна (Visual Studio 2003).
Зависание происходит как для отладочной, так и для релизной сборок. В отладочной сборке я вижу, что fclose()
вызывает _free_base()
, который зависает перед возвратом. Какой-то вызов в kernel32.dll => ntdll.dll => KernelBase.dll => ntdll.dll вращается. Вот сборка из ntdll.dll, которая зацикливается бесконечно:
77CEB83F cmp dword ptr [edi+4Ch],0
77CEB843 lea esi,[ebx-8]
77CEB846 je 77CEB85E
77CEB848 mov eax,dword ptr [edi+50h]
77CEB84B xor dword ptr [esi],eax
77CEB84D mov al,byte ptr [esi+2]
77CEB850 xor al,byte ptr [esi+1]
77CEB853 xor al,byte ptr [esi]
77CEB855 cmp byte ptr [esi+3],al
77CEB858 jne 77D19A0B
77CEB85E mov eax,200h
77CEB863 cmp word ptr [esi],ax
77CEB866 ja 77CEB815
77CEB868 cmp dword ptr [edi+4Ch],0
77CEB86C je 77CEB87E
77CEB86E mov al,byte ptr [esi+2]
77CEB871 xor al,byte ptr [esi+1]
77CEB874 xor al,byte ptr [esi]
77CEB876 mov byte ptr [esi+3],al
77CEB879 mov eax,dword ptr [edi+50h]
77CEB87C xor dword ptr [esi],eax
77CEB87E mov ebx,dword ptr [ebx+4]
77CEB881 lea eax,[edi+0C4h]
77CEB887 cmp ebx,eax
77CEB889 jne 77CEB83F
Есть идеи, что здесь может происходить?