다음을 통해 공유


관리 디버깅 도우미를 사용하여 오류 진단

MDA(관리 디버깅 도우미)는 CLR(공용 언어 런타임)과 함께 작동하여 런타임 상태 정보를 제공하는 디버깅 도우미입니다. 이 도우미는 이 경우가 아니면 트래핑할 수 없는 런타임 이벤트에 대한 정보 메시지를 생성합니다. MDA를 사용하여 관리 코드와 비관리 코드 사이에서 전환할 때 발생하는 찾기 어려운 응용 프로그램 버그를 격리할 수 있습니다. Windows 레지스트리에 키를 추가하거나 환경 변수를 설정하여 모든 MDA를 활성화 또는 비활성화할 수 있습니다. 응용 프로그램 구성 설정을 사용하여 특정 MDA를 활성화할 수 있습니다. 응용 프로그램의 구성 파일에서 일부 개별 MDA에 대한 구성 설정을 추가로 설정할 수 있습니다. 이러한 구성 파일은 런타임을 로드할 때 구문 분석되므로 관리되는 응용 프로그램을 시작하기 전에 MDA를 활성화해야 합니다. 이미 시작한 응용 프로그램에 대해서는 MDA를 활성화할 수 없습니다.

참고참고

MDA가 활성화되면 코드가 디버거에서 실행되지 않아도 활성화 상태로 유지됩니다.디버거가 없을 때 MDA 이벤트가 발생하면 이벤트 메시지가 처리되지 않은 예외가 아닐 경우에도 처리되지 않은 예외 대화 상자에 표시됩니다.이 대화 상자가 나타나지 않도록 하려면 코드가 디버깅 환경에서 실행되지 않을 경우에는 MDA 활성화 설정을 제거합니다.

참고참고

코드가 Visual Studio IDE(통합 개발 환경)에서 실행 중인 경우 특정 MDA 이벤트에 대해 예외 대화 상자가 나타나지 않게 할 수 있습니다.이렇게 하려면 디버그 메뉴에서 예외를 클릭합니다.디버그 메뉴에 예외 명령이 들어 있지 않으면 도구 메뉴에서 사용자 지정을 클릭하여 해당 명령을 추가합니다. 예외 대화 상자에서 관리 디버깅 도우미 목록을 확장한 다음 개별 MDA에 대한 Throw됨 확인란의 선택을 취소합니다.예를 들어 contextSwitchDeadlock MDA에 대해 예외 대화 상자가 나타나지 않게 하려면 관리 디버깅 도우미 목록에서 해당 이름 옆에 있는 Throw됨 확인란의 선택을 취소합니다.이 대화 상자를 사용하여 MDA를 활성화할 수도 있습니다.

다음 표에서는 .NET Framework와 함께 제공되는 MDA를 보여 줍니다.

asynchronousThreadAbort MDA

bindingFailure MDA

callbackOnCollectedDelegate MDA

contextSwitchDeadlock MDA

dangerousThreadingAPI MDA

dateTimeInvalidLocalFormat MDA

dirtyCastAndCallOnInterface MDA

disconnectedContext MDA

dllMainReturnsFalse MDA

exceptionSwallowedOnCallFromCom MDA

failedQI MDA

fatalExecutionEngineError MDA

gcManagedToUnmanaged MDA

gcUnmanagedToManaged MDA

illegalPrepareConstrainedRegion MDA

invalidApartmentStateChange MDA

invalidCERCall MDA

invalidFunctionPointerInDelegate MDA

invalidGCHandleCookie MDA

invalidIUnknown MDA

invalidMemberDeclaration MDA

invalidOverlappedToPinvoke MDA

invalidVariant MDA

jitCompilationStart MDA

loaderLock MDA

loadFromContext MDA

marshalCleanupError MDA

marshaling MDA

memberInfoCacheCreation MDA

moduloObjectHashcode MDA

nonComVisibleBaseClass MDA

notMarshalable MDA

openGenericCERCall MDA

overlappedFreeError MDA

pInvokeLog MDA

pInvokeStackImbalance MDA

