📄 ckcmdb.c
字号:
/* C K C M D B . C -- malloc debugger.*//* Author: Howie Kaye, Columbia University Center for Computing Activities. Copyright (C) 1985, 1999, Trustees of Columbia University in the City of New York. All rights reserved. See the C-Kermit COPYING.TXT file or the copyright text in the ckcmai.c module for disclaimer and permissions.*//* Use the real ones in this module! */#ifdef malloc#undef malloc#endif /* malloc */#ifdef calloc#undef calloc#endif /* calloc */#ifdef realloc#undef realloc#endif /* realloc */#ifdef free#undef free#endif /* free */#include "ckcsym.h"#include <stdio.h>#include "ckcdeb.h"#ifdef COHERENT_PROTOTYP ( FILE * fdopen, (int, char *) );#endif /* COHERENT *//* memdebug: variable to control memory debugging. if memdebug == 1, then action is always taken. if memdebug == 0, then no action is taken. if memdebug == -1, then the user is asked (works well with gdb).*/int memdebug = -1;int disabled = 0;int inited = 0;/* To use this package, compile your program with: -Dmalloc=dmalloc -Dfree=dfree =Dcalloc=dcalloc ... -DMDEBUG and then link it with ckcmdb.c.*/#ifdef MDEBUG#ifndef M_SIZE_T#ifdef NEXT#define M_SIZE_T size_t#else#ifdef SUNOS41#define M_SIZE_T unsigned#else#define M_SIZE_T int#endif /* SUNOS41 */#endif /* NEXT */#endif /* M_SIZE_T */#ifdef CK_ANSIC_PROTOTYP( void free, (void *) );_PROTOTYP( void * malloc, (size_t) );_PROTOTYP( void * realloc, (void *, size_t) );#else_PROTOTYP( VOID free, (char *) );_PROTOTYP( char * malloc, (M_SIZE_T) );_PROTOTYP( char * realloc, (char *, M_SIZE_T) );#endif /* NEXT */_PROTOTYP( VOID m_insert, (char *) );_PROTOTYP( int m_delete, (char *) );_PROTOTYP( char * dmalloc, (int) );_PROTOTYP( char * dcalloc, (int, int) );_PROTOTYP( char * drealloc, (char *, int) );_PROTOTYP( char *set_range_check, (char *, int) );_PROTOTYP( char *check_range, (char *) );_PROTOTYP( static char *maybe_check_range, (char *) );_PROTOTYP( static VOID maybe_quit, (char *) );_PROTOTYP( static int ask, (char *) );#ifndef min#define min(x,y) ((x) < (y) ? (x) : (y))#endif /* min */#define RANGE "ABCDEFGHIJKLMNOP"#define INTSIZE sizeof(int)#define LONGSIZE sizeof(long)#define RSIZE sizeof(RANGE)#define RFRONT min((RSIZE/2),LONGSIZE)#define RBACK min((RSIZE-RFRONT),LONGSIZE)char *dmalloc(size) int size; { char *cp; cp = malloc(size + RSIZE + INTSIZE); if (cp) { cp = set_range_check(cp, size); m_insert(cp); } return(cp);}char *dcalloc(nelem, elsize) int nelem, elsize; { char *cp; cp = dmalloc(nelem * elsize); if (cp) memset(cp, 0, nelem * elsize); return(cp);}char *drealloc(bp,size) char *bp; int size; { char *cp; if (bp == NULL) { maybe_quit("Freeing NULL pointer"); } else { m_delete(bp); cp = check_range(bp); } cp = realloc(cp, size + RSIZE + INTSIZE); if (cp) { cp = set_range_check(cp, size); m_insert(cp); } return(cp);}VOIDdfree(cp) char *cp; { if (cp == NULL) maybe_quit("Freeing NULL pointer"); else { switch(m_delete(cp)) { case 0: cp = maybe_check_range(cp); break; case 1: cp = check_range(cp); break; case 2: break; } }#ifndef CK_ANSIC return(free(cp));#endif /* CK_ANSIC */}char *set_range_check(cp,size) char *cp; int size; { register int i; int tmp = size; for(i = 0; i < INTSIZE; i++) { /* set the size in the string */ cp[i] = tmp & 0xff; tmp >>= 8; } cp += INTSIZE; /* skip the size */ for(i = 0; i < RFRONT; i++) /* set the front of the range check */ cp[i] = RANGE[i]; /* string */ cp += RFRONT; /* skip the front range check */ for(i = 0; i < RBACK; i++) /* set the back odf the range check */ cp[i+size] = RANGE[i+RFRONT]; return(cp);}/* Put calls to this routine in your code any place where you want to check whether you've copied too many characters into a malloc'd space.*/char *check_range(cp) char *cp; { register char *bp = cp - RFRONT - INTSIZE; char *xp = bp; register int i; int size = 0; for(i = 0 ; i < INTSIZE; i++) { /* get the size out of the string */ size <<= 8; size |= bp[INTSIZE-i-1] & 0xff; } bp += INTSIZE; for(i = 0; i < RFRONT; i++) /* check front range check */ if (bp[i] != RANGE[i]) { maybe_quit("leftside malloc buffer overrun"); break; } bp += RFRONT; /* skip front range check */ for(i = 0; i < RBACK; i++) /* check back range check */ if (bp[i+size] != RANGE[i+RFRONT]) { maybe_quit("rightside malloc buffer overrun"); break; } return(xp);}static char *maybe_check_range(cp) char *cp; { register char *bp = cp - RFRONT - INTSIZE; char *xp = bp; register int i; int size = 0; for(i = 0 ; i < INTSIZE; i++) { /* get the size out of the string */ size <<= 8; size |= bp[INTSIZE-i-1] & 0xff; } bp += INTSIZE; for(i = 0; i < RFRONT; i++) /* check front range check */ if (bp[i] != RANGE[i]) { return(cp); } bp += RFRONT; /* skip front range check */ for(i = 0; i < RBACK; i++) /* check back range check */ if (bp[i+size] != RANGE[i+RFRONT]) { fprintf(stderr,"rightside malloc buffer overrun\n"); abort(); break; } return(xp);}#define BUCKETS 10000char *m_used[BUCKETS];char *m_used2[BUCKETS];VOIDm_insert(cp) register char *cp; { register int i; if (disabled) return; for(i = 0; i < BUCKETS; i++) if (m_used[i] == 0) { m_used[i] = cp; return; } disabled ++;}static VOIDm_insert2(cp) register char *cp; { register int i; if (disabled) return; for(i = 0; i < BUCKETS; i++) if (m_used2[i] == 0) { m_used2[i] = cp; return; } disabled ++;}intm_delete(cp) register char *cp; { register int i; for(i = 0; i < BUCKETS; i++) if (m_used[i] == cp) { m_used[i] = 0; return(1); } for(i = 0; i < BUCKETS; i++) if (m_used2[i] == cp) { m_used2[i] = 0; return(2); } if (disabled) return(0); maybe_quit("Freeing unmalloc'ed pointer"); return(0);}VOIDm_init() { register int i; inited = 1; disabled = 0;#ifdef NEXT malloc_debug(2+4+8+16);#endif /* NEXT */ for(i = 0; i < BUCKETS; i++) m_used[i] = 0;}VOIDm_done() { register int i,j=0; if (disabled) return; for(i = 0; i < BUCKETS; i++) if (m_used[i] != 0) { if (memdebug) { if (j == 0) fprintf(stderr,"unfree'ed buffers, indices: "); fprintf(stderr,"%d, ", i); j++; } } if (j) fprintf(stderr,"\n"); for(i = 0; i < BUCKETS; i++) if (m_used2[i] != 0) { if (memdebug) { if (j == 0) fprintf(stderr,"unfree'ed registered buffers, indices: "); fprintf(stderr,"%d, ", i); j++; } } if (j) fprintf(stderr,"\n"); if (j) maybe_quit("Unfree'ed malloc buffers");}VOIDm_checkranges() { int i; for ( i = 0; i < BUCKETS; i++) if (m_used[i]) check_range(m_used[i]);}static VOIDmaybe_quit(str) char *str; { debug(F100,"mdebug maybe_quit","",0); if (memdebug == 0) return; fprintf(stderr,"%s\n",str); if (memdebug == 1) abort(); if (memdebug == -1) if (ask("Quit? ")) abort();}static intask(str) char *str; { char buf[100]; FILE *in; int fd; fd = dup(fileno(stdin)); in = fdopen(fd, "r"); while(1) { fprintf(stderr,str); fflush(stderr); if (fgets(buf, 99, in) == NULL) /* EOF? */ return(0); if (buf[0] == 'n' || buf[0] == 'N') { fclose(in); return(0); } if (buf[0] == 'y' || buf[0] == 'Y') { fclose(in); return(1); } fprintf(stderr,"please answer y/n.\n"); }}#endif /* MDEBUG */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -