簡體   English   中英

為什么 fclose 會掛起/死鎖? (視窗)

[英]Why would fclose hang / deadlock? (Windows)

我有一個目錄更改監視器進程,它從一組目錄中的文件中讀取更新。 我有另一個進程對這些目錄(測試程序)的大量文件執行小寫操作。 圖大約 100 個目錄,每個目錄有 10 個文件,每秒大約有 500 個文件被修改。

運行一段時間后,目錄監視器進程掛起對fclose()的調用,該方法基本上是拖尾文件。 在此方法中,我fopen()文件,檢查句柄是否有效,進行幾次搜索和讀取,然后調用fclose() 這些讀取都是由進程中的同一個線程執行的。 掛起后,線程永遠不會繼續。

我找不到任何關於為什么fclose()可能會死鎖而不是返回某種錯誤代碼的好信息。 該文檔確實提到_fclose_nolock() ,但它似乎對我不可用(Visual Studio 2003)。

調試和發布版本都會發生掛起。 在調試版本中,我可以看到fclose()調用_free_base() ,它在返回之前掛起。 Some kind of call into kernel32.dll => ntdll.dll => KernelBase.dll => ntdll.dll is spinning. 這是 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 

有什么想法可能在這里發生嗎?

我將此作為評論發布,但我意識到這本身可能是一個答案......

根據反匯編,我的猜測是您已經覆蓋了一些由ntdll維護的內部堆結構,並且它永遠循環遍歷鏈表。

特別是在循環開始時,當前列表節點似乎在ebx中。 在循環結束時,預期的最后一個節點(或終止符,如果你喜歡 - 它看起來有點像這些循環列表,最后一個節點與第一個節點相同,指向該節點的指針位於[edi+4Ch] ) 包含在eax中。 可能cmp ebx, eax的結果永遠不會相等,因為堆損壞引入的列表中有一些循環。

我不認為這與鎖有任何關系,否則我們會看到一些原子指令(例如lock cmpxchgxchg等)或調用其他同步函數。

我的文件關閉 function 也有同樣的情況。 在我的情況下,我通過找到嵌入的其他 function 主體而不是擁有自己的 function 來解決問題。

我也懷疑 (1) 被復制的文件的名稱 (2) Windows 調度(文件 IO 在下一個任務開始之前沒有完成。Windows 調度在幕后,所以它是多線程的,驗證,但是當我嘗試在循環中以 ASCII 格式保存許多數據時,我遇到了類似的問題。在這種情況下解決了二進制保存問題。)

我的環境,IDE:Visual Studio 2015,操作系統:Windows 7,語言:C++

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM