| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] | 
gnatmem 
gnatmem, is a tool that monitors dynamic allocation and
deallocation activity in a program, and displays information about
incorrect deallocations and possible sources of memory leaks. Gnatmem
provides three type of information:
15.1 Running gnatmem15.2 Switches for gnatmem15.3 Example of gnatmemUsage15.4 Implementation note 
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] | 
gnatmem 
The gnatmem command has the form
$ gnatmem [n] [-o file] user_program [program_arg]* or $ gnatmem [n] -i file  | 
Gnatmem must be supplied with the executable to examine, followed by its run-time inputs. For example, if a program is executed with the command:
$ my_program arg1 arg2  | 
gnatmem control using the command:
$ gnatmem my_program arg1 arg2  | 
The program is transparently executed under the control of the debugger
20.1 The GNAT Debugger GDB. This does not affect the behavior
of the program, except for sensitive real-time programs. When the program
has completed execution, gnatmem outputs a report containing general
allocation/deallocation information and potential memory leak.
For better results, the user program should be compiled with
debugging options 3.2 Switches for gnatgcc.
Here is a simple example of use:
*************** debut cc
   $ gnatmem test_gm
   Global information
   ------------------
      Total number of allocations        :  45
      Total number of deallocations      :   6
      Final Water Mark (non freed mem)   :  11.29 Kilobytes
      High Water Mark                    :  11.40 Kilobytes
   .
   .
   .
   Allocation Root # 2
   -------------------
    Number of non freed allocations    :  11
    Final Water Mark (non freed mem)   :   1.16 Kilobytes
    High Water Mark                    :   1.27 Kilobytes
    Backtrace                          :
      test_gm.adb:23 test_gm.alloc
   .
   .
   .
 | 
The first block of output give general information. In this case, the Ada construct "new" was executed 45 times, and only 6 calls to an unchecked deallocation routine occurred.
Subsequent paragraphs display information on all allocation roots. An allocation root is a specific point in the execution of the program that generates some dynamic allocation, such as a "new" construct. This root is represented by an execution backtrace (or subprogram call stack). By default the backtrace depth for allocations roots is 1, so that a root corresponds exactly to a source location. The backtrace can be made deeper, to make the root more specific.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] | 
gnatmem 
gnatmem recognizes the following switches:
-q
n
-o file
-i file
gnatmem
processing starting from file which has been generated
by a previous call to gnatmem
with the -o switch. This is useful for
post mortem processing.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] | 
gnatmem Usage 
The first example shows the use of gnatmem
on a simple leaking program.
Suppose that we have the following Ada program:
   with Unchecked_Deallocation;
   procedure Test_Gm is
      type T is array (1..1000) of Integer;
      type Ptr is access T;
      procedure Free is new Unchecked_Deallocation (T, Ptr);
      A : Ptr;
      procedure My_Alloc is
      begin
         A := new T;
      end My_Alloc;
      procedure My_DeAlloc is
         B : Ptr := A;
      begin
         Free (B);
      end My_DeAlloc;
   begin
      My_Alloc;
      for I in 1 .. 5 loop
         for J in I .. 5 loop
            My_Alloc;
         end loop;
         My_Dealloc;
      end loop;
   end;
 | 
The program needs to be compiled with debugging option:
$ gnatmake -g test_gm  | 
gnatmem is invoked simply with
$ gnatmem test_gm  | 
which produces the following output:
   Global information
   ------------------
      Total number of allocations        :  18
      Total number of deallocations      :   5
      Final Water Mark (non freed mem)   :  53.00 Kilobytes
      High Water Mark                    :  56.90 Kilobytes
   Allocation Root # 1
   -------------------
    Number of non freed allocations    :  11
    Final Water Mark (non freed mem)   :  42.97 Kilobytes
    High Water Mark                    :  46.88 Kilobytes
    Backtrace                          :
      test_gm.adb:11 test_gm.my_alloc
   Allocation Root # 2
   -------------------
    Number of non freed allocations    :   1
    Final Water Mark (non freed mem)   :  10.02 Kilobytes
    High Water Mark                    :  10.02 Kilobytes
    Backtrace                          :
      s-secsta.adb:81 system.secondary_stack.ss_init
   Allocation Root # 3
   -------------------
    Number of non freed allocations    :   1
    Final Water Mark (non freed mem)   :  12 Bytes
    High Water Mark                    :  12 Bytes
    Backtrace                          :
      s-secsta.adb:181 system.secondary_stack.ss_init
 | 
