우당탕탕 개발일지
[C언어] Makefile / GDB 본문
Makefile
Makefile은 make 명령이 읽는 빌드 규칙 파일이다. makefile을 사용하는 이유는 Incremental build를 사용하기 위해서다.
Incremental build는 반복적인 빌드 과정에서 변경된 소스코드에 의존성이 있는 대상들만 추려서 다시 빌드하는 기능이다.
✅ 기본 구조
target: dependencies
<TAB> recipe
Makefile은 대상(Target), 의존 관계(Dependency), 명령(Recipe) 세 가지로 이루어진다.
- target: 생성할 파일 이름 (예: 실행파일)
- dependencies: target을 만들기 위해 필요한 소스 파일들
- recipe: 실행할 명령어 (※ 반드시 탭 문자로 시작해야 함)
✅ 시스템 전용 옵션 (optional)
운영체제 또는 시스템 라이브러리 기능을 사용하기 위해 컴파일러에 주는 옵션이다. 주로 멀티스레딩, 실시간 기능, 네트워크 기능 등을 사용할 때 필요하다.
| 옵션 | 의미 | |
| -lpthread | POSIX 스레드 라이브러리 | pthread_create, pthread_mutex_* 등 멀티스레드 함수 |
| -lm | 수학 라이브러리 | sqrt, sin, cos, pow 등 사용 시 필요 |
| -lrt | 실시간 기능 라이브러리 (Linux) | clock_gettime, timer_create 등 실시간 API |
| -lnsl | Sun RPC, 네트워크 서비스 라이브러리 (구형) | gethostbyname, rpc 함수 등 (거의 안 씀) |
✅ 사용법
# 시스템 라이브러리
SYS_LIB= -lpthread -lm -lrt -lnsl
# 컴파일러 설정
CC= gcc
CFLAGS= -g -Wall -O2
LDFLAGS=
LIBS= $(SYS_LIB)
# 빌드할 실행 파일들
PROGS= test1 test2
all: $(PROGS)
%: %.c
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
clean::
-rm -f $(PROGS) *.o core
- CC: 사용할 C 컴파일러
- CFLAGS: 컴파일 옵션
- -g: 디버깅 정보 포함
- -Wall: 모든 경고 표시
- -02: 최적화
- LDFLAGS: 링커 옵션 / LDLIBS: 링커 라이브러리
- %: %.c: GNU Make의 패턴 규칙
- $@: 타겟 이름 (예: test)
- $^: 모든 의존 파일 (예: test.c)
make # 빌드 실행 (Makefile 읽음)
make clean # 중간파일 제거

GDB를 시작하기 전에는 디버깅 옵션으로 컴파일해야 한다. -g 옵션은 디버깅 정보를 바이너리에 포함시켜 GDB에서 변수명, 줄 번호 등을 알 수 있게 한다.
gcc -g test.c -o test
✅ GDB 실행 방법
- gdb <프로그램명>
- gdb <프로그램명> <core 파일명>
- gdb <프로그램명> <실행중인 프로세스 pid>
✅ 주요 명령어
| run 또는 r | 프로그램 실행 |
| break 또는 b | 중단점(breakpoint) 설정 |
| break main | main 함수에서 멈춤 |
| break 12 | 소스 코드 12번째 줄에서 멈춤 |
| next 또는 n | 현재 줄 한 줄 실행 (함수는 건너뜀) |
| step 또는 s | 현재 줄 한 줄 실행 (함수 내부로 진입) |
| continue 또는 c | 다음 중단점까지 계속 실행 |
| print x 또는 p x | 변수 x 값 출력 |
| display x | 계속 자동으로 x 출력 |
| info locals | 현재 함수의 지역 변수 목록 |
| info breakpoints | 설정된 중단점 목록 |
| delete 또는 del | 중단점 삭제 |
| list 또는 l | 코드 출력 (기본적으로 현재 위치 기준 주변 코드) |
| quit 또는 q | GDB 종료 |
GDB 사용 예시
$ gcc -g test.c -o test # 디버깅 정보 포함
$ gdb ./test
(gdb) b main # main 함수에 중단점
(gdb) display x # 실시간 변수 추적
(gdb) r 123 # 프로그램 실행 + 인자
(gdb) n # 한 줄 실행
(gdb) s # 함수 내부 진입
(gdb) p node # 변수 출력
(gdb) quit # 종료
✅ TUI(Text User Interface) 모드
Ctrl + x + a 단축키를 사용하면 다음과 같이 코드를 시각적으로 보며 디버깅할 수 있다.

✅ Backtrace
(gdb) bt
#0 main () at Prepare_test.c:38
(gdb) f 0
Segmentation fault가 발생하여 어디서 문제가 발생하였는지 확인하고 싶거나 함수 호출 경로를 추적하고 싶을 때 백트레이스를 출력한다. bt 명령어를 사용하면 현재 함수 호출 스택(trace)를 위에서부터 차례대로 출력한다. 즉, 현재 함수가 어떤 함수에 의해 호출되었는지를 역순으로 추적할 수 있다. f N 명령어 사용시 N번째 프레임으로 이동한다. 백트레이스는 다음과 같은 경우 사용한다.
- 프로그램이 죽었을 때 (예: segmentation fault)
- 어디서 문제가 발생했는지 확인하고 싶을 때
- 함수 호출 경로를 추적하고 싶을 때
✅ set
(gdb) p ret # 변수 값 확인
$1 = 5
(gdb) set ret = 10 # 변수 값 변경
(gdb) p ret
$2 = 10
GDB에서 단순히 변수 값을 확인할 때는 p 명령어를 쓰지만, 값을 변경하고 싶을 때는 set 명령어를 사용한다. 포인터나 구조체 필드도 변경이 가능하다.
(gdb) set x[3] = 99 // 배열 요소
(gdb) set ptr->value = 42 // 구조체 멤버
(gdb) set *p = 5 // 포인터가 가리키는 값
'Server > Linux, C' 카테고리의 다른 글
| [C언어] 동기화 (feat. Mutex API 사용해 은행 잔고 프로그램 구현하기) (0) | 2025.09.12 |
|---|---|
| [C언어] Thread (4) | 2025.06.25 |
| [C언어] 전처리기 (0) | 2025.05.25 |
| [Linux] 리눅스 파일과 파일 시스템 (1) | 2025.05.11 |
| [C언어] 문자열 (feat. strcpy, strtok_r 활용 예제) (0) | 2025.05.11 |