컨텍스트 변경

커널 모드 디버깅에는 동시에 실행되는 많은 프로세스, 스레드 및 사용자 세션이 있습니다. "가상 주소 0x80002000" 또는 " eax 레지스터"와 같은 구는 모호합니다. 이러한 구를 이해할 수 있는 컨텍스트 를 지정해야 합니다.

디버거에는 디버깅하는 동안 설정할 수 있는 5가지 컨텍스트가 있습니다.

  1. 세션 컨텍스트는 기본 사용자 세션을 나타냅니다.

  2. 프로세스 컨텍스트는 디버거가 가상 주소를 해석하는 방법을 결정합니다.

  3. 사용자 모드 주소 컨텍스트는 거의 직접 설정되지 않습니다. 이 컨텍스트는 프로세스 컨텍스트를 변경할 때 자동으로 설정됩니다.

  4. 레지스터 컨텍스트는 디버거가 레지스터를 해석하는 방법을 결정하고 스택 추적의 결과도 제어합니다. 해당 용어가 완전히 정확하지는 않지만 이 컨텍스트를 스레드 컨텍스트라고도 합니다. 명시적 컨텍스트는 레지스터 컨텍스트의 유형이기도 합니다. 명시적 컨텍스트를 지정하는 경우 해당 컨텍스트는 현재 레지스터 컨텍스트 대신 사용됩니다.

  5. 로컬 컨텍스트는 디버거가 지역 변수를 해석하는 방법을 결정합니다. 이 컨텍스트를 scope이라고도 합니다.

세션 컨텍스트

여러 로그온 세션을 동시에 실행할 수 있습니다. 각 로그온 세션에는 자체 프로세스가 있습니다.

!session 확장은 모든 로그온 세션을 표시하거나 현재 세션 컨텍스트를 변경합니다.

세션 컨텍스트는 세션 번호가 "-2"로 입력될 때 !sprocess!spoolused 확장에서 사용됩니다.

세션 컨텍스트가 변경되면 프로세스 컨텍스트가 해당 세션의 활성 프로세스로 자동으로 변경됩니다.

프로세스 컨텍스트

각 프로세스에는 가상 주소가 실제 주소에 매핑되는 방법을 기록하는 고유한 페이지 디렉터리가 있습니다. 프로세스 내의 스레드가 실행 중인 경우 Windows 운영 체제는 이 페이지 디렉터리를 사용하여 가상 주소를 해석합니다.

사용자 모드 디버깅 중에 현재 프로세스는 프로세스 컨텍스트를 결정합니다. 디버거 명령, 확장 및 디버깅 정보 창에 사용되는 가상 주소는 현재 프로세스의 페이지 디렉터리를 사용하여 해석됩니다.

커널 모드 디버깅 중에 .process(프로세스 컨텍스트 설정) 명령을 사용하여 프로세스 컨텍스트를 설정할 수 있습니다. 이 명령을 사용하여 가상 주소를 해석하는 데 사용되는 프로세스의 페이지 디렉터리를 선택합니다. 프로세스 컨텍스트를 설정한 후에는 주소를 사용하는 모든 명령에서 이 컨텍스트를 사용할 수 있습니다. 이 주소에서 중단점을 설정할 수도 있습니다. .process 명령에 /i 옵션을 포함하여 침습적 디버깅을 지정하면 커널 디버거를 사용하여 사용자 공간에서 중단점을 설정할 수도 있습니다.

커널 공간 함수에서 프로세스별 중단점을 사용하여 커널 디버거에서 사용자 모드 중단점을 설정할 수도 있습니다. 전략적 중단점을 설정하고 적절한 컨텍스트가 나올 때까지 기다립니다.

사용자 모드 주소 컨텍스트는 프로세스 컨텍스트의 일부입니다. 일반적으로 사용자 모드 주소 컨텍스트를 직접 설정할 필요가 없습니다. 프로세스 컨텍스트를 설정하면 사용자 모드 주소 컨텍스트가 프로세스에 대한 관련 페이지 테이블의 디렉터리 베이스로 자동으로 변경됩니다.

커널 모드 디버깅 중에 프로세스 컨텍스트를 설정하면 다른 .process 명령이 컨텍스트를 변경할 때까지 해당 프로세스 컨텍스트가 유지됩니다. 사용자 모드 주소 컨텍스트는 .process 또는 .context 명령이 변경할 때까지 유지됩니다. 이러한 컨텍스트는 대상 컴퓨터가 실행되면 변경되지 않으며 레지스터 컨텍스트 또는 로컬 컨텍스트 변경의 영향을 받지 않습니다.

컨텍스트 등록

각 스레드에는 자체 레지스터 값이 있습니다. 이러한 값은 스레드가 실행 중일 때 CPU 레지스터에 저장되고 다른 스레드가 실행 중일 때 메모리에 저장됩니다.

사용자 모드 디버깅 중에 현재 스레드는 일반적으로 레지스터 컨텍스트를 결정합니다. 디버거 명령, 확장 및 디버깅 정보 창의 레지스터에 대한 참조는 현재 스레드의 레지스터에 따라 해석됩니다.