Note that the GNAT run time contains itself a certain number of allocations that have no corresponding deallocation, as shown here for root #2 and root #1. This is a normal behavior when the number of non freed allocations is one, it locates dynamic data structures that the run time needs for the complete lifetime of the program. Note also that there is only one allocation root in the user program with a single line back trace: test_gm.adb:11 test_gm.my_alloc, whereas a careful analysis of the program shows that 'My_Alloc' is called at 2 different points in the source (line 21 and line 24). If those two allocation roots need to be distinguished, the backtrace depth parameter can be used:
$ gnatmem 3 test_gm  | 
which will give the following output:
   Global information
   ------------------
      Total number of allocations        :  18
      Total number of deallocations      :   5
      Final Water Mark (non freed mem)   :  53.00 Kilobytes
      High Water Mark                    :  56.90 Kilobytes
   Allocation Root # 1
   -------------------
    Number of non freed allocations    :  10
    Final Water Mark (non freed mem)   :  39.06 Kilobytes
    High Water Mark                    :  42.97 Kilobytes
    Backtrace                          :
      test_gm.adb:11 test_gm.my_alloc
      test_gm.adb:24 test_gm
      b_test_gm.c:52 main
   Allocation Root # 2
   -------------------
    Number of non freed allocations    :   1
    Final Water Mark (non freed mem)   :  10.02 Kilobytes
    High Water Mark                    :  10.02 Kilobytes
    Backtrace                          :
      s-secsta.adb:81  system.secondary_stack.ss_init
      s-secsta.adb:283 <system__secondary_stack___elabb>
      b_test_gm.c:33   adainit
   Allocation Root # 3
   -------------------
    Number of non freed allocations    :   1
    Final Water Mark (non freed mem)   :   3.91 Kilobytes
    High Water Mark                    :   3.91 Kilobytes
    Backtrace                          :
      test_gm.adb:11 test_gm.my_alloc
      test_gm.adb:21 test_gm
      b_test_gm.c:52 main
   Allocation Root # 4
   -------------------
    Number of non freed allocations    :   1
    Final Water Mark (non freed mem)   :  12 Bytes
    High Water Mark                    :  12 Bytes
    Backtrace                          :
      s-secsta.adb:181 system.secondary_stack.ss_init
      s-secsta.adb:283 <system__secondary_stack___elabb>
      b_test_gm.c:33   adainit
 | 
The allocation root #1 of the first example has been split in 2 roots #1 and #3 thanks to the more precise associated backtrace.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] | 
gnatmem executes the user program under the control of gnatgdb using
a script that sets breakpoints and gathers information on each dynamic
allocation and deallocation. The output of the script is then analyzed
by gnatmem
in order to locate memory leaks and their origin in the
program. Gnatmem works by recording each address returned by the
allocation procedure (__gnat_malloc)
along with the backtrace at the
allocation point. On each deallocation, the deallocated address is
matched with the corresponding allocation. At the end of the processing,
the unmatched allocations are considered potential leaks. All the
allocations associated with the same backtrace are grouped together and
form an allocation root. The allocation roots are then sorted so that
those with the biggest number of unmatched allocation are printed
first. A delicate aspect of this technique is to distinguish between the
data produced by the user program and the data produced by the gnatgdb
script. Currently, on systems that allow probing the terminal, the gnatgdb
command "tty" is used to force the program output to be redirected to the
current terminal while the gnatgdb output is directed to a file or to a
pipe in order to be processed subsequently by gnatmem.
| [ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |