1: /*
   2:   C K C M D B . C  --  malloc debugger.
   3: */
   4: 
   5: /*
   6:   Author: Howie Kaye, Columbia University Center for Computing Activities.
   7:   Copyright (C) 1985, 1992, Trustees of Columbia University in the City of New
   8:   York.  Permission is granted to any individual or institution to use this
   9:   software as long as it is not sold for profit.  This copyright notice must be
  10:   retained.  This software may not be included in commercial products without
  11:   written permission of Columbia University.
  12: */
  13: #include <stdio.h>
  14: #include "ckcdeb.h"
  15: /*
  16:   memdebug:
  17:   variable to control memory debugging.
  18:   if memdebug ==  1, then action is always taken.
  19:   if memdebug ==  0, then no action is taken.
  20:   if memdebug == -1, then the user is asked (works well with gdb).
  21: */
  22: int memdebug = -1;
  23: int disabled = 0;
  24: int inited = 0;
  25: /*
  26:   To use this package, compile your program with:
  27:   -Dmalloc=dmalloc -Dfree=dfree =Dcalloc=dcalloc ... -DMDEBUG
  28:   and then link it with ckcmdb.c.
  29: */
  30: #ifdef MDEBUG
  31: /* Use the real ones in this module! */
  32: #ifdef malloc
  33: #undef malloc
  34: #endif /* malloc */
  35: #ifdef calloc
  36: #undef calloc
  37: #endif /* calloc */
  38: #ifdef realloc
  39: #undef realloc
  40: #endif /* realloc */
  41: #ifdef free
  42: #undef free
  43: #endif /* free */
  44: 
  45: char *malloc(), *realloc();
  46: char *set_range_check();
  47: char *check_range();
  48: char *maybe_check_range();
  49: 
  50: #define min(x,y) ((x) < (y) ? (x) : (y))
  51: #define RANGE "ABCDEFGHIJKLMNOP"
  52: #define INTSIZE  sizeof(int)
  53: #define LONGSIZE sizeof(long)
  54: #define RSIZE    sizeof(RANGE)
  55: #define RFRONT   min((RSIZE/2),LONGSIZE)
  56: #define RBACK    min((RSIZE-RFRONT),LONGSIZE)
  57: 
  58: char *
  59: dmalloc(size) int size; {
  60:     char *cp;
  61: 
  62:     cp = malloc(size + RSIZE + INTSIZE);
  63:     if (cp) {
  64:     cp = set_range_check(cp, size);
  65:     m_insert(cp);
  66:     }
  67:     return(cp);
  68: }
  69: 
  70: char *
  71: dcalloc(nelem, elsize) int nelem, elsize; {
  72:     char *cp;
  73: 
  74:     cp = dmalloc(nelem * elsize);
  75:     if (cp)
  76:     bzero(cp, nelem * elsize);
  77:     return(cp);
  78: }
  79: 
  80: char *
  81: drealloc(bp,size) char *bp; int size; {
  82:     char *cp;
  83: 
  84:     if (bp == NULL) {
  85:     maybe_quit("Freeing NULL pointer");
  86:     } else {
  87:     m_delete(bp);
  88:     cp = check_range(bp);
  89:     }
  90:     cp = realloc(cp, size + RSIZE + INTSIZE);
  91:     if (cp) {
  92:     cp = set_range_check(cp, size);
  93:     m_insert(cp);
  94:     }
  95:     return(cp);
  96: }
  97: 
  98: dfree(cp) char *cp; {
  99:     if (cp == NULL)
 100:     maybe_quit("Freeing NULL pointer");
 101:     else {
 102:     switch(m_delete(cp)) {
 103:     case 0:
 104:         cp = maybe_check_range(cp);
 105:         break;
 106:     case 1:
 107:         cp = check_range(cp);
 108:         break;
 109:     case 2:
 110:         break;
 111:     }
 112:     }
 113:     return(free(cp));
 114: }
 115: 
 116: char *
 117: set_range_check(cp,size) char *cp; int size; {
 118:     register int i;
 119:     int tmp = size;
 120: 
 121:     for(i = 0; i < INTSIZE; i++) {  /* set the size in the string */
 122:     cp[i] = tmp & 0xff;
 123:     tmp >>= 8;
 124:     }
 125:     cp += INTSIZE;          /* skip the size */
 126: 
 127:     for(i = 0; i < RFRONT; i++)     /* set the front of the range check */
 128:     cp[i] = RANGE[i];       /* string */
 129: 
 130:     cp += RFRONT;           /* skip the front range check */
 131: 
 132:     for(i = 0; i < RBACK; i++)      /* set the back odf the range check */
 133:     cp[i+size] = RANGE[i+RFRONT];
 134: 
 135:     return(cp);
 136: }
 137: 
 138: /*
 139:   Put calls to this routine in your code any place where you want to
 140:   check whether you've copied too many characters into a malloc'd space.
 141: */
 142: char *
 143: check_range(cp) char *cp; {
 144:     register char *bp = cp - RFRONT - INTSIZE;
 145:     char *xp = bp;
 146:     register int i;
 147:     int size = 0;
 148: 
 149:     for(i = 0 ; i < INTSIZE; i++) { /* get the size out of the string */
 150:     size <<= 8;
 151:     size |= bp[INTSIZE-i-1] & 0xff;
 152:     }
 153:     bp += INTSIZE;
 154: 
 155:     for(i = 0; i < RFRONT; i++)     /* check front range check */
 156:     if (bp[i] != RANGE[i]) {
 157:         maybe_quit("leftside malloc buffer overrun");
 158:         break;
 159:     }
 160:     bp += RFRONT;           /* skip front range check */
 161: 
 162:     for(i = 0; i < RBACK; i++)      /* check back range check */
 163:     if (bp[i+size] != RANGE[i+RFRONT]) {
 164:         maybe_quit("rightside malloc buffer overrun");
 165:         break;
 166:     }
 167:     return(xp);
 168: }
 169: 
 170: static char *
 171: maybe_check_range(cp) char *cp; {
 172:     register char *bp = cp - RFRONT - INTSIZE;
 173:     char *xp = bp;
 174:     register int i;
 175:     int size = 0;
 176: 
 177:     for(i = 0 ; i < INTSIZE; i++) { /* get the size out of the string */
 178:     size <<= 8;
 179:     size |= bp[INTSIZE-i-1] & 0xff;
 180:     }
 181:     bp += INTSIZE;
 182: 
 183:     for(i = 0; i < RFRONT; i++)     /* check front range check */
 184:     if (bp[i] != RANGE[i]) {
 185:         return(cp);
 186:     }
 187:     bp += RFRONT;           /* skip front range check */
 188: 
 189:     for(i = 0; i < RBACK; i++)      /* check back range check */
 190:     if (bp[i+size] != RANGE[i+RFRONT]) {
 191:         fprintf(stderr,"rightside malloc buffer overrun\n");
 192:         abort();
 193:         break;
 194:     }
 195:     return(xp);
 196: }
 197: 
 198: #define BUCKETS 10000
 199: char *m_used[BUCKETS];
 200: char *m_used2[BUCKETS];
 201: 
 202: VOID
 203: m_insert(cp) register char *cp; {
 204:     register int i;
 205: 
 206:     if (disabled)
 207:     return;
 208: 
 209:     for(i = 0; i < BUCKETS; i++)
 210:     if (m_used[i] == 0) {
 211:         m_used[i] = cp;
 212:         return;
 213:     }
 214:     disabled ++;
 215: }
 216: 
 217: static
 218: m_insert2(cp) register char *cp; {
 219:     register int i;
 220: 
 221:     if (disabled)
 222:     return;
 223:     for(i = 0; i < BUCKETS; i++)
 224:     if (m_used2[i] == 0) {
 225:         m_used2[i] = cp;
 226:         return;
 227:     }
 228:     disabled ++;
 229: }
 230: 
 231: VOID
 232: m_delete(cp) register char *cp; {
 233:     register int i;
 234: 
 235:     for(i = 0; i < BUCKETS; i++)
 236:     if (m_used[i] == cp) {
 237:         m_used[i] = 0;
 238:         return(1);
 239:     }
 240:     for(i = 0; i < BUCKETS; i++)
 241:     if (m_used2[i] == cp) {
 242:         m_used2[i] = 0;
 243:         return(2);
 244:     }
 245:     if (disabled)
 246:     return(0);
 247: 
 248:     maybe_quit("Freeing unmalloc'ed pointer");
 249:     return(0);
 250: }
 251: 
 252: VOID
 253: m_init() {
 254:     register int i;
 255: 
 256:     inited = 1;
 257:     disabled = 0;
 258:     for(i = 0; i < BUCKETS; i++)
 259:       m_used[i] = 0;
 260: }
 261: 
 262: VOID
 263: m_done() {
 264:     register int i,j=0;
 265: 
 266:     if (disabled)
 267:     return;
 268:     for(i = 0; i < BUCKETS; i++)
 269:     if (m_used[i] != 0) {
 270:         if (memdebug) {
 271:         if (j == 0)
 272:             fprintf(stderr,"unfree'ed buffers, indices: ");
 273:         fprintf(stderr,"%d, ", i);
 274:         j++;
 275:         }
 276:     }
 277:     if (j)
 278:     fprintf(stderr,"\n");
 279:     for(i = 0; i < BUCKETS; i++)
 280:     if (m_used2[i] != 0) {
 281:         if (memdebug) {
 282:         if (j == 0)
 283:             fprintf(stderr,"unfree'ed registered buffers, indices: ");
 284:         fprintf(stderr,"%d, ", i);
 285:         j++;
 286:         }
 287:     }
 288:     if (j)
 289:     fprintf(stderr,"\n");
 290:     if (j)
 291:     maybe_quit("Unfree'ed malloc buffers");
 292: }
 293: 
 294: VOID
 295: m_checkranges() {
 296:     int i;
 297: 
 298:     for ( i = 0; i < BUCKETS; i++)
 299:     if (m_used[i])
 300:         check_range(m_used[i]);
 301: }
 302: 
 303: static VOID
 304: maybe_quit(str) char *str; {
 305:     debug(F100,"mdebug maybe_quit","",0);
 306:     if (memdebug == 0)
 307:     return;
 308:     fprintf(stderr,"%s\n",str);
 309:     if (memdebug == 1)
 310:     abort();
 311:     if (memdebug == -1)
 312:     if (ask("Quit? "))
 313:         abort();
 314: }
 315: 
 316: static int
 317: ask(str) char *str; {
 318:     char buf[100];
 319:     FILE *in;
 320:     int fd;
 321: 
 322:     fd = dup(fileno(stdin));
 323:     in = fdopen(fd, "r");
 324:     while(1) {
 325:     fprintf(stderr,str);
 326:     fflush(stderr);
 327:     if (fgets(buf, 99, in) == NULL) /* EOF? */
 328:         return(0);
 329:     if (buf[0] == 'n' || buf[0] == 'N') {
 330:         fclose(in);
 331:         return(0);
 332:     }
 333:     if (buf[0] == 'y' || buf[0] == 'Y') {
 334:         fclose(in);
 335:         return(1);
 336:     }
 337:     fprintf(stderr,"please answer y/n.\n");
 338:     }
 339: }
 340: #endif /* MDEBUG */

