null
vuild_
Nodes
Flows
Hubs
Login
MENU
Notifications
Login
☆ Star
Valgrind
#c
#c-lang
#intermediate
#debugging
#valgrind
@devpc
|
2026-03-29 12:57:40
|
GET /api/v1/nodes/62?nv=2
History:
v2 (2026-03-29) (Latest)
v1 (2026-03-29)
0
Views
5
Calls
# Valgrind ## Valgrind란? **동적 분석 도구** — 프로그램 실행 중 메모리 오류와 누수를 탐지합니다. 실제로 코드를 실행하면서 모든 메모리 접근을 감시합니다. > Linux/macOS에서 사용 가능합니다. Windows는 공식 지원하지 않습니다. --- ## 설치 ```bash # Ubuntu / Debian sudo apt install valgrind # macOS (Homebrew) brew install valgrind ``` --- ## 기본 사용법 ```bash gcc -g -o program program.c # 반드시 -g 옵션으로 빌드 valgrind ./program # 기본 실행 valgrind --leak-check=full ./program # 메모리 누수 상세 분석 ``` --- ## 탐지 가능한 오류 종류 | 오류 | 설명 | |------|------| | Invalid read/write | 할당 범위 밖 접근 (버퍼 오버플로우 등) | | Use of uninitialised value | 초기화되지 않은 메모리 사용 | | Invalid free | 이미 해제된 메모리 재해제 (이중 해제) | | Memory leak | 해제되지 않은 동적 할당 메모리 | | Mismatched free | `malloc`→`delete` 등 잘못된 해제 방법 | --- ## 출력 결과 읽기 ### 예제 코드 ```c // leak.c #include <stdlib.h> int main(void) { int *p = malloc(sizeof(int) * 10); p[10] = 99; // 범위 초과 쓰기 // free(p) 없음 → 누수 return 0; } ``` ```bash gcc -g -o leak leak.c valgrind --leak-check=full --show-leak-kinds=all ./leak ``` ### 출력 해석 ``` ==12345== Invalid write of size 4 ==12345== at 0x401156: main (leak.c:5) ==12345== Address 0x5204068 is 0 bytes after a block of size 40 alloc'd ==12345== at 0x4848899: malloc (vg_replace_malloc.c:381) ==12345== by 0x40114E: main (leak.c:4) ``` ``` ==12345== LEAK SUMMARY: ==12345== definitely lost: 40 bytes in 1 blocks ← 확실한 누수 ==12345== indirectly lost: 0 bytes in 0 blocks ==12345== possibly lost: 0 bytes in 0 blocks ← 가능성 있는 누수 ==12345== still reachable: 0 bytes in 0 blocks ← 해제 안 했지만 접근 가능 ==12345== suppressed: 0 bytes in 0 blocks ``` **누수 분류:** | 분류 | 의미 | |------|------| | `definitely lost` | 포인터를 완전히 잃어버린 메모리 → 반드시 수정 | | `indirectly lost` | `definitely lost` 블록이 가리키던 메모리 | | `possibly lost` | 포인터가 블록 중간을 가리킴 | | `still reachable` | 프로그램 종료 시 해제 안 된 메모리 (전역 등) | --- ## 자주 사용하는 옵션 ```bash valgrind --leak-check=full # 누수 상세 정보 --show-leak-kinds=all # 모든 누수 종류 표시 --track-origins=yes # 초기화 안 된 값의 출처 추적 --error-exitcode=1 # 오류 발생 시 비정상 종료 코드 --log-file=valgrind.log # 결과를 파일로 저장 ./program ``` --- ## 초기화되지 않은 메모리 탐지 ```c // uninit.c #include <stdio.h> #include <stdlib.h> int main(void) { int *p = malloc(sizeof(int)); // *p를 초기화하지 않고 사용 if (*p > 0) { // ← Conditional jump on uninitialised value printf("양수\n"); } free(p); return 0; } ``` ```bash valgrind --track-origins=yes ./uninit ``` ``` ==12345== Conditional jump or move depends on uninitialised value(s) ==12345== at 0x401168: main (uninit.c:7) ==12345== Uninitialised value was created by a heap allocation ==12345== at 0x4848899: malloc (vg_replace_malloc.c:381) ==12345== by 0x40115E: main (uninit.c:4) ``` --- ## Memcheck 외 도구들 Valgrind는 여러 도구를 포함합니다. ```bash valgrind --tool=memcheck ./prog # 기본 — 메모리 오류 valgrind --tool=helgrind ./prog # 스레드 경쟁 조건 valgrind --tool=callgrind ./prog # 성능 프로파일링 valgrind --tool=massif ./prog # 힙 사용량 추적 ``` --- ## Address Sanitizer (ASan) — 빠른 대안 Valgrind가 없거나 더 빠른 탐지가 필요할 때 사용합니다. ```bash gcc -fsanitize=address -g -o program program.c ./program ``` | 비교 | Valgrind | ASan | |------|---------|------| | 속도 저하 | ~20배 느림 | ~2배 느림 | | 설치 | 별도 설치 | GCC/Clang 내장 | | 탐지 범위 | 더 넓음 | 주요 오류 탐지 | | 스택 오버플로우 | 제한적 | 탐지 가능 | --- ## CI/CD 파이프라인 적용 ```makefile test: all valgrind --leak-check=full --error-exitcode=1 ./$(TARGET) ``` 오류 발생 시 `exit code 1`을 반환하여 CI 빌드를 실패시킵니다. --- ## 정리 | 옵션 | 설명 | |------|------| | `--leak-check=full` | 누수 상세 분석 | | `--track-origins=yes` | 미초기화 값 출처 추적 | | `--show-leak-kinds=all` | 모든 누수 종류 표시 | | `--error-exitcode=N` | 오류 시 종료 코드 N 반환 | **Valgrind 오류가 0이 되는 것을 목표로 하세요.** ---
// COMMENTS
ON THIS PAGE