Page 1 of 1

Detect memory leak using valgrind

Posted: Sun Mar 25, 2018 5:11 am
by danilocoelho
I'm trying detect memory leak in an console app running on linux.

I'm using PureBasic 5.62 (Linux - x64) in this case.

However, valgrind generate lot information.
Inclusive some procedures of PureBasic.

So, i wrote a basic program that pass in valgrind.
Procedure main()
If OpenConsole()
PrintN("Basic program...")
CloseConsole()
EndIf
EndProcedure

main()
Compiled with debug symbols:

Code: Select all

./pbcompiler ~/workspace/gitlab/projetos_bin/console_basic.pb -ds -e ~/workspace/gitlab/projetos_bin/console_basic
Valgrind memory leak check:

Code: Select all

danilo@pc-linux-mint ~/workspace/gitlab/projetos_bin $ valgrind --leak-check=yes ./console_basic
==15467== Memcheck, a memory error detector
==15467== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==15467== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==15467== Command: ./console_basic
==15467== 
Basic program...
==15467== 
==15467== HEAP SUMMARY:
==15467==     in use at exit: 0 bytes in 0 blocks
==15467==   total heap usage: 30 allocs, 30 frees, 3,671 bytes allocated
==15467== 
==15467== All heap blocks were freed -- no leaks are possible
==15467== 
==15467== For counts of detected and suppressed errors, rerun with: -v
==15467== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
So far, all right. But if you use these commands below, memory leaks happen.
  • * CountProgramParameters
    * UseLZMAPacker()

Code: Select all

UseLZMAPacker()

Procedure main()
  If OpenConsole()
    PrintN("Basic program...") 
    Protected count_prog_params = CountProgramParameters()
    PrintN("CountProgramParameters: " + Str(count_prog_params))
    CloseConsole()
  EndIf 
EndProcedure

main()
Valgrind memory leak check:

Code: Select all

