์ฝ˜ํ…์ธ  ๋Œ€ํ‘œ ์ด๋ฏธ์ง€ - ๐Ÿ” C์–ธ์–ด ๋””๋ฒ„๊น… ์™„์ „์ •๋ณต: GDB์™€ Valgrind๋กœ ๋ฉ”๋ชจ๋ฆฌ ์˜ค๋ฅ˜ ์žก์•„๋‚ด๊ธฐ

๐Ÿ” C์–ธ์–ด ๋””๋ฒ„๊น… ์™„์ „์ •๋ณต: GDB์™€ Valgrind๋กœ ๋ฉ”๋ชจ๋ฆฌ ์˜ค๋ฅ˜ ์žก์•„๋‚ด๊ธฐ

ํ”„๋กœ๊ทธ๋ž˜๋จธ์˜ ํ•„์ˆ˜ ๋ฌด๊ธฐ, ๋””๋ฒ„๊น… ๋„๊ตฌ ๋งˆ์Šคํ„ฐํ•˜๊ธฐ ๐Ÿ› ๏ธ

์•ˆ๋…•! ๐Ÿ‘‹ C์–ธ์–ด๋กœ ํ”„๋กœ๊ทธ๋žจ ์งœ๋‹ค๊ฐ€ ๊ฐ‘์ž๊ธฐ "Segmentation fault"๋ผ๋Š” ๋ฌด์‹œ๋ฌด์‹œํ•œ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณธ ์  ์žˆ์ง€? ์•„๋‹ˆ๋ฉด ํ”„๋กœ๊ทธ๋žจ์ด ๋ฉ€์ฉกํžˆ ๋Œ์•„๊ฐ€๋Š” ๊ฒƒ ๊ฐ™์€๋ฐ ์–ด๋”˜๊ฐ€์—์„œ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์ƒˆ๊ณ  ์žˆ๋‹ค๋Š” ๋А๋‚Œ? ๊ทธ๋Ÿด ๋•Œ ์šฐ๋ฆฌ์—๊ฒŒ ํ•„์š”ํ•œ ๊ฑด ๋ฐ”๋กœ ๊ฐ•๋ ฅํ•œ ๋””๋ฒ„๊น… ๋„๊ตฌ์•ผ! ์˜ค๋Š˜์€ C์–ธ์–ด ๊ฐœ๋ฐœ์ž๋ผ๋ฉด ๋ฐ˜๋“œ์‹œ ์•Œ์•„์•ผ ํ•  GDB์™€ Valgrind์— ๋Œ€ํ•ด ์นœ๊ตฌ์ฒ˜๋Ÿผ ํŽธํ•˜๊ฒŒ ์ด์•ผ๊ธฐํ•ด๋ณผ๊ฒŒ. ๐Ÿ˜Š

์‚ฌ์‹ค ๋””๋ฒ„๊น…์€ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์ ˆ๋ฐ˜ ์ด์ƒ์„ ์ฐจ์ง€ํ•œ๋‹ค๊ณ  ํ•ด๋„ ๊ณผ์–ธ์ด ์•„๋‹ˆ์•ผ. ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ์‹œ๊ฐ„๋ณด๋‹ค ๋ฒ„๊ทธ๋ฅผ ์ฐพ๊ณ  ๊ณ ์น˜๋Š” ์‹œ๊ฐ„์ด ๋” ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๊ฑฐ๋“ . ํŠนํžˆ C์–ธ์–ด๋Š” ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ง์ ‘ ๊ด€๋ฆฌํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํฌ์ธํ„ฐ ์˜ค๋ฅ˜, ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜, ๋ฒ„ํผ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๊ฐ™์€ ๋ฌธ์ œ๋“ค์ด ์ •๋ง ์ž์ฃผ ๋ฐœ์ƒํ•ด. ์ด๋Ÿฐ ๋ฌธ์ œ๋“ค์„ ํšจ๊ณผ์ ์œผ๋กœ ์ฐพ์•„๋‚ด๊ณ  ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด์ž! ๐Ÿš€

๐Ÿ› Memory Bug GDB Debugger Valgrind Memory Checker โœ… Clean Code

๐ŸŽฏ ๋””๋ฒ„๊น…์ด ์™œ ์ด๋ ‡๊ฒŒ ์ค‘์š”ํ• ๊นŒ?

ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์ฒ˜์Œ ๋ฐฐ์šธ ๋•Œ๋Š” "์ฝ”๋“œ๋งŒ ์ž˜ ์งœ๋ฉด ๋˜๋Š” ๊ฑฐ ์•„๋‹ˆ์•ผ?"๋ผ๊ณ  ์ƒ๊ฐํ•˜๊ธฐ ์‰ฌ์›Œ. ํ•˜์ง€๋งŒ ์‹ค์ œ ๊ฐœ๋ฐœ ํ˜„์žฅ์—์„œ๋Š” ์™„๋ฒฝํ•œ ์ฝ”๋“œ๋ฅผ ํ•œ ๋ฒˆ์— ์ž‘์„ฑํ•˜๋Š” ๊ฑด ๊ฑฐ์˜ ๋ถˆ๊ฐ€๋Šฅํ•ด. ํŠนํžˆ C์–ธ์–ด๋Š” ๋‹ค๋ฅธ ๊ณ ์ˆ˜์ค€ ์–ธ์–ด๋“ค๊ณผ ๋‹ฌ๋ฆฌ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋ฅผ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์ง์ ‘ ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‹ค์ˆ˜ํ•  ์—ฌ์ง€๊ฐ€ ํ›จ์”ฌ ๋งŽ์ง€. ๐Ÿค”

๐Ÿ’ก ์‹ค์ œ ํ†ต๊ณ„๋กœ ๋ณด๋Š” ๋””๋ฒ„๊น…์˜ ์ค‘์š”์„ฑ

์†Œํ”„ํŠธ์›จ์–ด ๊ฐœ๋ฐœ ํ”„๋กœ์ ํŠธ์—์„œ ๊ฐœ๋ฐœ์ž๋“ค์€ ํ‰๊ท ์ ์œผ๋กœ ์ „์ฒด ๊ฐœ๋ฐœ ์‹œ๊ฐ„์˜ 50~75%๋ฅผ ๋””๋ฒ„๊น…์— ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•ด. ๋˜ํ•œ ์†Œํ”„ํŠธ์›จ์–ด ๋ฒ„๊ทธ๋กœ ์ธํ•œ ๊ฒฝ์ œ์  ์†์‹ค์€ ์—ฐ๊ฐ„ ์ˆ˜์กฐ ์›์— ๋‹ฌํ•œ๋‹ค๋Š” ์—ฐ๊ตฌ ๊ฒฐ๊ณผ๋„ ์žˆ์–ด. ๊ทธ๋งŒํผ ๋””๋ฒ„๊น… ๋Šฅ๋ ฅ์€ ํ”„๋กœ๊ทธ๋ž˜๋จธ์˜ ํ•ต์‹ฌ ์—ญ๋Ÿ‰์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์ง€!

C์–ธ์–ด์—์„œ ์ž์ฃผ ๋ฐœ์ƒํ•˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ จ ์˜ค๋ฅ˜๋“ค์„ ์‚ดํŽด๋ณด๋ฉด:

**๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜(Memory Leak)** ๐Ÿ’ง
malloc์ด๋‚˜ calloc์œผ๋กœ ํ• ๋‹นํ•œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ freeํ•˜์ง€ ์•Š์•„์„œ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๊ณ„์† ์Œ“์ด๋Š” ๋ฌธ์ œ์•ผ. ํ”„๋กœ๊ทธ๋žจ์ด ์˜ค๋ž˜ ์‹คํ–‰๋˜๋ฉด ์‹œ์Šคํ…œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋‹ค ์žก์•„๋จน์–ด์„œ ๊ฒฐ๊ตญ ํฌ๋ž˜์‹œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์–ด.

**๋ฒ„ํผ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ(Buffer Overflow)** ๐Ÿ“ฆ
๋ฐฐ์—ด์˜ ํฌ๊ธฐ๋ฅผ ๋„˜์–ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์“ฐ๋Š” ๊ฒฝ์šฐ์•ผ. ์ด๊ฑด ๋‹จ์ˆœํžˆ ํ”„๋กœ๊ทธ๋žจ์ด ์ฃฝ๋Š” ๊ฒƒ์„ ๋„˜์–ด์„œ ๋ณด์•ˆ ์ทจ์•ฝ์ ์œผ๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ์–ด์„œ ์ •๋ง ์œ„ํ—˜ํ•ด.

**๋Œ•๊ธ€๋ง ํฌ์ธํ„ฐ(Dangling Pointer)** ๐Ÿ‘ป
์ด๋ฏธ ํ•ด์ œ๋œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์•ผ. ์˜ˆ์ธกํ•  ์ˆ˜ ์—†๋Š” ๋™์ž‘์„ ์ผ์œผํ‚ค๊ณ  ๋””๋ฒ„๊น…ํ•˜๊ธฐ๋„ ์ •๋ง ๊นŒ๋‹ค๋กœ์›Œ.

**์ด์ค‘ ํ•ด์ œ(Double Free)** โš ๏ธ
๊ฐ™์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋‘ ๋ฒˆ freeํ•˜๋Š” ๊ฒฝ์šฐ์ธ๋ฐ, ์ด๊ฒƒ๋„ ํ”„๋กœ๊ทธ๋žจ ํฌ๋ž˜์‹œ์˜ ์ฃผ์š” ์›์ธ ์ค‘ ํ•˜๋‚˜์•ผ.

๐Ÿ”ง GDB: ํ”„๋กœ๊ทธ๋ž˜๋จธ์˜ ํ˜„๋ฏธ๊ฒฝ

GDB(GNU Debugger)๋Š” C์–ธ์–ด ๊ฐœ๋ฐœ์ž๋“ค์ด ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ๋””๋ฒ„๊ฑฐ์•ผ. ๋ฆฌ๋ˆ…์Šค ํ™˜๊ฒฝ์—์„œ ๊ธฐ๋ณธ์œผ๋กœ ์ œ๊ณต๋˜๊ณ , ํ”„๋กœ๊ทธ๋žจ์˜ ์‹คํ–‰์„ ํ•œ ์ค„์”ฉ ์ถ”์ ํ•˜๋ฉด์„œ ๋ณ€์ˆ˜ ๊ฐ’์„ ํ™•์ธํ•˜๊ณ  ๋ฌธ์ œ๋ฅผ ์ฐพ์•„๋‚ผ ์ˆ˜ ์žˆ์–ด. ๋งˆ์น˜ ํ˜„๋ฏธ๊ฒฝ์œผ๋กœ ์„ธํฌ๋ฅผ ๊ด€์ฐฐํ•˜๋“ฏ์ด ์ฝ”๋“œ๋ฅผ ์„ธ๋ฐ€ํ•˜๊ฒŒ ๋“ค์—ฌ๋‹ค๋ณผ ์ˆ˜ ์žˆ์ง€! ๐Ÿ”ฌ

GDB ์„ค์น˜์™€ ๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•

๋Œ€๋ถ€๋ถ„์˜ ๋ฆฌ๋ˆ…์Šค ๋ฐฐํฌํŒ์—๋Š” GDB๊ฐ€ ๊ธฐ๋ณธ์œผ๋กœ ์„ค์น˜๋˜์–ด ์žˆ์–ด. ๋งŒ์•ฝ ์—†๋‹ค๋ฉด ๋‹ค์Œ ๋ช…๋ น์–ด๋กœ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ์–ด:

# Ubuntu/Debian
sudo apt-get install gdb

# CentOS/RHEL
sudo yum install gdb

# macOS (Homebrew ์‚ฌ์šฉ)
brew install gdb

GDB๋กœ ๋””๋ฒ„๊น…ํ•˜๋ ค๋ฉด ๋จผ์ € ํ”„๋กœ๊ทธ๋žจ์„ ์ปดํŒŒ์ผํ•  ๋•Œ -g ์˜ต์…˜์„ ๋ถ™์—ฌ์•ผ ํ•ด. ์ด ์˜ต์…˜์€ ๋””๋ฒ„๊น… ์ •๋ณด๋ฅผ ์‹คํ–‰ ํŒŒ์ผ์— ํฌํ•จ์‹œ์ผœ์ค˜:

gcc -g -o myprogram myprogram.c

์ด์ œ GDB๋ฅผ ์‹คํ–‰ํ•ด๋ณด์ž:

gdb ./myprogram

GDB ํ•ต์‹ฌ ๋ช…๋ น์–ด ๋งˆ์Šคํ„ฐํ•˜๊ธฐ

GDB๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋ช‡ ๊ฐ€์ง€ ํ•ต์‹ฌ ๋ช…๋ น์–ด๋ฅผ ์•Œ์•„์•ผ ํ•ด. ์ฒ˜์Œ์—๋Š” ๋ณต์žกํ•ด ๋ณด์ผ ์ˆ˜ ์žˆ์ง€๋งŒ, ๋ช‡ ๋ฒˆ ์จ๋ณด๋ฉด ๊ธˆ๋ฐฉ ์ต์ˆ™ํ•ด์งˆ ๊ฑฐ์•ผ! ๐Ÿ˜Š

๋ช…๋ น์–ด ์•ฝ์–ด ์„ค๋ช…
run r ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰
break b ์ค‘๋‹จ์ (breakpoint) ์„ค์ •
next n ๋‹ค์Œ ์ค„๋กœ ์ด๋™ (ํ•จ์ˆ˜ ๋‚ด๋ถ€๋กœ ๋“ค์–ด๊ฐ€์ง€ ์•Š์Œ)
step s ๋‹ค์Œ ์ค„๋กœ ์ด๋™ (ํ•จ์ˆ˜ ๋‚ด๋ถ€๋กœ ๋“ค์–ด๊ฐ)
continue c ๋‹ค์Œ ์ค‘๋‹จ์ ๊นŒ์ง€ ์‹คํ–‰
print p ๋ณ€์ˆ˜ ๊ฐ’ ์ถœ๋ ฅ
backtrace bt ํ˜ธ์ถœ ์Šคํƒ ์ถœ๋ ฅ
quit q GDB ์ข…๋ฃŒ

์‹ค์ „ ์˜ˆ์ œ: ์„ธ๊ทธ๋ฉ˜ํ…Œ์ด์…˜ ํดํŠธ ์žก๊ธฐ

์ž, ์ด์ œ ์‹ค์ œ๋กœ ๋ฒ„๊ทธ๊ฐ€ ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ GDB๋กœ ๋””๋ฒ„๊น…ํ•ด๋ณด์ž. ๋‹ค์Œ์€ ์ „ํ˜•์ ์ธ ์„ธ๊ทธ๋ฉ˜ํ…Œ์ด์…˜ ํดํŠธ๋ฅผ ์ผ์œผํ‚ค๋Š” ์ฝ”๋“œ์•ผ:

#include <stdio.h>
#include <string.h>

void buggy_function(char *str) {
    char buffer[10];
    strcpy(buffer, str);  // ์œ„ํ—˜ํ•œ ์ฝ”๋“œ!
    printf("Buffer: %s\n", buffer);
}

int main() {
    char *long_string = "This is a very long string that will overflow";
    buggy_function(long_string);
    return 0;
}

์ด ์ฝ”๋“œ๋ฅผ ์ปดํŒŒ์ผํ•˜๊ณ  ์‹คํ–‰ํ•˜๋ฉด ์„ธ๊ทธ๋ฉ˜ํ…Œ์ด์…˜ ํดํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฑฐ์•ผ. GDB๋กœ ๋””๋ฒ„๊น…ํ•ด๋ณด์ž:

$ gcc -g -o buggy buggy.c
$ gdb ./buggy

(gdb) run
Starting program: /path/to/buggy

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7e5c123 in strcpy () from /lib/x86_64-linux-gnu/libc.so.6

(gdb) backtrace
#0  0x00007ffff7e5c123 in strcpy () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x0000555555555189 in buggy_function (str=0x555555556004) at buggy.c:6
#2  0x00005555555551b7 in main () at buggy.c:12

(gdb) frame 1
#1  0x0000555555555189 in buggy_function (str=0x555555556004) at buggy.c:6
6           strcpy(buffer, str);

(gdb) print str
$1 = 0x555555556004 "This is a very long string that will overflow"

(gdb) print sizeof(buffer)
$2 = 10

๋ณด๋‹ค์‹œํ”ผ GDB๋Š” ์ •ํ™•ํžˆ ์–ด๋””์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”์ง€ ์•Œ๋ ค์ค˜. backtrace ๋ช…๋ น์œผ๋กœ ํ•จ์ˆ˜ ํ˜ธ์ถœ ์Šคํƒ์„ ํ™•์ธํ•˜๊ณ , print ๋ช…๋ น์œผ๋กœ ๋ณ€์ˆ˜ ๊ฐ’์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด. ์ด ๊ฒฝ์šฐ 46๋ฐ”์ดํŠธ ๋ฌธ์ž์—ด์„ 10๋ฐ”์ดํŠธ ๋ฒ„ํผ์— ๋ณต์‚ฌํ•˜๋ ค๊ณ  ํ•ด์„œ ๋ฒ„ํผ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฑฐ์•ผ!

