반응형

http://process3.blog.me/20065867268

WinDbg를 이용해서 Critical Section 추적해 보기. 

2009/04/17 17:16

복사http://process3.blog.me/20065867268


 최근에 덤프를 하나 분석하고 있는데 동기화 관련해서 이슈가 발생한것 같습니다. criticalsection 관련 WinDbg 명령하나를 정리합니다. 필요하신 분들 참고하세요~

 

1) 문제가 있는 CriticalSection 오브젝트가 있는지 확인한다.

 

0:019> !locks -o
Looking for orphaned critical sections

CritSec at 100a4824 could not be read
Perhaps the critical section was a global variable in a dll that was unloaded?

CritSec at 100a4648 could not be read
Perhaps the critical section was a global variable in a dll that was unloaded?

CritSec at 100a47e0 could not be read
Perhaps the critical section was a global variable in a dll that was unloaded?

CritSec at 100a4660 could not be read
Perhaps the critical section was a global variable in a dll that was unloaded?

Scanned 650 critical sections

 

총 650개 critical sections 중에 약 4개가 문제가 있는것 같습니다.

 

2)!cs 명령을 통해서 좀 더 자세하게 확인해 보겠습니다.

0:019> !cs -l
-----------------------------------------
DebugInfo          = 0x00154990
Critical section   = 0x008f211c (+0x8F211C)
LOCKED
LockCount          = 0x0
OwningThread       = 0x000001c0
RecursionCount     = 0x1
LockSemaphore      = 0x0
SpinCount          = 0x00000000
-----------------------------------------
DebugInfo          = 0x001497a0
Critical section   = 0x008f335c (+0x8F335C)
LOCKED
LockCount          = 0x0
OwningThread       = 0x00000204
RecursionCount     = 0x1
LockSemaphore      = 0x0
SpinCount          = 0x00000000
-----------------------------------------
DebugInfo          = 0x00149840
Critical section   = 0x008f304c (+0x8F304C)
LOCKED
LockCount          = 0x0
OwningThread       = 0x00000208
RecursionCount     = 0x1
LockSemaphore      = 0x0
SpinCount          = 0x00000000
Cannot read structure field value at 0x100a4828, error 0
Cannot determine if the critical section is locked or not.
-----------------------------------------
Critical section   = 0x100a4824 (+0x100A4824)
DebugInfo          = 0x0015a198
Cannot read structure field value at 0x100a464c, error 0
Cannot determine if the critical section is locked or not.
-----------------------------------------
Critical section   = 0x100a4648 (+0x100A4648)
DebugInfo          = 0x0015a2d0
Cannot read structure field value at 0x100a47e4, error 0
Cannot determine if the critical section is locked or not.
-----------------------------------------
Critical section   = 0x100a47e0 (+0x100A47E0)
DebugInfo          = 0x0015a2f8
Cannot read structure field value at 0x100a4664, error 0
Cannot determine if the critical section is locked or not.
-----------------------------------------
Critical section   = 0x100a4660 (+0x100A4660)
DebugInfo          = 0x0015a320
-----------------------------------------
DebugInfo          = 0x001676d8
Critical section   = 0x009609ac (+0x9609AC)
LOCKED
LockCount          = 0x0
OwningThread       = 0x0000064c
RecursionCount     = 0x1
LockSemaphore      = 0x0
SpinCount          = 0x00000000
-----------------------------------------
DebugInfo          = 0x001771e8
Critical section   = 0x00978664 (+0x978664)
LOCKED
LockCount          = 0x0
OwningThread       = 0x000001c0
RecursionCount     = 0x1
LockSemaphore      = 0x0
SpinCount          = 0x00000000
-----------------------------------------
DebugInfo          = 0x001478b0
Critical section   = 0x00978684 (+0x978684)
LOCKED
LockCount          = 0x0
OwningThread       = 0x000001c0
RecursionCount     = 0x1
LockSemaphore      = 0x0
SpinCount          = 0x00000000

...

 

이 프로그램이 생각보다 많은 Critical Section 오브젝트를 사용하고 LOCKED 되어 있는것도 많습니다.

또한 Looking for orphaned critical sections(소유자가 없는 Critical Section 오브젝트)도 4개나 있습니다.

 

3) 소유주가 없는 Critical Section 오브젝트를 좀 더 조사해 봅시다.

0:019> !cs -o 0x100a4648 
Cannot read DebugInfo adddress at 0x100a4648. Possible causes:
 - The critical section is not initialized, deleted or corrupted
 - The critical section was a global variable in a DLL that was unloaded
 - The memory is paged out

Cannot read structure field value at 0x100a464c, error 0
Cannot determine if the critical section is locked or not.
-----------------------------------------
Critical section   = 0x100a4648 (+0x100A4648)
DebugInfo          = 0x00000137

 아래 3가지 경우중에 하나이면 소유주가 없는  Critical Section 오브젝트가 생겨서 크래쉬가 발생하고 문제 해결이 정말 어려워지는 버그가 발생합니다.

 - 초기화 되지 않았거나 지워졌거나 오염된 경우(The critical section is not initialized, deleted or corrupted)
 - DLL에서 전역변수로 Critical Section 오브젝트가 선언되었는데 DLL이 언로드된 경우 (The critical section was a global variable in a DLL that was unloaded)
 - 메모리가 페이지 아웃된 경우 (The memory is paged out)

 

 

[Critical section 에서 문제가 발생할 수 있는 상황 정리]

1. InitializeCriticalSection(...) 함수를 호출 하지 않았다.
2. 여러번 InitializeCriticalSection(...) 호출되었고 DeleteCriticalSection(...)이 한번도 호출되지 않은 상황에서 다시 초기화된 경우
3. DeleteCriticalSection(...) 호출되었다 그러나 Critical section  오브젝트가 계속해서 참조되고 사용된다.
4. 스레드에서 EnterCriticalSection(...) 호출되고 사용된다. 그러나 LeaveCriticalSection(...).함수를 호출하지 않았다. 그리고 다른 스레드에서 EnterCriticalSection(...).함수를 호출해서 사용한다.

즉, 메모리에 선언되지 않았거나 메모리에서 지워진  Critical section   오브젝트를 사용하면 큰일 난다

 

1)초기화 하지 않은 Critical section 오브젝트

// Not initilize the Critical section.
// Global variable
CRITICAL_SECTION CriticalSection; 
int _tmain(int argc, _TCHAR* argv[])
{
    //InitializeCriticalSection(&CriticalSection);
    EnterCriticalSection(&CriticalSection);
  
    LeaveCriticalSection(&CriticalSection);

    DeleteCriticalSection(&CriticalSection);
    return 0;
}

 

2)삭제된 Critical section 오브젝트 참조하기
// Global variable
CRITICAL_SECTION CriticalSection; 
DWORD WINAPI ThreadProc( LPVOID lpParameter )
{
 //InitializeCriticalSection(&CriticalSection);
    // Request ownership of the critical section.
    EnterCriticalSection(&CriticalSection); 
    // Release ownership of the critical section.
    LeaveCriticalSection(&CriticalSection);
 DeleteCriticalSection(&CriticalSection);
 return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
    // Initialize the critical section one time only.
    InitializeCriticalSection(&CriticalSection);
 CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
  
 Sleep(3000);
 EnterCriticalSection(&CriticalSection);
 LeaveCriticalSection(&CriticalSection);
 DeleteCriticalSection(&CriticalSection);
 return 0;
}


출처 : 다년간의 프로그램밍 삽질(경험)->요즈음 나를 괴롭히는 버그... ㅠㅠ 그리고 구글 검색으로부터...


반응형

+ Recent posts