1

I have a program I wrote whose memory footprint grows over time. It eventually consumes all of the available system memory and then crashes the system.

I am trying to determine the source of what seems like a memory leak. I have run Valgrind on the code. It reports no definitely or indirectly lost memory. It does list possibly lost memory but without a lot of clarity. I could use some suggestions on how to track down this issue.

==13049== HEAP SUMMARY:
==13049==     in use at exit: 2,240,095 bytes in 3,720 blocks
==13049==   total heap usage: 50,296 allocs, 46,576 frees, 768,607,751 bytes allocated
==13049==
==13049== Searching for pointers to 3,720 not-freed blocks
==13049== Checked 56,807,736 bytes
==13049==
==13049== Thread 1:
==13049== 64 bytes in 4 blocks are possibly lost in loss record 1 of 11
==13049==    at 0x4844F70: malloc (in /usr/lib/valgrind/vgpreload_memcheck-arm64-linux.so)
==13049==
{
   <insert_a_suppression_name_here>
   Memcheck:Leak
   match-leak-kinds: possible
   fun:malloc
}
==13049== 184 bytes in 1 blocks are possibly lost in loss record 2 of 11
==13049==    at 0x48472C4: realloc (in /usr/lib/valgrind/vgpreload_memcheck-arm64-linux.so)
==13049==
{
   <insert_a_suppression_name_here>
   Memcheck:Leak
   match-leak-kinds: possible
   fun:realloc
}
==13049== 520 bytes in 20 blocks are possibly lost in loss record 3 of 11
==13049==    at 0x48473FC: memalign (in /usr/lib/valgrind/vgpreload_memcheck-arm64-linux.so)
==13049==
{
   <insert_a_suppression_name_here>
   Memcheck:Leak
   match-leak-kinds: possible
   fun:memalign
}
==13049== 643 bytes in 11 blocks are still reachable in loss record 4 of 11
==13049==    at 0x4845DFC: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-arm64-linux.so)
==13049==
{
   <insert_a_suppression_name_here>
   Memcheck:Leak
   match-leak-kinds: reachable
   fun:_Znam
}
==13049== 944 bytes in 47 blocks are still reachable in loss record 5 of 11
==13049==    at 0x4844F70: malloc (in /usr/lib/valgrind/vgpreload_memcheck-arm64-linux.so)
==13049==
{
   <insert_a_suppression_name_here>
   Memcheck:Leak
   match-leak-kinds: reachable
   fun:malloc
}
==13049== 3,408 bytes in 19 blocks are possibly lost in loss record 6 of 11
==13049==    at 0x48470CC: calloc (in /usr/lib/valgrind/vgpreload_memcheck-arm64-linux.so)
==13049==
{
   <insert_a_suppression_name_here>
   Memcheck:Leak
   match-leak-kinds: possible
   fun:calloc
}
==13049== 5,056 bytes in 7 blocks are still reachable in loss record 7 of 11
==13049==    at 0x48472C4: realloc (in /usr/lib/valgrind/vgpreload_memcheck-arm64-linux.so)
==13049==
{
   <insert_a_suppression_name_here>
   Memcheck:Leak
   match-leak-kinds: reachable
   fun:realloc
}
==13049== 37,304 bytes in 185 blocks are still reachable in loss record 8 of 11
==13049==    at 0x48470CC: calloc (in /usr/lib/valgrind/vgpreload_memcheck-arm64-linux.so)
==13049==
{
   <insert_a_suppression_name_here>
   Memcheck:Leak
   match-leak-kinds: reachable
   fun:calloc
}
==13049== 97,782 bytes in 1,739 blocks are still reachable in loss record 9 of 11
==13049==    at 0x48456C8: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-arm64-linux.so)
==13049==
{
   <insert_a_suppression_name_here>
   Memcheck:Leak
   match-leak-kinds: reachable
   fun:_Znwm
}
==13049== 124,585 bytes in 1,666 blocks are still reachable in loss record 10 of 11
==13049==    at 0x4845040: malloc (in /usr/lib/valgrind/vgpreload_memcheck-arm64-linux.so)
==13049==
{
   <insert_a_suppression_name_here>
   Memcheck:Leak
   match-leak-kinds: reachable
   fun:malloc
}
==13049== 1,969,605 bytes in 21 blocks are still reachable in loss record 11 of 11
==13049==    at 0x48473FC: memalign (in /usr/lib/valgrind/vgpreload_memcheck-arm64-linux.so)
==13049==
{
   <insert_a_suppression_name_here>
   Memcheck:Leak
   match-leak-kinds: reachable
   fun:memalign
}
==13049== LEAK SUMMARY:
==13049==    definitely lost: 0 bytes in 0 blocks
==13049==    indirectly lost: 0 bytes in 0 blocks
==13049==      possibly lost: 4,176 bytes in 44 blocks
==13049==    still reachable: 2,235,919 bytes in 3,676 blocks
==13049==                       of which reachable via heuristic:
==13049==                         newarray           : 1,536 bytes in 16 blocks
==13049==         suppressed: 0 bytes in 0 blocks

Valgrind was called with:

valgrind --child-silent-after-fork=yes --smc-check=stack --tool=memcheck --gen-suppressions=all --track-origins=yes --leak-check=full --num-callers=500 --leak-check=full --show-leak-kinds=all -v --show-reachable=yes /opt/fsoapp/bin/fsoapp

  • Generally, you want to increase the traceback and show where it's assigned. – o11c May 14 '19 at 01:20
  • The fact you have so much memory still reachable means you don't have a leak in the normal sense of the word. You are just using a lot of memory. You need to look at your program and see what stuff you are able to discard to reduce your memory footprint. – John3136 May 14 '19 at 01:26
  • @o11c, I already have --num-callers=500 so I should be seeing everything Valgrind is willing to show me. – black_spot1984 May 14 '19 at 01:36
  • 1
    Have you built with debug symbols turned on? – Stephen Newell May 14 '19 at 01:37
  • @John3136 I have looked over my code (It's not even that much code) and I do not see a place where I am repeatedly dynamically allocating memory. I'm trying to use Valgrind to help me uncover where all the memory is being allocated. Is there a better approach? – black_spot1984 May 14 '19 at 01:38
  • This is the output with debug symbols turned on. – black_spot1984 May 14 '19 at 01:41
  • 1
    You could have a hoarder grabbing more and more memory and running you out without leaving any obvious traces because on destruction it does give back all of its allocated memory. Then when the program exits and Valgrind does it's counting, everything is groovy. – user4581301 May 14 '19 at 01:59

1 Answers1

2

Use the options

   --leak-check=full --show-leak-kinds=all

to obtain the list of still reachable memory when your program terminates.

You can also interactively search for leaks using gdb+vgdb and valgrind. See http://www.valgrind.org/docs/manual/mc-manual.html#mc-manual.monitor-commands

In particular, the monitor commands 'block_list' and 'who_points_at' can help finding where the memory is being kept.

phd
  • 3,669
  • 1
  • 11
  • 12