Linux useful tool Valgrind(dynamic analysis). 02 Memcheck (leak)
Valgrind의 memcheck 기능 중 leak의 기능을 살펴보겠습니다.
이 기능은 heap메모리에 메모리 할당,메모리 해제을 분석합니다.
memory leak은 실행 시 '--leak-check' 옵션으로 추적할 수 있으며 기본 설정은 summry입니다.
* --leak-check=<no|summary|yes|full> [default: summary]
소스
빌드 및 실행
결과
아래와 같이 leak-check 옵션으로 레벨을 조정하면 메모리 누수 위치를 찾을 수 있습니다.
* debugging symbol이 같이 빌드되어야 합니다.
실행
이 기능은 heap메모리에 메모리 할당,메모리 해제을 분석합니다.
memory leak은 실행 시 '--leak-check' 옵션으로 추적할 수 있으며 기본 설정은 summry입니다.
* --leak-check=<no|summary|yes|full> [default: summary]
소스
빌드 및 실행
$ cc -o hello hello.c -g3 -O0
$ valgrind ./hello
|
결과
-bash-4.2$
valgrind ./hello
==31359== Memcheck, a memory error detector
==31359== Copyright (C) 2002-2013, and GNU GPL'd, by Julian
Seward et al.
==31359== Using Valgrind-3.9.0 and LibVEX; rerun with -h for
copyright info
==31359== Command: ./hello
==31359==
leak
==31359==
==31359== HEAP SUMMARY:
==31359== in use at exit: 10 bytes in 1
blocks
==31359== total heap usage: 1 allocs, 0 frees, 10
bytes allocated
==31359==
==31359== LEAK SUMMARY:
==31359== definitely
lost: 10 bytes in 1 blocks
==31359== indirectly lost: 0 bytes in 0 blocks
==31359== possibly lost: 0 bytes in 0 blocks
==31359== still reachable: 0 bytes in 0 blocks
==31359== suppressed: 0 bytes
in 0 blocks
==31359== Rerun with --leak-check=full to see details of leaked
memory
==31359==
==31359== For counts of detected and suppressed errors, rerun
with: -v
==31359== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2
from 2)
|
위와 같이 실행하면 메모리 누수는 확인이 되었는데 어디서 누수가 발생했는지 알수가 없습니다.
아래와 같이 leak-check 옵션으로 레벨을 조정하면 메모리 누수 위치를 찾을 수 있습니다.
* debugging symbol이 같이 빌드되어야 합니다.
실행
$
valgrind --leak-check=full ./hello
|
결과
샘플 코드에서는 definitely lost(명백한 누수)에 대한 예제입니다.
각 항목 별 누수의 경우는 아래와 같습니다.
Definitely lost(DL)는 3번 케이스와 같이 명확한 누수 경우 입니다.
Indirectly lost(IL)는 4,9번과 같이 root node가 손실되었고 이로 인해 하위에 있는 모든 블록이 손실된 경우 입니다.
Possibly lost는 5~8번과 같이 포인터 주소가 손실될 가능성이 있는 경우 입니다.
Still reachable는 1,2번의 경우 입니다. 일반적인 경우에는 문제가 되지 않습니다.
Possibly lost 예제.
-bash-4.2$
valgrind --leak-check=full ./hello
==31406== Memcheck, a memory error detector
==31406== Copyright (C) 2002-2013, and GNU GPL'd, by Julian
Seward et al.
==31406== Using Valgrind-3.9.0 and LibVEX; rerun with -h for
copyright info
==31406== Command: ./hello
==31406==
leak
==31406==
==31406== HEAP SUMMARY:
==31406== in use at exit: 10 bytes in 1
blocks
==31406== total heap usage: 1 allocs, 0 frees, 10
bytes allocated
==31406==
==31406== 10 bytes in 1 blocks are definitely lost in loss
record 1 of 1
==31406== at 0x4A0645D: malloc (in
/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==31406== by 0x400637:
main (hello.c:7)
==31406==
==31406== LEAK SUMMARY:
==31406== definitely lost: 10 bytes in 1 blocks
==31406== indirectly lost: 0 bytes in 0 blocks
==31406== possibly lost: 0 bytes in 0 blocks
==31406== still reachable: 0 bytes in 0 blocks
==31406== suppressed: 0 bytes
in 0 blocks
==31406==
==31406== For counts of detected and suppressed errors, rerun
with: -v
==31406== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2
from 2)
|
샘플 코드에서는 definitely lost(명백한 누수)에 대한 예제입니다.
각 항목 별 누수의 경우는 아래와 같습니다.
Pointer chain AAA Leak Case BBB Leak Case
------------- ------------- -------------
(1) RRR ------------> BBB DR
(2) RRR ---> AAA ---> BBB DR IR
(3) RRR BBB DL
(4) RRR AAA ---> BBB DL IL
(5) RRR ------?-----> BBB (y)DR, (n)DL
(6) RRR ---> AAA -?-> BBB DR (y)IR, (n)DL
(7) RRR -?-> AAA ---> BBB (y)DR, (n)DL (y)IR, (n)IL
(8) RRR -?-> AAA -?-> BBB (y)DR, (n)DL (y,y)IR, (n,y)IL, (_,n)DL
(9) RRR AAA -?-> BBB DL (y)IL, (n)DL
Pointer chain legend:
- RRR: a root set node or DR block
- AAA, BBB: heap blocks
- --->: a start-pointer
- -?->: an interior-pointer
Leak Case legend:
- DR: Directly reachable
- IR: Indirectly reachable
- DL: Directly lost
- IL: Indirectly lost
- (y)XY: it's XY if the interior-pointer is a real pointer
- (n)XY: it's XY if the interior-pointer is not a real pointer
- (_)XY: it's XY in either case
*참조 Valgrind manualDefinitely lost(DL)는 3번 케이스와 같이 명확한 누수 경우 입니다.
Indirectly lost(IL)는 4,9번과 같이 root node가 손실되었고 이로 인해 하위에 있는 모든 블록이 손실된 경우 입니다.
Possibly lost는 5~8번과 같이 포인터 주소가 손실될 가능성이 있는 경우 입니다.
Still reachable는 1,2번의 경우 입니다. 일반적인 경우에는 문제가 되지 않습니다.
Possibly lost 예제.
getline함수는 첫번째 인자에 메모리를 할당해 줍니다. 이 메모리는 종료 전에 free를 해야하는데 abort가 발생하여 포인터가 정상 위치로 돌아갈것이라는 것이 불분명하기 때문에 possible lost입니다.
유용한 옵션
--leak-check=<no|summary|yes|full> [default: summary]
--show-leak-kinds=<set> [default: definite,possible]
: definite,indirect,possible,reachable 또는 all 사용 가능
명령어 예제
valgrind --leak-check=full --show-leak-kinds=all --log-file="val.log" ./hello
-bash-4.2$ valgrind --leak-check=full --show-leak-kinds=all ./hello
==23840== Memcheck, a memory error detector
==23840== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==23840== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==23840== Command: ./hello
==23840==
input any : test
your input test
==23840==
==23840== HEAP SUMMARY:
==23840== in use at exit: 120 bytes in 1 blocks
==23840== total heap usage: 1 allocs, 0 frees, 120 bytes allocated
==23840==
==23840== 120 bytes in 1 blocks are possibly lost in loss record 1 of 1
==23840== at 0x4A0645D: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==23840== by 0x34CD46CDD4: getdelim (in /usr/lib64/libc-2.18.so)
==23840== by 0x4006FD: main (hello.c:10)
==23840==
==23840== LEAK SUMMARY:
==23840== definitely lost: 0 bytes in 0 blocks
==23840== indirectly lost: 0 bytes in 0 blocks
==23840== possibly lost: 120 bytes in 1 blocks
==23840== still reachable: 0 bytes in 0 blocks
==23840== suppressed: 0 bytes in 0 blocks
==23840==
==23840== For counts of detected and suppressed errors, rerun with: -v
==23840== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)
Aborted (core dumped)
-bash-4.2$
|
유용한 옵션
--leak-check=<no|summary|yes|full> [default: summary]
--show-leak-kinds=<set> [default: definite,possible]
: definite,indirect,possible,reachable 또는 all 사용 가능
명령어 예제
valgrind --leak-check=full --show-leak-kinds=all --log-file="val.log" ./hello
댓글
댓글 쓰기