Backend/C

Valgrind로 메모리 누수 체크하기!!

petitCoding 2011. 5. 13. 14:18

복잡한 프로그램을 개발하다보면,, 메모리 관리가 제대로 안될 때가 많다.
원래 malloc()해주고 free() 꼭 넣어주는게 정석이것만.. 진짜진짜 이게 잘 안된다..ㅋㅋ
그래서 프로그램이 죽기도 하고, 메모리 사용량이 계속 늘어나기도 하고, 프로그램을 죽였는데도
메모리 사용량이 줄어들지 않을 때도 있다.

입사하고서 그런 버그를 잡을 수 있는 획기적인 툴을 발견했다.
바로바로 Valgrind!!
지금까지 꾸준히 사용하고 있는 완소 툴이다 ♡

리눅스에서 valgrind -h 또는 valgrind --help  쳐보면, 다음과 같은 설명이 나온다.
사용법은 간단함.

 >valgrind -h usage: valgrind [options] prog-and-args
 common user options for all Valgrind tools, with defaults in [ ]:
    --tool=<name>             use the Valgrind tool named <name> [memcheck]
    -h --help                 show this message
    --help-debug              show this message, plus debugging options
    --version                 show version
    -q --quiet                run silently; only print error msgs
    -v --verbose              be more verbose, incl counts of errors
    --trace-children=no|yes   Valgrind-ise child processes? [no]
    --track-fds=no|yes        track open file descriptors? [no]
    --time-stamp=no|yes       add timestamps to log messages? [no]
    --log-fd=<number>         log messages to file descriptor [2=stderr]
    --log-file=<file>         log messages to <file>.<pid>
    --log-file-exactly=<file> log messages to <file>
    --log-file-qualifier=<VAR> incorporate $VAR in logfile name [none]
    --log-socket=ipaddr:port  log messages to socket ipaddr:port

  uncommon user options for all Valgrind tools:


    --run-libc-freeres=no|yes free up glibc memory at exit? [yes]
    --sim-hints=hint1,hint2,...  known hints:
                                 lax-ioctls, enable-outer [none]
    --show-emwarns=no|yes     show warnings about emulation limits? [no]
    --smc-check=none|stack|all  checks for self-modifying code: none,
                              only for code found in stacks, or all [stack]
    --kernel-variant=variant1,variant2,...  known variants: bproc [none]
                              handle non-standard kernel variants
  user options for Valgrind tools that report errors:
    --xml=yes                 all output is in XML (some tools only)
    --xml-user-comment=STR    copy STR verbatim to XML output
    --demangle=no|yes         automatically demangle C++ names? [yes]
    --num-callers=<number>    show <number> callers in stack traces [12]
    --error-limit=no|yes      stop showing new errors if too many? [yes]
    --error-exitcode=<number> exit code to return if errors found [0=disable]
    --show-below-main=no|yes  continue stack traces below main() [no]
    --suppressions=<filename> suppress errors described in <filename>
    --gen-suppressions=no|yes|all    print suppressions for errors? [no]
    --db-attach=no|yes        start debugger when errors detected? [no]
    --db-command=<command>    command to start debugger [gdb -nw %f %p]
    --input-fd=<number>       file descriptor for input [0=stdin]
    --max-stackframe=<number> assume stack switch for SP changes larger
                              than <number> bytes [2000000]
  user options for Memcheck:
    --leak-check=no|summary|full     search for memory leaks at exit?  [summary]
    --leak-resolution=low|med|high   how much bt merging in leak check [low]
    --show-reachable=no|yes          show reachable blocks in leak check? [no]
    --undef-value-errors=no|yes      check for undefined value errors [yes]
    --partial-loads-ok=no|yes        too hard to explain here; see manual [no]
    --freelist-vol=<number>          volume of freed blocks queue [5000000]
    --workaround-gcc296-bugs=no|yes  self explanatory [no]
    --alignment=<number>      set minimum alignment of allocations [8]
 ......이하생략

 


노랑색 하이라이트된것은 내가 자주 사용하는 애들..ㅎㅎㅎ

보통 다음과 같이 사용한다.

valgrind  프로그램 --tool=memcheck --leak-check=yes --show-reachable=yes --log-file="./valgrind_log


사용 예를 한번..들어보자면 

간단한 test 프로그램 작성 (메모리 누수 발생시킴)

 

#include <stdio.h>
#include <stdlib.h>
typedef struct _test_t {
    int data;
}test_t;
int main(void)
{
    test_t *test;
    test = malloc(sizeof(test_t));
    test->data = 3;
    printf("test->data = %d\n", test->data);

    return 0;
}


한눈에 봐도 메모리 누수가 일어날 것을 알수 있다...(free안했음)

valgrind 를  실행시키면, 

 valgrind ./test --tool=memcheck --leak-check=summary
==19358== Memcheck, a memory error detector.
==19358== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==19358== Using LibVEX rev 1732, a library for dynamic binary translation.
==19358== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==19358== Using valgrind-3.2.3, a dynamic binary instrumentation framework.
==19358== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==19358== For more details, rerun with: -v
==19358==
test->data = 3
==19358==
==19358== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 13 from 1)
==19358== malloc/free: in use at exit: 4 bytes in 1 blocks.
==19358== malloc/free: 1 allocs, 0 frees, 4 bytes allocated.
==19358== For counts of detected errors, rerun with: -v
==19358== searching for pointers to 1 not-freed blocks.
==19358== checked 48,380 bytes.
==19358==
==19358== LEAK SUMMARY:
==19358==    definitely lost: 4 bytes in 1 blocks.
==19358==      possibly lost: 0 bytes in 0 blocks.
==19358==    still reachable: 0 bytes in 0 blocks.
==19358==         suppressed: 0 bytes in 0 blocks.
==19358== Rerun with --leak-check=full to see details of leaked memory.

 

 라고 메모리 누수가 발생했음을 알려준다.
다시 free 루틴을 넣고 컴파일 한다음 valgrind를 돌리게 되면

 [root@lkalove]# valgrind ./test --tool=memcheck --leak-check=summary
==19427== Memcheck, a memory error detector.
==19427== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==19427== Using LibVEX rev 1732, a library for dynamic binary translation.

==19427== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==19427== Using valgrind-3.2.3, a dynamic binary instrumentation framework.
==19427== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==19427== For more details, rerun with: -v
==19427==
test->data = 3
==19427==
==19427== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 13 from 1)
==19427== malloc/free: in use at exit: 0 bytes in 0 blocks.
==19427== malloc/free: 1 allocs, 1 frees, 4 bytes allocated.
==19427== For counts of detected errors, rerun with: -v
==19427== All heap blocks were freed -- no leaks are possible.



다음과 같이 모든 메모리가 정상적으로  free되었고 메모리 누수가 없음을 알려준다!!

정말 좋은 툴




 

 

반응형

'Backend > C' 카테고리의 다른 글

valgrind  (0) 2011.05.26
gprof  (0) 2011.05.26
GDB  (0) 2011.05.26
memset()을 이용하여 메모리를 채워보자  (0) 2011.05.20
memcpy()를 이용한 메모리 카피!  (0) 2011.05.20