Segmentation Fault 디버깅 방법


Segmentation Fault 디버깅 방법 리눅스에서 발생하는 Segmentation fault (core dumped) 오류 또는 stack smashing detected 오류를 GDB를 이용하여 디버깅하는 방법을 알려드립니다. 이 오류는 주로 제한된 메모리 크기 보다 큰 사이즈의 데이터를 기록 할 때 발생하게 됩니다.

Segmentation Fault 디버깅 방법

환경

리눅스 환경에서 실행되는 프로그램을 디버깅 하는 방법입니다. 오류가 발생하는 소스코드가 있을 경우 보다 쉽게 오류 발생 위치를 찾아 낼 수 있습니다. gdb 프로그램이 설치지 되지 않았을 경우 먼저 gdb 프로그램을 설치해 주시기 바랍니다.

우분투 리눅스를 사용하는 환경일 경우 아래의 명령어로 gdb 패키지를 설치 하실 수 있습니다.

$ sudo apt install gdb gdb-dbg

예제 코드 다운로드

이 글에서 설명하는 전체 예제 코드는 아래의 git 명령어로 다운 받을 수 있습니다.

$ git clone https://hiseon.me/reps/gdb-segmentation-fault-example.git

main.cpp 소스코드를 확인하면, buf 사이즈가 100Byte 이지만 이 사이즈보 큰 데이터를 buf 버퍼에 저장하고 있음을 알 수 있습니다.

#include <string.h>

void f(void) {
  char buf[100];
  memcpy(buf, "hello, world", 1024);
}

int main() {
  f();
  return 0;
}

예제 소스코드 실행

아래의 명령어를 이용하여 소스코드를 빌드 후 실행합니다.

$ g++ -g main.cpp -o main
$ ./main
*** stack smashing detected ***: terminated
Aborted (core dumped)

스택 손상이 탐지되었다는 stack smashing detected 에러가 발생하게 됩니다.
최신 메모리 보호 기법으로 Segmentation fault 에러 대신에 이 에러가 발생하였습니다. 공격을 방지하기 위한 기능입니다.

-fno-stack-protector 옵션을 추가하여 빌드하였을 경우는 아래와 같이 Segmentation fault (core dumped) 오류가 발생함을 알 수 있습니다.

$  g++ -g -fno-stack-protector main.cpp -o main
$ ./main
Segmentation fault (core dumped)

GDB를 이용한 디버깅 방법

오류가 발생하는 코드의 위치를 GDB 명령어를 사용하여 원인을 찾아보도록 하겠습니다. 아래의 명령어를 이용하여 GDB를 실행합니다.

$ gdb ./main
Segmentation Fault 디버깅 방법

위의 모습은 문제가 발생하는 프로그램을 입력값으로 gdb 프로그램을 실행한 모습입니다.

아직 문제가 발생하는 프로그램이 실행되지 않았는데, run 명령어를 입력하여 문제가 발생하는 프로그램을 실행합니다.

Segmentation Fault 디버깅 방법

위의 실행 결과에서 나타나듯이 프로그램이 실행되다가 메모리 손상으로 정지되었다는 것을 나타냅니다. 현재의 위치에서 문제가 발생한 위치를 확인해 보도록 하겠습니다.

아래와 같이 BackTrace 정보를 확인하는 bt 명령어를 입력합니다.

Segmentation Fault 디버깅 방법

위에서 출력되는 결과와 같이 main.ccp 호스코드의 f 함수에서 부터 오류가 발생한 것을 알 수 있습니다.

문제가 발생되는 원인 위치가 확인되면 아래와 같이 quit 명령어를 입력하여 디버깅을 종료하면 됩니다.

stack smashing detected 오류 또는 Segmentation Fault 디버깅 방법 대해 설명드렸습니다.

추가적인 내용으로 C/C++ 프로그램을 개발 할때에 오류 발생을 최소화 하도록 단위 테스트를 실행하면서 개발 할 수도 있습니다. Google Test와 관련된 내용은 아래의 글을 참고해 주시기 바랍니다.

Google Test 사용법 예제

( 본문 인용시 출처를 밝혀 주시면 감사하겠습니다.)