운영체제 | Segmentation Fault

성수당·2025년 9월 12일

운영체제

목록 보기
19/31
post-thumbnail

🥔 Segmentation Fault란?

Segmentation Fault는 프로세스가 허용되지 않은 메모리 영역에 접근하려고 할 때 운영체제가 발생시키는 치명적인 오류다. 일반적으로 "Segfault" 또는 SIGSEGV 라고도 불리며, 대부분의 경우 잘못된 포인터 접근에서 발생한다.

흔히 C나 C++을 사용할 때 발생하는 오류이며, 메모리 안정성을 직접 관리해야 하는 언어 특성상 자주 마주치게 된다.

🥔 언제 발생하는가?

Segmentation Fault는 다음과 같은 상황에서 발생할 수 있다:

1. NULL 포인터 역참조

int *ptr = NULL;
*ptr = 10;  // Segfault 발생

2. 할당하지 않은 메모리 접근

int *arr;
arr[0] = 1;  // malloc 또는 new를 안함

3. 배열 범위 초과 접근

int arr[5];
arr[10] = 20;  // 유효 범위를 벗어남

4. 해제된 메모리 접근 (Use-after-free)

int *ptr = malloc(sizeof(int));
free(ptr);
*ptr = 5;  // 이미 해제된 메모리 접근

5. 읽기 전용 메모리 수정 시도

char *str = "hello";
str[0] = 'H';  // 문자열 상수는 읽기 전용 메모리일 수 있음

🥔 메커니즘: 운영체제의 시점

운영체제는 각 프로세스에게 고유한 가상 메모리 공간을 할당하며, 이 공간은 크게 다음 영역으로 나뉜다:

  • 코드 영역 (Text)
  • 데이터 영역 (Data, BSS)
  • 힙 (Heap)
  • 스택 (Stack)

이 중 프로세스는 자신에게 허용된 영역만 접근 가능하다. 만약 다른 영역을 침범하면, 운영체제는 하드웨어 예외(interrupt) 를 감지하여 SIGSEGV 시그널을 보내고, 프로세스를 강제 종료시킨다.

즉, Segmentation Fault는 운영체제가 메모리를 보호하기 위한 안전장치다.

🥔 Debugging 방법

1. gdb 사용하기 (GNU Debugger)

gcc -g main.c -o main
gdb ./main
(gdb) run
(gdb) backtrace

2. Valgrind 사용하기

valgrind ./main

3. 코드 검토

  • 포인터 초기화 여부 확인
  • 배열 크기 초과 여부 확인
  • 동적 메모리 할당 여부 확인 (malloc, free 순서)

🥔 예방 방법

방법설명
포인터 초기화NULL 또는 유효한 주소로 반드시 초기화할 것
범위 검사배열이나 포인터 연산 시 인덱스 범위 확인
동적 메모리 관리 주의할당한 메모리는 반드시 필요 시에만 해제
상수 문자열 수정 금지char str[] = "hello"; 형태로 복사하여 사용
안전한 함수 사용strncpy, snprintf 등 버퍼 제한 함수 사용

🥔 실제 예시: Stack Overflow

void recurse() {
    int arr[10000];
    recurse();  // 무한 재귀 → 스택 오버플로우 → 세그폴트
}

무한 재귀는 스택을 초과하게 되어 결국 Segmentation fault (core dumped) 를 발생시킨다.

🥔 요약 정리

항목설명
정의접근 불가능한 메모리 영역에 접근 시 발생하는 오류
시그널 이름SIGSEGV
흔한 원인NULL 포인터, 범위 초과, 해제된 메모리 접근 등
방지 방법포인터/배열 관리 철저, 디버깅 도구 활용
관련 도구gdb, valgrind, AddressSanitizer 등

🥔 마무리

Segmentation Fault는 단순한 오류가 아닌, 프로세스가 허용되지 않은 메모리 접근을 시도했음을 운영체제가 감지한 결과이다. 이는 메모리 보호 기법의 일환이며, 시스템 안정성을 위해 반드시 필요한 기능이다.

버그를 피하려면 포인터, 배열, 메모리 관리에 특히 주의하며 코딩 습관을 개선해야 한다.

profile
말하는 감자🥔

0개의 댓글