ckcmdb.c
资源名称:cku197.tar.Z [点击查看]
上传用户:dufan58
上传日期:2007-01-05
资源大小:3407k
文件大小:8k
源码类别:
通讯/手机编程
开发平台:
Windows_Unix
- /*
- 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);
- }
- VOID
- dfree(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 overrunn");
- abort();
- break;
- }
- return(xp);
- }
- #define BUCKETS 10000
- char *m_used[BUCKETS];
- char *m_used2[BUCKETS];
- VOID
- m_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 VOID
- m_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 ++;
- }
- int
- m_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);
- }
- VOID
- m_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;
- }
- VOID
- m_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");
- }
- VOID
- m_checkranges() {
- int i;
- for ( i = 0; i < BUCKETS; i++)
- if (m_used[i])
- check_range(m_used[i]);
- }
- static VOID
- maybe_quit(str) char *str; {
- debug(F100,"mdebug maybe_quit","",0);
- if (memdebug == 0)
- return;
- fprintf(stderr,"%sn",str);
- if (memdebug == 1)
- abort();
- if (memdebug == -1)
- if (ask("Quit? "))
- abort();
- }
- static int
- ask(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 */