9

我有一个目录更改监视器进程,它从一组目录中的文件中读取更新。我有另一个进程对这些目录(测试程序)的大量文件执行小写操作。图大约 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 

有什么想法可能在这里发生吗?

4

2 回答 2

3

我将此作为评论发布,但我意识到这本身可能是一个答案......

根据反汇编,我的猜​​测是您已经覆盖了由 维护的一些内部堆结构ntdll,并且它正在循环遍历链表。

特别是在循环开始时,当前列表节点似乎在ebx. 在循环结束时,预期的最后一个节点(或终止符,如果你喜欢 - 它看起来有点像这些循环列表,最后一个节点与第一个节点相同,指向该节点的指针在 at [edi+4Ch])包含在eax. 可能的结果cmp ebx, eax永远不会相等,因为堆损坏引入的列表中有一些循环。

我认为这与锁没有任何关系,否则我们会看到一些原子指令(例如lock cmpxchg,,xchg等)或对其他同步函数的调用。

于 2011-05-31T23:21:16.097 回答
0

我有一个与文件关闭功能相同的案例。就我而言,我通过定位嵌入其他函数体的关闭函数而不是拥有自己的函数来解决。

我也怀疑 (1) 被复制的文件的名称 (2) Windows 调度(文件 IO 在下一个任务开始之前没有完成。Windows 调度和多线程在幕后,所以很难验证,但是当我尝试在循环中以 ASCII 格式保存许多数据时,我遇到了类似的问题。在这种情况下解决了二进制保存问题。)

我的环境,IDE:Visual Studio 2015,操作系统:Windows 7,语言:C++

于 2017-06-02T23:02:15.277 回答