9

ディレクトリのセット内のファイルから更新を読み取るディレクトリ変更監視プロセスがあります。それらのディレクトリへの多くのファイルへの小さな書き込みを実行する別のプロセスがあります(テストプログラム)。それぞれに 10 個のファイルを含む約 100 個のディレクトリがあり、毎秒約 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。ループの終わりに、予想される最後のノード(または必要に応じてターミネーター-これらは循環リストであり、最後のノードは最初のノードと同じであり、このノードへのポインターはにあります[edi+4Ch])はに含まれていますeax。ヒープの破損によってリストにサイクルが発生するため、おそらくの結果がcmp ebx, eax等しくなることはありません。

これはロックとは何の関係もないと思います。そうしないと、いくつかのアトミック命令(たとえばlock cmpxchgxchgなど)または他の同期関数の呼び出しが表示されます。

于 2011-05-31T23:21:16.097 に答える