Tuesday, December 19, 2006

WaitForSingleObject をデバッグする

Visual Studio を使っていて、F5 を押してデバッグしようと思ったらとまってしまったので Visual Studio をデバッグしてみました。

今回参考にしたページはこちらです。
How to find out on which thread a blocked thread is waiting

Adplus
を使って devenv.exe のダンプをとり、調べてみると・・・

ビルド中で、何かを WaitForSingleObject で無制限に待っている状態です。
 

0:000> kb
ChildEBP RetAddr Args to Child
0012f184 7c94e9c0 7c8025db 000004fc 00000000 ntdll!KiFastSystemCallRet
0012f188 7c8025db 000004fc 00000000 00000000 ntdll!ZwWaitForSingleObject+0xc
0012f1ec 7c802542 000004fc ffffffff 00000000 kernel32!WaitForSingleObjectEx+0xa8
0012f200 53820169
000004fc ffffffff 00000000 kernel32!WaitForSingleObject+0x12
0012f288 537fc73d 00000000 09645e10 00000000 csproj!
RunProcess+0x135
0012f3c8 537fbe13 096682e0 096740b0 0012f428 csproj!CLangSatelliteAssembly::CallLinker+0x2fb
0012f3e8 537ba073 096682e0 00000001 0012f428 csproj!CLangSatelliteAssembly::Build+0x9a
0012f420 5377c54d 00000000 00000001 043bfc60 csproj!CLangSatelliteManager::Build+0xdc
0012f448 5377c59f 00000000 5377ce5c 00000000 csproj!CLangCompiler::GenerateSatellites+0xac
0012f450 5377ce5c 00000000 00000001 043bfc60 csproj!CLangCompiler::DoPostCompile+0x16
0012f480 5377ce04 00000001 00000000 043b2104 csproj!CVsProjBuildableProjectCfg::EndBuildProcess+0x51
0012f490 5377af59 043bfc64 00000001 00000000 csproj!CVsProjBuildableProjectCfg::BuildEnd+0x3b
0012f4c0 5377b113 00000000 00000000 043bfc60 csproj!CCSharpBuildCompiler::DoMainBuild+0x18b
0012f4d0 5377b2f1 00000000 043bfc64 039be3f8 csproj!CLangCompiler::StartCompilation+0x5d
0012f4f4 5377b396 039be3b4 500128a5 043bfc60 csproj!CVsProjBuildableProjectCfg::StartBuildProcess+0x1d6
0012f4fc 500128a5 043bfc60 039be3bc 00000000 csproj!CVsProjBuildableProjectCfg::StartBuild+0x3f
0012f518 500127c4 039be3b4 502eaf38 500133ca msenv!CSUIBuilder::DoBuild+0xbf
0012f524 500133ca 00000000 00000000 0012f5d0 msenv!CSUIBuilder::Run+0x41
0012f540 50012ba0 0012f56c 500c9aa9 00000113 msenv!CSlnUpdate::RunBuild+0x60
0012f548 500c9aa9 00000113 00000157 00000000 msenv!CSlnUpdate::HandleMsg+0x58


WaitForSingleObject の第一パラメータはハンドルなので、何を待っているのか確認してみます。
 

0:000> !handle 000004fc f
Handle 000004fc
Type Process
Attributes 0
GrantedAccess 0x1f0fff:
Delete,ReadControl,WriteDac,WriteOwner,Synch
Terminate,CreateThread,,VMOp,VMRead,VMWrite,DupHandle,CreateProcess,SetQuota,SetInfo,QueryInfo,SetPort
HandleCount 3
PointerCount 61
Name
Object specific information
Process Id
2568
Parent Process 2364
Base Priority 8
 

PID 2568 のプロセスを待っています。

自分自身のプロセス情報を見てみると・・・
0:000> |
. 0 id: 93c examine name: G:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE\devenv.exe
0:000> ?93c
Evaluate expression:
2364 = 0000093c
PID
が違うので、他のプロセスを待っています。

ここで adplus が出力しているプロセス リストを見てみると・・・

0 64 2568 al.exe Title: C:\WINDOWS2\Microsoft.NET\Framework\v1.1.4322\al.exe
Command Line:


リンカを待っていることがわかりました。

RunProcess
の引数を勘で適当にダンプしてみたら・・・
0:000> du 09645e10
09645e10 ""C:\WINDOWS2\Microsoft.NET\Frame"
09645e50 "work\v1.1.4322\
al.exe" /nologo /"
(略)
 
リンカを起動して、al.exe の起動か処理が完了してないのでハングしたことがわかりました。
でも、今回は al.exe のダンプを取ってなかったので、これ以上はわかりません。

ちょこっと他のスレッドも除いてみることにしました。
 

0:000> ~2s
eax=791d24e3 ebx=049afea4 ecx=00000080 edx=00000002 esi=00000000 edi=7ffde000
eip=7c94eb94 esp=049afe7c ebp=049aff18 iopl=0 nv up ei pl zr na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ntdll!KiFastSystemCallRet:
7c94eb94 c3 ret

0:002> kb
ChildEBP RetAddr Args to Child
049afe78 7c94e9ab 7c8094f2 00000003 049afea4 ntdll!KiFastSystemCallRet
049afe7c 7c8094f2 00000003 049afea4 00000001 ntdll!ZwWaitForMultipleObjects+0xc
049aff18 7c809c86 00000003 049aff58 00000000 kernel32!WaitForMultipleObjectsEx+0x12c
049aff34 791d1707
00000003 049aff58 00000000 kernel32!WaitForMultipleObjects+0x18
049aff9c 791d167e 00000000 7c953288 00000000 mscorwks!DebuggerRCThread::MainLoop+0x90
049affac 791d24ee 049affec 7c80b50b 047e1eb0 mscorwks!DebuggerRCThread::ThreadProc+0x68
049affb4 7c80b50b 047e1eb0 7c953288 00000000 mscorwks!DebuggerRCThread::ThreadProcStatic+0xb
049affec 00000000 791d24e3 047e1eb0 00000000 kernel32!BaseThreadStart+0x37

WaitForMultipleObjects
3 つのハンドルを待っています。
ポインタの内容をダンプして、次の 3 つのハンドルを待っていることがわかります。

0:002> dd 049aff58 L3
049aff58
0000029c 000002a4 00000294

内容を見てみると・・・

0:002> !handle 0000029c f
Handle 0000029c
Type Event
Attributes 0
GrantedAccess 0x1f0003:
Delete,ReadControl,WriteDac,WriteOwner,Synch
QueryState,ModifyState
HandleCount 2
PointerCount 4
Name
No object specific information available

イベント ハンドルです。
他の 2 つも同じですけど、イベント ハンドルはカーネル デバッグをしないとわからないので今回はここまでになります。

No comments:

Post a Comment