다음 명령 중 하나를 사용하여 사용자 모드 디버깅을 수행하는 동안 레지스터 컨텍스트를 현재 스레드가 아닌 값으로 변경할 수 있습니다.

.cxr(표시 컨텍스트 레코드)

.ecxr(표시 예외 컨텍스트 레코드)

커널 모드 디버깅 중에 다음 명령을 포함하여 다양한 디버거 명령을 사용하여 레지스터 컨텍스트를 제어할 수 있습니다.

.thread(레지스터 컨텍스트 설정)

.cxr(표시 컨텍스트 레코드)

.trap(디스플레이 트랩 프레임)

이러한 명령은 CPU 레지스터의 값을 변경하지 않습니다. 대신 디버거는 메모리의 위치에서 지정된 레지스터 컨텍스트를 검색합니다. 실제로 디버거는 저장된 레지스터 값만 검색할 수 있습니다. (다른 값은 동적으로 설정되며 저장되지 않습니다. 저장된 값은 스택 추적을 다시 만들기에 충분합니다.

레지스터 컨텍스트가 설정되면 k(Display Stack Backtrace)r(Registers)과 같은 레지스터 값을 사용하는 모든 명령에 새 레지스터 컨텍스트가 사용됩니다.

그러나 다중 프로세서 컴퓨터를 디버깅할 때 일부 명령을 사용하면 프로세서를 지정할 수 있습니다. (이러한 명령에 대한 자세한 내용은 다중 프로세서 구문을 참조하세요.) 명령에 대한 프로세서를 지정하는 경우 지정된 프로세서가 현재 활성 프로세서인 경우에도 명령은 현재 레지스터 컨텍스트 대신 지정된 프로세서에서 활성 스레드의 레지스터 컨텍스트를 사용합니다.

또한 레지스터 컨텍스트가 현재 프로세서 모드 설정과 일치하지 않는 경우 이러한 명령은 잘못되거나 의미 없는 출력을 생성합니다. 출력 오류를 방지하기 위해 레지스터 컨텍스트와 일치하도록 프로세서 모드를 변경할 때까지 레지스터 상태에 의존하는 명령이 실패합니다. 프로세서 모드를 변경하려면 .effmach(유효 머신) 명령을 사용합니다.

레지스터 컨텍스트를 변경하면 로컬 컨텍스트도 변경됩니다. 이러한 방식으로 레지스터 컨텍스트는 지역 변수 표시에 영향을 줄 수 있습니다.

애플리케이션 실행, 단계별 실행 또는 추적이 발생하면 프로그램 카운터의 위치와 일치하도록 레지스터 컨텍스트가 즉시 다시 설정됩니다. 사용자 모드에서는 현재 프로세스 또는 스레드가 변경된 경우에도 레지스터 컨텍스트가 다시 설정됩니다.

스택 추적은 스택 포인터 레지스터(x86 기반 프로세서의 esp )가 가리키는 위치에서 시작되므로 레지스터 컨텍스트는 스택 추적에 영향을 줍니다. 레지스터 컨텍스트가 잘못되었거나 액세스할 수 없는 값으로 설정된 경우 스택 추적을 가져올 수 없습니다.

.apply_dbp(컨텍스트에 데이터 중단점 적용) 명령을 사용하여 프로세서 중단점(데이터 중단점)을 특정 레지스터 컨텍스트에 적용할 수 있습니다 .

로컬 컨텍스트

프로그램이 실행 중인 경우 해당 변수의 scope 정의된 함수로만 확장되므로 지역 변수의 의미는 프로그램 카운터의 위치에 따라 달라집니다.

사용자 모드 또는 커널 모드 디버깅을 수행하는 경우 디버거는 현재 함수(스택의 현재 프레임)의 scope 로컬 컨텍스트로 사용합니다. 이 컨텍스트를 변경하려면 .frame(로컬 컨텍스트 설정) 명령을 사용하거나 호출 창에서 원하는 프레임을 두 번 클릭합니다.

사용자 모드 디버깅에서 로컬 컨텍스트는 항상 현재 스레드의 스택 추적 내 프레임입니다. 커널 모드 디버깅에서 로컬 컨텍스트는 항상 현재 레지스터 컨텍스트 스레드의 스택 추적 내에 있는 프레임입니다.

로컬 컨텍스트에 대해 한 번에 하나의 스택 프레임만 사용할 수 있습니다. 다른 프레임의 지역 변수에 액세스할 수 없습니다.

다음 이벤트가 발생하는 경우 로컬 컨텍스트가 다시 설정됩니다.

  • 모든 프로그램 실행, 단계별 실행 또는 추적

  • 모든 명령에서 스레드 구분 기호(~)를 사용하는 경우

  • 레지스터 컨텍스트에 대한 모든 변경 내용

!for_each_frame 확장을 사용하면 스택의 각 프레임에 대해 한 번 반복하여 단일 명령을 실행할 수 있습니다. 이 명령은 각 프레임에 대한 로컬 컨텍스트를 변경하고 지정된 명령을 실행한 다음 로컬 컨텍스트를 원래 값으로 반환합니다.