seven05
[CSAPP] 8. 예외적인 제어흐름(8.1,8.5) 본문
(전과 마찬가지로 단원 전체를 볼수있으면 당연히 좋지만 시간이 모자라는 관계로 일단은 코치님이 강조하신 부분들만 볼수밖에없었다. 다음에 시간이 생기면 다시 추가로 공부해보자!)
프로세서는 실행하는 명령어에 대응되는 주소값을 PC에 가지고있는데 실행하는 명령어에 따라 PC의 값이 변해가는 흐름을 제어 흐름(Control Transfer)이라고 한다. 제어흐름의 양상은 크게 3종류인데
- 메모리에 할당된 명령어를 순차적으로 처리 (대부분의 시간동안 이 제어 흐름을 따른다)
- 프로그램 상태 변화에 반응하여 제어 흐름이 변하는 경우(jump, call, return 등의 명령어를 수행하는 경우)
- 예외적인 제어 흐름(Exceptional Control Flow, ECF) (프로그램의 실행과 관련이 있거나 없거나) 시스템 변화에 반응
ECF를 공부해야 하는 이유
- 중요한 시스템 개념을 이해하기 위해서(OS가 입출력,프로세스,가상메모리구현등을 위한 기본적인 매커니즘)
- 응용프로그램이 OS에게 서비스를 요청하는 방식 이해(프로그램은 ECF의 한종류인 system call 을 이용하여 OS에게 특정 서비스를 요청함 -> 디스크에 데이터를 쓰거나, 네트워크로부터 데이터를 읽거나, 프로세스를 만들고 종료)
- 흥미로운 응용프로그램 작성가능 (ECF를 사용하여 앞서말한 여러 기능들 사용가능)
- 동시성을 이해하기위해서 (프로그램에 간섭하거나 동시에 실행되는 쓰레드등)
- 소프트웨어 수준의 예외가 동작하는 원리를 이해할수있음
8.1 예외 상황(Exceptions)
예외 상황(Exception)이란?: 프로세서 상태의 변화에 대한 반응으로 나타나는 제어 흐름의 갑작스러운 변화를 의미함. HW와 OS의 협력에 의해 구현되는 낮은 수준의 ECF이다. 따라서 하드웨어의 구현방식에 영향을 받고 시스템마다 다르다.
프로세서가 I_current를 실행하는 도중에 프로세서의 상태 변화를 감지하면 이를 이벤트(Event)라고 한다. 이벤트는 프로세서내의 비트로 인코딩 되어있으며, I_current의 실행과 관련이 있을수도 없을수도 있다. 이벤트 발생을 감지하는순간, 예외 테이블(Exception Table)이라고 불리는 점프 테이블을 참조하여 해당되는 예외 핸들러(Exception Handler)로의 간접 프로시저 호출(Indirect Procedure Call)을 수행한다. 예외 핸들러의 처리가 끝나면 3가지중 하나로 행동한다.
- I_current로 retrun
- I_next로 return
- Abort 루틴으로 return해서 프로그램을 종료
8.1.1 예외처리 (Exception Handling)
하나의 시스템 내에서 발생하는 모든 예외는 자신만의 예외 번호(Exception Number)를 가진다. (음이 아닌 정수, 고유번호)
프로세서를 설계하는 사람이 부여: 0으로 나누기 연산(Divide by Zero), 페이지 폴트(Page Fault)
커널을 설계하는 사람이 부여: 시스템 콜 (System Call), 외부 입출력 장치에 의한 인터럽트(Interrupt)
시스템이 부팅되는 순간, OS는 예외 테이블(Exception Table)을 메모리에 할당 하고 초기화한다.
런타임 시에 특정 이벤트의 발생을 감지함녀 해당이벤트의 예외번호 k를 결정한다. 그리고 프로세서는 예외 테이블의 k번째 엔트리를 참조함으로썬 해당되는 예외 핸들러를 간접적으로 호출한다.
예외 테이블의 시작 주소는 예외 테이블 베이스 레지스터(Exception Table Base Register) 라는 CPU의 레지스터를 저장함
일반적인 함수의 호출과 예외핸들러의 차이 (얼핏보면 일반적인 함수호출과 크게 달라보이지 않기때문에)
- 스택에 푸시하는 복귀 주소가 I_current 일수도, I_next 일수도 있다.
- 복귀주소이외에 추가적인 프로세서 상태 정보도 스택에 같이 푸시한다. (예외 핸들러가 리턴할때 프로세서 상태정보를 원래대로 돌려놓기 위함)
- 커널 모드로 실행된다(시스템 자원들에 대한 접근권한을 가진다는 의미 따라서 유저스택이 아니라 커널스택에 푸시)
8.1.2 예외 종류 (Exception Classes)
예외 종류 | 발생원인 | 동기/비동기 | 핸들러 처리 완료 후 리턴 | 통용 용어 |
인터럽트(Interrupt) | 입출력 장치로 인한 신호 | 비동기 | 다음 명령어로 복귀 | 인터럽트 |
트랩(Trap) | 의도적 예외 | 동기 | 다음 명령어로 복귀 | 시스템콜 |
Fault | 수정할 가능성이 있는 예외 | 동기 | 현재 명령어 or 종료 | 예외 |
Abort | 복구가 불가능한 하드웨어 오류 | 동기 | 프로그램 종료 |
- 인터럽트 (Interrupt): 외부의 입출력 장치로부터 전달받는 신호에 의한 예외 명령어의 실행결과가 아니기때문에 비동기적 예외이다. 처리가 끝나면 다음 명령어(I_next)로 리턴함.
- 트랩 (Trap): 명령어가 의도적으로 발생시킨 예외로 동기적 예외이다. 트랩인 예외 핸들러는 트랩 핸들러라고 부르며,다음 명령어(I_next)로 리턴함. 트랩의 용도는 커널에 서비스를 요청하는것이다. 이를 시스템 콜(System Call)라고 한다. 파일읽기(read),프로세스 만들기(fork),새로움 프로그램 로드(execve), 프로세스 종료(exit)가 있다. 프로세서는 유저 프로그램이 시스템 콜을 통해 이런 서비스들을 요청할수있게 syscall n 명령어를 제공한다.
- Fault: 특정 명령어의 실행 결과로 초래된 (회복 가능한) 에러에 의해 발생하는 예외로 동기적 예외이다. 에러를 고치는 것에 성공하면 현재 명령어(I_curr, Faulting 명령어)로 리턴하고 에러를 고칠 수 없으면 커널에 존재하는 abort 루틴으로 리턴하여 해당 프로그램을 종료한다. 대표적인 예시는 Page Fault가 있다. 가상메모리 파트에 나오는 부분이라 자세하게는 모르지만 대략적으로 보자면 메인 메모리에 존재하지 않은 가상 페이지에 접근하려고 시도하면 예외가 발생하여 예외 핸들러가 호출되고, 핸들러는 디스크에 있는 가상 페이지를 메인 메모리에 로드하고 로드 작업이 완료되면 fault 명령어로 복귀한다. 이렇게 하면 프로그램이 정상적으로 실행이 재개된다.
- Abort: 특정 명령어의 실행 결과로 초래된 복구 불가능한 발생되는 예외로 동기적 예외이다. 무조건 abort 루틴으로 리턴하여 프로그램을 종료한다.
X86-64 리눅스의 예외는 책을 참고하자!
8.5 시그널
나중에 수정 예정
'SW JUNGLE 9기 > CSAPP' 카테고리의 다른 글
[CSAPP] 7.Linking 링킹 (7.1,7.4,7.9) (1) | 2024.09.04 |
---|---|
[CSAPP] 3.7~3.9,11 어셈블리어가 함수와 배열을 표현하는 방법 (3) | 2024.09.04 |
[CSAPP] 3.1~3.6 어셈블리어 공부 (3) | 2024.09.04 |
[CSAPP] 부동소수점 부분 공부하다가 발견한 신기한 알고리즘 1/sqrt(x) (2) | 2024.09.04 |