Defined functions

ask defined in line 316; used 1 times
check_range defined in line 142; used 4 times
dcalloc defined in line 70; never used
dfree defined in line 98; never used
dmalloc defined in line 58; used 1 times
  • in line 74
drealloc defined in line 80; never used
m_checkranges defined in line 294; never used
m_delete defined in line 231; used 2 times
m_done defined in line 262; never used
m_init defined in line 252; never used
m_insert defined in line 202; used 2 times
m_insert2 defined in line 217; never used
maybe_check_range defined in line 170; used 2 times
maybe_quit defined in line 303; used 6 times
set_range_check defined in line 116; used 3 times

Defined variables

disabled defined in line 23; used 7 times
inited defined in line 24; used 1 times
m_used defined in line 199; used 8 times
m_used2 defined in line 200; used 5 times
memdebug defined in line 22; used 5 times

Defined macros

BUCKETS defined in line 198; used 10 times
INTSIZE defined in line 52; used 12 times
LONGSIZE defined in line 53; used 2 times
RANGE defined in line 51; used 7 times
RBACK defined in line 56; used 3 times
RFRONT defined in line 55; used 12 times
RSIZE defined in line 54; used 4 times
min defined in line 50; used 2 times
Last modified: 1992-11-24
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3075
Valid CSS Valid XHTML 1.0 Strict