본문 바로가기
Develop/Fundmental

SIGSEGV, SIGABRT 가 뭐지?🤷‍♂️

by 3-stack 2021. 9. 26.

Signal 기본 개념 & 종류

 

# 시그널?

리눅스에서는 프로세스끼리 서로 통신할 때 사용. 즉, 특정 프로세스가 다른 프로세스에 메시지를 보낼 때 이용.

사용자가 인터럽트 키를 통해 발생시키는 시그널, 프로세스가 발생시키는 시그널, 하드웨어가 발생시키는 시그널 등 다양함.

# signal list 확인
kill -l

# signal 보내는 방법
# kill -signal -pid
kill -9 1001

 

# 주요 시그널 

1. 프로그램 에러 시그널(SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGABRT)

- 심각한 프로그램 에러가 운영체제나 컴퓨터 자체에 의해 검출되었을 때 발생.

- 일반적으로 이 시그널들은 프로그램이 심각하게 깨져있고, 에러가 포함된 그 실행을 계속할 방법이 없음을 말함.
SIGFPE - 심각한 산술적 에러

"floating-point exception"에서 유래, 실제로 모든 산술적 에러에 작용.

프로그램이 정수 데이터를 저장하고 그 데이터에 플로팅-포인트 명령을 사용하면, 그 프로세서가 데이터를 플로팅-포인트 수로써 인식할 수 없기 때문에 종종 "유용하지 않은 연산"의 원인이 된다.
SIGILL - 비합법적인 명령(illegal instruction)"
쓸모없거나 특권이 부여된 명령어를 실행하려 했다는 의미. 전형적으로 실행 가능 파일이 훼손되었거나 문제가 있는 데이터를 실행하려 했다는 것. 포인터가 있을 것이라고 예상된 곳에서 유용하지 않은 오브젝트를 파싱하거나 자동 배열의 끝을 넘어서 기록을 하고(또는 자동 변수를 위한 포인터와 유사한 문제)
SIGSEGV - 할당된 메모리 범위를 벗어나는 곳에서 읽거나 쓰기를 시도
실제로 프로그램이 충분한 영역을 할당받지 못 할 때 시스템 메모리 보호 메커니즘에 의해 발생.

"segmentation violation"의 약자, SIGSEGV 상황이 발생되는 가장 일반적인 방법은 비참조 되는 널(defeferencing a null) 이나 초기화되지 않은 포인터에 의한 것. 널 포인터는 주소 0으로 참조되고 대부분의 운영체제는 이 주소가 유용하지 않기 때문에 비참조 널 포인터는 SIGSEGV가 발생. SIGSEGV 상황이 얻어지는 다른 일반적 경우는 배열에 포인터를 사용했을 때 그 배열의 끝을 체크하기를 실패했을 때이다. 
SIGBUS - 유용하지 않은 포인터가 비참조되었을 때 발생
SIGSEGV 처럼 초기화되지 않은 포인터를 참조할 때 발생. 두 시그널의 차이점은 SIGSEGV는 유용한 메모리에서 유용하지 못 한 엑세스를 지적하고, SIGBUS는 유용하지 못한 주소 엑세스를 지적한다. 
SIGABRT - abort가 호출되었음을 보고함으로써 발생.

2. 종료 시그널 (SIGHUP, SIGINT, SIGQUIT, SIGTERM, SIGKILL)
프로세스를 종료함을 알리기위해 사용.
SIGHUP - ("hang-up") 사용자 터미널의 단절을 보고하기 위해 사용, 네트워크 연결이 끊어짐 등.
SIGINT - ("program interrupt") 사용자가 INTR 문자를 (보통 C-c)을 입력했을 때 보내짐.
SIGQUIT - 다른 키_QUIT 문자, 보통 C-\_에 의해서 제어된다는 것을 제외하고는 SIGINT와 유사, 그 프로세스가 종료 될 때 프로그램 에러 시그널처럼 코어 파일 작성.
SIGTERM - 프로그램을 종료하는데 포괄적으로 사용. SIGKILL과 달리 블록되거나 무시되어질 수 있음.
SIGKILL - 즉각적인 프로그램 종료를 일으키기 위해서 사용. 블록, 무시될 수 없음.

3. 그 외 시그널

SIGABRT

- 비정상적인 종료, JVM(자바 바이트코드를 실행하는 실행기) 오류를 발견할 때마다 JVM이 발생시키는 시그널.

1) 메모리 할당이 안 된 메모리에 접근. 주로 malloc이 안 되어 발생.

2) 예외 처리를 위해 정상적으로 사용하는 경우. crash가 아니라 예외 처리로 발생하는 것.

 

# 시그널 종류

1 SIGHUP(HUP) 연결 끊기. 프로세스의 설정파일을 다시 읽는데 사용된다.
2 SIGINT(INT) 인터럽트
3 SIGQUIT(QUIT) 종료
4 SIGILL(ILL) 잘못된 명령
5 SIGTRAP(TRAP) 트렙 추적
6 SIGIOT(IOT) IOT 명령
7 SIGBUS(BUS) 버스 에러
8 SIGFPE(FPE) 고정소수점 예외
9 SIGKILL(KILL) 죽이기. 이 시그널은 잡히지 않는다.
10 SIGUSR1(USR1) 사용자 정의 시그널1
11 SIGSEGV(SEGV) 세그멘테이션 위반
12 SIGUSR2(USR2) 사용자 정의 시그널2
13 SIGPIPE(PIPE) 읽을 것이 없는 파이프에 대한 시그널
14 SIGALRM(ALRM) 경고 클럭
15 SIGTERM(TERM) 소프트웨어 종료 시그널, 일반적으로 kill 시그널이 전송되기 전에 전송된다. 잡히는 시그널이기 때문에 종료되는 것을 트랙할 수 있다.
16 SIGTKFLT 코프로세서 스택 실패
17 SIGCHLD(CHLD) 자식 프로세스의 상태변화
18 SIGCONT(CONT) STOP 시그널 이후 계속 진행할 때 사용.
19 SIGSTOP(STOP) 정지. 이 시그널 역시 잡을 수 없다.
20 SIGTSTP(TSTP) 키보드에 의해 발생하는 시그널로 Ctrl+Z로 생성된다.
21 SIGTTIN 백그라운드에서의 제어터미널 읽기
22 SIGTTOU 백그라운드에서의 제어터미널 쓰기
23 SIGURG 소켓에서의 긴급한 상태
24 SIGXCPU CPU 시간 제한 초과 setrlimit(2) 메뉴얼 패이지 참조
25 SIGXFSZ 파일 크기제한 초과 setrlimit(2) 메뉴얼 패이지 참조
26 SIGVTALRM 가상 시간 경고 setitimer(2) 메뉴얼 패이지 참조
27 SIGPROF 프로파일링 타이머 경고. setitimer(2) 메뉴얼 페이지 참조
28 SIGWINCH 윈도우 사이즈 변경
29 SIGIO 기술자에서 입출력이 가능함. fcntl(2) 메뉴얼 참조
30 SIGPWR 전원 실패
31 UNUSED 사용 안함

댓글