디버깅 중 프로그램 제어는 관리 코드에 중단점 설정, 관리 코드 및 비관리 코드 단계별 실행, 첫째 및 둘째 예외 처리 등으로 이루어집니다. 다음 단원에서는 디버거에서 CLR(공용 언어 런타임) 디버깅 API를 사용하여 이러한 작업을 수행하는 방법에 대해 설명합니다.
관리 코드에 중단점 설정
다음 목록에서는 관리 코드에 중단점을 설정하는 방법을 단계별로 설명합니다.
디버거가 지정된 함수의 모듈 개체를 가져옵니다. 디버거는 메타데이터 인터페이스를 지정하여 ICorDebugAppDomain::GetModuleFromMetaDataInterface 메서드를 호출하여 함수 모듈의 ICorDebugModule 개체를 가져옵니다.
디버거가 ICorDebugModule::GetFunctionFromToken 메서드를 호출하여 지정된 함수의 함수 개체를 가져옵니다.
디버거가 ICorDebugFunction::GetILCode 메서드를 호출하여 지정된 함수의 코드 개체를 가져옵니다.
디버거가 특정 오프셋과 함께 ICorDebugCode::CreateBreakpoint 메서드를 호출하여 관리 코드에 중단점을 만듭니다. CreateBreakpoint 메서드는 ICorDebugBreakpoint의 인스턴스를 반환합니다. 중단점이 활성 상태로 만들어집니다.
디버거가 현재 디버기 프로세스에 대해 ICorDebugController::Continue 메서드를 호출하여 해당 프로세스의 실행을 계속합니다.
스레드가 중단점에 도달하면 디버깅 API에서 ICorDebugManagedCallback::Breakpoint 콜백을 호출하여 디버기에 알립니다.
관리 코드 및 비관리 코드 단계별 실행
다음 목록에서는 디버거에서 관리 코드를 한 단계씩 실행하는 방법을 단계별로 설명합니다.
한 단계 실행이 발생할 스레드가 지정되면 디버거가 스텝퍼를 만듭니다. 디버거는 단계별로 실행되는 스레드에 대해 ICorDebugThread::CreateStepper 메서드를 호출합니다. 또는 디버거에서 단계별 실행이 발생하는 데 기준이 되는 프레임에 대해 ICorDebugFrame::CreateStepper 메서드를 호출할 수 있습니다. 스텝퍼가 만들어지면 프로세스가 중지되는 것으로 가정합니다.
디버거가 ICorDebugStepper::Step 메서드를 호출하여 스레드를 단계별로 실행합니다.
디버거가 현재 디버기 프로세스에 대해 ICorDebugController::Continue 메서드를 호출하여 해당 프로세스의 실행을 계속합니다.
디버거 API에서 단계가 완료되었음을 디버거에 알립니다. 디버깅 API에서는 디버거가 런타임에 등록한 개체에 대해 ICorDebugManagedCallback::StepComplete 메서드를 호출합니다.
디버거가 ICorDebugStepper::Step 메서드를 호출하여 스레드를 단계별로 다시 실행합니다.
디버거가 현재 디버기 프로세스에 대해 ICorDebugController::Continue 메서드를 호출하여 해당 프로세스의 실행을 계속합니다.
다음 목록에서는 비관리 코드의 단계별 실행 방법에 대해 설명합니다.
디버거가 네이티브 코드에서 단계별 실행을 선택적으로 건너뜁니다. 이전 프레임이 다시 활성화될 때까지 디버거는 ICorDebugStepper::StepOut 메서드를 호출하여 네이티브 코드 단계별 실행을 건너뜁니다. 관리 코드에 재진입하면 디버깅 API에서 ICorDebugManagedCallback::StepComplete 메서드를 호출합니다.
선택적으로 디버거가 관리 코드의 다음 섹션에 대해 한 단계씩 코드를 실행합니다. 이전 관리 코드 프레임에 재진입하거나 비관리 코드가 새 관리 코드를 호출할 때 제어가 디버거에 반환되도록 디버거에서 ICorDebugStepper::Step 메서드를 호출합니다.
디버거가 현재 디버기 프로세스에 대해 ICorDebugController::Continue 메서드를 호출하여 해당 프로세스의 실행을 계속합니다.
디버깅 API에서 ICorDebugUnmanagedCallback::DebugEvent 메서드를 호출하여 비관리 코드를 단계별로 실행하고 있음을 디버거에 알립니다.
예외 처리
다음 목록에서는 첫째 및 둘째 예외를 처리하는 방법을 단계별로 설명합니다.
CLR에서 첫째 예외가 발생했음을 디버거에 알립니다. 디버깅 API에서는 디버거가 런타임에 등록한 ICorDebugManagedCallback 인터페이스의 ICorDebugManagedCallback::Exception 메서드를 호출합니다.
디버거가 예외에 대한 정보를 가져옵니다. 디버거는 콜백에 전달된 ICorDebugThread 개체에 대해 ICorDebugThread::GetCurrentException 메서드를 호출하여 예외 개체(ICorDebugValue)를 가져옵니다.
디버거가 예외에 대한 ICorDebugObjectValue 개체를 가져옵니다. 디버거는 QueryInterface 메서드를 호출하여 예외에 대한 ICorDebugObjectValue 개체를 가져옵니다.
디버거가 ICorDebugObjectValue::GetClass 메서드를 호출하여 throw된 예외 개체의 클래스를 가져옵니다.
디버거가 예외를 무시하고 그냥 계속하려고 합니다.
CLR에서 둘째 예외가 발생했음을 디버거에 알립니다. 디버깅 API에서는 ICorDebugManagedCallback::Exception 메서드를 호출하고 예외가 둘째 예외임을 지정합니다.
사용자가 이 예외가 중요하지 않은 것으로 결정합니다. 디버거가 현재 디버기 스레드에 대해 ICorDebugThread::ClearCurrentException 메서드를 호출합니다. 이 메서드는 예외를 지우고 이 예외가 throw되는 것을 막습니다.
디버거가 현재 디버기 프로세스에 대해 ICorDebugController::Continue 메서드를 호출하여 해당 프로세스의 실행을 계속합니다.