            LMDBG - lightweight modular malloc debugger

====================================================================
                      INSTALLATION

See INSTALL file

====================================================================
                      PREPARATIONS

LMDBG uses /proc/PID/maps file, so on NetBSD and Linux
I strongly recomment to mount it, otherwise lmdbg-sym(1)
may work incorrectly.

====================================================================
                      DOCUMENTATION/TUTORIAL

- LMDBG is a lightweight malloc debugger for UNIX-like OSes that
  follows so called "UNIX way", traditional principles of programming
  under UNIX. Instead of providing single program that can do
  everything LMDBG provides a set of standalone programs that work
  together: lmdbg-run, lmdbg-sym, lmdbg-leaks, lmdbg-sysleaks,
  lmdbg-stat, lmdbg-grep and lmdbg-sort.

- Unlike many other malloc debuggers (electric-fence, dmalloc,
  valgrind etc.) LMDBG does *NOT* protect your memory in any way.
  This is just not a goal of it.

- lmdbg-run is a main lmdbg utility. It runs application and creates a
  log file (or fifo) where all
  malloc/calloc/realloc/free/memalign/posix_memalign/aligned_alloc invocations are
  registered with their input (bytes count and/or pointer), output
  (pointer) and FULL STACKTRACE (pointers).

   Example:
     $ cat tests/test2.c
     #include <stdlib.h>

     int main ()
     {
        void *p1 = NULL;
        void *p2 = NULL;

        p1 = malloc (555);
        p2 = realloc (p2, 666);
        p2 = realloc (p2, 777);
        p2 = realloc (p2, 888);

        return 0;
     }
     $ gcc -O0 -g -o _test2 tests/test2.c
     $ lmdbg-run -o _log ./_test2 
     $ cat _log
     malloc ( 555 ) --> 0xbb901400
      0xbbbe58e8
      0xbbbe5b03
      0x8048738
      0x8048584
      0x80484e7
     realloc ( NULL , 666 ) --> 0xbb901800
      0xbbbe58e8
      0xbbbe5a37
      0x804874e
      0x8048584
      0x80484e7
     realloc ( 0xbb901800 , 777 ) --> 0xbb901c00
      0xbbbe58e8
      0xbbbe5a37
      0x8048764
      0x8048584
      0x80484e7
     realloc ( 0xbb901c00 , 888 ) --> 0xbb901800
      0xbbbe58e8
      0xbbbe5a37
      0x804877a
      0x8048584
      0x80484e7
     $

  NOTE: Full stacktrace allows you to analyse your application, i.e.
  you can detect what blocks/components require more memory than
  others and why. lmdbg-sym is a very important tool for this, see
  below.

- lmdbg-leaks analyses a log file generated by lmdbg-run and output
  all found memory leaks

  Example:

     $ lmdbg-leaks _log   
     realloc ( 0xbb901c00 , 888 ) --> 0xbb901800
      0xbbbe58e8
      0xbbbe5a37
      0x804877a
      0x8048584
      0x80484e7
     malloc ( 555 ) --> 0xbb901400
      0xbbbe58e8
      0xbbbe5b03
      0x8048738
      0x8048584
      0x80484e7
     $

- lmdbg-sym converts addresses to symbols and position in the source
  code if it is possible

  Example:

     $ lmdbg-sym ./_test2 _log
     malloc ( 555 ) --> 0xbb901400
      0xbbbe58e8
      0xbbbe5b03
      0x8048738      tests/test2.c:8    main
      0x8048584
      0x80484e7
     realloc ( NULL , 666 ) --> 0xbb901800
      0xbbbe58e8
      0xbbbe5a37
      0x804874e      tests/test2.c:9    main
      0x8048584
      0x80484e7
     realloc ( 0xbb901800 , 777 ) --> 0xbb901c00
      0xbbbe58e8
      0xbbbe5a37
      0x8048764      tests/test2.c:10        main
      0x8048584
      0x80484e7
     realloc ( 0xbb901c00 , 888 ) --> 0xbb901800
      0xbbbe58e8
      0xbbbe5a37
      0x804877a      tests/test2.c:11        main
      0x8048584
      0x80484e7
     $

- lmdbg-sysleaks - greps or skips system memory leaks found in
  libc, libdl, C++ stl etc. See tests/lmdbg*.conf files.
  The default config files are: ~/.lmdbg.conf and /etc/lmdbg.conf

- lmdbg = lmdbg-run + lmdbg-leaks + lmdbg-sym + lmdbg-sysleaks

  That is lmdbg is all-in-one higher level tool.

   Example:

     $ lmdbg -v -o _log ./_test2
     Memory leaks were detected and saved to file '_log'
     $ cat _log
     realloc ( 0xbb901c00 , 888 ) --> 0xbb901800
      0xbbbe58e8
      0xbbbe5a37
      0x804877a      tests/test2.c:11        main
      0x8048584
      0x80484e7
     malloc ( 555 ) --> 0xbb901400
      0xbbbe58e8
      0xbbbe5b03
      0x8048738      tests/test2.c:8 main
      0x8048584
      0x80484e7
     $

