Linuxias
Developer's Delight
Linuxias
  • Category
    • AI
      • Deep Learning
      • Machine Learning
      • Data Science
      • Framework
      • MLOps
      • Paper-Review
      • Tips
    • Android
      • Kotlin
      • Component
      • Compose
      • Compose UI
      • Material
      • Testing
    • Software Architecture
      • Architecture Pattern
      • Design Pattern
      • Requirement Engineering
    • Linux
      • Compile & Link
      • Command & Tool
      • Container
      • Debugging & Testing
      • Profiling
      • Kernel Analysis
      • Server
      • Shell Script
      • System Programming
    • Language
      • Carbon
      • C,C++
      • C#
      • Java
      • Python
    • ETC
      • Data Struct | Algorithm
      • git
      • Security
    • Book
    • 경제공부
      • 세금
      • 부동산
hELLO · Designed By 정상우.
Linuxias

Developer's Delight

[valgrind] Memory debugging & profiling tool
Linux/Debugging & Testing

[valgrind] Memory debugging & profiling tool

2018. 7. 26. 16:16
반응형
Valgrind는 리눅스 실행파일(excutable)을 디버깅하고 프로파일링할 수 있는 툴입니다. 오픈소스이며 C/C++ 로 작성된 프로그램을 디버깅하는데 매우 유용하죠. 간단한 사용법과 몇 가지 기초적인 옵션에 대해 설명드리고자 합니다.

1.  설치
$ sudo apt install valgrind
$ sudo apt install massif-visualizer





2. 예제 프로그램

valgrind를 이용해 프로파일링 하기 전에 예제 프로그램을 하나 작성하였습니다. 코드는 아래와 같습니다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <stdio.h>
#include <stdlib.h>
int test1()
{
 // 메모리 할당 및 해제 
    int *m;
    m = (int *)malloc(sizeof(int));
    free(m);
}
int test2()
{
 // 메모리 Leak
    int *m;
    m = (int *)malloc(sizeof(int));
}
int test3()
{
 // 메모리 Leak
    int *m[10];
    for (int i = 0; i < 10; i++)
        m[i] = (int *)malloc(sizeof(int));
    for (int i = 0; i < 5; i++)
        free(m[i]);
}
int test4()
{
 // 할당되지 않은 메모리 해제
    int *m;
    free(m);
}
int test5()
{
 // Double free 문제
    int *m;
    m = (int *)malloc(sizeof(int));
    free(m);
    free(m);
}
int test6()
{
 // 초기화 되지 않은 변수 사용
    int x;
    if( x == 3 )
        return 0;
}
int main(int argc, char *argv[])
{
    test1();
    test2();
    test3();
    test4();
    test5();
    test6();
    return 0;
}
Colored by Color Scripter
cs




3. valgrind memcheck

위에서 작성한 코드를 기반으로 아래와 같이 valgrind를 이용해 프로파일링 해 보았습니다. --leak-check 옵션과 --tool , 그리고 파일로 저장하기 위한 --log-file 옵션을 사용하였습니다.


