본문 바로가기

프로그래밍(TA, AA)/C C++

[시스템프로그래밍] Segmentation Fault

Segmentation Fault는 컴퓨터 소프트웨어의 실행 중에 일어날 수 있는 특수한 오류입니다. 세그멘테이션 위반, 세그멘테이션 실패 라고도 하며, 세그폴트(Segfault)로 줄여서 쓰기도 합니다. Segmentation Fault는 프로그램이 허용되지 않은 메모리 영역에 접근을 시도하거나, 허용되지 않은 방법으로 메모리 영역에 접근을 시도할 경우 발생합니다. (예를 들어, 읽기 전용 영역에 어떤 내용을 쓰려고 시도하거나, 운영 체제에서 사용하는 영역에 다른 내용을 덮어쓰려 하는 경우) 모토로라 68000 등의 프로세서 기반 시스템들은 이러한 오류를 주소나 버스 오류로 취급하는 경향이 있습니다.


세그멘테이션은 운영 체제에서 사용하는 메모리 관리 및 보호의 한 기법입니다. 이것은 페이징으로 대부분 대체되었지만, 세그멘테이션이라는 용어는 'Segmentation Fault'이라는 용어에서 볼 수 있듯이 여전히 사용되고 있습니다. 주로 사용되는 메모리 관리 정책이 페이징이지만 몇몇 운영 체제는 여전히 일부 논리 레벨에서 세그멘테이션을 사용하기도 합니다.


유닉스 계열 운영 체제들에서는, 잘못된 메모리에 접근하는 프로세스는 SIGSEGV 신호를 받습니다. 마이크로소프트 윈도에서는, 잘못된 메모리에 접근하는 프로세스는 STATUS_ACCESS_VIOLATION 예외 처리를 받습니다.



예제


다음은 메모리 보호를 사용하는 플랫폼에서 세그멘테이션 결함을 만드는 ANSI C 코드입니다.

const char *s = "hello world";
*s = 'H';

위 코드를 포함하는 프로그램이 컴파일되면, 문자열 "hello world"는 이 프로그램에서 읽기 전용이 됩니다. 프로그램이 로드되었을 때, 운영 체제는 이 문자열과 상수 데이터를 메모리의 읽기 전용 세그먼트에 배치합니다. 프로그램이 실행되면, 변수 's'는 이 문자열의 위치를 가리키게 되고, 'H'라는 문자열을 변수 s를 통해 메모리에 기록하려는 시도는 곧 세그멘테이션 결함을 일으키게 됩니다.


세그멘테이션 경고가 발생하는 조건이나 그것을 사용자에게 알려주는 방법은 운영 체제에 따라서도 다릅니다. 널 포인터 역참조(주소 '0'을 참조하는 포인터인 널 포인터를 통한 읽기나 쓰기로, C에서 '아무것도 가리키지 않는 포인터'를 나타내기 위해서 또는 오류 지시자로 사용)는 흔히 일어나는 오류이기 때문에, 대부분의 운영 체제는 메모리의 첫 페이지를 살피며, 따라서 여기에 접근하면 세그멘테이션 결함이 발생합니다.