Exceptional Control Flow의 약자로
프로세스 실행과 관련이 없는 시스템의 상태 변화에 대응하기 위해서
시스템은 제어흐름의 갑작스런 변화를 만든다.
이를 ECF = Exceptional Control Flow라고 한다.
예외가 발생하면 예외 테이블이라고 불리는 점프 테이블을 통해 해당 Exception에 적힌 운영체제 서브루틴(예외처리 핸들러)를 실행합니다. 예외 발생 시 프로세서는 핸들러로 분기하기 전에 스택에 반환 주소와 프로세서 상태도 스택에 푸시해서 핸들러가 반환될 때 중단된 프로그램을 재시작할 수 있도록 합니다. 이때 예외 핸들러는 커널 모드에서 실행되어 시스템 리소스에 대한 완전한 접근 권한을 가집니다.
핸들러가 동작을 마치고 나면 이벤트 종류에 따라서 크게 3가지 중 한 가지 일이 발생한다.
1. 핸들러가 제어권을 이벤트가 발생했을 때 실행되고 있던 인스트럭션으로 돌려준다.
2. 핸들러가 예외가 발생하지 않았다면 실행했을 인스트럭션으로 돌려준다.
3. 핸들러는 중단된 프로그램을 종료한다.
예외 테이블에 각 예외 유형은 고유한 양의 정수 예외 번호로 할당됩니다. 시스템 부팅할 때 운영체제는 예외 테이블이라는 점프 테이블을 할당하고 초기화하여 각 예외 핸들러의 주소를 포함시킵니다.
Interrupt
외부 이벤트에 의해 발생 - 주로 I/O장치
비동기
실행 후 이전 프로세스로 돌아갈 수 있음.
Trap
소프트웨어 요청으로 발생 - 시스템 콜로 사용자모드에서 커널모드로 전환해
시스템에 영향을 주는 코드를 실행한 다음 기존에 실행하던 프로세스로 돌아간다.
동기
실행 후 이전 프로세스로 돌아갈 수 있음.
Fault
소프트웨어 실행 오류로 발생
동기
실행 후 오류가 해결되어야만 이전 프로세스로 돌아갈 수 있음.
Abort
시스템 오류로 발생
시스템 오류로 인해 강제종료될 수 있다.
실행 후 이전 프로세스로 돌아갈 수 없음.
프로세스는 실행 프로그램의 인스턴스이다.
예외처리를 통해서 프로세스라는 개념을 운영체제에 구현할 수 있다.
프로세스는 실행 프로그램의 추상화로 사용자 입장에서 현재 실행되는 프로그램이 시스템에서
돌아가는 유일한 프로그램이고 프로세서와 메모리를 독점하고 있는 것처럼 보인다.
이는 예외처리를 통해 가능하다.
커널이 스케줄링을 통해 어떤 프로세스를 실행하고 다른 프로세스를 보류할 지 정한다.
그리고 스케줄링을 통해 다른 프로세스에게 제어권을 넘기는 것을 문맥전환(context switch)라고 한다. 이때 문맥전환은 잘 짜여진 예외처리를 통해 이루어지고 멀티태스킹을 가능하게 한다.
커널이 시스템 콜을 실행중일 때에도 context switch가 일어날 수 있다.
유닉스 시스템 레벨 함수가 에러를 만났을 때, 일반적으로 -1을 반환하고 글로벌 정수 변수 errno를 설정하여 어떤 문제가 발생했는지를 나타냅니다. 프로그래머들은 항상 에러를 확인해야 하지만, 많은 경우 코드가 더 길어지고 읽기 어려워진다는 이유로 에러 체크를 생략합니다.
프로세스가 종료(terminate)된 후에도 커널은 이를 시스템에서 바로 지우지 않고 부모 프로세스가 이를 회수(reap)할 때까지 terminated 상태를 유지한다.
이렇게 종료되었지만 회수되지 않은 프로세스를 zombie라고 한다.
시그널은 특정 타입의 이벤트가 시스템에 발생했음을 프로세스에게 알려주는 역할을 한다.
유저에게 보이지 않는(user-invisible) HW exception들을 유저에게 노출시키는 역할도 수행한다.
시그널 보내기(sending a signal): 커널이 목적지 프로세스의 context 상태 일부를 갱신해서 시그널을 목적지 프로세스로 보낸다.
시그널 받기(receiving a signal): 커널에 의해 특정 방식으로 signal에 반응할 것을 명령받을 때, 이를 signal을 받았다고 함
시그널 핸들러로 반응하는 종류 3가지
pending signal: 보냈지만, 받아지지 않은 signal.
같은 종류의 signal은 하나만 pending 상태에 있을 수 있음
여전히 프로세스가 받을 수 있는 상태
blocked signal: 시그널이 pending상태에서 프로세스가 받지 못하도록 막혀있는 상태