๐ŸŽ“ ํ”„๋กœ ํŒ: GDB์—์„œ ์ค‘๋‹จ์ ์„ ์„ค์ •ํ•  ๋•Œ๋Š” ์ค„ ๋ฒˆํ˜ธ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ํ•จ์ˆ˜ ์ด๋ฆ„์œผ๋กœ๋„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์–ด. ์˜ˆ๋ฅผ ๋“ค์–ด break buggy_function์ด๋ผ๊ณ  ํ•˜๋ฉด ํ•ด๋‹น ํ•จ์ˆ˜์˜ ์‹œ์ž‘ ๋ถ€๋ถ„์— ์ค‘๋‹จ์ ์ด ์„ค์ •๋ผ. ๋˜ํ•œ ์กฐ๊ฑด๋ถ€ ์ค‘๋‹จ์ ๋„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์–ด: break 10 if x > 5์ฒ˜๋Ÿผ ๋ง์ด์•ผ!

GDB์˜ ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ๋“ค

GDB๋Š” ๊ธฐ๋ณธ ๊ธฐ๋Šฅ ์™ธ์—๋„ ์ •๋ง ๊ฐ•๋ ฅํ•œ ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ๋“ค์„ ์ œ๊ณตํ•ด. ์ด๋Ÿฐ ๊ธฐ๋Šฅ๋“ค์„ ์•Œ๋ฉด ๋””๋ฒ„๊น… ํšจ์œจ์ด ๋ช‡ ๋ฐฐ๋Š” ์˜ฌ๋ผ๊ฐ€!

**์›Œ์น˜ํฌ์ธํŠธ(Watchpoint)** ๐Ÿ‘€
ํŠน์ • ๋ณ€์ˆ˜์˜ ๊ฐ’์ด ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ํ”„๋กœ๊ทธ๋žจ์„ ๋ฉˆ์ถ”๊ฒŒ ํ•  ์ˆ˜ ์žˆ์–ด. ์–ธ์ œ ์–ด๋””์„œ ๋ณ€์ˆ˜๊ฐ€ ๋ฐ”๋€Œ๋Š”์ง€ ์ถ”์ ํ•˜๊ธฐ ์ •๋ง ์ข‹์ง€:

(gdb) watch my_variable
Hardware watchpoint 2: my_variable

(gdb) continue
Continuing.
Hardware watchpoint 2: my_variable

Old value = 0
New value = 42

**๋ฉ”๋ชจ๋ฆฌ ๋คํ”„** ๐Ÿ’พ
๋ฉ”๋ชจ๋ฆฌ์˜ ํŠน์ • ์˜์—ญ์„ ์ง์ ‘ ๋“ค์—ฌ๋‹ค๋ณผ ์ˆ˜ ์žˆ์–ด. ํฌ์ธํ„ฐ๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์ •๋ง ์˜ฌ๋ฐ”๋ฅธ์ง€ ํ™•์ธํ•  ๋•Œ ์œ ์šฉํ•ด:

(gdb) x/10x buffer
0x7fffffffe3b0: 0x73696854  0x20736920  0x65762061  0x6c207972
0x7fffffffe3c0: 0x20676e6f  0x69727473  0x7420676e  0x20746168

**์—ญ๋ฐฉํ–ฅ ๋””๋ฒ„๊น…(Reverse Debugging)** โฎ๏ธ
์ตœ์‹  ๋ฒ„์ „์˜ GDB๋Š” ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰์„ ๊ฑฐ๊พธ๋กœ ๋Œ๋ฆด ์ˆ˜ ์žˆ์–ด! ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ•œ ์ง€์ ์—์„œ ์—ญ์œผ๋กœ ์ถ”์ ํ•˜๋ฉด์„œ ์›์ธ์„ ์ฐพ์„ ์ˆ˜ ์žˆ์ง€:

(gdb) record
(gdb) continue
... (๋ฒ„๊ทธ ๋ฐœ์ƒ)
(gdb) reverse-step
(gdb) reverse-continue

๐Ÿ›ก๏ธ Valgrind: ๋ฉ”๋ชจ๋ฆฌ ์˜ค๋ฅ˜์˜ ํƒ์ •

GDB๊ฐ€ ํ”„๋กœ๊ทธ๋žจ์˜ ์‹คํ–‰ ํ๋ฆ„์„ ์ถ”์ ํ•˜๋Š” ๋„๊ตฌ๋ผ๋ฉด, Valgrind๋Š” ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์„ ๊ฐ์‹œํ•˜๋Š” ์ „๋ฌธ๊ฐ€์•ผ. ํŠนํžˆ Memcheck๋ผ๋Š” ๋„๊ตฌ๋Š” ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜, ์ž˜๋ชป๋œ ๋ฉ”๋ชจ๋ฆฌ ์ ‘๊ทผ, ์ดˆ๊ธฐํ™”๋˜์ง€ ์•Š์€ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ ๋“ฑ์„ ์ฐพ์•„๋‚ด๋Š” ๋ฐ ํƒ์›”ํ•ด. ๐Ÿ•ต๏ธ

Valgrind ์„ค์น˜ํ•˜๊ธฐ

Valgrind๋„ ๋Œ€๋ถ€๋ถ„์˜ ๋ฆฌ๋ˆ…์Šค ๋ฐฐํฌํŒ์—์„œ ์‰ฝ๊ฒŒ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ์–ด:

# Ubuntu/Debian
sudo apt-get install valgrind

# CentOS/RHEL
sudo yum install valgrind

# macOS๋Š” ๊ณต์‹ ์ง€์›์ด ์ œํ•œ์ ์ด์ง€๋งŒ ์‹œ๋„ํ•ด๋ณผ ์ˆ˜ ์žˆ์–ด
brew install valgrind

Valgrind ๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•

Valgrind๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฑด ์ •๋ง ๊ฐ„๋‹จํ•ด. ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ๋ช…๋ น ์•ž์— valgrind๋งŒ ๋ถ™์ด๋ฉด ๋ผ:

valgrind ./myprogram

๋” ์ž์„ธํ•œ ์ •๋ณด๋ฅผ ๋ณด๋ ค๋ฉด ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์–ด:

valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./myprogram

๊ฐ ์˜ต์…˜์˜ ์˜๋ฏธ๋ฅผ ์‚ดํŽด๋ณด๋ฉด:

- --leak-check=full: ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜์— ๋Œ€ํ•œ ์ƒ์„ธํ•œ ์ •๋ณด ์ œ๊ณต
- --show-leak-kinds=all: ๋ชจ๋“  ์ข…๋ฅ˜์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ํ‘œ์‹œ
- --track-origins=yes: ์ดˆ๊ธฐํ™”๋˜์ง€ ์•Š์€ ๊ฐ’์˜ ์ถœ์ฒ˜ ์ถ”์ 

์‹ค์ „ ์˜ˆ์ œ: ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ์ฐพ๊ธฐ

๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ์žˆ๋Š” ๊ฐ„๋‹จํ•œ ํ”„๋กœ๊ทธ๋žจ์„ ๋งŒ๋“ค์–ด๋ณด์ž:

#include <stdlib.h>
#include <string.h>

char* create_string(const char* text) {
    char* str = (char*)malloc(strlen(text) + 1);
    strcpy(str, text);
    return str;
}

int main() {
    for (int i = 0; i < 10; i++) {
        char* message = create_string("Hello, World!");
        // free(message)๋ฅผ ๊นœ๋นกํ–ˆ์–ด!
    }
    return 0;
}

์ด ์ฝ”๋“œ๋ฅผ ์ปดํŒŒ์ผํ•˜๊ณ  Valgrind๋กœ ์‹คํ–‰ํ•ด๋ณด์ž:

$ gcc -g -o leak leak.c
$ valgrind --leak-check=full ./leak

==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; rerun with -h for copyright info
==12345== Command: ./leak
==12345==
==12345==
==12345== HEAP SUMMARY:
==12345==     in use at exit: 140 bytes in 10 blocks
==12345==   total heap usage: 11 allocs, 1 frees, 1,164 bytes allocated
==12345==
==12345== 140 (14 direct, 126 indirect) bytes in 10 blocks are definitely lost
==12345==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12345==    by 0x108667: create_string (leak.c:5)
==12345==    by 0x1086B4: main (leak.c:12)
==12345==
==12345== LEAK SUMMARY:
==12345==    definitely lost: 140 bytes in 10 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: 1 errors from 1 contexts (suppressed: 0 from 0)

์™€! Valgrind๊ฐ€ ์ •ํ™•ํžˆ ์–ด๋””์„œ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋ˆ„์ˆ˜๋˜๊ณ  ์žˆ๋Š”์ง€ ์•Œ๋ ค์ฃผ๋„ค! ๐Ÿ’ก 140๋ฐ”์ดํŠธ๊ฐ€ 10๊ฐœ ๋ธ”๋ก์—์„œ ๋ˆ„์ˆ˜๋˜๊ณ  ์žˆ๊ณ , ์ •ํ™•ํžˆ ์–ด๋А ์ค„์—์„œ ํ• ๋‹น๋˜์—ˆ๋Š”์ง€๊นŒ์ง€ ๋ณด์—ฌ์ค˜. ์ด์ œ ํ•ด๋‹น ๋ถ€๋ถ„์— free(message)๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋ผ!

Valgrind๊ฐ€ ์ฐพ์•„๋‚ด๋Š” ๋‹ค์–‘ํ•œ ์˜ค๋ฅ˜๋“ค

Valgrind๋Š” ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ์™ธ์—๋„ ๋‹ค์–‘ํ•œ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ จ ์˜ค๋ฅ˜๋ฅผ ์ฐพ์•„๋‚ด. ์‹ค์ œ๋กœ ์–ด๋–ค ์˜ค๋ฅ˜๋“ค์„ ํƒ์ง€ํ•˜๋Š”์ง€ ์˜ˆ์ œ์™€ ํ•จ๊ป˜ ์‚ดํŽด๋ณด์ž:

1. ์ž˜๋ชป๋œ ๋ฉ”๋ชจ๋ฆฌ ์ฝ๊ธฐ/์“ฐ๊ธฐ

#include <stdlib.h>

int main() {
    int* array = (int*)malloc(10 * sizeof(int));
    array[10] = 42;  // ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚œ ์ ‘๊ทผ!
    free(array);
    return 0;
}

Valgrind ์ถœ๋ ฅ:

==12346== Invalid write of size 4
==12346==    at 0x108654: main (example.c:5)
==12346==  Address 0x522d068 is 0 bytes after a block of size 40 alloc'd

2. ์ดˆ๊ธฐํ™”๋˜์ง€ ์•Š์€ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ

#include <stdio.h>

int main() {
    int x;
    if (x == 10) {  // x๊ฐ€ ์ดˆ๊ธฐํ™”๋˜์ง€ ์•Š์•˜์–ด!
        printf("x is 10\n");
    }
    return 0;
}

Valgrind ์ถœ๋ ฅ:

==12347== Conditional jump or move depends on uninitialised value(s)
==12347==    at 0x108654: main (example.c:5)

3. ์ด์ค‘ ํ•ด์ œ(Double Free)

#include <stdlib.h>

int main() {
    int* ptr = (int*)malloc(sizeof(int));
    free(ptr);
    free(ptr);  // ๊ฐ™์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋‘ ๋ฒˆ ํ•ด์ œ!
    return 0;
}

Valgrind ์ถœ๋ ฅ:

==12348== Invalid free() / delete / delete[] / realloc()
==12348==    at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12348==    by 0x108668: main (example.c:6)
==12348==  Address 0x522d040 is 0 bytes inside a block of size 4 free'd
โš ๏ธ ์ฃผ์˜์‚ฌํ•ญ: Valgrind๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ๊ฐ€์ƒ ๋จธ์‹ ์—์„œ ์‹คํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‹คํ–‰ ์†๋„๊ฐ€ 10~50๋ฐฐ ์ •๋„ ๋А๋ ค์ ธ. ๊ทธ๋ž˜์„œ ๊ฐœ๋ฐœ ๋‹จ๊ณ„์—์„œ ํ…Œ์ŠคํŠธ์šฉ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ , ์‹ค์ œ ๋ฐฐํฌ ๋ฒ„์ „์—์„œ๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒŒ ์ผ๋ฐ˜์ ์ด์•ผ. ํ•˜์ง€๋งŒ ์ด ์ •๋„ ์†๋„ ์ €ํ•˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ์˜ค๋ฅ˜๋ฅผ ์ฐพ์•„๋‚ด๋Š” ๋Œ€๊ฐ€๋กœ๋Š” ์ถฉ๋ถ„ํžˆ ๊ฐ์ˆ˜ํ•  ๋งŒํ•œ ๊ฐ€์น˜๊ฐ€ ์žˆ์–ด!

๐ŸŽจ GDB์™€ Valgrind ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๊ธฐ

GDB์™€ Valgrind๋Š” ๊ฐ๊ฐ ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ์ง€๋งŒ, ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ์‹œ๋„ˆ์ง€ ํšจ๊ณผ๊ฐ€ ์—„์ฒญ๋‚˜! Valgrind๋กœ ๋ฉ”๋ชจ๋ฆฌ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ๊ฒฌํ•˜๊ณ , GDB๋กœ ์ •ํ™•ํ•œ ์›์ธ์„ ํŒŒ์•…ํ•˜๋Š” ์‹์œผ๋กœ ์กฐํ•ฉํ•  ์ˆ˜ ์žˆ์–ด. ๐Ÿ”ฅ

Valgrind์™€ GDB ์—ฐ๋™ํ•˜๊ธฐ

Valgrind๋Š” GDB ์„œ๋ฒ„ ๋ชจ๋“œ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์–ด. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด Valgrind๊ฐ€ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ๊ฒฌํ–ˆ์„ ๋•Œ GDB๋กœ ํ”„๋กœ๊ทธ๋žจ ์ƒํƒœ๋ฅผ ์ž์„ธํžˆ ์‚ดํŽด๋ณผ ์ˆ˜ ์žˆ์ง€:

# ํ„ฐ๋ฏธ๋„ 1: Valgrind๋ฅผ GDB ์„œ๋ฒ„ ๋ชจ๋“œ๋กœ ์‹คํ–‰
valgrind --vgdb=yes --vgdb-error=0 ./myprogram

# ํ„ฐ๋ฏธ๋„ 2: GDB๋ฅผ ์‹คํ–‰ํ•˜๊ณ  Valgrind์— ์—ฐ๊ฒฐ
gdb ./myprogram
(gdb) target remote | vgdb

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด Valgrind๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ๊ฒฌํ•˜๋Š” ์ˆœ๊ฐ„ GDB๋กœ ํ”„๋กœ๊ทธ๋žจ์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์–ด. ๋ณ€์ˆ˜ ๊ฐ’์„ ํ™•์ธํ•˜๊ณ , ์Šคํƒ์„ ์ถ”์ ํ•˜๊ณ , ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋คํ”„ํ•  ์ˆ˜ ์žˆ์ง€!

์‹ค์ „ ์›Œํฌํ”Œ๋กœ์šฐ

์‹ค์ œ ๊ฐœ๋ฐœ์—์„œ ์ด ๋‘ ๋„๊ตฌ๋ฅผ ์–ด๋–ป๊ฒŒ ํ™œ์šฉํ•˜๋Š”์ง€ ๋‹จ๊ณ„๋ณ„๋กœ ์‚ดํŽด๋ณด์ž:

**1๋‹จ๊ณ„: ์ดˆ๊ธฐ ํ…Œ์ŠคํŠธ** ๐Ÿงช
๋จผ์ € ํ”„๋กœ๊ทธ๋žจ์„ ์ผ๋ฐ˜์ ์œผ๋กœ ์‹คํ–‰ํ•ด์„œ ๋ˆˆ์— ๋ณด์ด๋Š” ๋ฒ„๊ทธ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•ด. ์ด ๋‹จ๊ณ„์—์„œ ์„ธ๊ทธ๋ฉ˜ํ…Œ์ด์…˜ ํดํŠธ๋‚˜ ๋ช…ํ™•ํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋ฐ”๋กœ GDB๋กœ ๋„˜์–ด๊ฐ€.

**2๋‹จ๊ณ„: Valgrind ์Šค์บ”** ๐Ÿ”
ํ”„๋กœ๊ทธ๋žจ์ด ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์—ฌ๋„ Valgrind๋กœ ๋ฉ”๋ชจ๋ฆฌ ์˜ค๋ฅ˜๋ฅผ ์ฒดํฌํ•ด. ํŠนํžˆ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋Š” ํ”„๋กœ๊ทธ๋žจ์ด ์งง๊ฒŒ ์‹คํ–‰๋  ๋•Œ๋Š” ๋ฌธ์ œ๊ฐ€ ์•ˆ ๋˜์ง€๋งŒ, ์˜ค๋ž˜ ์‹คํ–‰๋˜๋ฉด ์‹ฌ๊ฐํ•œ ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ์–ด.

valgrind --leak-check=full --show-leak-kinds=all \
         --track-origins=yes --log-file=valgrind.log ./myprogram

**3๋‹จ๊ณ„: ์˜ค๋ฅ˜ ๋ถ„์„** ๐Ÿ“Š
Valgrind ๋กœ๊ทธ๋ฅผ ๋ถ„์„ํ•ด์„œ ์–ด๋–ค ์ข…๋ฅ˜์˜ ์˜ค๋ฅ˜๊ฐ€ ์žˆ๋Š”์ง€ ํŒŒ์•…ํ•ด. "definitely lost"๋Š” ํ™•์‹คํ•œ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ณ , "possibly lost"๋Š” ์ž ์žฌ์  ๋ฌธ์ œ์•ผ.

**4๋‹จ๊ณ„: GDB๋กœ ์ƒ์„ธ ๋””๋ฒ„๊น…** ๐ŸŽฏ
Valgrind๊ฐ€ ์ง€์ ํ•œ ๋ถ€๋ถ„์„ GDB๋กœ ์ž์„ธํžˆ ๋“ค์—ฌ๋‹ค๋ด. ์ค‘๋‹จ์ ์„ ์„ค์ •ํ•˜๊ณ , ๋ณ€์ˆ˜ ๊ฐ’์„ ์ถ”์ ํ•˜๋ฉด์„œ ์ •ํ™•ํ•œ ์›์ธ์„ ์ฐพ์•„๋‚ด.

**5๋‹จ๊ณ„: ์ˆ˜์ • ๋ฐ ์žฌ๊ฒ€์ฆ** โœ…
์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•œ ํ›„ ๋‹ค์‹œ Valgrind๋กœ ๊ฒ€์‚ฌํ•ด์„œ ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ด. ํ•œ ๊ฐ€์ง€ ๋ฒ„๊ทธ๋ฅผ ๊ณ ์น˜๋‹ค๊ฐ€ ๋‹ค๋ฅธ ๋ฒ„๊ทธ๋ฅผ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์œผ๋‹ˆ๊นŒ!

๐Ÿ’ช ์‹ค์ „ ๋””๋ฒ„๊น… ํŒ๊ณผ ๋ฒ ์ŠคํŠธ ํ”„๋ž™ํ‹ฐ์Šค

์ด๋ก ์€ ์ถฉ๋ถ„ํžˆ ๋ฐฐ์› ์œผ๋‹ˆ, ์ด์ œ ์‹ค์ „์—์„œ ๋ฐ”๋กœ ์จ๋จน์„ ์ˆ˜ ์žˆ๋Š” ํŒ๋“ค์„ ๊ณต์œ ํ• ๊ฒŒ! ์ด๊ฑด ๋‚ด๊ฐ€ ์ˆ˜๋…„๊ฐ„ C์–ธ์–ด๋กœ ๊ฐœ๋ฐœํ•˜๋ฉด์„œ ํ„ฐ๋“ํ•œ ๋…ธํ•˜์šฐ๋“ค์ด์•ผ. ๐Ÿ˜Ž

๋””๋ฒ„๊น…์„ ์‰ฝ๊ฒŒ ๋งŒ๋“œ๋Š” ์ฝ”๋”ฉ ์Šต๊ด€

1. ๋ฐฉ์–ด์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ

ํฌ์ธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— ํ•ญ์ƒ NULL ์ฒดํฌ๋ฅผ ํ•ด:
char* str = get_string();
if (str == NULL) {
    fprintf(stderr, "Error: get_string returned NULL\n");
    return -1;
}
// ์ด์ œ ์•ˆ์ „ํ•˜๊ฒŒ str ์‚ฌ์šฉ
2. ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ํ›„ ์ฆ‰์‹œ ํ•ด์ œ ๊ณ„ํš ์„ธ์šฐ๊ธฐ

malloc์„ ์“ฐ๋Š” ์ˆœ๊ฐ„ ๋ฐ”๋กœ ๊ทธ ์•„๋ž˜์— ์ฃผ์„์œผ๋กœ free๋ฅผ ์–ด๋””์„œ ํ• ์ง€ ์ ์–ด๋‘ฌ:
char* buffer = (char*)malloc(SIZE);
// TODO: free(buffer) in cleanup_function()

// ... ์ฝ”๋“œ ...

cleanup_function() {
    free(buffer);
}
3. ๋””๋ฒ„๊ทธ ๋งคํฌ๋กœ ํ™œ์šฉ

