Provided by: duma_2.5.15-1.1ubuntu1_amd64 bug


       DUMA - DUMA Malloc Debugger


       #include <stdlib.h>

       void * malloc (size_t size);

       void free (void *ptr);

       void * realloc (void *ptr, size_t size);

       void * calloc (size_t nelem, size_t elsize);

       void * memalign (size_t alignment, size_t size);

       void * valloc (size_t size);

       extern int DUMA_ALIGNMENT;

       extern int DUMA_PROTECT_BELOW;

       extern int DUMA_PROTECT_FREE;

       extern int DUMA_ALLOW_MALLOC_0;

       extern int DUMA_FILL;


       DUMA  helps  you detect two common programming bugs: software that overruns the boundaries
       of a malloc() memory allocation, and software that touches a memory  allocation  that  has
       been  released  by free(). Unlike other malloc() debuggers, DUMA will detect read accesses
       as well as writes, and it will pinpoint the exact instruction that causes an error. It has
       been in use at Pixar since 1987, and at many other sites for years.

       DUMA  uses  the  virtual  memory hardware of your computer to place an inaccessible memory
       page immediately after (or before, at the user's  option)  each  memory  allocation.  When
       software reads or writes this inaccessible page, the hardware issues a segmentation fault,
       stopping the program at the  offending  instruction.  It  is  then  trivial  to  find  the
       erroneous  statement  using  your  favorite debugger. In a similar manner, memory that has
       been released by free() is made inaccessible, and any code that  touches  it  will  get  a
       segmentation fault.

       Simply linking your application with libduma.a will allow you to detect most, but not all,
       malloc buffer overruns and accesses of free memory.  If you want  to  be  reasonably  sure
       that  you've  found  all bugs of this type, you'll have to read and understand the rest of
       this man page.


       Link your program with the library libduma.a  .   Make  sure  you  are  not  linking  with
       -lmalloc,  -lmallocdebug, or with other malloc-debugger or malloc-enhancer libraries.  You
       can only use one at a time.  If your system administrator has installed  DUMA  for  public
       use, you'll be able to use the -lduma argument to the linker, otherwise you'll have to put
       the path-name for libduma.a in the linker's  command  line.   You  can  also  use  dynamic
       linking.  If  you're  using a Bourne shell, the statement export
       will cause DUMA to be loaded to run all dynamic executables.   The  command  duma  command
       runs a single command under DUMA.

       Some systems will require special arguments to the linker to assure that you are using the
       DUMA malloc() and not the one from your C library.

       Run your program using a debugger.  It's easier to work this way than  to  create  a  core
       file and post-mortem debug it. DUMA can create huge core files, and some operating systems
       will thus take minutes simply to dump core! Some operating systems will not create  usable
       core files from programs that are linked with DUMA.  If your program has one of the errors
       detected by DUMA, it will get a segmentation fault (SIGSEGV) at the offending instruction.
       Use the debugger to locate the erroneous statement, and repair it.


       DUMA  has four configuration switches that can be enabled via the shell environment, or by
       setting the value of global integer variables using a debugger. These switches change what
       bugs DUMA will detect, so it's important that you know how to use them.

              This  is  an  integer  that specifies the alignment for any memory allocations that
              will be returned by malloc(), calloc(), and realloc().  The value is  specified  in
              bytes,  thus  a  value  of  4  will cause memory to be aligned to 32-bit boundaries
              unless your system doesn't have  a  8-bit  characters.  DUMA_ALIGNMENT  is  set  to
              sizeof(int) by default, since that is generally the word-size of your CPU.  If your
              program requires that allocations be aligned to 64-bit boundaries and  you  have  a
              32-bit int you'll have to set this value to 8. This is the case when compiling with
              the -mips2 flag  on  MIPS-based  systems  such  as  those  from  SGI.   The  memory
              allocation  that  is  returned  by  DUMA  malloc()  is  aligned  using the value in
              DUMA_ALIGNMENT, and its size the multiple of that value that  is  greater  than  or
              equal  to  the  requested  size.   For  this reason, you will sometimes want to set
              DUMA_ALIGNMENT to 0 (no alignment), so that you can detect overruns  of  less  than
              your  CPU's  word  size.  Be  sure  to  read the section WORD-ALIGNMENT AND OVERRUN
              DETECTION in this manual page before you try  this.   To  change  this  value,  set
              DUMA_ALIGNMENT  in  the  shell  environment  to  an integer value, or assign to the
              global integer variable DUMA_ALIGNMENT using a debugger.

              DUMA usually places an inaccessible page immediately after each memory  allocation,
              so that software that runs past the end of the allocation will be detected. Setting
              DUMA_PROTECT_BELOW to 1 causes DUMA to  place  the  inaccessible  page  before  the
              allocation  in  the  address  space, so that under-runs will be detected instead of
              over-runs.   When  DUMA_PROTECT_BELOW  is  set,  the  DUMA_ALIGNMENT  parameter  is
              ignored.   All  allocations  will be aligned to virtual-memory-page boundaries, and
              their size will be the exact size that was requested.  To change  this  value,  set
              DUMA_PROTECT_BELOW  in  the shell environment to an integer value, or assign to the
              global integer variable DUMA_PROTECT_BELOW using a debugger.

              DUMA usually returns free memory to a pool from which it may  be  re-allocated.  If
              you suspect that a program may be touching free memory, set DUMA_PROTECT_FREE to 1.
              This will cause DUMA to never re-allocate memory once it has been  freed,  so  that
              any  access  to  free  memory  will  be detected. Some programs will use tremendous
              amounts of  memory  when  this  parameter  is  set.   To  change  this  value,  set
              DUMA_PROTECT_FREE  in  the  shell environment to an integer value, or assign to the
              global integer variable DUMA_PROTECT_FREE using a debugger.

              By default, DUMA traps calls to malloc() with a size  of  zero,  because  they  are
              often  the  result  of  a  software  bug.  If  DUMA_ALLOW_MALLOC_0 is non-zero, the
              software will not trap calls to malloc() with a  size  of  zero.   To  change  this
              value,  set  DUMA_ALLOC_MALLOC_0  in  the shell environment to an integer value, or
              assign to the global integer variable DUMA_ALLOC_MALLOC_0 using a debugger.

              When set to a  value  between  0  and  255,  every  byte  of  allocated  memory  is
              initialized  to  that  value.  This  can help detect reads of uninitialized memory.
              When set to -1, some memory is filled with zeroes (the operating system default  on
              most  systems) and some memory will retain the values written to it during its last


       There is a conflict between the alignment restrictions that malloc()  operates  under  and
       the  debugging strategy used by DUMA. When detecting overruns, DUMA malloc() allocates two
       or more virtual memory pages for each allocation. The last page is  made  inaccessible  in
       such a way that any read, write, or execute access will cause a segmentation fault.  Then,
       DUMA malloc() will return an address such that  the  first  byte  after  the  end  of  the
       allocation  is on the inaccessible page.  Thus, any overrun of the allocation will cause a
       segmentation fault.

       It follows that the address returned by malloc() is the address of the  inaccessible  page
       minus  the  size  of the memory allocation.  Unfortunately, malloc() is required to return
       word-aligned allocations, since many CPUs can only access  a  word  when  its  address  is
       aligned.   The  conflict happens when software makes a memory allocation using a size that
       is not a multiple of the word size, and expects to do word accesses  to  that  allocation.
       The  location  of the inaccessible page is fixed by hardware at a word-aligned address. If
       DUMA malloc() is to return an aligned address, it must increase the size of the allocation
       to  a  multiple of the word size.  In addition, the functions memalign() and valloc() must
       honor explicit specifications on the alignment of the memory allocation, and this, as well
       can  only  be  implemented  by increasing the size of the allocation.  Thus, there will be
       situations in which the end of a  memory  allocation  contains  some  padding  space,  and
       accesses of that padding space will not be detected, even if they are overruns.

       DUMA  provides  the  variable  DUMA_ALIGNMENT  so  that  the  user can control the default
       alignment used by malloc(), calloc(), and realloc().  To debug  overruns  as  small  as  a
       single  byte,  you  can  set  DUMA_ALIGNMENT  to  zero.  This will result in DUMA malloc()
       returning unaligned addresses for allocations with sizes that are not a  multiple  of  the
       word  size.  This  is  not a problem in most cases, because compilers must pad the size of
       objects so that alignment restrictions are honored when storing those objects  in  arrays.
       The  problem  surfaces  when software allocates odd-sized buffers for objects that must be
       word-aligned. One case of this is software that allocates a buffer to contain a  structure
       and a string, and the string has an odd size (this example was in a popular TIFF library).
       If word references are made to un-aligned buffers, you  will  see  a  bus  error  (SIGBUS)
       instead  of  a  segmentation  fault. The only way to fix this is to re-write the offending
       code to make byte references or not make odd-sized allocations, or to  set  DUMA_ALIGNMENT
       to the word size.

       Another  example  of software incompatible with DUMA_ALIGNMENT < word-size is the strcmp()
       function and other string functions on SunOS (and probably Solaris), which make word-sized
       accesses  to character strings, and may attempt to access up to three bytes beyond the end
       of a string. These result in a segmentation fault (SIGSEGV). The only way around  this  is
       to  use  versions  of  the  string  functions that perform byte references instead of word


       1.     Link with libduma.a as explained above.

       2.     Run your program in a debugger and fix any overruns or accesses to free memory.

       3.     Quit the debugger.

       4.     Set DUMA_PROTECT_BELOW = 1 in the shell environment.

       5.     Repeat step 2, this time repairing underruns if they occur.

       6.     Quit the debugger.

       7.     Read the restrictions in the section on WORD-ALIGNMENT AND OVERRUN DETECTION.   See
              if  you  can  set DUMA_ALIGNMENT to 0 and repeat step 2. Sometimes this will be too
              much work, or there will be problems with library routines for which you don't have
              the source, that will prevent you from doing this.


       Since  DUMA  uses  at  least  two virtual memory pages for each of its allocations, it's a
       terrible memory hog. I've sometimes found it necessary to add a swap file using  swapon(8)
       so  that the system would have enough virtual memory to debug my program. Also, the way we
       manipulate memory results in various cache and translation buffer  entries  being  flushed
       with  each call to malloc or free. The end result is that your program will be much slower
       and use more resources while you are debugging it with DUMA.

       Don't leave libduma.a linked into production software! Use it only for debugging.


       Hayati Ayguen


       I have tried to do as good a job as I can on this software, but I doubt that  it  is  even
       theoretically  possible  to  make it bug-free.  This software has no warranty. It will not
       detect some bugs that you might expect it to detect, and will indicate that some  non-bugs
       are bugs.


       Copyright 1987-1999 Bruce Perens. All rights reserved.
       This program is free software; you can redistribute it and/or modify it under the terms of
       the GNU General Public License, Version 2, as published by the Free Software Foundation. A
       copy of this license is distributed with this software in the file "COPYING".

       This  program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
       without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR  PURPOSE.
       Read the file "COPYING" for more details.


       Bruce Perens
       1563 Solano Ave. #349
       Berkeley, CA 94707
       Telephone: 510-526-1165


       /dev/zero: Source of memory pages (via mmap(2)).


       malloc(3), mmap(2), mprotect(2), swapon(8)


       Segmentation  Fault:  Examine the offending statement for violation of the boundaries of a
       memory allocation.
       Bus Error: See the section on WORD-ALIGNMENT AND OVERRUN DETECTION.  in this manual page.


       My explanation of the alignment issue could be improved.

       Some Sun systems running SunOS 4.1 were reported to signal an access to a  protected  page
       with SIGBUS rather than SIGSEGV, I suspect this is an undocumented feature of a particular
       Sun hardware version, not just the operating system.  On these systems, dumatest will fail
       with  a  bus error until you modify the Makefile to define PAGE_PROTECTION_VIOLATED_SIGNAL
       as SIGBUS.

       There are, without doubt, other bugs and porting issues. Please contact me via  e-mail  if
       you have any bug reports, ideas, etc.


       Purify  does  a  much  more  thorough  job  than  DUMA,  and does not have the huge memory
       overhead.  Checkergcc, a modified version of the  GNU  C  Compiler  that  instruments  all
       memory  references,  is available on Linux systems and where GCC is used. It performs some
       of the same tasks as Purify, but only on code that it has compiled.

                                        10-September-2005                                 DUMA(3)