raceOnRCWCleanup MDA

reentrancy MDA

releaseHandleFailed MDA

reportAvOnComRelease MDA

streamWriterBufferedDataLost MDA

virtualCERCall MDA

기본적으로 .NET Framework는 모든 관리되는 디버거에 대해 MDA의 하위 집합을 활성화합니다. Visual Studio의 디버그 메뉴에서 예외를 클릭하고 관리 디버깅 도우미 목록을 확장하여 기본 집합을 볼 수 있습니다.

MDA 사용 및 사용 안 함

레지스트리 키, 환경 변수 및 응용 프로그램 구성 설정을 사용하여 MDA를 활성화 및 비활성화할 수 있습니다. 응용 프로그램 구성 설정을 사용하려면 레지스트리 키나 환경 변수를 활성화해야 합니다.

Visual Studio 2005 이상 버전에서는 호스팅 프로세스를 사용할 경우 기본 집합에 있는 MDA를 비활성화하거나 기본 집합에 없는 MDA를 활성화할 수 없습니다. 호스팅 프로세스는 기본적으로 사용되기 때문에 해당 프로세스를 명시적으로 사용하지 않도록 설정해야 합니다.

Visual Studio에서 호스팅 프로세스를 사용하지 않도록 설정하려면 다음을 수행합니다.

  1. 솔루션 탐색기에서 프로젝트를 선택합니다.

  2. 프로젝트 메뉴에서 속성을 선택합니다.

    프로젝트 디자이너 창이 나타납니다.

  3. 디버그 탭을 클릭합니다.

  4. 디버거 사용 섹션에서 Visual Studio 호스팅 프로세스 사용 확인란의 선택을 취소합니다.

그러나 호스팅 프로세스를 사용하지 않으면 성능에 영향을 줄 수 있습니다. MDA 알림을 받을 때마다 Visual Studio가 MDA 대화 상자를 표시하지 않도록 하여 MDA를 비활성화할 필요가 없도록 만들 수 있습니다. 이렇게 하려면 디버그 메뉴에서 예외를 클릭하고 관리 디버깅 도우미 목록을 확장한 다음 개별 MDA의 Throw됨 확인란을 선택하거나 선택 취소합니다.

레지스트리 키를 통한 MDA 활성화 및 비활성화

Windows 레지스트리에 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\MDA 하위 키(REG_SZ 형식, 값 1)를 추가하여 MDA를 활성화할 수 있습니다. 다음 예제를 MDAEnable.reg 텍스트 파일에 복사한 다음 Windows 탐색기에서 파일 이름을 두 번 클릭하면 해당 컴퓨터에서 MDA가 활성화됩니다.

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]
"MDA"="1"

MDA를 비활성화하려면 Windows 레지스트리 편집기를 사용하여 MDA 하위 키를 0으로 설정합니다. 다음 예제를 MDADisable.reg 텍스트 파일에 복사한 다음 Windows 탐색기에서 파일 이름을 두 번 클릭해도 됩니다.

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]
"MDA"="0"

기본적으로 일부 MDA는 레지스트리 키를 추가하지 않아도 디버거에 연결된 응용 프로그램을 실행할 때 활성화됩니다. 이러한 도우미의 예로는 pInvokeStackImbalance MDAinvalidApartmentStateChange MDA가 있습니다. 이 단원 앞부분의 설명대로 MDADisable.reg 파일을 실행하여 이러한 도우미를 비활성화할 수 있습니다.

환경 변수를 통한 MDA 활성화 및 비활성화

