|
|
1.1 ! root 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) 1986, 1990 by The Trustees of Columbia University in ! 8: the City of New York. Permission is granted to any individual or ! 9: institution to use, copy, or redistribute this software so long as it ! 10: is not sold for profit, provided this copyright notice is retained. ! 11: */ ! 12: #include <stdio.h> ! 13: #include "ckcdeb.h" ! 14: /* ! 15: memdebug: ! 16: variable to control memory debugging. ! 17: if memdebug == 1, then action is always taken. ! 18: if memdebug == 0, then no action is taken. ! 19: if memdebug == -1, then the user is asked (works well with gdb). ! 20: */ ! 21: int memdebug = -1; ! 22: /* ! 23: To use this package, compile your program with: ! 24: -Dmalloc=dmalloc -Dfree=dfree =Dcalloc=dcalloc ... -DMDEBUG ! 25: and then link it with ckcmdb.c. ! 26: */ ! 27: #ifdef MDEBUG ! 28: /* Use the real ones in this module! */ ! 29: #ifdef malloc ! 30: #undef malloc ! 31: #endif /* malloc */ ! 32: #ifdef calloc ! 33: #undef calloc ! 34: #endif /* calloc */ ! 35: #ifdef realloc ! 36: #undef realloc ! 37: #endif /* realloc */ ! 38: #ifdef free ! 39: #undef free ! 40: #endif /* free */ ! 41: ! 42: char *malloc(), *realloc(); ! 43: char *set_range_check(), *check_range(); ! 44: ! 45: #define min(x,y) ((x) < (y) ? (x) : (y)) ! 46: #define RANGE "ABCDEFGHIJKLMNOP" ! 47: #define INTSIZE sizeof(int) ! 48: #define LONGSIZE sizeof(long) ! 49: #define RSIZE sizeof(RANGE) ! 50: #define RFRONT min((RSIZE/2),LONGSIZE) ! 51: #define RBACK min((RSIZE-RFRONT),LONGSIZE) ! 52: ! 53: char * ! 54: dmalloc(size) int size; { ! 55: char *cp; ! 56: ! 57: cp = malloc(size + RSIZE + INTSIZE); ! 58: if (cp) { ! 59: cp = set_range_check(cp, size); ! 60: m_insert(cp); ! 61: } ! 62: return(cp); ! 63: } ! 64: ! 65: char * ! 66: dcalloc(nelem, elsize) int nelem, elsize; { ! 67: char *cp; ! 68: ! 69: cp = dmalloc(nelem * elsize); ! 70: if (cp) ! 71: bzero(cp, nelem * elsize); ! 72: return(cp); ! 73: } ! 74: ! 75: char * ! 76: drealloc(bp,size) char *bp; int size; { ! 77: char *cp; ! 78: ! 79: if (bp == NULL) { ! 80: maybe_quit("Freeing NULL pointer"); ! 81: } else { ! 82: m_delete(bp); ! 83: cp = check_range(bp); ! 84: } ! 85: cp = realloc(cp, size + RSIZE + INTSIZE); ! 86: if (cp) { ! 87: cp = set_range_check(cp, size); ! 88: m_insert(cp); ! 89: } ! 90: return(cp); ! 91: } ! 92: ! 93: dfree(cp) char *cp; { ! 94: if (cp == NULL) ! 95: maybe_quit("Freeing NULL pointer"); ! 96: else { ! 97: m_delete(cp); ! 98: cp = check_range(cp); ! 99: } ! 100: return(free(cp)); ! 101: } ! 102: ! 103: char * ! 104: set_range_check(cp,size) char *cp; int size; { ! 105: register int i; ! 106: int tmp = size; ! 107: ! 108: for(i = 0; i < INTSIZE; i++) { /* set the size in the string */ ! 109: cp[i] = tmp & 0xff; ! 110: tmp >>= 8; ! 111: } ! 112: cp += INTSIZE; /* skip the size */ ! 113: ! 114: for(i = 0; i < RFRONT; i++) /* set the front of the range check */ ! 115: cp[i] = RANGE[i]; /* string */ ! 116: ! 117: cp += RFRONT; /* skip the front range check */ ! 118: ! 119: for(i = 0; i < RBACK; i++) /* set the back odf the range check */ ! 120: cp[i+size] = RANGE[i+RFRONT]; ! 121: ! 122: return(cp); ! 123: } ! 124: ! 125: /* ! 126: Put calls to this routine in your code any place where you want to ! 127: check whether you've copied too many characters into a malloc'd space. ! 128: */ ! 129: char * ! 130: check_range(cp) char *cp; { ! 131: register char *bp = cp - RFRONT - INTSIZE; ! 132: char *xp = bp; ! 133: register int i; ! 134: int size = 0; ! 135: ! 136: for(i = 0 ; i < INTSIZE; i++) { /* get the size out of the string */ ! 137: size <<= 8; ! 138: size |= bp[INTSIZE-i-1] & 0xff; ! 139: } ! 140: bp += INTSIZE; ! 141: ! 142: for(i = 0; i < RFRONT; i++) /* check front range check */ ! 143: if (bp[i] != RANGE[i]) { ! 144: maybe_quit("leftside malloc buffer overrun"); ! 145: break; ! 146: } ! 147: bp += RFRONT; /* skip front range check */ ! 148: ! 149: for(i = 0; i < RBACK; i++) /* check back rnage check */ ! 150: if (bp[i+size] != RANGE[i+RFRONT]) { ! 151: maybe_quit("rightside malloc buffer overrun"); ! 152: break; ! 153: } ! 154: return(xp); ! 155: } ! 156: ! 157: #define BUCKETS 10000 ! 158: char *m_used[BUCKETS]; ! 159: ! 160: VOID ! 161: m_insert(cp) register char *cp; { ! 162: register int i; ! 163: ! 164: for(i = 0; i < BUCKETS; i++) ! 165: if (m_used[i] == 0) { ! 166: m_used[i] = cp; ! 167: return; ! 168: } ! 169: } ! 170: ! 171: VOID ! 172: m_delete(cp) register char *cp; { ! 173: register int i; ! 174: ! 175: for(i = 0; i < BUCKETS; i++) ! 176: if (m_used[i] == cp) { ! 177: m_used[i] = 0; ! 178: return; ! 179: } ! 180: maybe_quit("Freeing unmalloc'ed pointer"); ! 181: } ! 182: ! 183: VOID ! 184: m_init() { ! 185: register int i; ! 186: for(i = 0; i < BUCKETS; i++) ! 187: m_used[i] = 0; ! 188: } ! 189: ! 190: VOID ! 191: m_done() { ! 192: register int i,j; ! 193: ! 194: for(i = 0; i < BUCKETS; i++) ! 195: if (m_used[i] != 0) { ! 196: if (memdebug) { ! 197: if (j == 0) ! 198: fprintf(stderr,"unfree'ed buffers, indices: "); ! 199: fprintf(stderr,"%d, ", i); ! 200: j++; ! 201: } ! 202: } ! 203: if (j) ! 204: fprintf(stderr,"\n"); ! 205: if (j) ! 206: maybe_quit("Unfree'ed malloc buffers"); ! 207: } ! 208: ! 209: VOID ! 210: m_checkranges() { ! 211: int i; ! 212: ! 213: for ( i = 0; i < BUCKETS; i++) ! 214: if (m_used[i]) ! 215: check_range(m_used[i]); ! 216: } ! 217: ! 218: static VOID ! 219: maybe_quit(str) char *str; { ! 220: debug(F100,"mdebug maybe_quit","",0); ! 221: if (memdebug == 0) ! 222: return; ! 223: fprintf(stderr,"%s\n",str); ! 224: if (memdebug == 1) ! 225: abort(); ! 226: if (memdebug == -1) ! 227: if (ask("Quit? ")) ! 228: abort(); ! 229: } ! 230: ! 231: static int ! 232: ask(str) char *str; { ! 233: char buf[100]; ! 234: FILE *in; ! 235: int fd; ! 236: ! 237: fd = dup(fileno(stdin)); ! 238: in = fdopen(fd, "r"); ! 239: while(1) { ! 240: fprintf(stderr,str); ! 241: fflush(stderr); ! 242: if (fgets(buf, 99, in) == NULL) /* EOF? */ ! 243: return(0); ! 244: if (buf[0] == 'n' || buf[0] == 'N') { ! 245: fclose(in); ! 246: return(0); ! 247: } ! 248: if (buf[0] == 'y' || buf[0] == 'Y') { ! 249: fclose(in); ! 250: return(1); ! 251: } ! 252: fprintf(stderr,"please answer y/n.\n"); ! 253: } ! 254: } ! 255: #endif /* MDEBUG */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.