- lmdbg-stat - given output of lmdbg-run or other lmdbg-* utilities
  on input lmdbg-stat outputs a total and per-stacktrace statistical
  information about memory alocations.

     $ cat -n testme.c
           1  #include <stdlib.h>
           2  
           3  int main ()
           4  {
           5          int i;
           6          void *p1, *p2;
           7          p1 = malloc (100);
           8          for (i=0; i < 3; ++i){
           9                  p2 = realloc (NULL, 10+30*i);
          10          }
          11          free (p1);
          12          free (p2);
          13  
          14          return 0;
          15  }
     $ cc -O0 -g -o testme testme.c
     $ lmdbg-run -o log -p 'lmdbg-stat | lmdbg-sym ./testme' ./testme     
     $ cat log
     info stat total_leaks: 50
     info stat total_allocs: 4
     info stat total_free_cnt: 2
     stacktrace peak: 120 max: 70 allocs: 3 leaks: 50
      0xbbbe2bc3     lmdbg.c:101     log_stacktrace
      0xbbbe3498     lmdbg.c:456     realloc
      0x8048788      testme.c:9      main
      0x80485b4      
      0x8048517      
     stacktrace peak: 100 max: 100 allocs: 1
      0xbbbe2bc3     lmdbg.c:101     log_stacktrace
      0xbbbe33bd     lmdbg.c:431     malloc
      0x8048757      testme.c:7      main
      0x80485b4      
      0x8048517      
     $ 

- lmdbg-grep - given an output of lmdbg-stat on input lmdbg-grep
  outputs global information and those stacktraces that match the
  specified AWK expression.

     $ cat log                    
     stacktrace peak: 120 max: 70 allocs: 3 leaks: 50
      0xbbbe2bc3     lmdbg.c:101     log_stacktrace
      0xbbbe3498     lmdbg.c:456     realloc
      0x8049700      testme.c:902    func1
      0x8048788      testme.c:9      main
      0x80485b4      
      0x8048517      
     stacktrace peak: 100 max: 100 allocs: 1
      0xbbbe2bc3     lmdbg.c:101     log_stacktrace
      0xbbbe33bd     lmdbg.c:431     malloc
      0x8049654      testme.c:450    func2
      0x8048757      testme.c:7      main
      0x80485b4      
      0x8048517      
     $ lmdbg-grep 'leaks > 0' log 
     stacktrace peak: 120 max: 70 allocs: 3 leaks: 50
      0xbbbe2bc3     lmdbg.c:101     log_stacktrace
      0xbbbe3498     lmdbg.c:456     realloc
      0x8049700      testme.c:902    func1
      0x8048788      testme.c:9      main
      0x80485b4      
      0x8048517      
     $ lmdbg-grep '!leaks' log    
     stacktrace peak: 100 max: 100 allocs: 1
      0xbbbe2bc3     lmdbg.c:101     log_stacktrace
      0xbbbe33bd     lmdbg.c:431     malloc
      0x8049654      testme.c:450    func2
      0x8048757      testme.c:7      main
      0x80485b4      
      0x8048517      
     $ lmdbg-grep 'addrline ~ /\tfunc2/' log  
     stacktrace peak: 100 max: 100 allocs: 1
      0xbbbe2bc3     lmdbg.c:101     log_stacktrace
      0xbbbe33bd     lmdbg.c:431     malloc
      0x8049654      testme.c:450    func2
      0x8048757      testme.c:7      main
      0x80485b4      
      0x8048517      
     $ lmdbg-grep 'allocs > 1000 || peak > 1000000' log   
     $

- lmdbg-sort - see manual page.

- lmdbg-head - this filter outputs the first <count> stacktraces,
               see manual page.

- lmdbg-strip

  Example:

     $ cat tests/test2.c
     #include <stdlib.h>

     int main ()
     {
        void *p1 = NULL;
        void *p2 = NULL;

        p1 = malloc (555);
        p2 = realloc (p2, 666);
        p2 = realloc (p2, 777);
        p2 = realloc (p2, 888);

        return 0;
     }
     $ lmdbg-run  -p 'lmdbg-sym -p | lmdbg-strip -ars' -o _log ./_test2
     $ cat _log
     info progname ./_test2
     malloc ( 555 ) --> 0xXYZ num: 1
                     log_stacktrace
                     malloc
                     main
     realloc ( NULL , 666 ) --> 0xXYZ num: 2
                     log_stacktrace
                     realloc
                     main
     realloc ( 0xXYZ , 777 ) --> 0xXYZ num: 3
                     log_stacktrace
                     realloc
                     main
     realloc ( 0xXYZ , 888 ) --> 0xXYZ num: 4
                     log_stacktrace
                     realloc
                     main
     $

- lmdbg-module

  Example:

     XXX

====================================================================
                          QUICK GUIDE

lmdbg            --help
lmdbg-run        --help
lmdbg-leaks      --help
lmdbg-sysleaks   --help
lmdbg-sym        --help
lmdbg-stat       --help
lmdbg-sort       --help
lmdbg-head       --help
lmdbg-grep       --help
lmdbg-strip      --help
lmdbg-modules    --help

Sample of usage:

user@host$ lmdbg-run -o /tmp/PROG.log PROG ARG1 ARG2 ... ARGN
user@host$ lmdbg-leak < /tmp/PROG.log > /tmp/PROG.log2
user@host$ lmdbg-sym PROG \
   < /tmp/PROG.log2 > /tmp/PROG_LEAKS_SRC.log3

====================================================================
                AUTHOR: Aleksey Cheusov <vle@gmx.net>

====================================================================
                LICENSE: MIT

====================================================================
                      ACKNOWLEDGEMENTS

Idea to use full stacktraces was stolen from YAMD
  by Nate Eldredge

Idea to use gdb(1) for resolving symbols was stolen from ccmalloc
  by Armin Biere

Idea to use /proc/<pid>/maps was stolen from google-perftools
  by Google Inc. <opensource@google.com>

stacktrace(3) API is compatible with GNU libc's backtrace(3)