์กฐ๊ฑด๋ถ€ ์ปดํŒŒ์ผ์„ ํ™œ์šฉํ•ด์„œ ๋””๋ฒ„๊ทธ ์ •๋ณด๋ฅผ ์‰ฝ๊ฒŒ ์ผœ๊ณ  ๋Œ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด:
#ifdef DEBUG
    #define DEBUG_PRINT(fmt, ...) \
        fprintf(stderr, "DEBUG %s:%d: " fmt "\n", \
                __FILE__, __LINE__, ##__VA_ARGS__)
#else
    #define DEBUG_PRINT(fmt, ...) do {} while(0)
#endif

// ์‚ฌ์šฉ ์˜ˆ
DEBUG_PRINT("Variable x = %d", x);

๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ํŒจํ„ด

๋ฉ”๋ชจ๋ฆฌ ์˜ค๋ฅ˜๋ฅผ ์˜ˆ๋ฐฉํ•˜๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์€ ์ผ๊ด€๋œ ํŒจํ„ด์„ ๋”ฐ๋ฅด๋Š” ๊ฑฐ์•ผ. ๋‹ค์Œ์€ ๊ฒ€์ฆ๋œ ํŒจํ„ด๋“ค์ด์•ผ:

**RAII ์Šคํƒ€์ผ (Resource Acquisition Is Initialization)** ๐Ÿ—๏ธ
C++์˜ ๊ฐœ๋…์ด์ง€๋งŒ C์—์„œ๋„ ๋น„์Šทํ•˜๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์–ด:

typedef struct {
    char* data;
    size_t size;
} Buffer;

Buffer* buffer_create(size_t size) {
    Buffer* buf = (Buffer*)malloc(sizeof(Buffer));
    if (buf == NULL) return NULL;
    
    buf->data = (char*)malloc(size);
    if (buf->data == NULL) {
        free(buf);
        return NULL;
    }
    
    buf->size = size;
    return buf;
}

void buffer_destroy(Buffer* buf) {
    if (buf == NULL) return;
    free(buf->data);
    free(buf);
}

// ์‚ฌ์šฉ
Buffer* buf = buffer_create(1024);
if (buf != NULL) {
    // ๋ฒ„ํผ ์‚ฌ์šฉ
    buffer_destroy(buf);  // ๊น”๋”ํ•˜๊ฒŒ ์ •๋ฆฌ
}

**์†Œ์œ ๊ถŒ ๋ช…ํ™•ํžˆ ํ•˜๊ธฐ** ๐Ÿ“
ํ•จ์ˆ˜๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹นํ•˜๋ฉด ๋ˆ„๊ฐ€ ํ•ด์ œํ•  ์ฑ…์ž„์ด ์žˆ๋Š”์ง€ ๋ช…ํ™•ํžˆ ํ•ด:

// ํ˜ธ์ถœ์ž๊ฐ€ freeํ•ด์•ผ ํ•จ์„ ๋ช…์‹œ
// Returns: Newly allocated string (caller must free)
char* create_greeting(const char* name) {
    size_t len = strlen("Hello, ") + strlen(name) + 1;
    char* greeting = (char*)malloc(len);
    if (greeting != NULL) {
        sprintf(greeting, "Hello, %s", name);
    }
    return greeting;
}

์„ฑ๋Šฅ๊ณผ ๋””๋ฒ„๊น…์˜ ๊ท ํ˜•

๋””๋ฒ„๊น… ์ฝ”๋“œ๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์œผ๋ฉด ํ”„๋กœ๊ทธ๋žจ์ด ๋А๋ ค์งˆ ์ˆ˜ ์žˆ์–ด. ํ•˜์ง€๋งŒ ์ ์ ˆํ•œ ๊ท ํ˜•์„ ์ฐพ์œผ๋ฉด ๋‘˜ ๋‹ค ์žก์„ ์ˆ˜ ์žˆ์ง€:

๐Ÿš€ ์„ฑ๋Šฅ ํŒ: ๋””๋ฒ„๊ทธ ๋นŒ๋“œ์™€ ๋ฆด๋ฆฌ์Šค ๋นŒ๋“œ๋ฅผ ๋ถ„๋ฆฌํ•ด. ๊ฐœ๋ฐœํ•  ๋•Œ๋Š” -g -O0 (๋””๋ฒ„๊ทธ ์ •๋ณด ํฌํ•จ, ์ตœ์ ํ™” ์—†์Œ)์œผ๋กœ ์ปดํŒŒ์ผํ•˜๊ณ , ๋ฐฐํฌํ•  ๋•Œ๋Š” -O2 -DNDEBUG (์ตœ์ ํ™” ํ™œ์„ฑํ™”, ๋””๋ฒ„๊ทธ ์ฝ”๋“œ ์ œ๊ฑฐ)๋กœ ์ปดํŒŒ์ผํ•ด. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ฐœ๋ฐœ ์ค‘์—๋Š” ๋””๋ฒ„๊น…์ด ์‰ฝ๊ณ , ๋ฐฐํฌ ๋ฒ„์ „์€ ๋น ๋ฅด๊ฒŒ ์‹คํ–‰๋ผ!

๐ŸŒŸ ๊ณ ๊ธ‰ ๋””๋ฒ„๊น… ๊ธฐ๋ฒ•

๊ธฐ๋ณธ์„ ๋„˜์–ด์„œ ๋” ๊นŠ์ด ๋“ค์–ด๊ฐ€๋ณด์ž! ์ด๋Ÿฐ ๊ธฐ๋ฒ•๋“ค์„ ์•Œ๋ฉด ์ •๋ง ๊นŒ๋‹ค๋กœ์šด ๋ฒ„๊ทธ๋„ ์žก์„ ์ˆ˜ ์žˆ์–ด. ๐ŸŽ“

์ฝ”์–ด ๋คํ”„ ๋ถ„์„

ํ”„๋กœ๊ทธ๋žจ์ด ํฌ๋ž˜์‹œํ•˜๋ฉด ์ฝ”์–ด ๋คํ”„ ํŒŒ์ผ์ด ์ƒ์„ฑ๋ผ. ์ด๊ฑด ํ”„๋กœ๊ทธ๋žจ์ด ์ฃฝ๋Š” ์ˆœ๊ฐ„์˜ ๋ฉ”๋ชจ๋ฆฌ ์Šค๋ƒ…์ƒท์ด์•ผ. GDB๋กœ ์ด๊ฑธ ๋ถ„์„ํ•  ์ˆ˜ ์žˆ์–ด:

# ์ฝ”์–ด ๋คํ”„ ํ™œ์„ฑํ™”
ulimit -c unlimited

# ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ (ํฌ๋ž˜์‹œ ๋ฐœ์ƒ)
./myprogram

# ์ฝ”์–ด ๋คํ”„ ๋ถ„์„
gdb ./myprogram core

(gdb) backtrace
(gdb) info registers
(gdb) print variable_name

์ฝ”์–ด ๋คํ”„๋Š” ํŠนํžˆ ์žฌํ˜„ํ•˜๊ธฐ ์–ด๋ ค์šด ๋ฒ„๊ทธ๋ฅผ ๋””๋ฒ„๊น…ํ•  ๋•Œ ์ •๋ง ์œ ์šฉํ•ด. ํ”„๋กœ๊ทธ๋žจ์ด ์ฃฝ์€ ์ˆœ๊ฐ„์˜ ๋ชจ๋“  ์ •๋ณด๊ฐ€ ๋‹ด๊ฒจ ์žˆ๊ฑฐ๋“ !

๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ๋””๋ฒ„๊น…

๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ”„๋กœ๊ทธ๋žจ์€ ๋””๋ฒ„๊น…ํ•˜๊ธฐ ์ •๋ง ๊นŒ๋‹ค๋กœ์›Œ. ๋ ˆ์ด์Šค ์ปจ๋””์…˜์ด๋‚˜ ๋ฐ๋“œ๋ฝ ๊ฐ™์€ ๋ฌธ์ œ๋“ค์€ ํƒ€์ด๋ฐ์— ๋”ฐ๋ผ ๋ฐœ์ƒํ•˜๊ฑฐ๋‚˜ ์•ˆ ํ•˜๊ฑฐ๋“ . GDB๋Š” ์Šค๋ ˆ๋“œ ๋””๋ฒ„๊น…์„ ์œ„ํ•œ ํŠน๋ณ„ํ•œ ๋ช…๋ น์–ด๋“ค์„ ์ œ๊ณตํ•ด:

(gdb) info threads          # ๋ชจ๋“  ์Šค๋ ˆ๋“œ ๋ชฉ๋ก
(gdb) thread 2              # ์Šค๋ ˆ๋“œ 2๋กœ ์ „ํ™˜
(gdb) thread apply all bt   # ๋ชจ๋“  ์Šค๋ ˆ๋“œ์˜ ๋ฐฑํŠธ๋ ˆ์ด์Šค
(gdb) set scheduler-locking on  # ํ˜„์žฌ ์Šค๋ ˆ๋“œ๋งŒ ์‹คํ–‰

Valgrind์˜ Helgrind ๋„๊ตฌ๋Š” ์Šค๋ ˆ๋“œ ๊ด€๋ จ ์˜ค๋ฅ˜๋ฅผ ์ฐพ๋Š” ๋ฐ ํŠนํ™”๋˜์–ด ์žˆ์–ด:

valgrind --tool=helgrind ./myprogram

Helgrind๋Š” ๋ฐ์ดํ„ฐ ๋ ˆ์ด์Šค, ์ž˜๋ชป๋œ ๋ฎคํ…์Šค ์‚ฌ์šฉ, ๋ฝ ์ˆœ์„œ ๋ฌธ์ œ ๋“ฑ์„ ํƒ์ง€ํ•ด์ค˜.

ํ”„๋กœํŒŒ์ผ๋ง๊ณผ ๋””๋ฒ„๊น…์˜ ๊ฒฐํ•ฉ

๋•Œ๋กœ๋Š” ๋ฒ„๊ทธ๊ฐ€ ์•„๋‹ˆ๋ผ ์„ฑ๋Šฅ ๋ฌธ์ œ๋ฅผ ๋””๋ฒ„๊น…ํ•ด์•ผ ํ•  ๋•Œ๋„ ์žˆ์–ด. Valgrind์˜ Callgrind ๋„๊ตฌ๋Š” ํ”„๋กœ๊ทธ๋žจ์˜ ์„ฑ๋Šฅ์„ ๋ถ„์„ํ•ด์ค˜:

valgrind --tool=callgrind ./myprogram
callgrind_annotate callgrind.out.12345

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์–ด๋А ํ•จ์ˆ˜๊ฐ€ ๊ฐ€์žฅ ๋งŽ์ด ํ˜ธ์ถœ๋˜๊ณ , ์–ด๋””์„œ ์‹œ๊ฐ„์„ ๋งŽ์ด ์“ฐ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์–ด. KCachegrind ๊ฐ™์€ GUI ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์‹œ๊ฐ์ ์œผ๋กœ ๋ถ„์„ํ•  ์ˆ˜๋„ ์žˆ์ง€!

๋””๋ฒ„๊น… ๋„๊ตฌ ๋น„๊ต GDB 95% ์‹คํ–‰ ํ๋ฆ„ ์ถ”์  Valgrind 90% ๋ฉ”๋ชจ๋ฆฌ ์˜ค๋ฅ˜ ํƒ์ง€ Helgrind 75% ์Šค๋ ˆ๋“œ ์˜ค๋ฅ˜ ํƒ์ง€ Callgrind 70% ์„ฑ๋Šฅ ํ”„๋กœํŒŒ์ผ๋ง

๐ŸŽฏ ์‹ค๋ฌด์—์„œ์˜ ๋””๋ฒ„๊น… ์ „๋žต

์ด๋ก ๊ณผ ๋„๊ตฌ๋ฅผ ์•„๋Š” ๊ฒƒ๋„ ์ค‘์š”ํ•˜์ง€๋งŒ, ์‹ค์ œ ํ”„๋กœ์ ํŠธ์—์„œ ์–ด๋–ป๊ฒŒ ์ ์šฉํ•˜๋Š”์ง€๊ฐ€ ๋” ์ค‘์š”ํ•ด. ์‹ค๋ฌด ๊ฒฝํ—˜์„ ๋ฐ”ํƒ•์œผ๋กœ ํšจ๊ณผ์ ์ธ ๋””๋ฒ„๊น… ์ „๋žต์„ ๊ณต์œ ํ• ๊ฒŒ! ๐Ÿ’ผ

๋ฒ„๊ทธ ์žฌํ˜„ ๊ฐ€๋Šฅ์„ฑ ํ™•๋ณด

๋””๋ฒ„๊น…์˜ ์ฒซ ๋ฒˆ์งธ ๋‹จ๊ณ„๋Š” ๋ฒ„๊ทธ๋ฅผ ์•ˆ์ •์ ์œผ๋กœ ์žฌํ˜„ํ•˜๋Š” ๊ฑฐ์•ผ. ์žฌํ˜„ํ•  ์ˆ˜ ์—†๋Š” ๋ฒ„๊ทธ๋Š” ๊ณ ์น  ์ˆ˜ ์—†๊ฑฐ๋“ ! ๋‹ค์Œ ์ •๋ณด๋“ค์„ ๊ธฐ๋กํ•ด๋‘ฌ:

- ์ •ํ™•ํ•œ ์ž…๋ ฅ ๋ฐ์ดํ„ฐ
- ์‹คํ–‰ ํ™˜๊ฒฝ (OS, ์ปดํŒŒ์ผ๋Ÿฌ ๋ฒ„์ „, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฒ„์ „)
- ์‹คํ–‰ ์ˆœ์„œ์™€ ํƒ€์ด๋ฐ
- ์—๋Ÿฌ ๋ฉ”์‹œ์ง€์™€ ๋กœ๊ทธ

// ์žฌํ˜„ ๊ฐ€๋Šฅํ•œ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ์ž‘์„ฑ
void test_buffer_overflow() {
    char buffer[10];
    const char* input = "This is too long";
    
    // ๋ฒ„๊ทธ ์žฌํ˜„
    strcpy(buffer, input);  // ์—ฌ๊ธฐ์„œ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๋ฐœ์ƒ
    
    // ์˜ˆ์ƒ ๊ฒฐ๊ณผ vs ์‹ค์ œ ๊ฒฐ๊ณผ ๊ธฐ๋ก
    printf("Expected: Safe copy\n");
    printf("Actual: Buffer overflow\n");
}

์ด์ง„ ํƒ์ƒ‰ ๋””๋ฒ„๊น…

ํฐ ํ”„๋กœ์ ํŠธ์—์„œ ๋ฒ„๊ทธ์˜ ์œ„์น˜๋ฅผ ๋ชจ๋ฅผ ๋•Œ๋Š” ์ด์ง„ ํƒ์ƒ‰ ๋ฐฉ์‹์„ ์จ. ์ฝ”๋“œ์˜ ์ค‘๊ฐ„ ์ง€์ ์— ๋กœ๊ทธ๋ฅผ ์ฐ์–ด์„œ ๋ฒ„๊ทธ๊ฐ€ ๊ทธ ์ „์— ๋ฐœ์ƒํ•˜๋Š”์ง€ ํ›„์— ๋ฐœ์ƒํ•˜๋Š”์ง€ ํ™•์ธํ•˜๊ณ , ๋ฒ”์œ„๋ฅผ ์ ˆ๋ฐ˜์”ฉ ์ขํ˜€๊ฐ€๋Š” ๊ฑฐ์•ผ:

void complex_function() {
    // ์‹œ์ž‘
    DEBUG_PRINT("Starting complex_function");
    
    step1();
    DEBUG_PRINT("After step1");  // ์—ฌ๊ธฐ๊นŒ์ง€๋Š” ์ •์ƒ
    
    step2();
    DEBUG_PRINT("After step2");  // ์—ฌ๊ธฐ์„œ ๋ฌธ์ œ ๋ฐœ์ƒ!
    
    step3();
    DEBUG_PRINT("After step3");
}

ํšŒ๊ท€ ํ…Œ์ŠคํŠธ ์ž๋™ํ™”

๋ฒ„๊ทธ๋ฅผ ๊ณ ์ณค์œผ๋ฉด ๊ฐ™์€ ๋ฒ„๊ทธ๊ฐ€ ๋‹ค์‹œ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋„๋ก ํ…Œ์ŠคํŠธ๋ฅผ ์ž๋™ํ™”ํ•ด. ๊ฐ„๋‹จํ•œ ์Šคํฌ๋ฆฝํŠธ๋กœ๋„ ์ถฉ๋ถ„ํ•ด:

#!/bin/bash
# test_memory.sh

echo "Running memory tests..."

# Valgrind๋กœ ๋ฉ”๋ชจ๋ฆฌ ํ…Œ์ŠคํŠธ
valgrind --leak-check=full --error-exitcode=1 ./myprogram test_input.txt

if [ $? -eq 0 ]; then
    echo "โœ… Memory test passed"
else
    echo "โŒ Memory test failed"
    exit 1
fi

# ์ถ”๊ฐ€ ํ…Œ์ŠคํŠธ๋“ค...
./myprogram test1.txt
./myprogram test2.txt
./myprogram test3.txt

echo "All tests completed!"

๐ŸŒ ์žฌ๋Šฅ๋„ท์—์„œ ๋””๋ฒ„๊น… ์Šคํ‚ฌ ๊ณต์œ ํ•˜๊ธฐ

๋””๋ฒ„๊น…์€ ์ •๋ง ๊ฐ€์น˜ ์žˆ๋Š” ๊ธฐ์ˆ ์ด์•ผ. ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋“ค์ด ๋””๋ฒ„๊น…์— ์–ด๋ ค์›€์„ ๊ฒช๊ณ  ์žˆ๊ณ , ์ด๋Ÿฐ ๊ธฐ์ˆ ์„ ๋ฐฐ์šฐ๊ณ  ์‹ถ์–ด ํ•ด. ์žฌ๋Šฅ๋„ท ๊ฐ™์€ ํ”Œ๋žซํผ์—์„œ๋Š” ์ด๋Ÿฐ ์ „๋ฌธ ์ง€์‹์„ ๊ณต์œ ํ•˜๊ณ  ์ˆ˜์ต์„ ์ฐฝ์ถœํ•  ์ˆ˜๋„ ์žˆ์–ด! ๐ŸŽ“

์˜ˆ๋ฅผ ๋“ค์–ด, "C์–ธ์–ด ๋ฉ”๋ชจ๋ฆฌ ๋””๋ฒ„๊น… 1:1 ์ฝ”์นญ", "Valgrind ์‹ค์ „ ํ™œ์šฉ๋ฒ•", "๋ณต์žกํ•œ ๋ฒ„๊ทธ ํ•ด๊ฒฐ ์ปจ์„คํŒ…" ๊ฐ™์€ ์žฌ๋Šฅ์„ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ์ง€. ์‹ค์ œ๋กœ ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋“ค์ด ํŠน์ • ๋ฒ„๊ทธ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐ ๋„์›€์ด ํ•„์š”ํ•ด์„œ ์ „๋ฌธ๊ฐ€์˜ ์กฐ์–ธ์„ ๊ตฌํ•˜๊ณค ํ•ด. ๋„ˆ์˜ ๋””๋ฒ„๊น… ๋…ธํ•˜์šฐ๊ฐ€ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ๋Š” ์ •๋ง ๊ท€์ค‘ํ•œ ์ž์‚ฐ์ด ๋  ์ˆ˜ ์žˆ์–ด!

๋˜ํ•œ ์žฌ๋Šฅ๋„ท์—์„œ ๋‹ค๋ฅธ ์ „๋ฌธ๊ฐ€๋“ค์˜ ๋””๋ฒ„๊น… ํŒ์„ ๋ฐฐ์šธ ์ˆ˜๋„ ์žˆ์–ด. ํ˜ผ์ž ๊ณ ๋ฏผํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๊ฒฝํ—˜ ๋งŽ์€ ๊ฐœ๋ฐœ์ž์—๊ฒŒ ๋ฐฐ์šฐ๋ฉด ํ›จ์”ฌ ๋น ๋ฅด๊ฒŒ ์„ฑ์žฅํ•  ์ˆ˜ ์žˆ๊ฑฐ๋“ . ํŠนํžˆ ์‹ค๋ฌด์—์„œ ๋งˆ์ฃผ์น˜๋Š” ๋ณต์žกํ•œ ๋ฌธ์ œ๋“ค์€ ์ฑ…์ด๋‚˜ ๋ฌธ์„œ๋งŒ์œผ๋กœ๋Š” ํ•ด๊ฒฐํ•˜๊ธฐ ์–ด๋ ค์šธ ๋•Œ๊ฐ€ ๋งŽ์•„. ๊ทธ๋Ÿด ๋•Œ ์‹ค์ „ ๊ฒฝํ—˜์ด ํ’๋ถ€ํ•œ ๋ฉ˜ํ† ์˜ ๋„์›€์„ ๋ฐ›์œผ๋ฉด ์ •๋ง ํฐ ๋„์›€์ด ๋ผ! ๐Ÿ’ช

๐Ÿ“š ์ถ”๊ฐ€ ํ•™์Šต ๋ฆฌ์†Œ์Šค์™€ ๋„๊ตฌ๋“ค

GDB์™€ Valgrind ์™ธ์—๋„ ์•Œ์•„๋‘๋ฉด ์ข‹์€ ๋„๊ตฌ๋“ค๊ณผ ๋ฆฌ์†Œ์Šค๋ฅผ ์†Œ๊ฐœํ• ๊ฒŒ:

์œ ์šฉํ•œ ๋””๋ฒ„๊น… ๋„๊ตฌ๋“ค

**AddressSanitizer (ASan)** ๐Ÿ”ฌ
๊ตฌ๊ธ€์ด ๊ฐœ๋ฐœํ•œ ๋ฉ”๋ชจ๋ฆฌ ์˜ค๋ฅ˜ ํƒ์ง€ ๋„๊ตฌ์•ผ. Valgrind๋ณด๋‹ค ๋น ๋ฅด๊ณ  (2~3๋ฐฐ ๋А๋ฆผ vs 10~50๋ฐฐ ๋А๋ฆผ), ์ปดํŒŒ์ผ ํƒ€์ž„์— ํ†ตํ•ฉ๋ผ:

gcc -fsanitize=address -g -o myprogram myprogram.c
./myprogram

**UndefinedBehaviorSanitizer (UBSan)** โšก
์ •์˜๋˜์ง€ ์•Š์€ ๋™์ž‘(undefined behavior)์„ ์ฐพ์•„๋‚ด๋Š” ๋„๊ตฌ์•ผ:

gcc -fsanitize=undefined -g -o myprogram myprogram.c

**Electric Fence** ๐Ÿ”Œ
๋ฉ”๋ชจ๋ฆฌ ์˜ค๋ฅ˜๋ฅผ ์ฆ‰์‹œ ํƒ์ง€ํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์•ผ. ๊ฐ malloc ํ˜ธ์ถœ๋งˆ๋‹ค ๋ณดํ˜ธ ํŽ˜์ด์ง€๋ฅผ ํ• ๋‹นํ•ด์„œ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๋ฅผ ์ฆ‰์‹œ ์žก์•„๋‚ด:

gcc -o myprogram myprogram.c -lefence
./myprogram

๋””๋ฒ„๊น… ํ•™์Šต ์ž๋ฃŒ

- **GDB ๊ณต์‹ ๋ฌธ์„œ**: ๊ฐ€์žฅ ๊ถŒ์œ„ ์žˆ๋Š” ์ž๋ฃŒ. ๋ชจ๋“  ๋ช…๋ น์–ด์™€ ๊ธฐ๋Šฅ์ด ์ƒ์„ธํžˆ ์„ค๋ช…๋˜์–ด ์žˆ์–ด.
- **Valgrind ์‚ฌ์šฉ์ž ๋งค๋‰ด์–ผ**: Valgrind์˜ ๋ชจ๋“  ๋„๊ตฌ์™€ ์˜ต์…˜์„ ๋‹ค๋ฃจ๋Š” ์™„๋ฒฝํ•œ ๊ฐ€์ด๋“œ.
- **"The Art of Debugging with GDB, DDD, and Eclipse"**: ์‹ค์ „ ๋””๋ฒ„๊น… ๊ธฐ๋ฒ•์„ ๋‹ค๋ฃจ๋Š” ํ›Œ๋ฅญํ•œ ์ฑ….
- **"Effective Debugging"**: 66๊ฐ€์ง€ ๋””๋ฒ„๊น… ์ „๋žต์„ ์†Œ๊ฐœํ•˜๋Š” ์‹ค์šฉ์ ์ธ ์ฑ….

๐ŸŽฌ ๋งˆ๋ฌด๋ฆฌํ•˜๋ฉฐ

์™€! ์—ฌ๊ธฐ๊นŒ์ง€ ์ •๋ง ๊ธด ์—ฌ์ •์ด์—ˆ์–ด. ๐Ÿ˜… C์–ธ์–ด ๋””๋ฒ„๊น…๊ณผ GDB, Valgrind์— ๋Œ€ํ•ด ์ •๋ง ๋งŽ์€ ๊ฑธ ๋‹ค๋ค˜์ง€? ์ฒ˜์Œ์—๋Š” ๋ณต์žกํ•ด ๋ณด์ผ ์ˆ˜ ์žˆ์ง€๋งŒ, ํ•˜๋‚˜์”ฉ ์‹ค์Šตํ•˜๋‹ค ๋ณด๋ฉด ๊ธˆ๋ฐฉ ์ต์ˆ™ํ•ด์งˆ ๊ฑฐ์•ผ.

๋””๋ฒ„๊น…์€ ๋‹จ์ˆœํžˆ ๋ฒ„๊ทธ๋ฅผ ์ฐพ๋Š” ๊ฒƒ ์ด์ƒ์˜ ์˜๋ฏธ๊ฐ€ ์žˆ์–ด. ์ฝ”๋“œ๋ฅผ ๊นŠ์ด ์ดํ•ดํ•˜๊ณ , ํ”„๋กœ๊ทธ๋žจ์˜ ๋™์ž‘ ์›๋ฆฌ๋ฅผ ํŒŒ์•…ํ•˜๊ณ , ๋” ๋‚˜์€ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ๋˜๋Š” ๊ณผ์ •์ด์•ผ. ๋ฒ„๊ทธ๋ฅผ ๋งŒ๋‚˜๋ฉด ์ขŒ์ ˆํ•˜์ง€ ๋ง๊ณ , ์˜คํžˆ๋ ค ๋ฐฐ์šธ ๊ธฐํšŒ๋ผ๊ณ  ์ƒ๊ฐํ•ด! ๐ŸŒŸ

๐ŸŽ“ ์ตœ์ข… ์กฐ์–ธ: ๋””๋ฒ„๊น… ๋„๊ตฌ๋“ค์„ ๋ฐฐ์šฐ๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์€ ์ง์ ‘ ์‚ฌ์šฉํ•ด๋ณด๋Š” ๊ฑฐ์•ผ. ์ž‘์€ ํ”„๋กœ๊ทธ๋žจ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์„œ ์˜๋„์ ์œผ๋กœ ๋ฒ„๊ทธ๋ฅผ ๋งŒ๋“ค์–ด๋ณด๊ณ , ๊ทธ๊ฑธ ์ฐพ์•„๋‚ด๋Š” ์—ฐ์Šต์„ ํ•ด๋ด. ์ฒ˜์Œ์—๋Š” ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๊ฒ ์ง€๋งŒ, ์ ์  ๋นจ๋ผ์ง€๊ณ  ์ž์—ฐ์Šค๋Ÿฌ์›Œ์งˆ ๊ฑฐ์•ผ. ๊ทธ๋ฆฌ๊ณ  ๋ง‰ํžˆ๋Š” ๋ถ€๋ถ„์ด ์žˆ์œผ๋ฉด ์ฃผ์ €ํ•˜์ง€ ๋ง๊ณ  ์ปค๋ฎค๋‹ˆํ‹ฐ๋‚˜ ์žฌ๋Šฅ๋„ท ๊ฐ™์€ ํ”Œ๋žซํผ์—์„œ ๋„์›€์„ ๊ตฌํ•ด. ํ•จ๊ป˜ ๋ฐฐ์šฐ๊ณ  ์„ฑ์žฅํ•˜๋Š” ๊ฒŒ ๊ฐ€์žฅ ํšจ๊ณผ์ ์ด๋‹ˆ๊นŒ! ๐Ÿ’ช

๊ธฐ์–ตํ•ด, ๋ชจ๋“  ํ›Œ๋ฅญํ•œ ํ”„๋กœ๊ทธ๋ž˜๋จธ๋“ค๋„ ์ฒ˜์Œ์—๋Š” ์ดˆ๋ณด์˜€๊ณ , ์ˆ˜๋งŽ์€ ๋ฒ„๊ทธ์™€ ์”จ๋ฆ„ํ•˜๋ฉด์„œ ์„ฑ์žฅํ–ˆ์–ด. ๋„ˆ๋„ ์ถฉ๋ถ„ํžˆ ํ•  ์ˆ˜ ์žˆ์–ด! GDB์™€ Valgrind๋ฅผ ๋งˆ์Šคํ„ฐํ•˜๋ฉด C์–ธ์–ด ๊ฐœ๋ฐœ์ด ํ›จ์”ฌ ์ฆ๊ฑฐ์›Œ์งˆ ๊ฑฐ์•ผ. ํ™”์ดํŒ…! ๐Ÿš€

๋””๋ฒ„๊น… ๋งˆ์Šคํ„ฐ๋กœ์˜ ์—ฌ์ • ๐Ÿ“š ํ•™์Šต ๐Ÿ”ง ์‹ค์Šต ๐Ÿ› ๋ฒ„๊ทธ ํ•ด๊ฒฐ ๐Ÿ’ช ์„ฑ์žฅ ๐Ÿ† ๋งˆ์Šคํ„ฐ

์ด์ œ ๋„ˆ๋Š” C์–ธ์–ด ๋””๋ฒ„๊น…์˜ ํ•ต์‹ฌ ๋„๊ตฌ๋“ค์„ ์•Œ๊ฒŒ ๋˜์—ˆ์–ด. GDB๋กœ ํ”„๋กœ๊ทธ๋žจ์˜ ์‹คํ–‰์„ ์ถ”์ ํ•˜๊ณ , Valgrind๋กœ ๋ฉ”๋ชจ๋ฆฌ ์˜ค๋ฅ˜๋ฅผ ์ฐพ์•„๋‚ด๊ณ , ๋‹ค์–‘ํ•œ ๋””๋ฒ„๊น… ๊ธฐ๋ฒ•์œผ๋กœ ๋ณต์žกํ•œ ๋ฒ„๊ทธ๋„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์ง€. ์ด ์ง€์‹์„ ๋ฐ”ํƒ•์œผ๋กœ ๋” ์•ˆ์ •์ ์ด๊ณ  ํšจ์œจ์ ์ธ ํ”„๋กœ๊ทธ๋žจ์„ ๋งŒ๋“ค์–ด๋ด! ๐ŸŽ‰

ํ–‰๋ณตํ•œ ์ฝ”๋”ฉ, ๊ทธ๋ฆฌ๊ณ  ์„ฑ๊ณต์ ์ธ ๋””๋ฒ„๊น… ๋˜๊ธธ ๋ฐ”๋ผ! ๐Ÿ˜Šโœจ

๋Œ“๊ธ€ ์ž‘์„ฑ

์ด ๊ธ€์— ๋Œ€ํ•œ ์—ฌ๋Ÿฌ๋ถ„์˜ ์ƒ๊ฐ์„ ๋“ค๋ ค์ฃผ์„ธ์š”

๋Œ“๊ธ€ 0
๋Œ“๊ธ€์„ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘์ž…๋‹ˆ๋‹ค.

์•„์ง ๋Œ“๊ธ€์ด ์—†์Šต๋‹ˆ๋‹ค.