Finding Memory Leak using Valgrind

Dah hampir tiga minggu ini gw stuck ama research gw gara-gara si “segmentation fault” d program gw. Program ini gw develop pertama kali d “Visual C++ 2008” nya Windows. Tapi, setelah gw selesei bikin smua class + function2nya yang penting2, pas gw compile bukannya jalan, eeh yang ada malahan gw-nya yang d maki2 ama si compilernya, “heap corruption detected at xxxxx”. Trus, gw cobain debug programnya tapi tetep aj dia corrupt. Stuck d windows gw cobain compile d Linux. Setelah gw compile, ini bukannya jalan juga yang ada malah gw makin d maki-maki ama tu compiler, haaahahahah, salahnya nambah lagi, stress .. . Lalu si gw coba nulis ulang codingannya sambil nyari-nyari article ama tutorial d si tempat om. Buat nyingkat waktu, yang gw cuman cari article tentang class, default constructor, copy constructor, overloading assignment operator, pointer, reference, dan array. Makin puyeng dah . Dah gw ubek-ubek tu internet, library, tetep aja masih belum ada pencerahan, program gw masih aj error. Ada satu article yang bilang, itu gara2 gw ngedelete 2 kali, tapi pas gw trace satu2 codingan gw, kaga ada tu perintah gw nge-delete dobel.

Debugging

Debugging

Segmetation Fault

Segmetation Fault

