[컴퓨터 시스템] 4. 디버거는 실행을 보는 창이다
디버깅을 막연히 '에러를 잡는 감'으로 배우면 시간이 오래 걸립니다. 시스템 공부에서는 특히 프로그램이 지금 어느 상태에 있는지 직접 보는 태도가 중요하고, 그래서 디버거는 선택 도구가 아니라 학습 도구에 가깝습니다.
이번 글에서는 GDB와 Valgrind를 기능 목록으로 소개하기보다, 어떤 질문에 답하게 해주는지 중심으로 정리합니다. 포인터와 메모리 감각이 아직 약하다면 3편을 먼저 보고 오는 편이 좋습니다.
- 디버깅을 감이 아니라 상태 관찰로 보는 관점
- GDB가 특히 강한 질문 세 가지
- 작은 버그 예제로 breakpoint, step, print, backtrace 읽기
- Valgrind가 메모리 문제에서 왜 강한지
- 실전에서 GDB와 Valgrind를 어떤 순서로 쓰면 좋은지
1. 디버깅은 정답 찍기가 아니라 상태를 좁혀 가는 과정이다
오류가 났을 때 코드를 한참 바라보다가 감으로 수정하는 습관은 초반엔 자주 생깁니다. 하지만 시스템 수준 문제는 메모리 상태, 함수 호출 순서, 실제 값이 어떻게 변했는지까지 봐야 하므로 눈으로 관찰하는 도구가 훨씬 중요합니다.
그래서 디버깅의 첫 전환점은 '왜 틀렸지?'보다 '지금 상태가 내가 예상한 상태와 어디서 어긋났지?'로 질문을 바꾸는 데 있습니다.
2. GDB는 세 가지 질문에 특히 강하다
GDB의 명령은 많지만, 초반에는 세 가지 질문으로 묶어 이해하면 훨씬 쉽습니다. 지금 어디까지 왔는지, 지금 값이 무엇인지, 여기까지 어떤 흐름으로 왔는지를 묻는 도구라고 생각하면 됩니다.
| 질문 | 대표 명령 감각 | 왜 중요한가 |
|---|---|---|
| 지금 어디에 있는가 | break, run, next, step | 문제가 처음 드러나는 지점을 찾는다 |
| 지금 값이 무엇인가 | print, display | 예상과 실제 값 차이를 확인한다 |
| 어떤 호출 흐름으로 왔는가 | backtrace | 잘못된 경로를 타고 온 지점을 좁힌다 |
3. 아주 작은 버그 예제로 흐름을 따라가 보자
실전 디버깅은 커다란 프로그램에서도 결국 작은 관찰의 반복입니다. 짧은 예제로 먼저 감각을 잡아두면 이후 복잡한 코드에서도 같은 질문을 반복할 수 있습니다.
#include <stdio.h>
int main(void) {
int arr[3] = {1, 2, 3};
int i;
int sum = 0;
for (i = 0; i <= 3; i++) {
sum += arr[i];
}
printf("%d\n", sum);
return 0;
}4. Valgrind는 메모리 문제를 다른 방식으로 드러낸다
GDB가 현재 상태를 직접 들여다보는 창이라면, Valgrind는 메모리 사용 패턴을 감시하는 검사기처럼 볼 수 있습니다. 특히 해제 후 접근, 초기화되지 않은 값 사용, 누수 같은 문제에서 강합니다.
| 도구 | 강한 질문 | 대표 상황 |
|---|---|---|
| GDB | 지금 어디서 어떤 값으로 실행 중인가 | 크래시 지점 좁히기, 호출 흐름 추적 |
| Valgrind | 메모리를 잘못 쓰고 있지 않은가 | 누수, 해제 후 접근, 초기화 안 된 값 추적 |
5. 실제로는 두 도구를 같이 쓰는 편이 자연스럽다
세그폴트가 났다면 먼저 GDB로 어디서 멈췄는지 봅니다. 그런데 그 원인이 이미 사라진 메모리를 가리킨 포인터라면, Valgrind가 더 먼저 힌트를 줄 수도 있습니다. 도구를 경쟁 관계로 보기보다 질문 종류에 따라 나눠 쓰는 편이 좋습니다.
6. 디버깅을 공부 습관으로 만들려면
디버깅은 에러가 났을 때만 하는 특별 행사처럼 느껴지기 쉽습니다. 하지만 작은 예제라도 breakpoint를 걸어 보고, 값이 바뀌는 순간을 직접 확인하는 습관을 들이면 뒤의 시스템 주제도 훨씬 잘 보입니다.
특히 포인터, 배열, 스택 프레임처럼 눈에 안 보이는 개념은 디버거를 켜야 비로소 공부거리가 됩니다.
7. 직접 해볼 문제: 어떤 도구부터 켤지 정해 보자
이 문제는 도구 이름 암기보다 질문 종류를 분류하는 연습입니다.
이번 글에서 기억할 것
스스로 점검
다음 글 예고
다음 글에서는 데이터가 결국 비트로 저장된다는 사실을 바탕으로, 정수와 signed/unsigned, overflow가 왜 헷갈리는지 정리합니다.
'학습 자료 글 > 컴퓨터시스템' 카테고리의 다른 글
| 컴퓨터시스템 기초 6. 바이트 순서는 왜 값을 다르게 보이게 만들까 (0) | 2026.03.31 |
|---|---|
| 컴퓨터시스템 기초 5. 데이터는 왜 결국 비트로 표현될까 (0) | 2026.03.31 |
| 컴퓨터시스템 기초 3. 포인터와 메모리를 같이 이해해야 하는 이유 (0) | 2026.03.31 |
| 컴퓨터시스템 기초 2. C는 왜 시스템의 입구가 되는가 (0) | 2026.03.31 |
| 컴퓨터시스템 기초 1. 프로그램은 어디에서 실행될까 (0) | 2026.03.31 |