www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2000/01/01/17:59:46

Message-ID: <386E2A6E.9282965F@teleline.es>
Date: Sat, 01 Jan 2000 17:25:18 +0100
From: Mariano Alvarez =?iso-8859-1?Q?Fern=E1ndez?= <malfer AT teleline DOT es>
X-Mailer: Mozilla 4.5 [es] (Win95; I)
X-Accept-Language: es
MIME-Version: 1.0
To: djgpp-workers AT delorie DOT com
Subject: Mini malloc debugger
Reply-To: djgpp-workers AT delorie DOT com

Here, there are my patch to add the mini-malloc debugger to the stock
malloc routine for DJGPP, I have used the malloc.c in the last 2.03
alpha lib to make the diff.

It's the same utility I mailed for fmalloc.c to the djgpp list, and Eli
pointed to me to do the same for the stock malloc.c.

The overhead is so little (I think) that using constructions like
"if( mini_malloc_debugger ) do things" are unnecessary, the only
question is if any-body disagree whith that. I really think is
very useful.

Here are the diff:

*** src/libc/ansi/stdlib/malloc.old Fri Aug 20 18:46:58 1999
--- src/libc/ansi/stdlib/malloc.c Tue Dec 28 23:44:28 1999
***************
*** 6,11 ****
--- 6,17 ----
  #include <string.h>
  #include <unistd.h>

+ long malloc_info_memory = 0;
+ long malloc_info_nomem = 0;
+ long malloc_info_nmalloc = 0;
+ long malloc_info_nfree = 0;
+ long malloc_info_nfree0 = 0;
+
  typedef struct BLOCK {
    size_t size;
    struct BLOCK *next;
***************
*** 97,103 ****
    return rv;
  }

! #define RET(rv) CHECK(rv); ENDSZ(rv) |= 1; rv->size |= 1; return
DATA(rv)

  void *
  malloc(size_t size)
--- 103,110 ----
    return rv;
  }

! #define RETD(rv) malloc_info_memory += (rv->size & ~1) + 16; return
DATA( rv )
! #define RET(rv) CHECK(rv); ENDSZ(rv) |= 1; rv->size |= 1; RETD(rv)

  void *
  malloc(size_t size)
***************
*** 106,111 ****
--- 113,119 ----
    BLOCK *rv, **prev;
    static BLOCK *expected_sbrk = 0;

+   malloc_info_nmalloc++;
    if (size<ALIGN) size = ALIGN;
    size = (size+(ALIGN-1))&~(ALIGN-1);
  #if DEBUG
***************
*** 119,125 ****
      if (rv)
      {
        smallblocks[size/ALIGN] = rv->next;
!       return DATA(rv);
      }
    }
  #endif
--- 127,133 ----
      if (rv)
      {
        smallblocks[size/ALIGN] = rv->next;
!       RETD(rv);
      }
    }
  #endif
***************
*** 194,200 ****
--- 202,211 ----
    chunk_size = size+16; /* two ends plus two placeholders */
    rv = (BLOCK *)sbrk(chunk_size);
    if (rv == (BLOCK *)(-1))
+   {
+     malloc_info_nomem++;
      return 0;
+   }
  #if DEBUG
    printf("sbrk(%d) -> %08x, expected %08x\n", chunk_size, rv,
expected_sbrk);
  #endif
***************
*** 281,289 ****
--- 292,306 ----
  {
    int b;
    BLOCK *block;
+
+   malloc_info_nfree++;
    if (ptr == 0)
+   {
+     malloc_info_nfree0++;
      return;
+   }
    block = (BLOCK *)((char *)ptr-4);
+   malloc_info_memory -= (block->size & ~1) + 16;

  #if NUMSMALL
    if (block->size < SMALL)

And here, there are the documentation, I don't know where to put it, and
it will be nice if somebody check my horrible english.

-----------------------------------
The DJGPP mini-malloc debugger.

This mini-malloc debugger is intended for use during program
development, using a little group of global variables. They are:

malloc_info_memory   store the real heap memory used at any time.
malloc_info_nomem    times malloc return whith no memory.
malloc_info_nmalloc  times malloc was called.
malloc_info_nfree    times free was called.
malloc_info_nfree0   times free was called whith a NULL pointer.

How to use.

First you must to declare the variables in the routine you use to show
the data:

extern long malloc_info_memory;
extern long malloc_info_nomem;
extern long malloc_info_nmalloc;
extern long malloc_info_nfree;
extern long malloc_info_nfree0;

The prefered method is to check the malloc_info values before and after
run a new feature in your program, you must find that the next
expresions:

     1) malloc_info_memory
     2) malloc_info_nmalloc - malloc_info_nfree - malloc_info_nomem

are equals before and after, and the malloc_info_nfree0 is always 0. If
not you have a memory hole.

You must note that some libc routines can get some memory from the heap
and don't free it, so if you find there are a little difference in the
second expresion, check again whithout ending the program.

Here there are a simple routine to do the test, you can call it whith
show_malloc_info( stdout ) or show_malloc_info( stderr ).

void show_malloc_info( FILE *f )
{
  extern long malloc_info_memory;
  extern long malloc_info_nomem;
  extern long malloc_info_nmalloc;
  extern long malloc_info_nfree;
  extern long malloc_info_nfree0;

  fprintf( f,"Mem:%ld Dif:%ld\n",
              malloc_info_memory,
              malloc_info_nmalloc - malloc_info_nfree -
malloc_info_nomem );
  if( malloc_info_nfree0 ) > 0 )
    fprintf( f,"%ld NULL pointers dereferences!\n",
               malloc_info_nfree0 );
}

If you are using a GUI or a TUI it will be better to write your own
routine and asociate it to a hot key, showing the values in a window.

Grettings. M.Alvarez



- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019