$ valgrind --leak-check=full --tool=memcheck --log-file=valgrind.log ./{example}
$ cat valgrind.log
==30517== Memcheck, a memory error detector
==30517== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==30517== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==30517== Command: ./file_test
==30517== Parent PID: 30177
==30517== 
==30517== Conditional jump or move depends on uninitialised value(s)
==30517==    at 0x4C2EDA1: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==30517==    by 0x400A88: test4 (main.c:33)
==30517==    by 0x400B2E: main (main.c:60)
==30517== 
==30517== Invalid free() / delete / delete[] / realloc()
==30517==    at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==30517==    by 0x400A88: test4 (main.c:33)
==30517==    by 0x400B2E: main (main.c:60)
==30517==  Address 0xbfdaca3afdd85a00 is not stack'd, malloc'd or (recently) free'd
==30517== 
==30517== Invalid free() / delete / delete[] / realloc()
==30517==    at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==30517==    by 0x400AC5: test5 (main.c:42)
==30517==    by 0x400B38: main (main.c:61)
==30517==  Address 0x5204840 is 0 bytes inside a block of size 4 free'd
==30517==    at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==30517==    by 0x400AB9: test5 (main.c:41)
==30517==    by 0x400B38: main (main.c:61)
==30517==  Block was alloc'd at
==30517==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==30517==    by 0x400AA9: test5 (main.c:40)
==30517==    by 0x400B38: main (main.c:61)
==30517== 
==30517== Conditional jump or move depends on uninitialised value(s)
==30517==    at 0x400AE1: test6 (main.c:49)
==30517==    by 0x400B42: main (main.c:62)
==30517== 
==30517== 
==30517== HEAP SUMMARY:
==30517==     in use at exit: 24 bytes in 6 blocks
==30517==   total heap usage: 14 allocs, 10 frees, 1,076 bytes allocated
==30517== 
==30517== 4 bytes in 1 blocks are definitely lost in loss record 1 of 2
==30517==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==30517==    by 0x4009D8: test2 (main.c:15)
==30517==    by 0x400B1A: main (main.c:58)
==30517== 
==30517== 20 bytes in 5 blocks are definitely lost in loss record 2 of 2
==30517==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==30517==    by 0x400A15: test3 (main.c:24)
==30517==    by 0x400B24: main (main.c:59)
==30517== 
==30517== LEAK SUMMARY:
==30517==    definitely lost: 24 bytes in 6 blocks
==30517==    indirectly lost: 0 bytes in 0 blocks
==30517==      possibly lost: 0 bytes in 0 blocks
==30517==    still reachable: 0 bytes in 0 blocks
==30517==         suppressed: 0 bytes in 0 blocks
==30517== 
==30517== For counts of detected and suppressed errors, rerun with: -v
==30517== Use --track-origins=yes to see where uninitialised values come from
==30517== ERROR SUMMARY: 6 errors from 6 contexts (suppressed: 0 from 0)
cs




4. massif-visualizer

Text 기반으로 작성된 결과를 보는것도 좋지만 결과가 굉장히 많을 땐 정리하기 쉽지 않습니다. 이런 경우를 위해 massif-visualizer를 이용합니다. massif는 위 예제 코드를 사용하지 않고, 더 많은 memory leak을 발생시키는 예제를 사용하였습니다. --tool 옵션에 massif를 입력하고 실행합니다. 그럼 아래와 같이 massif.out.{PID} 이름으로 파일이 생성됩니다.


$ valgrind --tool=massif ./{example}
==31010== Massif, a heap profiler
==31010== Copyright (C) 2003-2015, and GNU GPL'd, by Nicholas Nethercote
==31010== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==31010== Command: ./file_test
==31010== 
$ ls massif.*
massif.out.31010 
$massif-visualizer massif.out.31010
Colored by Color Scripter
cs


파일을 massif-visualizer를 이용해 오픈하면 아래와 같은 결과를 볼 수 있습니다. 좌측의 그래프는 시간에 따른 메모리 사용량 증가율이고 오른쪽은 상세 결과입니다. ^^




추가적인 옵션들은 지속적으로 정리해서 올려야 할 것 같습니다. 감사합니다.

반응형
저작자표시 (새창열림)

'Linux > Debugging & Testing' 카테고리의 다른 글

[gdb] The GNU Debugger : 1. Introduction  (2) 2018.08.13
[SOLVE] valgrind: failed to start tool 'memcheck' for platform... ': No such file or directory  (0) 2018.07.27
/Proc FileSystem - Kernel  (0) 2018.04.10
/Proc FileSystem - Process in More detail  (2) 2018.04.10
/Proc Filesystem - Process  (0) 2018.03.20
    'Linux/Debugging & Testing' 카테고리의 다른 글
    • [gdb] The GNU Debugger : 1. Introduction
    • [SOLVE] valgrind: failed to start tool 'memcheck' for platform... ': No such file or directory
    • /Proc FileSystem - Kernel
    • /Proc FileSystem - Process in More detail
    Linuxias
    Linuxias
    I want to be a S/W developer who benefits people.

    티스토리툴바