Ver2.0 ๐ ๏ธ Valgrind๋ก ๋ฉ๋ชจ๋ฆฌ ์ค๋ฅ ์ก์๋ด๊ธฐ ๐

๐ ๏ธ Valgrind๋ก ๋ฉ๋ชจ๋ฆฌ ์ค๋ฅ ์ก์๋ด๊ธฐ ๐
C ํ๋ก๊ทธ๋๋ฐ์ ์จ์ ์ , ๋ฉ๋ชจ๋ฆฌ ์ค๋ฅ์์ ์ ์
์๋ ํ์ธ์ ์ฌ๋ฌ๋ถ! ์ค๋์ C ํ๋ก๊ทธ๋๋ฐํ ๋ ์ง์ง ๊ณจ์น ์ํ ๋ฉ๋ชจ๋ฆฌ ์ค๋ฅ๋ฅผ ์ฐพ์๋ด๋ ์ด๊ฐ๋ ฅ ๋๊ตฌ์ธ Valgrind์ ๋ํด ์์๋ณผ๊ฒ์! ๐
C ์ธ์ด๋ก ์ฝ๋ฉํ๋ค ๋ณด๋ฉด ์ด๋ฐ ๊ฒฝํ ์์ผ์์ฃ ? ํ๋ก๊ทธ๋จ์ด ๊ฐ์๊ธฐ '์ธ๊ทธ๋ฉํ ์ด์ ์ค๋ฅ'๋ผ๋ฉด์ ๋ป์ด๋ฒ๋ฆฌ๊ฑฐ๋, ์๋๋ฉด ๋ ๋ฌด์์ด ๊ฑด ๊ฒ์ผ๋ก๋ ๋ฉ์ฉกํ๋ฐ ๋ค์์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์๊ณ ์๋ ๊ฒฝ์ฐ... ์ง์ง ์ฐพ๊ธฐ ์ด๋ ต์ฃ ? ใ ใ
๊ทผ๋ฐ ๊ฑฑ์ ๋ง์ธ์! Valgrind๋ผ๋ ์์ฒญ๋ ์น๊ตฌ๊ฐ ์์ด์. ์ด ๋๊ตฌ๋ ๋ง์น ๋ฉ๋ชจ๋ฆฌ ์ธ๊ณ์ CCTV ๊ฐ์์ ์ฌ๋ฌ๋ถ์ ํ๋ก๊ทธ๋จ์ด ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ด๋ป๊ฒ ์ฌ์ฉํ๋์ง ๋ค ์ง์ผ๋ณด๊ณ ์๋ต๋๋ค. ๐
์ด ๊ธ์์๋ Valgrind๊ฐ ๋ญ์ง, ์ด๋ป๊ฒ ์ค์นํ๊ณ ์ฌ์ฉํ๋์ง, ๊ทธ๋ฆฌ๊ณ ์ด๋ค ์ข ๋ฅ์ ๋ฉ๋ชจ๋ฆฌ ์ค๋ฅ๋ค์ ์ก์๋ผ ์ ์๋์ง ์์ธํ ์์๋ณผ ๊ฑฐ์์. ํนํ C ํ๋ก๊ทธ๋๋ฐ์ ๋ฐฐ์ฐ๋ ๋ถ๋ค์ด๋ ๊ฐ๋ฐ์๋ถ๋ค์๊ฒ ๊ผญ ํ์ํ ๋ด์ฉ์ด๋ ๋๊น์ง ํจ๊ปํด์! ๐
๐ ๋ชฉ์ฐจ
- Valgrind๋ ๋ฌด์์ธ๊ฐ์?
- Valgrind ์ค์นํ๊ธฐ
- Valgrind ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
- ์ฃผ์ ๋ฉ๋ชจ๋ฆฌ ์ค๋ฅ ์ ํ๊ณผ ํด๊ฒฐ๋ฒ
- Valgrind ๊ณ ๊ธ ๊ธฐ๋ฅ ์ดํด๋ณด๊ธฐ
- ์ค์ ์์ ๋ก ๋ฐฐ์ฐ๋ Valgrind
- ์์ฃผ ๋ฌป๋ ์ง๋ฌธ๋ค
1. Valgrind๋ ๋ฌด์์ธ๊ฐ์? ๐ค
Valgrind๋ ๋ฉ๋ชจ๋ฆฌ ์ค๋ฅ์ ๋์๋ฅผ ์ฐพ์๋ด๋ ๊ฐ๋ ฅํ ๋๊ตฌ์์. 2000๋ ๋ ์ด๋ฐ์ ๋ฑ์ฅํด์ ์ง๊ธ๊น์ง C/C++ ๊ฐ๋ฐ์๋ค์ ํ์ ๋๊ตฌ๋ก ์๋ฆฌ์ก์์ฃ . ์ด๋ฆ์ด ์ข ํน์ดํ์ฃ ? ๋ถ์ ๋ฝ ์ ํ์์ ์๊ฐ์ ๋ฐ์๋ค๊ณ ํด์! ใ ใ ใ
Valgrind์ ๊ฐ์ฅ ์ ๋ช ํ ๊ธฐ๋ฅ์ Memcheck์ธ๋ฐ์, ์ด๊ฒ ๋ฐ๋ก ๋ฉ๋ชจ๋ฆฌ ๊ด๋ จ ๋ฌธ์ ๋ฅผ ์ฐพ์๋ด๋ ํต์ฌ ๊ธฐ๋ฅ์ด์์. ๊ทธ ์ธ์๋ ์บ์ ๋ฏธ์ค, ์ค๋ ๋ ๋ฌธ์ ๋ฑ์ ๋ถ์ํ๋ ๋ค์ํ ๋๊ตฌ๋ค์ด ์์ด์.
Valgrind๊ฐ ๋์ฒด ์ด๋ป๊ฒ ์๋ํ๋ ๊ฑธ๊น์? ๐ง ๊ฐ๋จํ ๋งํ๋ฉด, ์ฌ๋ฌ๋ถ์ ํ๋ก๊ทธ๋จ์ ๊ฐ์ CPU ์์์ ์คํ์ํค๋ฉด์ ๋ชจ๋ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ์ ๊ฐ์ํด์. ๊ทธ๋์ ์ข ๋๋ฆฌ๊ธด ํ์ง๋ง(์๋ ์๋์ ์ฝ 10~30๋ฐฐ), ๋ฉ๋ชจ๋ฆฌ ๋ฌธ์ ๋ฅผ ์ ํํ๊ฒ ์ฐพ์๋ผ ์ ์์ด์!
์์ฆ ๊ฐ์ ์๋์ ๊ฐ๋ฐ์๋ก ์ฑ์ฅํ๋ ค๋ฉด ์ด๋ฐ ๋๊ตฌ๋ค์ ์ ํ์ฉํ๋ ๊ฒ์ด ์ค์ํ๋ฐ์, ์ฌ๋ฅ๋ท ๊ฐ์ ํ๋ซํผ์์๋ Valgrind ๊ฐ์ ๋๊ตฌ ํ์ฉ๋ฒ์ ๋ฐฐ์ธ ์ ์๋ ๊ฐ์๋ค์ด ์ธ๊ธฐ๊ฐ ๋ง๋๋ผ๊ณ ์. ๊ฐ๋ฐ์์ ์ค๋ ฅ์ ํ ๋จ๊ณ ์ ๊ทธ๋ ์ด๋ํ๋ ๋ฐ ํฐ ๋์์ด ๋๋๊น์! ๐ช
2. Valgrind ์ค์นํ๊ธฐ ๐ง
์, ์ด์ Valgrind๋ฅผ ์ค์นํด๋ณผ๊น์? ์ด์์ฒด์ ๋ณ๋ก ์ค์น ๋ฐฉ๋ฒ์ด ๋ค๋ฅด๋ ํ์ธํด๋ณด์ธ์!
Linux์์ ์ค์นํ๊ธฐ ๐ง
๋ฆฌ๋ ์ค๋ Valgrind์ ๊ณ ํฅ์ด๋ผ ์ค์น๊ฐ ์ด๊ฐ๋จ์ด์์!
Ubuntu/Debian:
sudo apt-get install valgrind
Fedora/RHEL/CentOS:
sudo dnf install valgrind
Arch Linux:
sudo pacman -S valgrind
macOS์์ ์ค์นํ๊ธฐ ๐
๋งฅ์์๋ Homebrew๋ฅผ ์ด์ฉํ๋ฉด ์ฝ๊ฒ ์ค์นํ ์ ์์ด์:
brew install valgrind
โ ๏ธ ์ฃผ์: ์ต์ macOS ๋ฒ์ ์์๋ Valgrind๊ฐ ์๋ฒฝํ๊ฒ ์ง์๋์ง ์์ ์ ์์ด์. ํธํ์ฑ ๋ฌธ์ ๊ฐ ์๋ค๋ฉด Docker๋ ๊ฐ์๋จธ์ ์ ์ฌ์ฉํ๋ ๊ฒ๋ ๋ฐฉ๋ฒ์ด์์!
Windows์์ ์ค์นํ๊ธฐ ๐ช
์๋์ฐ์์๋ ์ง์ ์ง์์ด ์ ๋์ง๋ง, ๋ค์ ๋ฐฉ๋ฒ์ผ๋ก ์ฌ์ฉํ ์ ์์ด์:
- WSL(Windows Subsystem for Linux) ์ค์น
- WSL์์ Ubuntu ๋ฑ์ ๋ฆฌ๋ ์ค ๋ฐฐํฌํ ์ค์น
- ๋ฆฌ๋ ์ค ๋ฐฐํฌํ ๋ด์์ Valgrind ์ค์น
๋๋ Cygwin์ด๋ MinGW ํ๊ฒฝ์์ ์๋ํด๋ณผ ์๋ ์์ด์.
์ค์น๊ฐ ์๋ฃ๋์๋ค๋ฉด ํฐ๋ฏธ๋์์ ๋ค์ ๋ช ๋ น์ด๋ก ์ ๋๋ก ์ค์น๋๋์ง ํ์ธํด๋ณด์ธ์:
valgrind --version
๋ฒ์ ์ ๋ณด๊ฐ ๋์ค๋ฉด ์ฑ๊ณต์ ๋๋ค! ๐ ์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก Valgrind๋ฅผ ์ฌ์ฉํด๋ณผ ์ค๋น๊ฐ ๋์ด์!
3. Valgrind ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ ๐
์, ์ด์ Valgrind๋ฅผ ์ด๋ป๊ฒ ์ฌ์ฉํ๋์ง ์์๋ณผ๊ฒ์! ์ง์ง ์ฌ์์, ๊ฑฑ์ ๋ง์ธ์~ ใ ใ
๊ธฐ๋ณธ ๋ช ๋ น์ด ๊ตฌ์กฐ
Valgrind์ ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ์ ์ด๋ ๊ฒ ์๊ฒผ์ด์:
valgrind [valgrind-์ต์
] [ํ๋ก๊ทธ๋จ] [ํ๋ก๊ทธ๋จ-์ธ์]
๊ฐ์ฅ ๋ง์ด ์ฌ์ฉํ๋ Memcheck ๋๊ตฌ๋ฅผ ์ฌ์ฉํ๋ ๊ธฐ๋ณธ ๋ช ๋ น์ด๋ ์ด๋ ์ต๋๋ค:
valgrind --tool=memcheck [ํ๋ก๊ทธ๋จ]
์ฌ์ค memcheck๋ ๊ธฐ๋ณธ ๋๊ตฌ๋ผ์ ์๋ตํด๋ ๋ผ์:
valgrind [ํ๋ก๊ทธ๋จ]
๊ฐ๋จํ ์์ ๋ก ์์ํด๋ณด๊ธฐ
๋จผ์ ๋ฉ๋ชจ๋ฆฌ ์ค๋ฅ๊ฐ ์๋ ๊ฐ๋จํ C ํ๋ก๊ทธ๋จ์ ๋ง๋ค์ด๋ณผ๊ฒ์:
// memory_error.c
#include <stdlib.h>
int main() {
int *x = malloc(10 * sizeof(int));
x[10] = 0; // ๋ฐฐ์ด ๋ฒ์๋ฅผ ๋ฒ์ด๋ ์ ๊ทผ! ํ ๋น๋ ํฌ๊ธฐ๋ 0~9๊น์ง์ธ๋ฐ 10์ ์ ๊ทผ
// ๋ฉ๋ชจ๋ฆฌ ํด์ ๋ฅผ ์ ํจ (๋ฉ๋ชจ๋ฆฌ ๋์)
return 0;
}
์ด ์ฝ๋๋ฅผ ์ปดํ์ผํ๊ณ Valgrind๋ก ์คํํด๋ณผ๊ฒ์:
gcc -g memory_error.c -o memory_error
valgrind ./memory_error
-g ์ต์ ์ ๋๋ฒ๊น ์ ๋ณด๋ฅผ ํฌํจํด์ ์ปดํ์ผํ๋ผ๋ ์๋ฏธ์์. ์ด๋ ๊ฒ ํ๋ฉด Valgrind๊ฐ ๋ ์์ธํ ์ ๋ณด๋ฅผ ์ ๊ณตํด์ค์!
์คํํ๋ฉด ๋๋ต ์ด๋ฐ ๊ฒฐ๊ณผ๊ฐ ๋์ฌ ๊ฑฐ์์:
==12345== Memcheck, a memory error detector
==12345== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==12345== Using Valgrind-3.15.0 and LibVEX...
==12345== Command: ./memory_error
==12345==
==12345== Invalid write of size 4
==12345== at 0x109177: main (memory_error.c:5)
==12345== Address 0x4a37068 is 0 bytes after a block of size 40 alloc'd
==12345== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==12345== by 0x109166: main (memory_error.c:4)
==12345==
==12345== HEAP SUMMARY:
==12345== in use at exit: 40 bytes in 1 blocks
==12345== total heap usage: 1 allocs, 0 frees, 40 bytes allocated
==12345==
==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
==12345==
==12345== For lists of detected and suppressed errors, rerun with: -s
==12345== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
์ฐ์! ๐ฒ Valgrind๊ฐ ๋ ๊ฐ์ง ๋ฌธ์ ๋ฅผ ์ฐพ์๋์ด์:
- Invalid write: ๋ฐฐ์ด ๋ฒ์๋ฅผ ๋ฒ์ด๋ ์ ๊ทผ (x[10])
- Memory leak: malloc์ผ๋ก ํ ๋นํ ๋ฉ๋ชจ๋ฆฌ๋ฅผ freeํ์ง ์์
์ด๋ ๊ฒ Valgrind๋ ์คํ ์ค์ ๋ฐ์ํ๋ ๋ฉ๋ชจ๋ฆฌ ์ค๋ฅ๋ฅผ ์ ํํ ์๋ ค์ฃผ๊ณ , ์ด๋ ์ฝ๋ ๋ผ์ธ์์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋์ง๊น์ง ์๋ ค์ค์! ์ง์ง ๊ฐ๋ฐ์์ ๊ตฌ์ธ์ฃผ ์๋๊ฒ ์ด์? ใ ใ ใ
์์ฃผ ์ฌ์ฉํ๋ ์ต์ ๋ค
Valgrind๋ฅผ ๋ ํจ๊ณผ์ ์ผ๋ก ์ฌ์ฉํ ์ ์๋ ์ ์ฉํ ์ต์ ๋ค์ด์์:
--leak-check=full: ๋ฉ๋ชจ๋ฆฌ ๋์์ ๋ํ ์์ธํ ์ ๋ณด ์ ๊ณต
--show-leak-kinds=all: ๋ชจ๋ ์ข
๋ฅ์ ๋ฉ๋ชจ๋ฆฌ ๋์ ํ์
--track-origins=yes: ์ด๊ธฐํ๋์ง ์์ ๊ฐ์ ์ถ์ฒ ์ถ์
--verbose: ๋ ์์ธํ ์ถ๋ ฅ
--log-file=ํ์ผ๋ช
: ๊ฒฐ๊ณผ๋ฅผ ํ์ผ๋ก ์ ์ฅ
์ด ์ต์ ๋ค์ ์กฐํฉํด์ ์ฌ์ฉํ๋ฉด ๋ ์์ธํ ๋ถ์์ด ๊ฐ๋ฅํด์:
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./memory_error
์ด๋ฐ ์์ผ๋ก Valgrind๋ฅผ ์ฌ์ฉํ๋ฉด C ํ๋ก๊ทธ๋๋ฐ์์ ๊ฐ์ฅ ๊น๋ค๋ก์ด ๋ฉ๋ชจ๋ฆฌ ๋ฌธ์ ๋ค์ ์ฝ๊ฒ ์ฐพ์๋ผ ์ ์์ด์! ๐
4. ์ฃผ์ ๋ฉ๋ชจ๋ฆฌ ์ค๋ฅ ์ ํ๊ณผ ํด๊ฒฐ๋ฒ ๐จ
C ํ๋ก๊ทธ๋๋ฐ์์ ๋ง๋ ์ ์๋ ์ฃผ์ ๋ฉ๋ชจ๋ฆฌ ์ค๋ฅ ์ ํ๋ค๊ณผ Valgrind๊ฐ ์ด๋ป๊ฒ ์ด๋ฅผ ์ฐพ์๋ด๋์ง, ๊ทธ๋ฆฌ๊ณ ์ด๋ป๊ฒ ํด๊ฒฐํ ์ ์๋์ง ์์๋ณผ๊ฒ์!
1. ๋ฉ๋ชจ๋ฆฌ ๋์ (Memory Leak) ๐ง
๋ฉ๋ชจ๋ฆฌ ๋์๋ ํ ๋น๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํด์ ํ์ง ์์ ๋ฐ์ํ๋ ๋ฌธ์ ์์. ํ๋ก๊ทธ๋จ์ด ์ค๋ ์คํ๋ ์๋ก ์ฌ์ฉ ๊ฐ๋ฅํ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ค์ด๋ค์ด ๊ฒฐ๊ตญ ์์คํ ์ฑ๋ฅ ์ ํ๋ ํ๋ก๊ทธ๋จ ์ถฉ๋์ ์ผ์ผํฌ ์ ์์ด์.
์์ ์ฝ๋:
void memory_leak_example() {
int *array = malloc(100 * sizeof(int));
// ์ฌ๊ธฐ์ array ์ฌ์ฉ
// free(array); // ์ด ์ค์ด ์์ผ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์ ๋ฐ์!
return;
}
Valgrind ์ถ๋ ฅ:
==12345== HEAP SUMMARY:
==12345== in use at exit: 400 bytes in 1 blocks
==12345== total heap usage: 1 allocs, 0 frees, 400 bytes allocated
==12345==
==12345== LEAK SUMMARY:
==12345== definitely lost: 400 bytes in 1 blocks
ํด๊ฒฐ์ฑ : ํ ๋นํ ๋ฉ๋ชจ๋ฆฌ๋ ๋ฐ๋์ free()๋ก ํด์ ํด์ฃผ์ธ์! ํนํ ํจ์๋ฅผ ๋น ์ ธ๋๊ฐ๊ธฐ ์ ์ ํด์ ํ๋ ๊ฒ์ ์์ง ๋ง์ธ์.
2. ์๋ชป๋ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ (Invalid Memory Access) ๐ซ
๋ฐฐ์ด ๋ฒ์๋ฅผ ๋ฒ์ด๋๊ฑฐ๋, ์ด๋ฏธ ํด์ ๋ ๋ฉ๋ชจ๋ฆฌ์ ์ ๊ทผํ๊ฑฐ๋, NULL ํฌ์ธํฐ๋ฅผ ์ญ์ฐธ์กฐํ ๋ ๋ฐ์ํด์. ์ด๋ฐ ์ค๋ฅ๋ ์ธ๊ทธ๋ฉํ ์ด์ ์ค๋ฅ(Segmentation Fault)๋ฅผ ์ผ์ผํค๋ ์ฃผ๋ฒ์ด์์!
์์ ์ฝ๋:
void invalid_access_example() {
int *array = malloc(5 * sizeof(int));
array[5] = 10; // ์ค๋ฅ! ์ธ๋ฑ์ค๋ 0~4๊น์ง๋ง ์ ํจ
free(array);
array[0] = 5; // ์ค๋ฅ! ์ด๋ฏธ ํด์ ๋ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ
int *ptr = NULL;
*ptr = 10; // ์ค๋ฅ! NULL ํฌ์ธํฐ ์ญ์ฐธ์กฐ
}
Valgrind ์ถ๋ ฅ:
==12345== Invalid write of size 4
==12345== at 0x109177: invalid_access_example (example.c:4)
==12345== Address 0x4a37054 is 0 bytes after a block of size 20 alloc'd
ํด๊ฒฐ์ฑ : ํญ์ ๋ฐฐ์ด ๋ฒ์๋ฅผ ํ์ธํ๊ณ , ํฌ์ธํฐ๊ฐ ์ ํจํ์ง ํ์ธํ์ธ์. ๊ทธ๋ฆฌ๊ณ ํด์ ๋ ๋ฉ๋ชจ๋ฆฌ๋ ์ ๋ ์ ๊ทผํ์ง ๋ง์ธ์!
3. ์ด๊ธฐํ๋์ง ์์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ (Uninitialized Memory) โ
๋ณ์๋ฅผ ์ด๊ธฐํํ์ง ์๊ณ ์ฌ์ฉํ๋ฉด ์ฐ๋ ๊ธฐ๊ฐ์ด ๋ค์ด์์ด ์์ธกํ ์ ์๋ ๋์์ ์ผ์ผํฌ ์ ์์ด์.
์์ ์ฝ๋:
void uninitialized_memory_example() {
int x;
if(x > 10) { // ์ค๋ฅ! x๊ฐ ์ด๊ธฐํ๋์ง ์์
printf("x is greater than 10\n");
}
int *array = malloc(5 * sizeof(int));
// array ๊ฐ์ ์ด๊ธฐํํ์ง ์์
printf("First element: %d\n", array[0]); // ์ด๊ธฐํ๋์ง ์์ ๊ฐ ์ฌ์ฉ
free(array);
}
Valgrind ์ถ๋ ฅ:
==12345== Conditional jump or move depends on uninitialised value(s)
==12345== at 0x109177: uninitialized_memory_example (example.c:3)
==12345==
==12345== Use of uninitialised value of size 8
==12345== at 0x109190: uninitialized_memory_example (example.c:8)
ํด๊ฒฐ์ฑ : ๋ณ์๋ฅผ ์ฌ์ฉํ๊ธฐ ์ ์ ํญ์ ์ด๊ธฐํํ์ธ์! malloc()์ผ๋ก ํ ๋นํ ๋ฉ๋ชจ๋ฆฌ๋ ์๋์ผ๋ก ์ด๊ธฐํ๋์ง ์์ผ๋ ํ์ํ๋ค๋ฉด memset()์ด๋ calloc()์ ์ฌ์ฉํ์ธ์.
4. ์ด์ค ํด์ (Double Free) ๐
์ด๋ฏธ ํด์ ํ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ค์ ํด์ ํ๋ ค๊ณ ํ ๋ ๋ฐ์ํ๋ ์ค๋ฅ์์.
์์ ์ฝ๋:
void double_free_example() {
int *ptr = malloc(sizeof(int));
*ptr = 10;
free(ptr);
free(ptr); // ์ค๋ฅ! ์ด๋ฏธ ํด์ ๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ค์ ํด์
}
Valgrind ์ถ๋ ฅ:
==12345== Invalid free() / delete / delete[] / realloc()
==12345== at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==12345== by 0x109177: double_free_example (example.c:6)
==12345== Address 0x4a37040 is 0 bytes inside a block of size 4 free'd
ํด๊ฒฐ์ฑ : ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํด์ ํ ํ์๋ ํฌ์ธํฐ๋ฅผ NULL๋ก ์ค์ ํ๊ณ , free()๋ฅผ ํธ์ถํ๊ธฐ ์ ์ NULL ์ฒดํฌ๋ฅผ ํ์ธ์.
if (ptr != NULL) {
free(ptr);
ptr = NULL;
}
์ด๋ฐ ๋ฉ๋ชจ๋ฆฌ ์ค๋ฅ๋ค์ C ํ๋ก๊ทธ๋๋ฐ์์ ์ ๋ง ํํ๊ฒ ๋ฐ์ํ๋๋ฐ, Valgrind ๊ฐ์ ๋๊ตฌ ์์ด๋ ์ฐพ๊ธฐ๊ฐ ์ ๋ง ์ด๋ ค์์. ํนํ ๋๊ท๋ชจ ํ๋ก์ ํธ์์๋ ๋๋์ฑ์! ๊ทธ๋์ ์ฌ๋ฅ๋ท ๊ฐ์ ๊ณณ์์ C ์ธ์ด ๊ฐ์๋ฅผ ๋ค์ ๋ Valgrind ์ฌ์ฉ๋ฒ๋ ํจ๊ป ๋ฐฐ์ฐ๋ฉด ๊ฐ๋ฐ ์ค๋ ฅ์ด ํ ์ฌ๋ผ๊ฐ ์ ์์ด์! ๐
5. Valgrind ๊ณ ๊ธ ๊ธฐ๋ฅ ์ดํด๋ณด๊ธฐ ๐
๊ธฐ๋ณธ์ ์ธ ๋ฉ๋ชจ๋ฆฌ ์ค๋ฅ ๊ฒ์ถ ์ธ์๋ Valgrind๋ ๋ค์ํ ๊ณ ๊ธ ๊ธฐ๋ฅ์ ์ ๊ณตํด์. ์ด์ ์ข ๋ ๊น์ด ๋ค์ด๊ฐ๋ณผ๊น์? ๐
Cachegrind: ์บ์ ํ๋กํ์ผ๋ง ๐
ํ๋ก๊ทธ๋จ์ ์บ์ ์ฌ์ฉ๋์ ๋ถ์ํด์ ์ฑ๋ฅ ๋ณ๋ชฉ ํ์์ ์ฐพ์๋ด๋ ๋๊ตฌ์์.
valgrind --tool=cachegrind ./my_program
์ด ๋ช
๋ น์ด๋ฅผ ์คํํ๋ฉด ์บ์ ๋ฏธ์ค, ์ฐธ์กฐ ๋ฑ์ ๋ํ ์์ธํ ์ ๋ณด๋ฅผ ์ป์ ์ ์์ด์. ๊ฒฐ๊ณผ๋ cachegrind.out.xxxx ํ์ผ๋ก ์ ์ฅ๋๋๋ฐ, ์ด๊ฑธ cg_annotate ๋๊ตฌ๋ก ๋ถ์ํ ์ ์์ด์:
cg_annotate cachegrind.out.xxxx
์ด ๊ธฐ๋ฅ์ ํ๋ก๊ทธ๋จ์ ์ฑ๋ฅ์ ์ต์ ํํ ๋ ์ด๋ค ํจ์๊ฐ ์บ์๋ฅผ ๋ง์ด ์ฌ์ฉํ๋์ง ์ ์ ์์ด์ ์ ๋ง ์ ์ฉํด์!
Callgrind: ํจ์ ํธ์ถ ํ๋กํ์ผ๋ง ๐
ํจ์ ํธ์ถ ๊ทธ๋ํ์ ๊ฐ ํจ์์ ์คํ ๋น์ฉ์ ๋ถ์ํด์ฃผ๋ ๋๊ตฌ์์.
valgrind --tool=callgrind ./my_program
๊ฒฐ๊ณผ๋ callgrind.out.xxxx ํ์ผ๋ก ์ ์ฅ๋๋ฉฐ, callgrind_annotate๋ KCachegrind(GUI ๋๊ตฌ)๋ก ์๊ฐํํ ์ ์์ด์:
callgrind_annotate callgrind.out.xxxx
์ด ๋๊ตฌ๋ ์ด๋ค ํจ์๊ฐ ๊ฐ์ฅ ๋ง์ ์๊ฐ์ ์๋นํ๋์ง ์๋ ค์ฃผ๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ ์ต์ ํ์ ๋งค์ฐ ์ ์ฉํด์!
Massif: ํ ํ๋กํ์ผ๋ฌ ๐
ํ๋ก๊ทธ๋จ์ ํ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ์๊ฐ์ ๋ฐ๋ผ ๋ถ์ํด์ฃผ๋ ๋๊ตฌ์์.
valgrind --tool=massif ./my_program
๊ฒฐ๊ณผ๋ massif.out.xxxx ํ์ผ๋ก ์ ์ฅ๋๋ฉฐ, ms_print ๋๊ตฌ๋ก ๋ถ์ํ ์ ์์ด์:
ms_print massif.out.xxxx
์ด ๋๊ตฌ๋ ํ๋ก๊ทธ๋จ์ด ์ธ์ , ์ผ๋ง๋ ๋ง์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋์ง ์๊ฐํํด์ฃผ๊ธฐ ๋๋ฌธ์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ์ต์ ํํ๋ ๋ฐ ํฐ ๋์์ด ๋ผ์!
Helgrind: ์ค๋ ๋ ์ค๋ฅ ๊ฒ์ถ๊ธฐ ๐งต
๋ฉํฐ์ค๋ ๋ ํ๋ก๊ทธ๋จ์์ ๋ฐ์ํ๋ ๋ฐ์ดํฐ ๋ ์ด์ค์ ๋ฝ ๋ฌธ์ ๋ฅผ ์ฐพ์๋ด๋ ๋๊ตฌ์์.
valgrind --tool=helgrind ./my_threaded_program
์ด ๋๊ตฌ๋ ๋ค์๊ณผ ๊ฐ์ ๋ฌธ์ ๋ค์ ์ฐพ์๋ผ ์ ์์ด์:
- ๋ฐ์ดํฐ ๋ ์ด์ค (์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์์ ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ์ ์ ๊ทผ)
- ๋ฝ ์์ ์๋ฐ (๋ฐ๋๋ฝ ๊ฐ๋ฅ์ฑ)
- ์๋ชป๋ pthread API ์ฌ์ฉ
๋ฉํฐ์ค๋ ๋ ํ๋ก๊ทธ๋๋ฐ์ ์ ๋ง ์ด๋ ค์ด๋ฐ, Helgrind๊ฐ ์์ผ๋ฉด ๋์ ๋ณด์ด์ง ์๋ ๋์์ฑ ๋ฒ๊ทธ๋ฅผ ์ฐพ๋ ๋ฐ ํฐ ๋์์ด ๋ผ์!
DRD: ๋ ๋ค๋ฅธ ์ค๋ ๋ ์ค๋ฅ ๊ฒ์ถ๊ธฐ ๐
Helgrind์ ๋น์ทํ์ง๋ง ๋ค๋ฅธ ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํด ์ค๋ ๋ ๋ฌธ์ ๋ฅผ ์ฐพ์๋ด๋ ๋๊ตฌ์์.
valgrind --tool=drd ./my_threaded_program
DRD๋ Helgrind๋ณด๋ค ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ ์ฌ์ฉํ๊ณ ํน์ ์ ํ์ ์ค๋ฅ๋ฅผ ๋ ์ ์ฐพ์๋ด๊ธฐ๋ ํด์. ๋ ๋๊ตฌ๋ฅผ ๋ชจ๋ ์ฌ์ฉํด๋ณด๋ฉด ๋ ๋ง์ ๋ฌธ์ ๋ฅผ ๋ฐ๊ฒฌํ ์ ์์ด์!
์ฌ์ฉ์ ์ ์ ๋ฉ๋ชจ๋ฆฌ ์ฒดํฌ ๐ ๏ธ
Valgrind์ ํด๋ผ์ด์ธํธ ์์ฒญ(Client Requests) API๋ฅผ ์ฌ์ฉํ๋ฉด ์ฝ๋์์ ์ง์ Valgrind์๊ฒ ํน์ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ์ฒดํฌํ๋๋ก ์์ฒญํ ์ ์์ด์.
์๋ฅผ ๋ค์ด, ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์์ด์:
#include <valgrind/memcheck.h>
void check_memory() {
int *array = malloc(10 * sizeof(int));
// Valgrind์๊ฒ ์ด ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ด๊ธฐํ๋์ง ์์๋ค๊ณ ํ์
VALGRIND_MAKE_MEM_UNDEFINED(array, 10 * sizeof(int));
// ํน์ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ด ์ ๊ทผ ๊ฐ๋ฅํ์ง ํ์ธ
VALGRIND_CHECK_MEM_IS_ADDRESSABLE(array, 10 * sizeof(int));
// ํน์ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ด ์ด๊ธฐํ๋์๋์ง ํ์ธ
VALGRIND_CHECK_MEM_IS_DEFINED(array, 10 * sizeof(int));
free(array);
}
์ด๋ฐ ๊ณ ๊ธ ๊ธฐ๋ฅ๋ค์ ํ์ฉํ๋ฉด ๋จ์ํ ๋ฉ๋ชจ๋ฆฌ ์ค๋ฅ ๊ฒ์ถ์ ๋์ด์ ํ๋ก๊ทธ๋จ์ ์ฑ๋ฅ๊ณผ ์์ ์ฑ์ ํฌ๊ฒ ํฅ์์ํฌ ์ ์์ด์. ํนํ ๋๊ท๋ชจ ํ๋ก์ ํธ์์๋ ์ด๋ฐ ๋๊ตฌ๋ค์ด ์ ๋ง ๋น์ ๋ฐํ๋ต๋๋ค! โจ
6. ์ค์ ์์ ๋ก ๋ฐฐ์ฐ๋ Valgrind ๐ป
์ด๋ก ์ ์ถฉ๋ถํ ๋ฐฐ์ ์ผ๋ ์ด์ ์ค์ ์์ ๋ฅผ ํตํด Valgrind๋ฅผ ์ ๋๋ก ํ์ฉํด๋ณผ๊ฒ์! ์ค์ ๋ก ์์ฃผ ๋ง๋๋ ๋ฉ๋ชจ๋ฆฌ ์ค๋ฅ ์ํฉ๋ค์ ์ดํด๋ณผ๊ฑฐ์์.
์์ 1: ๋ฉ๋ชจ๋ฆฌ ๋์ ์ฐพ๊ธฐ
๋จผ์ ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ์๋ ๊ฐ๋จํ ํ๋ก๊ทธ๋จ์ ๋ง๋ค์ด๋ณผ๊ฒ์:
// memory_leak_example.c
#include <stdlib.h>
#include <stdio.h>
void function_with_leak() {
int *data = malloc(100 * sizeof(int));
data[0] = 1; // ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ
// free(data)๋ฅผ ํธ์ถํ์ง ์์
}
int main() {
for(int i = 0; i < 10; i++) {
function_with_leak(); // 10๋ฒ ํธ์ถํ๋ฉด 10๋ฒ ๋์ ๋ฐ์
}
printf("Program completed\n");
return 0;
}
์ด ํ๋ก๊ทธ๋จ์ ์ปดํ์ผํ๊ณ Valgrind๋ก ์คํํด๋ณผ๊ฒ์:
gcc -g memory_leak_example.c -o memory_leak_example
valgrind --leak-check=full ./memory_leak_example
๊ฒฐ๊ณผ:
==12345== HEAP SUMMARY:
==12345== in use at exit: 4,000 bytes in 10 blocks
==12345== total heap usage: 10 allocs, 0 frees, 4,000 bytes allocated
==12345==
==12345== 4,000 bytes in 10 blocks are definitely lost in loss record 1 of 1
==12345== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==12345== by 0x109177: function_with_leak (memory_leak_example.c:5)
==12345== by 0x109199: main (memory_leak_example.c:11)
Valgrind๊ฐ ์ ํํ 10๊ฐ์ ๋ฉ๋ชจ๋ฆฌ ๋ธ๋ก์ด ๋์๋์๋ค๊ณ ์๋ ค์ฃผ๋ค์! ๊ทธ๋ฆฌ๊ณ ์ด๋ค ํจ์์์ ๋ฐ์ํ๋์ง๋ ์ ํํ ์๋ ค์ค์.
ํด๊ฒฐ์ฑ :
void function_with_leak() {
int *data = malloc(100 * sizeof(int));
data[0] = 1;
free(data); // ๋ฉ๋ชจ๋ฆฌ ํด์ ์ถ๊ฐ
}
์์ 2: ๋ฐฐ์ด ๋ฒ์ ์ด๊ณผ ์ ๊ทผ
๋ฐฐ์ด ๋ฒ์๋ฅผ ๋ฒ์ด๋๋ ์ ๊ทผ์ ํ๋ ํ๋ก๊ทธ๋จ์ ๋ง๋ค์ด๋ณผ๊ฒ์:
// buffer_overflow.c
#include <stdio.h>
int main() {
int array[5] = {1, 2, 3, 4, 5};
// ๋ฐฐ์ด ๋ฒ์ ๋ด ์ ๊ทผ (์ ์)
printf("array[4] = %d\n", array[4]);
// ๋ฐฐ์ด ๋ฒ์ ์ด๊ณผ ์ ๊ทผ (์ค๋ฅ)
printf("array[10] = %d\n", array[10]);
return 0;
}
์ปดํ์ผํ๊ณ Valgrind๋ก ์คํ:
gcc -g buffer_overflow.c -o buffer_overflow
valgrind ./buffer_overflow
๊ฒฐ๊ณผ:
==12345== Invalid read of size 4
==12345== at 0x109177: main (buffer_overflow.c:10)
==12345== Address 0xffefffb28 is 24 bytes after a block of size 20 in stack
Valgrind๊ฐ ๋ฐฐ์ด ๋ฒ์๋ฅผ ๋ฒ์ด๋ ์ฝ๊ธฐ ์ ๊ทผ์ ์ ํํ ์ฐพ์๋์ด์! ์ด๋ฐ ์ค๋ฅ๋ C์์๋ ์ปดํ์ผ๋ฌ๊ฐ ์ก์๋ด์ง ๋ชปํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์์ ๋ฐํ์์ ์ด์ํ ๊ฐ์ด ์ถ๋ ฅ๋๊ฑฐ๋ ๋ ์ฌ๊ฐํ ๋ฌธ์ ๋ฅผ ์ผ์ผํฌ ์ ์์ด์.
์์ 3: ์ด๊ธฐํ๋์ง ์์ ๋ณ์ ์ฌ์ฉ
์ด๊ธฐํํ์ง ์์ ๋ณ์๋ฅผ ์ฌ์ฉํ๋ ํ๋ก๊ทธ๋จ์ ๋ง๋ค์ด๋ณผ๊ฒ์:
// uninitialized.c
#include <stdio.h>
int main() {
int x; // ์ด๊ธฐํํ์ง ์์
int y = 10;
if(x > 0) { // ์ด๊ธฐํ๋์ง ์์ x ์ฌ์ฉ
printf("x is positive: %d\n", x);
} else {
printf("x is not positive: %d\n", x);
}
int result = x + y; // ์ด๊ธฐํ๋์ง ์์ ๊ฐ์ผ๋ก ๊ณ์ฐ
printf("Result: %d\n", result);
return 0;
}
์ปดํ์ผํ๊ณ Valgrind๋ก ์คํ:
gcc -g uninitialized.c -o uninitialized
valgrind --track-origins=yes ./uninitialized
๊ฒฐ๊ณผ:
==12345== Conditional jump or move depends on uninitialised value(s)
==12345== at 0x109177: main (uninitialized.c:7)
==12345== Uninitialised value was created by a stack allocation
==12345== at 0x109166: main (uninitialized.c:4)
==12345==
==12345== Use of uninitialised value of size 4
==12345== at 0x109199: main (uninitialized.c:14)
Valgrind๊ฐ ์ด๊ธฐํ๋์ง ์์ ๊ฐ์ ์ฌ์ฉ์ ์ ํํ ์ฐพ์๋์ด์! --track-origins=yes ์ต์
๋๋ถ์ ์ด๋์ ์ด๊ธฐํ๋์ง ์์ ๊ฐ์ด ์์ฑ๋์๋์ง๋ ์ ์ ์์ด์.
ํด๊ฒฐ์ฑ :
int main() {
int x = 0; // ์ด๊ธฐํ ์ถ๊ฐ
int y = 10;
// ์ด์ ์์ ํ๊ฒ ์ฌ์ฉ ๊ฐ๋ฅ
if(x > 0) {
printf("x is positive: %d\n", x);
} else {
printf("x is not positive: %d\n", x);
}
int result = x + y;
printf("Result: %d\n", result);
return 0;
}
์์ 4: ํด์ ํ ์ฌ์ฉ (Use After Free)
๋ฉ๋ชจ๋ฆฌ๋ฅผ ํด์ ํ ํ์ ์ ๊ทผํ๋ ํ๋ก๊ทธ๋จ์ ๋ง๋ค์ด๋ณผ๊ฒ์:
// use_after_free.c
#include <stdlib.h>
#include <stdio.h>
int main() {
int *ptr = (int*)malloc(sizeof(int));
*ptr = 10;
printf("Before free: *ptr = %d\n", *ptr);
free(ptr); // ๋ฉ๋ชจ๋ฆฌ ํด์
// ํด์ ํ ์ ๊ทผ (์ค๋ฅ)
*ptr = 20; // ์ฐ๊ธฐ ์ ๊ทผ
printf("After free: *ptr = %d\n", *ptr); // ์ฝ๊ธฐ ์ ๊ทผ
return 0;
}
์ปดํ์ผํ๊ณ Valgrind๋ก ์คํ:
gcc -g use_after_free.c -o use_after_free
valgrind ./use_after_free
๊ฒฐ๊ณผ:
==12345== Invalid write of size 4
==12345== at 0x109177: main (use_after_free.c:12)
==12345== Address 0x4a37040 is 0 bytes inside a block of size 4 free'd
==12345== at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==12345== by 0x109166: main (use_after_free.c:9)
==12345==
==12345== Invalid read of size 4
==12345== at 0x109199: main (use_after_free.c:13)
Valgrind๊ฐ ํด์ ๋ ๋ฉ๋ชจ๋ฆฌ์ ๋ํ ์ฝ๊ธฐ์ ์ฐ๊ธฐ ์ ๊ทผ ๋ชจ๋ ์ฐพ์๋์ด์! ์ด๋ฐ ์ค๋ฅ๋ ์ ๋ง ์ํํ๋ฐ, ๋๋ก๋ ํ๋ก๊ทธ๋จ์ด ์ถฉ๋ํ์ง ์๊ณ ๊ณ์ ์คํ๋๋ฉด์ ์์์น ๋ชปํ ๋์์ ํ ์ ์์ด์.
ํด๊ฒฐ์ฑ :
int main() {
int *ptr = (int*)malloc(sizeof(int));
*ptr = 10;
printf("Before free: *ptr = %d\n", *ptr);
free(ptr);
ptr = NULL; // ํด์ ํ NULL๋ก ์ค์
// NULL ์ฒดํฌ ์ถ๊ฐ
if (ptr != NULL) {
*ptr = 20;
printf("After free: *ptr = %d\n", *ptr);
}
return 0;
}
์ด๋ฐ ์ค์ ์์ ๋ค์ ํตํด Valgrind๊ฐ ์ผ๋ง๋ ๊ฐ๋ ฅํ ๋๊ตฌ์ธ์ง ๋๊ปด์ง์๋์? ๐ฒ C ํ๋ก๊ทธ๋๋ฐ์์ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ จ ๋ฒ๊ทธ๋ ์ฐพ๊ธฐ ์ ๋ง ์ด๋ ค์ด๋ฐ, Valgrind๋ ์ด๋ฐ ๋ฌธ์ ๋ค์ ์ ํํ ์ง์ด๋ด์ค์!
์ฌ๋ฅ๋ท์์ C ํ๋ก๊ทธ๋๋ฐ ๊ฐ์๋ฅผ ๋ค์ผ์๋ ๋ถ๋ค์ด๋ผ๋ฉด, ๊ผญ Valgrind ์ฌ์ฉ๋ฒ๋ ํจ๊ป ์ตํ๋ณด์ธ์. ์ฝ๋ฉ ์ค๋ ฅ์ด ํ ๋จ๊ณ ์ ๊ทธ๋ ์ด๋๋ ๊ฑฐ์์! ๐ฏ
7. ์์ฃผ ๋ฌป๋ ์ง๋ฌธ๋ค โ
Valgrind๋ฅผ ์ฌ์ฉํ๋ฉด์ ๋ง์ ๋ถ๋ค์ด ๊ถ๊ธํดํ์๋ ์ง๋ฌธ๋ค์ ๋ชจ์๋ดค์ด์!
Q: Valgrind๊ฐ ๋๋ฌด ๋๋ ค์. ๋ ๋น ๋ฅด๊ฒ ์ฌ์ฉํ ๋ฐฉ๋ฒ์ด ์๋์? ๐ข
A: ๋ค, Valgrind๋ ๊ธฐ๋ณธ์ ์ผ๋ก ํ๋ก๊ทธ๋จ์ 10~30๋ฐฐ ๋๋ฆฌ๊ฒ ์คํํด์. ์๋๋ฅผ ์กฐ๊ธ ๊ฐ์ ํ๋ ค๋ฉด:
- ์ต์ ํ ์ต์ ์์ด ์ปดํ์ผ(-O0)ํ๋ฉด Valgrind๊ฐ ๋ ์ ํํ ๊ฒฐ๊ณผ๋ฅผ ์ ๊ณตํด์.
--undef-value-errors=no์ต์ ์ผ๋ก ์ด๊ธฐํ๋์ง ์์ ๊ฐ ๊ฒ์ฌ๋ฅผ ๋ ์ ์์ด์(๊ถ์ฅํ์ง ์์์).- ํ๋ก๊ทธ๋จ์ ์ผ๋ถ๋ถ๋ง ๋ถ์ํ๋ ค๋ฉด
VALGRIND_DISABLE_ERROR_REPORTING์VALGRIND_ENABLE_ERROR_REPORTING๋งคํฌ๋ก๋ฅผ ์ฌ์ฉํ ์ ์์ด์.
ํ์ง๋ง ์ ํํ ๋ถ์์ ์ํด์๋ ์๊ฐ์ด ํ์ํ๋ ์ฐธ๊ณ ๊ธฐ๋ค๋ฆผ์ด ํ์ํด์! โณ
Q: Valgrind๊ฐ "still reachable" ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ๋ณด๊ณ ํด์. ์ด๊ฒ ๋ฌธ์ ์ธ๊ฐ์? ๐ค
A: "still reachable"์ ํ๋ก๊ทธ๋จ์ด ์ข ๋ฃ๋ ๋ ์์ง ํฌ์ธํฐ๋ก ์ ๊ทผ ๊ฐ๋ฅํ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์๋ฏธํด์. ์๋ฐํ ๋งํ๋ฉด ๋์๋ ์๋์์. ํ๋ก๊ทธ๋จ์ด ์ข ๋ฃ๋๋ฉด OS๊ฐ ์ด ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ์ํ๊ธฐ ๋๋ฌธ์ด์ฃ .
ํ์ง๋ง ์ข์ ์ต๊ด์ ์ํด ๊ฐ๋ฅํ๋ฉด ๋ชจ๋ ํ ๋น๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ช ์์ ์ผ๋ก ํด์ ํ๋ ๊ฒ์ด ์ข์์! ํนํ ์ค๋ ์คํ๋๋ ํ๋ก๊ทธ๋จ์ด๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์๋ ์ค์ํด์.
Q: ์์คํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ๋ฐ์ํ๋ ์ค๋ฅ๋ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ๋์? ๐
A: ์์คํ
๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ๋ฐ์ํ๋ ์ค๋ฅ๋ ๋ณดํต ๋ฌด์ํด๋ ๋ผ์. Valgrind๋ --suppressions ์ต์
์ผ๋ก ์ด๋ฐ ์ค๋ฅ๋ฅผ ์จ๊ธธ ์ ์์ด์:
valgrind --suppressions=/path/to/suppression.supp ./my_program
๊ธฐ๋ณธ ์ ๊ณต๋๋ ์ต์ ํ์ผ๋ ์๊ณ , ์ง์ ๋ง๋ค ์๋ ์์ด์:
valgrind --gen-suppressions=all ./my_program
Q: Valgrind๊ฐ ์ค๋ฅ๋ฅผ ๋ณด๊ณ ํ์ง๋ง ๋ด ์ฝ๋์์๋ ๋ฌธ์ ๊ฐ ์์ด ๋ณด์ฌ์. ์ ๊ทธ๋ด๊น์? ๐งฉ
A: ๋ช ๊ฐ์ง ๊ฐ๋ฅ์ฑ์ด ์์ด์:
- ์ต์ ํ ์ปดํ์ผ(-O2, -O3)๋ก ์ธํด ์ฝ๋๊ฐ ๋ณํ๋์์ ์ ์์ด์. ๋๋ฒ๊น ํ ๋๋ -O0 ์ต์ ์ ์ฌ์ฉํด๋ณด์ธ์.
- ์๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ ์ ์์ด์.
- ์กฐ๊ฑด๋ถ ์ค๋ฅ์ผ ์ ์์ด์. ํน์ ์ ๋ ฅ์ด๋ ์ํฉ์์๋ง ๋ฐ์ํ๋ ์ค๋ฅ์ฃ .
Valgrind๋ ๊ฑฐ์ ํญ์ ์ค์ ๋ฌธ์ ๋ฅผ ๋ณด๊ณ ํด์. ์คํ(false positive)์ด ์๊ธด ํ์ง๋ง ๋๋ฌผ์ด์!
Q: Windows์์ Valgrind ๋์ ์ฌ์ฉํ ์ ์๋ ๋๊ตฌ๊ฐ ์๋์? ๐ช
A: ๋ค, Windows์์๋ ๋ค์ ๋๊ตฌ๋ค์ ๊ณ ๋ คํด๋ณผ ์ ์์ด์:
- Dr. Memory: Valgrind์ ์ ์ฌํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ฉฐ Windows์์ ๋ค์ดํฐ๋ธ๋ก ๋์ํด์.
- Visual Studio์ ๋ฉ๋ชจ๋ฆฌ ๊ฒ์ฌ ๋๊ตฌ: Visual Studio์ ๋ด์ฅ๋ ๋ฉ๋ชจ๋ฆฌ ๋์ ๋ฐ ์ค๋ฅ ๊ฒ์ถ ๋๊ตฌ๊ฐ ์์ด์.
- Intel Inspector: ์์ฉ ๋๊ตฌ์ง๋ง ๋งค์ฐ ๊ฐ๋ ฅํ ๋ฉ๋ชจ๋ฆฌ ๋ฐ ์ค๋ ๋ ์ค๋ฅ ๊ฒ์ถ ๊ธฐ๋ฅ์ ์ ๊ณตํด์.
ํ์ง๋ง ๊ฐ๋ฅํ๋ค๋ฉด WSL(Windows Subsystem for Linux)์์ Valgrind๋ฅผ ์ฌ์ฉํ๋ ๊ฒ๋ ์ข์ ๋ฐฉ๋ฒ์ด์์!
Q: Valgrind ๊ฒฐ๊ณผ๋ฅผ ๋ ๋ณด๊ธฐ ์ข๊ฒ ๋ณผ ์ ์๋ ๋ฐฉ๋ฒ์ด ์๋์? ๐จ
A: ๋ค, ๋ช ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์์ด์:
- valkyrie: Valgrind์ GUI ํ๋ก ํธ์๋๋ก, ๊ฒฐ๊ณผ๋ฅผ ์๊ฐ์ ์ผ๋ก ๋ณด์ฌ์ค์.
- KCachegrind: Callgrind ๊ฒฐ๊ณผ๋ฅผ ์๊ฐํํ๋ ๋๊ตฌ์์.
- --log-file ์ต์ ์ผ๋ก ๊ฒฐ๊ณผ๋ฅผ ํ์ผ๋ก ์ ์ฅํ ํ ํ ์คํธ ์๋ํฐ๋ก ๋ณด๋ฉด ์์ ๊ตฌ๋ถ์ด ๋ ์ ๋ณด์ผ ์ ์์ด์.
IDE ํตํฉ๋ ์์ด์. Eclipse CDT, CLion, Visual Studio Code ๋ฑ์์ Valgrind ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉํ ์ ์์ด์!
์ด๋ฐ ์ง๋ฌธ๋ค์ด Valgrind๋ฅผ ์ฌ์ฉํ๋ฉด์ ์๊ธธ ์ ์๋ ์๋ฌธ์ ๋ค์ ํด๊ฒฐํ๋ ๋ฐ ๋์์ด ๋๊ธธ ๋ฐ๋ผ์! ๋ ๊ถ๊ธํ ์ ์ด ์์ผ์๋ฉด ์ฌ๋ฅ๋ท ์ปค๋ฎค๋ํฐ์์ ์ง๋ฌธํด๋ณด์ธ์. ๋ง์ ๊ฐ๋ฐ์๋ค์ด ๊ธฐ๊บผ์ด ๋์์ ์ค ๊ฑฐ์์! ๐
๋ง์น๋ฉฐ ๐ฏ
์ง๊ธ๊น์ง Valgrind๋ฅผ ์ฌ์ฉํ ๋ฉ๋ชจ๋ฆฌ ์ค๋ฅ ๊ฒ์ถ์ ๋ํด ์์๋ดค์ด์! ์ด๋์? ์๊ฐ๋ณด๋ค ์ฝ์ฃ ? ใ ใ ใ
C ํ๋ก๊ทธ๋๋ฐ์์ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ๋ ์ ๋ง ๊น๋ค๋ก์ด ๋ถ๋ถ์ด์ง๋ง, Valgrind ๊ฐ์ ๊ฐ๋ ฅํ ๋๊ตฌ๊ฐ ์์ผ๋ฉด ํจ์ฌ ์์ํ๊ฒ ๋๋ฒ๊น ํ ์ ์์ด์. ๋ฉ๋ชจ๋ฆฌ ๋์, ์๋ชป๋ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ, ์ด๊ธฐํ๋์ง ์์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ ๋ฑ C ํ๋ก๊ทธ๋๋จธ๋ค์ด ์์ฃผ ๊ฒช๋ ๋ฌธ์ ๋ค์ ์ฝ๊ฒ ์ฐพ์๋ผ ์ ์์ฃ !
ํนํ ๋๊ท๋ชจ ํ๋ก์ ํธ์์๋ Valgrind ๊ฐ์ ๋๊ตฌ ์์ด ๋ฉ๋ชจ๋ฆฌ ์ค๋ฅ๋ฅผ ์ฐพ์๋ด๊ธฐ๊ฐ ๊ฑฐ์ ๋ถ๊ฐ๋ฅ์ ๊ฐ๊น์์. ๊ทธ๋์ ์ ๋ฌธ ๊ฐ๋ฐ์๋ค์ ํญ์ ์ด๋ฐ ๋๊ตฌ๋ค์ ์ ๊ทน ํ์ฉํ๋ต๋๋ค.
์ฌ๋ฌ๋ถ๋ ์ด์ Valgrind๋ฅผ ์ฌ์ฉํด์ ๋ ์์ ์ ์ด๊ณ ๋ฉ๋ชจ๋ฆฌ ๋์ ์๋ C ํ๋ก๊ทธ๋จ์ ๋ง๋ค์ด๋ณด์ธ์! ์ฒ์์๋ ์ข ์ด์ํ ์ ์์ง๋ง, ์ต์ํด์ง๋ฉด ๊ฐ๋ฐ ๊ณผ์ ์์ ์์ด์๋ ์ ๋ ํ์ ๋๊ตฌ๊ฐ ๋ ๊ฑฐ์์! ๐ฏ
ํน์ C ํ๋ก๊ทธ๋๋ฐ์ด๋ ๋ฉ๋ชจ๋ฆฌ ๋๋ฒ๊น ์ ๋ํด ๋ ๋ฐฐ์ฐ๊ณ ์ถ์ผ์๋ค๋ฉด, ์ฌ๋ฅ๋ท์์ ๊ด๋ จ ๊ฐ์๋ฅผ ์ฐพ์๋ณด์ธ์. ๋ค์ํ ์ ๋ฌธ๊ฐ๋ค์ด ์ฌ๋ฌ๋ถ์ ํ๋ก๊ทธ๋๋ฐ ์ค๋ ฅ ํฅ์์ ๋์์ค ๊ฑฐ์์! ๐
๋ฉ๋ชจ๋ฆฌ ์ค๋ฅ ์๋ ํ๋ณตํ ์ฝ๋ฉ ๋์ธ์! ๐
๊ด๋ จ ํค์๋
๋๊ธ ์์ฑ
์ด ๊ธ์ ๋ํ ์ฌ๋ฌ๋ถ์ ์๊ฐ์ ๋ค๋ ค์ฃผ์ธ์
๋ก๊ทธ์ธ์ด ํ์ํฉ๋๋ค
๋๊ธ์ ์์ฑํ๋ ค๋ฉด ๋จผ์ ๋ก๊ทธ์ธํด์ฃผ์ธ์.
๋๊ธ 0
์ง์์ธ์ ์ฒ - ์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
- ์ ์๊ถ ๋ฐ ์์ ๊ถ: ๋ณธ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ๋ ์ AI ๊ธฐ์ ๋ก ์์ฑ๋์์ผ๋ฉฐ, ๋ํ๋ฏผ๊ตญ ์ ์๊ถ๋ฒ ๋ฐ ๊ตญ์ ์ ์๊ถ ํ์ฝ์ ์ํด ๋ณดํธ๋ฉ๋๋ค.
- AI ์์ฑ ์ปจํ ์ธ ์ ๋ฒ์ ์ง์: ๋ณธ AI ์์ฑ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ์ง์ ์ฐฝ์๋ฌผ๋ก ์ธ์ ๋๋ฉฐ, ๊ด๋ จ ๋ฒ๊ท์ ๋ฐ๋ผ ์ ์๊ถ ๋ณดํธ๋ฅผ ๋ฐ์ต๋๋ค.
- ์ฌ์ฉ ์ ํ: ์ฌ๋ฅ๋ท์ ๋ช ์์ ์๋ฉด ๋์ ์์ด ๋ณธ ์ปจํ ์ธ ๋ฅผ ๋ณต์ , ์์ , ๋ฐฐํฌ, ๋๋ ์์ ์ ์ผ๋ก ํ์ฉํ๋ ํ์๋ ์๊ฒฉํ ๊ธ์ง๋ฉ๋๋ค.
- ๋ฐ์ดํฐ ์์ง ๊ธ์ง: ๋ณธ ์ปจํ ์ธ ์ ๋ํ ๋ฌด๋จ ์คํฌ๋ํ, ํฌ๋กค๋ง, ๋ฐ ์๋ํ๋ ๋ฐ์ดํฐ ์์ง์ ๋ฒ์ ์ ์ฌ์ ๋์์ด ๋ฉ๋๋ค.
- AI ํ์ต ์ ํ: ์ฌ๋ฅ๋ท์ AI ์์ฑ ์ปจํ ์ธ ๋ฅผ ํ AI ๋ชจ๋ธ ํ์ต์ ๋ฌด๋จ ์ฌ์ฉํ๋ ํ์๋ ๊ธ์ง๋๋ฉฐ, ์ด๋ ์ง์ ์ฌ์ฐ๊ถ ์นจํด๋ก ๊ฐ์ฃผ๋ฉ๋๋ค.
์์ง ๋๊ธ์ด ์์ต๋๋ค.