MDA 활성화는 레지스트리 키를 재정의하는 환경 변수 COMPLUS_MDA로도 제어할 수 있습니다. COMPLUS_MDA 문자열은 대/소문자를 구분하지 않고 MDA 이름 또는 기타 특수 제어 문자열의 세미콜론으로 구분된 목록입니다. 관리되거나 관리되지 않는 디버거에서 시작하면 MDA 집합이 기본적으로 활성화됩니다. 이 작업을 수행하려면 환경 변수나 레지스트리 키 값 앞에 디버거에서 기본적으로 활성화되는 세미콜론으로 구분된 MDA 목록을 암시적으로 추가합니다. 특수 제어 문자열은 다음과 같습니다.

  • 0 - 모든 MDA를 비활성화합니다.

  • 1 - ApplicationName.mda.config에서 MDA 설정을 읽습니다.

  • managedDebugger - 관리되는 실행 파일이 디버거에서 시작될 때 암시적으로 활성화된 모든 MDA를 명시적으로 활성화합니다.

  • unmanagedDebugger - 관리되지 않는 실행 파일이 디버거에서 시작될 때 암시적으로 활성화된 모든 MDA를 명시적으로 활성화합니다.

충돌하는 설정이 있으면 가장 최근 설정이 이전 설정을 재정의합니다.

  • COMPLUS_MDA=0은 디버거에서 암시적으로 활성화되는 MDA를 포함하여 모든 MDA를 비활성화합니다.

  • COMPLUS_MDA=gcUnmanagedToManaged는 gcUnmanagedToManaged 및 디버거에서 암시적으로 활성화되는 모든 MDA를 활성화합니다.

  • COMPLUS_MDA=0;gcUnmanagedToManaged는 gcUnmanagedToManaged를 활성화하지만 이 경우가 아니면 디버거에서 암시적으로 활성화될 MDA를 비활성화합니다.

응용 프로그램별 구성 설정을 통한 MDA 활성화 및 비활성화

응용 프로그램의 MDA 구성 파일에서 개별적으로 일부 도우미를 활성화, 비활성화 및 구성할 수 있습니다. MDA를 구성하기 위해 응용 프로그램 구성 파일을 사용할 수 있도록 설정하려면 MDA 레지스트리 키나 COMPLUS_MDA 환경 변수를 설정해야 합니다. 응용 프로그램 구성 파일은 일반적으로 응용 프로그램 실행 파일(.exe)과 같은 디렉터리에 있습니다. 파일 이름은 ApplicationName.mda.config 형식(예: notepad.exe.mda.config)을 사용합니다. 응용 프로그램 구성 파일에서 활성화되는 도우미에는 특히 해당 도우미의 동작을 제어하는 데 사용되는 특성 또는 요소가 있을 수 있습니다. 다음 예제에서는 marshaling MDA를 활성화하고 구성하는 방법을 보여 줍니다.

<mdaConfig>
  <assistants>
    <marshaling>
      <methodFilter>
        <match name="*"/>
      </methodFilter>
      <fieldFilter>
        <match name="*"/>
      </fieldFilter>
    </marshaling>
  </assistants>
</mdaConfig>

Marshaling MDA는 응용 프로그램에서 각 관리와 비관리 간 전환에 대해 관리되지 않는 형식으로 마샬링되고 있는 관리되는 형식에 대한 정보를 내보냅니다. Marshaling MDA는 각각 <methodFilter> 및 <fieldFilter> 자식 요소에서 제공하는 메서드 및 구조 필드의 이름도 필터링할 수 있습니다.

다음 예제에서는 해당 기본 설정을 사용하여 여러 MDA를 활성화하는 방법을 보여 줍니다.

<mdaConfig>
  <assistants>
    <illegalPrepareConstrainedRegion />
    <invalidCERCall />
    <openGenericCERCall />
    <virtualCERCall />
  </assistants>
</mdaConfig>
중요중요

구성 파일에서 여러 도우미를 지정할 때는 사전순으로 나열해야 합니다.예를 들어 virtualCERCall 및 invalidCERCall MDA를 모두 활성화하려면 <invalidCERCall /> 항목을 <virtualCERCall /> 항목 앞에 추가해야 합니다.항목이 사전순으로 되어 있지 않으면 처리되지 않은 잘못된 구성 파일 예외 메시지가 표시됩니다.

MDA 출력

MDA 출력은 pInvokeStackImbalance MDA의 출력을 보여 주는 다음 예제와 비슷합니다.

A call to PInvoke function 'MDATest!MDATest.Program::StdCall' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

참고 항목

기타 리소스

디버깅, 추적 및 프로파일링