2012-06-07 2 views
3

C# 2.0의 threadpool을 사용하는 멀티 스레드 응용 프로그램이 몇 주 간격으로 중단됩니다.windbg을 사용하여 멈춘 C# 응용 프로그램에서 교착 상태 감지

 
3073 05b4e144   1   1 17c45c30 1884 518 023dfc2c MyProg.MyChildClass 

979 개 모니터를 들고 스레드가 ArrayList에 있지만 대기중인 모든 다른 스레드가 잠금되어

는 내가 같이 수백 줄을 삭제 한

 
!syncblk 

Index SyncBlock MonitorHeld Recursion Owning Thread Info SyncBlock Owner 
    201 05b9493c   979   1 05bc1040 bcc 45 022f3490 System.Collections.ArrayList 
2875 05b4c914   1   1 17b99e10 1af8 290 024862d8 MyProg.MyChildClass 
3045 05b4dbec   1   1 17ca7e98 1990 664 02392120 MyProg.MyChildClass 
3046 05b4dc1c   1   1 17ca8668 1038 666 02394b00 MyProg.MyChildClass 
3194 05b4f80c   3   1 05b5b638 1594 31 02537b88 MyProg.MyChildClass 
3072 05b4e114   1   1 17d660f0 1120 848 023dd578 MyProg.MyChildClass 
3073 05b4e144   1   1 17c45c30 1884 518 023dfc2c MyProg.MyChildClass 
3390 05b51cfc   3   1 16cefcc0 1350 102 02768868 MyProg.MyChildClass 
3072 05b4e114   1   1 17d660f0 1120 848 023dd578 MyProg.MyChildClass 
3073 05b4e144   1   1 17c45c30 1884 518 023dfc2c MyProg.MyChildClass 

syncblk했다 다른 객체에 독자 잠금을 얻으려고합니다.

나는 어떤 자물쇠가 획득하려고 시도하는 모든 자물쇠인지 알지만 누가 자물쇠를 잡고 있는지 알지 못합니다. 어떻게 찾을 수 있습니까 ??

MonitorHeld = 1 인 모든 스레드의 clrstack 및 dso 출력은 비슷합니다. 979 개의 잠금 (id = 45) 및 reader 스레드 대기 (id = 290) 스레드의 dso 및 clrstack 출력은 다음과 같습니다. 마찬가지로, 내가 ~ * 전자를 수행 할 때! Monitor.Enter 모든 스레드가 다음 2 개 스레드

 
0:000> ~45e !clrstack 
OS Thread Id: 0xbcc (45) 
ESP  EIP  
17fbe590 77d2013d [GCFrame: 17fbe590] 
17fbe6cc 77d2013d [HelperMethodFrame: 17fbe6cc] System.Threading.Monitor.Enter(System.Object) 
17fbe720 00638427 MyProg.MyParentClass.ClockTimeElapsed(System.DateTime) 
17fbe798 00637cf6 MyProg.MyEngine.ClockTimeElapsed(System.Object) 
17fbe830 71df843f System.Threading._TimerCallback.TimerCallback_Context(System.Object) 
17fbe838 71e302ff System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) 
17fbe850 71df83ab System.Threading._TimerCallback.PerformTimerCallback(System.Object) 
17fbe9dc 74071b4c [GCFrame: 17fbe9dc] 
 
0:000> ~45e!dso 
OS Thread Id: 0xbcc (45) 
ESP/REG Object Name 
17fbe5a8 022a2ff4 System.Globalization.DaylightTime 
17fbe5ac 022a2f3c System.Int32 
17fbe5c8 02537b88 MyProg.MyChildClass 
17fbe738 02537b88 MyProg.MyChildClass 
17fbe740 02537b88 MyProg.MyChildClass 
17fbe7ac 11572f28 System.Collections.ArrayList+ArrayListEnumeratorSimple 
17fbe7b0 022f3490 System.Collections.ArrayList 
17fbe7b4 0231860c System.String Error loading MyConfig.txt 
17fbe7c0 022f3014 MyProg.MyEngine 
17fbe84c 0231b48c System.Threading._TimerCallback 
17fbe9fc 0231b48c System.Threading._TimerCallback 
 
0:000> ~290e !clrstack 
OS Thread Id: 0x1af8 (290) 
ESP  EIP  
2e77f39c 77d2013d [HelperMethodFrame_1OBJ: 2e77f39c] System.Threading.ReaderWriterLock.AcquireReaderLockInternal(Int32) 
2e77f3f8 0c3630d4 MyProg.MyEngine.GetBuyValue() 
2e77f424 076fd4ad MyProg.MyParentClass.Execute(System.Object) 
2e77f474 71e19fcf System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(System.Object) 
2e77f47c 71e302ff System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) 
2e77f494 71e1a533 System.Threading._ThreadPoolWaitCallback.PerformWaitCallbackInternal(System.Threading._ThreadPoolWaitCallback) 
2e77f4a8 71e1a3c9 System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(System.Object) 
2e77f638 74071b4c [GCFrame: 2e77f638] 
 
0:000> ~290e!dso 
OS Thread Id: 0x1af8 (290) 
ESP/REG Object Name 
2e77f35c 022f3014 MyProg.MyEngine 
2e77f360 02369b98 System.Threading.ContextCallback 
2e77f378 02369b98 System.Threading.ContextCallback 
2e77f3dc 023188f8 System.Threading.ReaderWriterLock 
2e77f400 024862d8 MyProg.MyChildClass 
2e77f410 02369b98 System.Threading.ContextCallback 
2e77f430 024862d8 MyProg.MyChildClass 
2e77f43c 024862d8 MyProg.MyChildClass 
2e77f460 02369b98 System.Threading.ContextCallback 
2e77f490 1156dd74 System.Threading._ThreadPoolWaitCallback 
+0

미안하지만 형식이 바뀌 었습니다 ... 명령 출력의 올바른 형식으로 게시하려면 어떻게해야합니까? – bsobaid

+0

** pre ** 태그 사용. –

+0

Adriano에게 감사드립니다. – bsobaid

답변

3

난 당신이해야한다고 생각에 clrstack와 같은 스택을 가지고 을 clrstack 이 사람 http://stevestechspot.com/에 의해 작성된 확장 DLL SOSEX를 시도하십시오. 교착 상태를 찾으려는 시도가있는 !dlk 명령이 있으며 최근에 사용자에게 관심이있는 새로운 명령이 추가되었습니다.

mlocks - 관리되는 모든 잠금 장치와 관리되지 않는 CriticalSections, 과 소유자 스레드 ID를 나열합니다. ! mwaits - 기다리는 모든 스레드 을 나열하고, 확인할 수 있으면 대기중인 잠금 개체를 나열합니다.

+0

+1 나는 그 도구를 잘 몰랐다. –

+0

항상 교착 상태를 감지하지는 않습니다. 나도 그걸 시험해 봤고 그건 나에게 교착 상태를 찾지 못했다. 또 다른 관련 명령은! analyze -v -hang입니다. 이것은 실행하는데 좀 더 오래 걸리므로, windbg는 동결되었습니다. – bsobaid

+0

@bsobaid는'! locks'를 시도하지만 아주 오랜 시간 동안 실행되어 양조를합니다 :) – EdChum