세그멘테이션 오류(Segmentation Fault)는 대표적인 런타임 오류 중 하나로, 잘못된 메모리 접근으로 인해 발생합니다. 예를 들어 유효하지 않은 배열 인덱스에 접근하거나, 접근이 제한된 메모리 주소를 포인터가 가리키는 경우 등이 대표적입니다. 이 글에서는 GDB(GNU Debugger) 도구를 사용해 이러한 오류의 발생 위치를 효과적으로 찾아내는 방법을 알아보겠습니다.
오류가 발생하는 코드 예제
먼저 의도적으로 세그멘테이션 오류를 일으키는 간단한 코드를 살펴봅시다.
#include <stdio.h>
main() {
int* ptr = NULL;
*ptr = 1; // 알 수 없는 메모리 위치에 접근 시도
printf("%p\n", ptr);
}위 코드는 NULL 포인터에 값을 대입하고 있으므로, 프로그램 실행 시 반드시 크래시가 발생합니다.
1단계: 코드 컴파일 및 실행
디버깅 정보를 포함시키기 위해 -g 옵션을 붙여 다음과 같이 컴파일합니다.
gcc -g program_name.c
컴파일 후 생성된 실행 파일을 실행합니다.
soumyadeep@soumyadeep-VirtualBox:~/Cpp_progs$ ./a.out Segmentation fault (core dumped)
실행 결과 Segmentation fault (core dumped) 메시지와 함께 프로그램이 비정상 종료되었습니다. 하지만 이 메시지만으로는 어느 부분에서 문제가 발생했는지 알 수 없습니다. 바로 이 지점에서 GDB가 필요합니다.
2단계: GDB로 디버깅 시작
터미널에서 아래 명령어를 입력하여 GDB를 실행합니다.
gdb ./a.out core
GDB가 시작되면 실행 파일의 심볼(symbol) 정보를 읽어옵니다.
soumyadeep@soumyadeep-VirtualBox:~/Cpp_progs$ gdb ./a.out core GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git Copyright (C) 2018 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <https://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <https://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from ./a.out...done. /home/soumyadeep/Cpp_progs/core: No such file or directory. (gdb)
참고로 코어(core) 파일이 존재하지 않더라도 괜찮습니다. GDB 내부에서 직접 프로그램을 실행하며 오류를 추적할 수 있습니다.
3단계: 프로그램 실행 및 오류 위치 확인
(gdb) 프롬프트에서 r(run의 약자)을 입력하고 Enter 키를 누릅니다.
Starting program: /home/soumyadeep/Cpp_progs/a.out Program received signal SIGSEGV, Segmentation fault. 0x000055555555465e in main () at 1230.find_seg_error.c:5 5 *ptr = 1; //trying to access unknown memory location (gdb)
GDB는 프로그램이 SIGSEGV 신호를 받은 정확한 지점을 보여줍니다. 출력 결과를 보면 다음과 같은 핵심 정보를 확인할 수 있습니다.
- 발생 파일: 1230.find_seg_error.c
- 발생 라인: 5번째 줄
- 문제 코드:
*ptr = 1;— NULL 포인터 역참조
이처럼 컴파일 시 -g 옵션을 사용하면 소스 코드의 파일명과 라인 번호까지 정확히 표시되므로 디버깅이 훨씬 수월해집니다.
4단계: GDB 종료
오류 원인을 파악했다면 quit 명령으로 GDB를 종료합니다.
(gdb) quit A debugging session is active. Inferior 1 [process 2794] will be killed. Quit anyway? (y or n) y
실행 중인 디버깅 세션이 있다는 안내 메시지가 나타나면 y를 입력해 강제 종료합니다.
정리
GDB를 활용한 세그멘테이션 오류 추적 절차를 요약하면 다음과 같습니다.
gcc -g옵션으로 디버깅 정보를 포함해 컴파일한다.- 프로그램을 실행해 오류 발생 여부를 확인한다.
gdb ./a.out으로 디버거를 시작한다.r명령으로 프로그램을 실행하면 크래시가 발생한 파일, 함수, 라인 번호가 출력된다.
이 방법을 숙지해 두면 복잡한 C/C++ 프로젝트에서도 메모리 관련 오류를 빠르게 해결할 수 있습니다.