Akhirnya, setelah debuging satu2 yang ngga berhasil itu, si gw ngubek2 si om lagi. Kali ini ada orang yang bilang klo mo nyari memory leak problem sekalian d tunjukin d mana errornya itu pke tool namanya valgrind. Hohoho, langsung dah gw cobain tu program, cari d repo, langusng install. Pas udah ke install langsung gw uji coba. Ini cara makenya :

  1. Build dulu program yang akan d check
  2. Ketik perintah d bawah ini d ikuti dengan path program yang telah d build d langkah pertama, Contoh :masdel@masdel ~ $ valgrind -v --leak-check=full --tool=memcheck /home/masdel/Documents/MyConsApp/MyHull/bin/Debug/MyHull
  3. Cara nge-analisis-nya
    Berikut ini contoh output program gw :

    -- deleted --
    ==13275== 1 errors in context 39 of 42:
    ==13275== Invalid read of size 8
    ==13275==    at 0x80492AB: CPoint3D::CPoint3D(CPoint3D const&) (main.cpp:63)
    ==13275==    by 0x80498F9: RefineKnotVectCurve(int, int, int, double*, double*, CPoint3D*, CPoint3D*, double*) (main.cpp:495)
    ==13275==    by 0x804E011: main (main.cpp:1179)
    ==13275==  Address 0x42c60ec is 0 bytes after a block of size 196 alloc'd
    ==13275==    at 0x402630E: operator new[](unsigned int) (vg_replace_malloc.c:268)
    ==13275==    by 0x804D579: main (main.cpp:1093)
    ==13275==
    ==13275== 1 errors in context 40 of 42:
    ==13275== Invalid read of size 8
    ==13275==    at 0x804929F: CPoint3D::CPoint3D(CPoint3D const&) (main.cpp:62)
    ==13275==    by 0x80498F9: RefineKnotVectCurve(int, int, int, double*, double*, CPoint3D*, CPoint3D*, double*) (main.cpp:495)
    ==13275==    by 0x804E011: main (main.cpp:1179)
    ==13275==  Address 0x42c6104 is not stack'd, malloc'd or (recently) free'd
    ==13275==
    ==13275== 1 errors in context 41 of 42:
    ==13275== Invalid read of size 8
    ==13275==    at 0x8049293: CPoint3D::CPoint3D(CPoint3D const&) (main.cpp:61)
    ==13275==    by 0x80498F9: RefineKnotVectCurve(int, int, int, double*, double*, CPoint3D*, CPoint3D*, double*) (main.cpp:495)
    ==13275==    by 0x804E011: main (main.cpp:1179)
    ==13275==  Address 0x42c60fc is not stack'd, malloc'd or (recently) free'd
    ==13275==
    ==13275== 1 errors in context 42 of 42:
    ==13275== Invalid read of size 8
    ==13275==    at 0x8049287: CPoint3D::CPoint3D(CPoint3D const&) (main.cpp:60)
    ==13275==    by 0x80498F9: RefineKnotVectCurve(int, int, int, double*, double*, CPoint3D*, CPoint3D*, double*) (main.cpp:495)
    ==13275==    by 0x804E011: main (main.cpp:1179)
    ==13275==  Address 0x42c60f4 is 8 bytes after a block of size 196 alloc'd
    ==13275==    at 0x402630E: operator new[](unsigned int) (vg_replace_malloc.c:268)
    ==13275==    by 0x804D579: main (main.cpp:1093)
    --13275--
    --13275-- supp:     17 Debian libc6 (2.9.x) stripped dynamic linker
    ==13275==
    ==13275== IN SUMMARY: 42 errors from 42 contexts (suppressed: 17 from 1)
    ==13275==
    ==13275== malloc/free: in use at exit: 324 bytes in 1 blocks.
    ==13275== malloc/free: 13 allocs, 12 frees, 2,416 bytes allocated.
    ==13275==
    ==13275== searching for pointers to 1 not-freed blocks.
    ==13275== checked 96,444 bytes.
    ==13275==
    ==13275== 1 errors in context 39 of 42:
    ==13275== Invalid read of size 8
    ==13275==    at 0x80492AB: CPoint3D::CPoint3D(CPoint3D const&) (main.cpp:63)
    ==13275==    by 0x80498F9: RefineKnotVectCurve(int, int, int, double*, double*, CPoint3D*, CPoint3D*, double*) (main.cpp:495)
    ==13275==    by 0x804E011: main (main.cpp:1179)
    ==13275==  Address 0x42c60ec is 0 bytes after a block of size 196 alloc'd
    ==13275==    at 0x402630E: operator new[](unsigned int) (vg_replace_malloc.c:268)
    ==13275==    by 0x804D579: main (main.cpp:1093)
    ==13275==
    ==13275== 1 errors in context 40 of 42:
    ==13275== Invalid read of size 8
    ==13275==    at 0x804929F: CPoint3D::CPoint3D(CPoint3D const&) (main.cpp:62)
    ==13275==    by 0x80498F9: RefineKnotVectCurve(int, int, int, double*, double*, CPoint3D*, CPoint3D*, double*) (main.cpp:495)
    ==13275==    by 0x804E011: main (main.cpp:1179)
    ==13275==  Address 0x42c6104 is not stack'd, malloc'd or (recently) free'd
    ==13275==
    ==13275== 1 errors in context 41 of 42:
    ==13275== Invalid read of size 8
    ==13275==    at 0x8049293: CPoint3D::CPoint3D(CPoint3D const&) (main.cpp:61)
    ==13275==    by 0x80498F9: RefineKnotVectCurve(int, int, int, double*, double*, CPoint3D*, CPoint3D*, double*) (main.cpp:495)
    ==13275==    by 0x804E011: main (main.cpp:1179)
    ==13275==  Address 0x42c60fc is not stack'd, malloc'd or (recently) free'd
    ==13275==
    ==13275== 1 errors in context 42 of 42:
    ==13275== Invalid read of size 8
    ==13275==    at 0x8049287: CPoint3D::CPoint3D(CPoint3D const&) (main.cpp:60)
    ==13275==    by 0x80498F9: RefineKnotVectCurve(int, int, int, double*, double*, CPoint3D*, CPoint3D*, double*) (main.cpp:495)
    ==13275==    by 0x804E011: main (main.cpp:1179)
    ==13275==  Address 0x42c60f4 is 8 bytes after a block of size 196 alloc'd
    ==13275==    at 0x402630E: operator new[](unsigned int) (vg_replace_malloc.c:268)
    ==13275==    by 0x804D579: main (main.cpp:1093)--13275-- --13275-- supp:     17 Debian libc6 (2.9.x) stripped dynamic linker
    ==13275==
    ==13275== IN SUMMARY: 42 errors from 42 contexts (suppressed: 17 from 1)
    ==13275==
    ==13275== malloc/free: in use at exit: 324 bytes in 1 blocks.
    ==13275== malloc/free: 13 allocs, 12 frees, 2,416 bytes allocated.
    ==13275==
    ==13275== searching for pointers to 1 not-freed blocks.
    ==13275== checked 96,444 bytes.
    ==13275==
    -- deleted --


    Ambil salah satu part dari output d atas, d sni gw ambil line 02-10;

    ==13275== Invalid read of size 8
    ==13275== at 0x80492AB: CPoint3D::CPoint3D(CPoint3D const&)(main.cpp:63)
    ==13275== by 0x80498F9: RefineKnotVectCurve(int, int, int, double*, double*, CPoint3D*, CPoint3D*, double*) (main.cpp:495)
    ==13275== by 0x804E011: main (main.cpp:1179)
    ==13275== Address 0x42c60ec is 0 bytes after a block of size 196 alloc'd
    ==13275== at 0x402630E: operator new[](unsigned int) (vg_replace_malloc.c:268)
    ==13275== by 0x804D579: main (main.cpp:1093)


    Supaya jelas nge-analisisnya, d sni gw ambil yang bagian ini, misal:
    ==13275== at 0x80492AB: CPoint3D::CPoint3D(CPoint3D const&) (main.cpp:63)
    Ini artinya bahwa error ada d file main.cpp line 63 d address 0x80492AB, klo kita liat d atas CPoint3D::CPoint3D(CPoint3D const&) merupakan definisi dari copy constructor dari sebuah class. Jadi, gampangnya si valgrind ini mo bilang bahwa si definisi copy constructor salah. Namun, klo udah ngerasa bener liat baris setelahnya. Untuk contoh d atas baris setelahnya ialah :

    ==13275== by 0x80498F9: RefineKnotVectCurve(int, int, int, double*, double*, CPoint3D*, CPoint3D*, double*) (main.cpp:495)

    D sni d tunjukin klo errornya d function RefineKnotVectCurve d line 495, d line 495 gw tertulis :
    for (int j=b-1;j<=np;j++)
    {
    //int ii = j+r+1;
    //*(qw+ii) = *(pw+j);
    qw[j+r+1] = pw[j]; // Line 495
    }

    Keknya bener tu code, ngga ada yang aneh. Tapi setelah gw cek, ternyata eh ternyata si pw[j] ini ngakses nilai yang d luar range dia akhirnya error dah. Jadi, ketemu errornya d mana !! :D.

  4. Setelah gw benerin :
    Setelah d benerin

    Setelah d benerin

Itulah pengalaman gw, jadi yang punya masalah ama memory leak, gw rekomendasiin pake software ini dah, tapi sayang d windows kaga ada adanya cuman d Linux ama Mac OS. : )

Happy coding all : )

Leave a comment