간단한 사용법
$ valgrind --leak-resolution=high --trace-malloc=yes --leak-check=yes --show-reachable=yes -v [프로그램 전체 경로]
$ valgrind --leak-resolution=high --leak-check=yes --show-reachable=yes -v [프로그램 전체 경로]
$ valgrind --db-attach=yes --leak-resolution=high --leak-check=yes --show-reachable=yes -v ./test_hanl
실행이 끝난 다음에 malloc/free 된 메모리들에 대한 현황을 ERROR SUMMARY라는 이름으로 알려줍니다. leak된 것들이 있다면 어떤 종류이고 어떤 내용이 들어있는지 등등을 자세히 알려주니 그것을 보시면 디버깅이 손쉬울 겁니다. 혹 출력되는 메시지가 너무 많아 방해가 되면 valgrind --trace-malloc=yes 를 빼주셔도 이 경우에는 별 상관 없을겁니다. malloc/free 될때마다 뿌려주는 메시지를 출력안하는 것입니다.
만약 한번의 alloc에 대해 두번의 free가 가해졌다면 아래와 같은 메시지가 그 위치를 알려줍니다. 보시다시피 main.c의 52번째줄에서 이미 free한 메모리 블럭에 대해 main.c의 53번째줄에서 잘못된 free를 수행한 걸로 나옵니다.
ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) ==29279== ==29279== 1 errors in context 1 of 1: ==29279== Invalid free() / delete / delete[] ==29279== at 0x40025E87: free (in /usr/lib/valgrind/vgskin_memcheck.so) ==29279== by 0x80489C3: main (main.c:53) ==29279== by 0x4024190A: __libc_start_main (in /lib/libc-2.3.2.so) ==29279== by 0x80488E0: (within /home/youlsa/src/montgomery/actiontag) ==29279== Address 0x4109C024 is 0 bytes inside a block of size 200 free'd ==29279== at 0x40025E87: free (in /usr/lib/valgrind/vgskin_memcheck.so) ==29279== by 0x80489B2: main (main.c:52) ==29279== by 0x4024190A: __libc_start_main (in /lib/libc-2.3.2.so) ==29279== by 0x80488E0: (within /home/youlsa/src/montgomery/actiontag) ==29279== IN SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Advanced using of valgrind
1. 우선 소스를 -g 옵션으로 컴파일 할것을 추천한다.
- 안해도 에러를 잡을수 있으나, 보다 정확하고 이해하기 쉬운 에러 레포트를 뽑을 수 있다.
- 컴파일할때 optimization level 이 02 또는 그 이상일때 Memcheck가 오동작 할수 있다.
-0 옵션을 쓸 것을 제안한다. 옵티마이즈도 하면서 오동작 가능성을 최대한 줄일수 있다.
Meanning of Error code
- Invalid read of size 4
- 잘못된 메모리 번지를 가르킬때 발생한다. 주로 파라미터의 범위를 검사하지 않았을때 프로그래머가 의도하지 않은 인덱스가 넘어와 발생한다.
- 모든 인덱스의 범위를 체크하는건 상당히 귀찮은 일이다. 그러나 그것때문에 디버깅하는건 몇백배 귀찮은 일이다.
- 잘못된 메모리 번지를 가르킬때 발생한다. 주로 파라미터의 범위를 검사하지 않았을때 프로그래머가 의도하지 않은 인덱스가 넘어와 발생한다.
- Conditional jump or move depends on uninitialised value(s)
- 변수 초기화 없이 사용되는 경우, 경우에 따라 문제가 되지 않을 수도 있지만 초기화하지 않은 변수로 배열을 접근할 경우 발생할수 있다.
- 변수 초기화 없이 사용되는 경우, 경우에 따라 문제가 되지 않을 수도 있지만 초기화하지 않은 변수로 배열을 접근할 경우 발생할수 있다.
uninitialised value of size 4
#define TEST "TEST" int main() { int i; char buffer[1024]; printf("%c\n",buffer[i]); }
==16814== Use of uninitialised value of size 4 ==16814== at 0x8048393: main (test.c:11) ==16814== ==16814== Invalid read of size 1 ==16814== at 0x8048393: main (test.c:11) ==16814== Address 0xBF3FB5A4 is not stack'd, malloc'd or (recently) free'd ==16814== ==16814== Process terminating with default action of signal 11 (SIGSEGV): dumping core ==16814== Access not within mapped region at address 0xBF3FB5A4 ==16814== at 0x8048393: main (test.c:11) ==16814== ==16814== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 14 from 1) ==16814== malloc/free: in use at exit: 0 bytes in 0 blocks. ==16814== malloc/free: 0 allocs, 0 frees, 0 bytes allocated. ==16814== For counts of detected errors, rerun with: -v ==16814== No malloc'd blocks -- no leaks are possible.
Conditional jump or move depends on uninitialised value
int main() { int i = 1; char buffer[1024]; printf("%s\n",&buffer[i]); }