Detecting memory leaks

Memory management needs to be done carefully when an application is coded in C or C++, since it is the developer's responsibility to manage the memory. For this purpose, we are going to use a Linux-only tool called Valgrind. It can be used to detect memory leaks or generate profiling data, among many other useful sanity checks on the running code.

Firstly, the following section is a small tutorial on Valgrind where we will discuss using Valgrind with ZeroMQ.

Introduction to Valgrind

You could compile your program with the –g parameter to include debugging information. In that case, error messages will include exact line numbers. Using –O1 can result in inaccurate messages, and using –O2 or –O3 definitely results in inaccurate messages.

Consider the following example:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char const *argv[]) {

  char* a = malloc(4);
  int b;
  printf("b = %d
", b);

  return 0;
}

Let's compile with gcc –g –o test test.c. Now, it is time to run Valgrind to check for memory leaks. Let's run the following command:

valgrind --leak-check=full --show-reachable=yes test

Once we run the previous command, Valgrind will check for memory errors using the memcheck tool. You could specify it using tool=memcheck, but this would be pointless in this case since memcheck is the default tool. The output would be something similar to the following:

==98190== Conditional jump or move depends on uninitialised value(s)
==98190==    at 0x2D923: __vfprintf 
==98190==    by 0x4AC5A: vfprintf_l
==98190==    by 0x952BE: printf
==98190==    by 0x1F5E: main (test.c:8)

==98190== 4 bytes in 1 blocks are definitely lost in loss record 1 of 5
==98190==    at 0xF656: malloc (vg_replace_malloc.c:195)
==98190==    by 0x1F46: main (test.c:6)

==98190== LEAK SUMMARY:
==98190==    definitely lost: 4 bytes in 1 blocks
==98190==    indirectly lost: 0 bytes in 0 blocks
==98190==      possibly lost: 0 bytes in 0 blocks

Let's now describe the preceding output:

  • We could ignore 98190 since it is the process ID
  • Conditional jump or move depends on uninitialised value(s) means we have uninitialized variables in our code
  • definitely lost means there is a memory leak and we need to fix it
  • indirectly lost means the blocks that point to another block are lost
  • possibly lost means there is a memory leak, unless you really know what you are doing

By default, Valgrind uses $PREFIX/lib/valgrind/default.supp. However, we need to create our own suppression file to use with ZeroMQ, which would be something like the following:

{
   <socketcall_sendto>
   Memcheck:Param
   socketcall.sendto(msg)
   fun:send
   ...
}
{
   <socketcall_sendto>
   Memcheck:Param
   socketcall.send(msg)
   fun:send
   ...
}

Then you could run Valgrind with arguments similar to the following:

valgrind --leak-check=full --show-reachable=yes --suppressions=zeromq.supp server

Here we can say that running code under Valgrind has severe impacts on the performance and can introduce timeouts in some cases.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.208.183