danilo@pc-linux-mint ~/workspace/gitlab/projetos_bin $ valgrind --leak-check=yes ./console_basic
==15792== Memcheck, a memory error detector
==15792== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==15792== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==15792== Command: ./console_basic
==15792== 
Basic program...
CountProgramParameters: 0
==15792== 
==15792== HEAP SUMMARY:
==15792==     in use at exit: 216 bytes in 3 blocks
==15792==   total heap usage: 33 allocs, 30 frees, 20,282 bytes allocated
==15792== 
==15792== 16 bytes in 1 blocks are possibly lost in loss record 1 of 3
==15792==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==15792==    by 0x424C1D: SYS_AllocateMemory (in /home/danilo/workspace/gitlab/projetos_bin/console_basic)
==15792==    by 0x424CCC: SYS_AllocateMemoryWithSize (in /home/danilo/workspace/gitlab/projetos_bin/console_basic)
==15792==    by 0x4040F0: PB_Object_InitThreadMemory (in /home/danilo/workspace/gitlab/projetos_bin/console_basic)
==15792==    by 0x4032C2: PB_InitProcess (in /home/danilo/workspace/gitlab/projetos_bin/console_basic)
==15792==    by 0x40302B: ??? (in /home/danilo/workspace/gitlab/projetos_bin/console_basic)
==15792==    by 0x424ABF: ??? (in /home/danilo/workspace/gitlab/projetos_bin/console_basic)
==15792==    by 0x40205F: errmsg (in /home/danilo/workspace/gitlab/projetos_bin/console_basic)
==15792==    by 0xFFEFFF2FF: ???
==15792== 
==15792== 64 bytes in 1 blocks are possibly lost in loss record 2 of 3
==15792==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==15792==    by 0x424C1D: SYS_AllocateMemory (in /home/danilo/workspace/gitlab/projetos_bin/console_basic)
==15792==    by 0x424CCC: SYS_AllocateMemoryWithSize (in /home/danilo/workspace/gitlab/projetos_bin/console_basic)
==15792==    by 0x4042CC: PB_Object_Init (in /home/danilo/workspace/gitlab/projetos_bin/console_basic)
==15792==    by 0x403FE9: PB_InitPacker (in /home/danilo/workspace/gitlab/projetos_bin/console_basic)
==15792==    by 0x403026: ??? (in /home/danilo/workspace/gitlab/projetos_bin/console_basic)
==15792==    by 0x424ABF: ??? (in /home/danilo/workspace/gitlab/projetos_bin/console_basic)
==15792==    by 0x40205F: errmsg (in /home/danilo/workspace/gitlab/projetos_bin/console_basic)
==15792==    by 0xFFEFFF2FF: ???
==15792== 
==15792== 136 bytes in 1 blocks are possibly lost in loss record 3 of 3
==15792==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==15792==    by 0x424C1D: SYS_AllocateMemory (in /home/danilo/workspace/gitlab/projetos_bin/console_basic)
==15792==    by 0x424CCC: SYS_AllocateMemoryWithSize (in /home/danilo/workspace/gitlab/projetos_bin/console_basic)
==15792==    by 0x4042F2: PB_Object_Init (in /home/danilo/workspace/gitlab/projetos_bin/console_basic)
==15792==    by 0x403FE9: PB_InitPacker (in /home/danilo/workspace/gitlab/projetos_bin/console_basic)
==15792==    by 0x403026: ??? (in /home/danilo/workspace/gitlab/projetos_bin/console_basic)
==15792==    by 0x424ABF: ??? (in /home/danilo/workspace/gitlab/projetos_bin/console_basic)
==15792==    by 0x40205F: errmsg (in /home/danilo/workspace/gitlab/projetos_bin/console_basic)
==15792==    by 0xFFEFFF2FF: ???
==15792== 
==15792== LEAK SUMMARY:
==15792==    definitely lost: 0 bytes in 0 blocks
==15792==    indirectly lost: 0 bytes in 0 blocks
==15792==      possibly lost: 216 bytes in 3 blocks
==15792==    still reachable: 0 bytes in 0 blocks
==15792==         suppressed: 0 bytes in 0 blocks
==15792== 
==15792== For counts of detected and suppressed errors, rerun with: -v
==15792== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
I have a lot of source code to refactor / modularize, if I find more memory leak in PureBasic procedures, I'll add it here.
If someone in the user community can help by detecting more memory leaks, we can report it to the development team.

Thank you!

Re: Detect memory leak using valgrind

Posted: Sun Apr 01, 2018 10:23 pm
by danilocoelho
As I said before, I checked out more PureBasic commands with memory leak.
Many of the leaks are not as expressive in the amount of memory, but the valgrind detects all these errors and presents them.
This makes it difficult to track memory leaks in our own purebasic code.
Of course, the ideal would be to fix memory leaks, but I believe that some are not necessarily in the PureBasic code itself (eg memory leak isFont and isGadget).

Code: Select all

Procedure main()
  If OpenConsole()
    PrintN("Basic program...") 
    PrintN("IsDatabase: " + IsDatabase(1))
    PrintN("IsFile: " + IsFile(1))
    PrintN("IsFont: " + IsFont(1))
    PrintN("IsFTP: " + IsFTP(1))
    PrintN("IsGadget: " + IsGadget(1))
    PrintN("IsImage: " + IsImage(1))
    PrintN("IsJSON: " + IsJSON(1))
    PrintN("IsLibrary: " + IsLibrary(1))    
    PrintN("IsMail: " + IsMail(1))
    PrintN("IsRuntime: " + IsRuntime("test"))    
    PrintN("IsXML: " + IsXML(1))
    CloseConsole()
  EndIf 
EndProcedure

main()
Valgrind leak check generate a log file with 5595 lines:

Code: Select all

danilo@pc-linux-mint ~/workspace/gitlab/projetos_bin $ valgrind --log-file=r.txt --leak-check=yes ./console_basic 
Fortunately I found the memory leak in my console application. :D
After correcting the leak, I saw that the problem was neither a memory leak itself, but an excessive memory consumption.
The algorithm I did was consuming almost 1.5 GB of RAM.
The problem was that I was using a structured list with some maps that by default allocated 512 slots already in Map creation.