DirectShow DirectShow 의 사용법 DirectShow 의 기본 태스크 DirectShow 의 디버그   [목차열람] [주소복사] [슬롯비우기]
DirectShow 의 디버그
 
Microsoft DirectX 9.0

DirectShow 의 디버그

이 주제는 Microsoft® DirectShow® 애플리케이션과 필터를 디버그 할 때의 힌트를 몇개인가 제공한다. 여기서 설명하는 디버그 기능의 대부분은 DirectShow base class 라이브러리를 필요로 한다. 더 자세한 정보는, 「DirectShow base class」를 참조할것.

Assert 체크

Assert 체크 라이브러리를 사용하는 것. Assert는 코드내의 필요 조건, 충분조건에 대해 생성 한 가정을 검증한다. DirectShow 는 몇개의 Assert 매크로를 제공한다. 더 자세한 정보는, 「Assert 매크로와 breakpoint 매크로」를 참조할것.

개체명

디버그 빌드에서는,CBaseObject 클래스로부터 파생한 개체의 글로벌 리스트가 있다. 개체가 생성 되면 그 개체는 리스트에 추가된다. 그 개체가 파기되면 리스트로부터 소거된다. 개체의 리스트를 표시하려면 ,DbgDumpObjectRegister 함수를 호출하는 것.

CBaseObject base class (와 거기로부터 파생된 대부분의 클래스)의 생성자 메서드에는 개체명에 대한 파라미터가 포함되어 있다. 그것을 식별하는 고유의 이름을 개체에 붙이는 것. 이름의 선언에 NAME 매크로를 사용하면 이름의 캐릭터 라인은 디버그 빌드시에만 할당할 수 있다. 리테일 빌드에서는, 그 이름은 NULL 가 된다.

디버그 로깅

DbgLog 함수는 프로그램 실행시에 디버그 메시지를 표시한다. 이 함수를 사용해 애플리케이션이나 필터의 실행을 트레이스 하는 것. 반환값이나, 변수의 값, 그 이외의 임의의 관련 정보를 로그 할 수 있다.

모든 디버그 메시지는 LOG_TRACE 나 LOG_ERROR 와 같은 메시지 타입, 메시지의 중요도를 나타내는 디버그 레벨을 가지고 있다. 낮은 디버그 레벨은 높은 레벨보다 중요해진다.

다음의 예에서는, 가짜의 필터가 핀 배열로부터 있는 핀을 접속 해제한다. 접속 해제가 성공하면 필터는 LOG_TRACE 메시지를 표시한다. 그것이 실패 하면, LOG_ERROR 메시지를 표시한다.

hr = m_PinArray[iPin]->Disconnect();
if (FAILED(hr))
{
    DbgLog((LOG_ERROR, 1, TEXT("Could not disconnect pin %d.  HRESULT = %#x", iPin, hr));
 
   // 에러 처리 코드 (생략).
}
DbgLog((LOG_TRACE, 3, TEXT("Disconnected pin %d"), iPin));

디버그중에, 각 메시지 타입의 디버그 레벨을 설정할 수 있다. 또 각 모듈 (DLL 혹은 실행 모듈)은 자기 자신의 디버그 레벨을 보관 유지한다. 필터를 테스트하고 있다면, 그 필터를 가지는 DLL 의 디버그 레벨을 올리는 것.

더 자세한 정보는, 「디버그 출력 함수」를 참조할것.

크리티컬 섹션

데드 록을 보다 용이하게 추적하려면 , 호출 코드가 주어진 크리티컬 섹션 자신을 소유하고 있을지 어떨지를 확인하는 Assert를 인클루드 하는 것. CritCheckInCritCheckOut 함수는 호출해 원의 thread가 크리티컬 섹션을 소유하고 있을지 어떨지를 나타낸다. 보통, Assert 매크로 내부로부터 이러한 함수가 호출된다.

크리티컬 섹션이 취득, 릴리즈 되었을 때에,DbgLockTrace 함수를 사용해 트레이스 할 수도 있다.

포인터의 유효성 평가

디버그 빌드시에 포인터의 유효성을 확인하는 것. 예를 들어,ValidateReadPtr 매크로는 지정한 포인터가 읽어들여 가능한 메모리를 가리키고 있는지를 체크한다. 현재, DirectShow 포인터 유효성 평가 매크로는 IsBadReadPtr 와 같은 Microsoft® Win32® 포인터 유효성 평가 함수를 사용한다. 어느 시스템에서는, 이러한 함수가 지정한 범위에서 페이지 마다 스왑을 일으키는 경우가 있다. 이것은 현저하게 퍼포먼스를 저하시킨다. 더 자세한 정보는, 「포인터 유효 매크로」를 참조할것.

트러블 슈팅의 힌트

이하의 힌트는, 애플리케이션으로 데드 록이나 크래쉬의 발생을 회피하기 위해서 도움이 된다.

글로벌 개체

글로벌 C++ 개체는, 생성자 메서드로 DirectShow 개체를 생성 하거나 소멸자 메서드로 개체를 릴리즈 해서는 안 된다. 이와 같이 하면, 다음과 같은 이유로써 애플리케이션이 무한하게 블록 한다.

thread는, DLL 의 엔트리 포인트 함수내에 있는 동안은 종료할 수 없다. Kernel 32 는, 엔트리 포인트 함수내에서는 글로벌 프로세스 잠금을 보관 유지해, 잠금에 의해 thread를 종료할 수 없게 된다. DirectShow 개체에는 독자적인 thread를 가지는 것이 있으므로, DLL 엔트리 포인트 함수내로부터 릴리즈 하면 블록 할 가능성이 있다. 애플리케이션에 글로벌 C++ 개체가 있는 경우, C 런타임 DLL 는 DLL 가 언로드되었을 때에 개체의 소멸자를 호출한다. 소멸자가 DirectShow 개체를 릴리즈 하면, 결과적으로 블록 할 가능성이 있다.

같은 이유로써, DLL 는 엔트리 포인트 루틴으로 DirectShow 개체를 생성 또는 릴리즈 해서는 안 된다.

인터페이스의 릴리즈

애플리케이션이 메시지를 아직 처리하고 있어, 메시지 루프를 빠지기 전에, 모든 DirectShow 인터페이스 포인터를 릴리즈 하는 것. 그렇게 하지 않으면 일부의 DirectShow 개체는 클린업 루틴의 실행중에 메시지를 송신하기 위해(때문에), 다양한 Assert가 나타나는 일이 있다.

(그 때문에, ATL CWindowImpl 클래스를 사용하는 경우는,OnFinalMessage 가 인터페이스를 릴리즈 할 때까지 대기하지 않는 것. 인터페이스의 릴리즈는, WM_CLOSE 메시지를 처리할 경우에 실시하는 것. )

참조 카운트

Quartz.dll 의 디버그 버전은 언로드 할 때 DirectShow 개체에 릴리즈되지 않은 참조 카운트가 있을지 어떨지를 체크한다. 참조 카운트가 있는 경우, Assert가 발생한다.

g_cFGObjects == 0 

이 Assert가 실패했을 경우, 애플리케이션으로 참조 카운트가 누수 한 것을 의미한다. 코드를 다시 봐, 모든 인터페이스 포인터를 릴리즈 하고 있을지 어떨지 확인하는 것.

참조

↑TOP