컴퓨터 시스템

[컴퓨터 구조] 예외 상황

우디혜 2020. 10. 11. 21:20

예외 상황

프로세서의 상태 변화에 대한 대응이다. 프로세서가 이벤트 발생을 감지하면 exception handler라는 운영체제 서브루틴으로 들어가 예외 상황을 처리한 후 중단 되었던 프로그램을 다시 실행하거나 중단한다. 예외의 종류로는 인터럽트, 오류, 중단 등이 있다.

 

 

예외 상황 중 오류(Fault)와 중단(Abort)의 차이

오류 ( Fault )

Potentially recoverable error 즉, 핸들러가 정정할 가능성이 있는 상태의 경우에는 fault handler로 제어를 넘겨준다. 핸들러가 에러 조건을 정정하게되면 오류를 발생시킨 인스트럭션을 return하여 재실행하고, 그렇지 못한 경우에는 abort 루틴으로 리턴하여 프로그램을 종료한다.

 

중단 ( Abort )

주로 DRAM 혹은 SRAM이 고장날 때 발생하는 패리티 에러, 하드웨어 고장 등의 치명적인 에러에서 발생한다. 햄들러는 제어를 프로그램을 종료하는 중단 루틴으로 넘겨주고 프로그램을 종료한다.

 

인터럽트 ( Interrupt )

CPU가 프로그램을 실행하고 있을 때 I/O device 등에서 예외상황이 발생하여 처리가 필요할 경우 CPU에 알려 처리하는 기술.

 

인터럽트 예시

CPU에서 프로그램이 실행되고 있을 때

  • I/O device 등에서 장치 이슈 발생

    • 파일 처리가 완료되었다는 것을 시그널을 보내 CPU에 알려주고, OS는 파일처리가 완료된 프로세서를 block 상태에서 ready 상태로 상태를 변경한다

  • 이외의 예외 상황 발생

    • 0으로 나누는 연산 시행시, OS가 해당 프로세스 중지 혹은 에러 표시

주요 인터럽트

  1. 0으로 나누는 연산 ( Divide by zero interrupt )

  2. 타이머 인터럽트 - 선점형 스케줄러에 필요

 

인터럽트 종류

1. 내부 인터럽트 (소프트웨어 인터럽트) - 트랩 (Trap)

  • 프로그램 내부에서 잘못된 명령 혹은 데이터 사용 시 발생

  • 특정 인스트럭션을 실행해서 발생한 예외 이벤트로 발생 시점이 고정적이기 때문에 동기적이다.

    • 0으로 나누거나, 사용자 모드에서 허용되지 않은 명령 혹은 공간 접근, 계산 결과가 overflow 혹은 underflow (표현할 수 있는 수 이상 혹은 이하를 처리해야할 때 발생)가 날 때

    • 사용자가 의도적으로 system call을 호출하는 경우

 

2. 외부 인터럽트 (하드웨어 인터럽트) - 보통 그냥 인터럽트를 이야기 할 때

  • 주로 하드웨어에서 발생하는 이벤트(프로그램 외부)

  • 발생 시점, 시간이 일정하지 않기 때문에 비동기적으로 발생한다.

    • 전원 이상 혹은 기계 문제, 키보드 등 IO 관련 이벤트, Timer 이벤트가 발생할 때

 

인터럽트와 프로세스

  1. 프로세스 실행 중 인터럽트 발생

  2. 현 프로세스 상태를 저장하고 실행 중단

  3. IDT(Interrupt Discriptor Table)에서 해당 인터럽트 번호를 통해 인터럽트 처리 함수를 찾아 실행 (OS)

  4. 현 프로세스 재실행

 

IDT ( Interrupt Discriptor Table )

각 인터럽트 이벤트마다 부여되는 번호와 실행코드를 가리키는 주소가 기록되어있다. 컴퓨터 부팅시 OS가 IDT를 할당하고 예외 상황에 대한 정보를 초기화한다.

 

프로세스 구조

kernel virtual memory kernel space
stack ↓ user space
shared library
heap ↑
data
text(code)

 

text : 코드를 저장하는 영역( read only ).

data : 변수 혹은 초기화된 데이터를 저장하는 영역( read and write ).

heap : 코드에서 동적으로 만들어지는 데이터 영역이며, 동적 메모리 할당기라고도 불린다.

stack : 임시 데이터(함수 호출, 로컬 변수 등), run time에 만들어진다. esp라는 레지스터가 스택 프레임의 최상단을 가리키는 스택포인터(stack pointer) 역할을 한다.

 

Data 영역

.bss 는 초기화되지 않은 전역변수, .data는 초기화 값이 있는 전역변수를 저장한다.

 

동적 메모리 할당

가상 메모리 영역을 mmap 함수가 생성하거나 삭제할 수 있지만, 런타임에 추가적인 가상메모리가 필요할 경우에는 동적 메모리 할당기로 알려진 heap이 프로세스의 가상메모리 영역을 동적으로 관리한다. 커널은 힙의 맨 위를 가리키는 brk 변수를 사용하여 heap을 트레킹한다. 

 

  1. 명시적 할당기 ( explicit allocator )

    • 명시적으로 메모리를 할당하거나 반환하는 방법을 말한다. 예를 들어, 메모리 할당 시에는 malloc을 호출하고 free를 이용해 할당된 블록을 반환할 수 있다.

  2. 묵시적 할당기 ( Implicit allocator ) == 가비지 컬렉터 ( Garbage Collector)

    • 할당된 블록이 더 이상 프로그램에 의해 사용되지 않았을 때는 자동으로 반환시켜준다. 이와 같은 작업을 가비지 컬렉션이라고 한다. Lisp, java와 같은 언어가 가비지 컬랙터를 사용한다.

동적 메모리를 사용하는 이유

프로그램을 실행시키기 전에는 자료 구조의 크기를 알 수 없는 경우가 있기 때문이다.

 

메모리 누수 ( Leak )

할당된 블록들을 반환하지 않고 리턴하여 힙에 가비지를 생성할 때 발생한다. leak가 자주 발생하게 되면 힙에 가비지가 쌓이게 되고 최악의 경우에는 전체 가상 주소 공간을 소모하게 된다. 백그라운드에서 계속 실행이 되는 데몬이라는 서버 프로세스는 서버가 죽을 때까지 계속 실행이 되기 때문에 자원 소비가 크다.