운영체제

시스템 콜과 예외처리

소재훈 2021. 9. 26. 15:23

시스템 콜

시스템 콜이란 OS에 있는 함수를 호출하는 것을 말한다. 위의 그림은 시스템 콜이 일어나는 과정을 보여주고 있다. 시스템 콜이란 OS에 있는 함수를 호출하는 것으로 시스템 콜의 처리를 할 때, 시스템 콜은 일종의 인터럽트로 처리되어 linux에서는 인터럽트 번호가 128인 인터럽트를 걸게 된다. 단 인터럽트를 걸기 전에 시스템 콜 함수의 파라미터를 넘겨주어야 하는데, 사용자 영역과 커널 영역은 완전히 다른 메모리 영역이기 때문에 사용자 영역에서는 kernel 영역에 접근할 수 없다. 그렇기 때문에 파라미터 값들을 레지스터에 넣어주고 eax라는 레지스터에 시스템 콜 번호를 넣어준다. 그래야만 커널에서 인터럽트가 걸렸을 때 어떤 시스템 콜을 호출했는지 알 수 있다. 

libc에 있는 함수를 wrapper 함수라고 한다. 레지스터에 actual parameter의 값들과 시스템 콜 번호를 한꺼번에 포장해서 인터럽트를 걸기 때문에 wrapper 함수라고 부른다. 인터럽트가 걸리면 항상 0~255번 의 정보가 있는 인터럽트 테이블로 오게 되고 인터럽트 테이블에는 0~255번 까지 인터럽트를 처리하는 핸들러의 주소가 들어있다.

 

 

open() 시스템 콜 함수를 호출했을 때

open()이라는 시스템 콜 함수를 호출하게 되면 결국 실제로 처리해 주는 것은 sys.open() 함수가 된다. 이때 open()에서 직접 control이 sys.open()으로 가는 것이 아니라 

1. 첫 번째 호출이 libc의 open()으로 가고

2. Interrupt 128번이 걸리면서 system call로 갔다가

3. sys.open()이 실행되게 된다.

 

한마디로 정리하면 시스템 콜을 호출하게 되면 바로 커널 안의 함수가 호출되는 것이 아니라 래퍼 함수를 거치고 시스템 콜이라는 함수를 거쳐서 함수를 호출해 준다고 기억하자.


예외(Exception)

리눅스에서는 인터럽트 벡터라는 것이 존재한다.

리눅스에서 인터럽트 벡터

0~31: non-maskable interrupt, 예외
32~255: 하드웨어 장치에 대한 인터럽트
128: 시스템 콜 인터럽트이다. 모든 시스템 콜은 128번을 통해 들어온다.

하드웨어 인터럽트 처리과정

입출력 인터럽트 핸들링

위 그림의 PIC(Programmable Interrupt Controller)라는 칩에는 여러 입출력 장치들이 달려있고, 인터럽트가 걸리게 되면 CPU 쪽에 인터럽트가 왔음을 알려주는 장치이다. 그러면 운영체제에서 인터럽트 테이블에 가서 처리 하게 된다. 

위 그림에서 인터럽트가 걸렸을 때 IDT[32+n] 로 처리해 주는 것을 볼 수 있는데, 이는 0~31번의 인터럽트는 이미 할당되어 있기 때문에 하드웨어 인터럽트는 32번부터 시작해야 한다. 예를들어 0번이 걸리게 되면 운영체제에 와서는 32번이 된다. 

IRQ는  Interrupt Request Queue를 의미하고 이후 핸들러 루틴의 주소를 따라 처리되고 돌아가게 된다.


예외 핸들러

예외 핸들러가 보내는 시그널

위 표는 소프트웨어 예외가 발생했을 때 실행되는 예외 행들러와 시그널을 나타내는 표이다.

예를 들어서 위 표의 0번 예외인 나누기 에러 즉 x = y / z; 와 같은 명령문을 수행했을 때 z = 0 그럼 Interrupt vector table에 따라 예외 핸들러인 divede_error() 메서드가 실행된다. 이때 divide_error()에서는 어떤 예외에 대한 처리를 하는 것이 아니라 시그널만 보내는 역할을 한다.

그리고 아래의 표는 시그널이 발생했을 때의 동작과 설명을 나타낸다. 

리눅스/i386 내 처음 31개 시그널

예를 들어 8번 시그널이 발생했다고 가정하면  시그널이 오면 PCB 테이블의 시그널 부분에서 8번 시그널 부분을 0에서 1로 바꾸어 준다.

그리고 시스템 콜 함수를 수행하고 사용자 모드로 돌아가기 직전에 운영체제에서 pending signal의 처리를 해준다. PCB의 시그널 테이블을 돌면서 1로 되어있는 것이 있다면 그 시그널에 대한 처리를 하고 돌아가는 것이다. 이 때 시그널의 처리는 PCB에 있는 시그널의 처리지침을 따르고 처리지침의 내용은 위 표의 내용과 동일하다. 

 

시그널의 기본동작에서 dump란?

unix, linux 에서 abort 시킬 때 프로세스의 이미지, 메모리의 내용을 dump core라는 파일에 만들어, 나중에 사용자가 볼 수 있게 하는데 그때의 용어를 덤프라고 한다. 간단히 abort 로 이해하면 된다.

 

sicaction(8, IGNORE)라는 시스템 콜을 이용하면 8번 시그널이 들어왔을 때  IGNORE 하겠다.라는 의미로 시그널 처리지침을 오버 로딩할 수 있다. 

'운영체제' 카테고리의 다른 글

파일시스템 수정  (0) 2021.12.05
쓰레드와 병행처리(Tread and Concurrency)  (0) 2021.09.26
Context Switching과 Process Tree  (0) 2021.09.23
Process Control Block(PCB)와 스케줄링  (0) 2021.09.23
프로세스의 생명주기  (0) 2021.09.23