해제 절차
업데이트: 2007년 11월
해제 코드 배열은 내림차순으로 정렬됩니다. 예외가 발생하면 운영 체제의 컨텍스트 레코드에 전체 컨텍스트가 저장됩니다. 그런 다음 예외 디스패치 논리가 호출되고 예외 처리기를 찾기 위해 다음 단계가 반복적으로 실행됩니다.
컨텍스트 레코드에 저장되어 있는 현재 RIP를 사용하여 현재 함수(연결된 UNWIND_INFO 엔트리의 경우 함수 부분)를 설명하는 RUNTIME_FUNCTION 테이블 엔트리를 검색합니다.
함수 테이블 엔트리를 찾지 못한 경우 이는 리프 함수에 배치되고 RSP가 반환 포인터를 직접 처리합니다. [RSP]의 반환 포인터는 업데이트된 컨텍스트에 저장되고 시뮬레이션된 RSP는 8만큼 증가한 다음 1단계를 반복합니다.
함수 테이블 엔트리를 찾은 경우 RIP는 a) 에필로그, b) 프롤로그 또는 c) 예외 처리기에서 다룰 수 있는 코드라는 세 가지 영역 안에 배치될 수 있습니다.
a) RIP가 에필로그 안에 있는 경우 컨트롤이 함수를 벗어나면 이 함수에 대한 이 예외와 관련된 예외 처리기가 있을 수 없고 호출자 함수의 컨텍스트를 계산하기 위해 에필로그의 효과가 지속되어야 합니다. RIP가 에필로그 안에 있는지 확인하기 위해 RIP가 포함된 코드 스트림을 검사합니다. 적합한 에필로그의 뒷부분과 이 코드 스트림이 일치하면 코드 스트림이 에필로그에 있는 것이므로 각 명령을 처리할 때마다 업데이트된 컨텍스트 레코드를 사용하여 에필로그의 나머지 부분을 시뮬레이션합니다. 그런 다음 1단계를 반복합니다.
b) RIP가 프롤로그 안에 있는 경우 컨트롤이 함수를 시작하지 않으면 이 함수에 대한 이 예외와 관련된 예외 처리기가 있을 수 없고 호출자 함수의 컨텍스트를 계산하기 위해 프롤로그의 효과가 취소되어야 합니다. 함수 시작 부분에서 RIP까지의 거리가 해제 정보에 인코딩된 프롤로그 크기보다 작거나 같으면 RIP가 프롤로그 안에 있는 것입니다. 오프셋이 함수 시작 부분에서 RIP까지의 오프셋보다 작거나 같은 첫 번째 엔트리의 해제 코드 배열을 통해 앞쪽으로 스캐닝한 다음 해제 코드 배열에 있는 나머지 모든 항목의 효과를 실행 취소하여 프롤로그의 효과를 해제합니다. 그런 다음 1단계를 반복합니다.
c) RIP가 프롤로그나 에필로그 안에 포함되어 있지 않고 함수에 예외 처리기가 있는 경우(UNW_FLAG_EHANDLER를 설정한 경우) 언어별 처리기가 호출됩니다. 이 처리기는 해당 데이터를 스캐닝하고 적절한 필터 함수를 호출합니다. 언어별 처리기에서는 예외가 처리되었음을 알리거나 검색을 계속 진행함을 알리는 값을 반환할 수 있습니다. 이 처리기에서 직접 해제를 시작할 수도 있습니다.
언어별 처리기가 처리된 상태를 반환하는 경우 예외는 원래 컨텍스트 레코드를 계속 사용합니다.
언어별 처리기가 없거나 처리기가 "계속 검색" 상태를 반환하는 경우 컨텍스트 레코드를 호출자의 상태로 해제해야 합니다. 이를 위해서는 해제 코드 배열 요소를 모두 처리하고 각 처리 결과를 취소해야 합니다. 그런 다음 1단계를 반복합니다.
연결된 해제 정보가 관련된 경우에도 이러한 기본 단계는 그대로 따릅니다. 유일한 차이점은 해제 코드 배열을 처리하여 프롤로그의 효과를 해제하는 동안 배열의 끝에 도달하면 상위 해제 정보에 연결되고 여기서 찾은 전체 해제 코드 배열이 진행된다는 점입니다. 이러한 연결 과정은 UNW_CHAINED_INFO 플래그가 없는 해제 정보에 도달하고 해당 해제 코드 배열의 진행을 마칠 때까지 계속됩니다.
해제 데이터 집합의 최소 크기는 8바이트입니다. 이는 128바이트 이하의 스택만 할당된 함수를 나타내며 비volatile 레지스터를 하나만 저장할 수 있습니다. 이는 해제 코드가 없는 길이가 0인 프롤로그에 대한 연결된 해제 정보 구조체의 크기이기도 합니다.