⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbmalloc.c

📁 debug source code under unix platform.
💻 C
字号:
/* * mpatrol * A library for controlling and tracing dynamic memory allocations. * Copyright (C) 1997-2002 Graeme S. Roy <graeme.roy@analog.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307, USA. *//* * Dbmalloc-compatible interface.  Implements Dbmalloc functions using * mpatrol.  Dbmalloc is copyright (C) 1990-1992 Conor P. Cahill. */#include "config.h"#include "dbmalloc.h"#include <stdio.h>#if TARGET == TARGET_WINDOWS#include <io.h>#else /* TARGET */#include <unistd.h>#endif /* TARGET */#if MP_IDENT_SUPPORT#ident "$Id: dbmalloc.c,v 1.14 2002/01/08 20:05:10 graeme Exp $"#else /* MP_IDENT_SUPPORT */static MP_CONST MP_VOLATILE char *dbmalloc_id = "$Id: dbmalloc.c,v 1.14 2002/01/08 20:05:10 graeme Exp $";#endif /* MP_IDENT_SUPPORT *//* The structure used to pass information to the callback function from * __mp_iterate() when __mpt_dbmallocdump() and __mpt_dbmalloclist() are * called. */typedef struct listinfo{    int file;            /* file descriptor */    unsigned long event; /* upper event bound */    int header : 1;      /* header output flag */    int dump : 1;        /* dump output flag */}listinfo;#ifdef __cplusplusextern "C"{#endif /* __cplusplus *//* Indicates if this module has been initialised. */static int malloc_initialised;/* Specifies that more details should be shown when __mpt_dbmallocdump() is * called. */static int malloc_detail;/* Display the header for __mpt_dbmallocdump() and __mpt_dbmalloclist(). */staticvoidprintheader(int f){    char b[70 + (sizeof(void *) * 2)];    size_t i;    for (i = 0; i < 22 + sizeof(void *); i++)        b[i] = '*';    strcpy(b + i, " Dump of Malloc Chain ");    i += strlen(b + i);    while (i < 68 + (sizeof(void *) * 2))        b[i++] = '*';    b[i++] = '\n';    b[i] = '\0';    if (f > 0)        write(f, b, i);    else        __mp_printf(b);    for (i = 0; i < sizeof(void *) - 4; i++)        b[i] = ' ';    strcpy(b + i, "POINTER");    i += strlen(b + i);    while (i < 4 + (sizeof(void *) * 2))        b[i++] = ' ';    strcpy(b + i, "FILE  WHERE         LINE      ALLOC        DATA     "           "HEX DUMP\n");    i += strlen(b + i);    if (f > 0)        write(f, b, i);    else        __mp_printf(b);    for (i = 0; i < sizeof(void *) - 4; i++)        b[i] = ' ';    strcpy(b + i, "TO DATA");    i += strlen(b + i);    while (i < 5 + (sizeof(void *) * 2))        b[i++] = ' ';    strcpy(b + i, "ALLOCATED         NUMBER     FUNCT       LENGTH  "           "OF BYTES 1-7\n");    i += strlen(b + i);    if (f > 0)        write(f, b, i);    else        __mp_printf(b);    for (i = 0; i < sizeof(void *) * 2; i++)        b[i] = '-';    b[i++] = ' ';    while (i < 21 + (sizeof(void *) * 2))        b[i++] = '-';    b[i++] = ' ';    while (i < 29 + (sizeof(void *) * 2))        b[i++] = '-';    b[i++] = ' ';    while (i < 44 + (sizeof(void *) * 2))        b[i++] = '-';    b[i++] = ' ';    while (i < 52 + (sizeof(void *) * 2))        b[i++] = '-';    b[i++] = ' ';    while (i < 67 + (sizeof(void *) * 2))        b[i++] = '-';    b[i++] = '\n';    b[i] = '\0';    if (f > 0)        write(f, b, i);    else        __mp_printf(b);}/* The callback function that is called by __mp_iterate() for every heap * allocation that has changed since a specified heap event. */staticintcallback(MP_CONST void *p, void *t){    char b[69 + (sizeof(void *) * 2)];    char m[64];    listinfo *i;    __mp_allocstack *a;    __mp_allocinfo d;    __mp_symbolinfo s;    size_t j, n;    if (!__mp_info(p, &d))        return 0;    i = (listinfo *) t;    if ((d.event <= i->event) && (!d.freed || (i->dump && malloc_detail)) &&        (!d.marked || i->dump))    {        if (!i->header)        {            printheader(i->file);            i->header = 1;        }        sprintf(b, "%0*lX ", sizeof(void *) * 2, d.block);        n = strlen(b);        if (d.file != NULL)        {            sprintf(m, "%7lu", d.line);            sprintf(b + n, "%-20.20s %7.7s ", d.file, m);        }        else            sprintf(b + n, "%-28s ", "unknown");        n += strlen(b + n);        sprintf(m, "%s(%lu)", __mp_function(d.type), d.alloc);        sprintf(b + n, "%-14.14s ", m);        n += strlen(b + n);        sprintf(m, "%7lu", d.size);        sprintf(b + n, "%7.7s ", m);        n += strlen(b + n);        for (j = 0; (j < 7) && (j < d.size); j++)            sprintf(m + (j << 1), "%02X", ((unsigned char *) d.block)[j]);        m[j << 1] = '\0';        sprintf(b + n, "%s\n", m);        n += strlen(b + n);        if (i->file > 0)            write(i->file, b, n);        else            __mp_printf(b);        for (a = d.stack; a != NULL; a = a->next)        {            for (n = 0; n <= sizeof(void *) * 2; n++)                b[n] = ' ';            strcpy(b + n, "-> ");            n += 3;            if (__mp_syminfo(a->addr, &s))                if (i->file > 0)                {                    write(i->file, b, n);                    write(i->file, s.name, strlen(s.name));                    if (s.file != NULL)                    {                        write(i->file, " in ", 4);                        write(i->file, s.file, strlen(s.file));                        sprintf(b, "(%lu)\n", s.line);                        write(i->file, b, strlen(b));                    }                    else                        write(i->file, "\n", 1);                }                else if (s.file != NULL)                    __mp_printf("%s%s in %s(%lu)\n", b, s.name, s.file, s.line);                else                    __mp_printf("%s%s\n", b, s.name);            else            {                sprintf(b + n, "%0*lX\n", sizeof(void *) * 2, a->addr);                n += strlen(b + n);                if (i->file > 0)                    write(i->file, b, n);                else                    __mp_printf(b);            }        }        return 1;    }    return 0;}/* Set a malloc library option. */int__mpt_dbmallocoption(int c, union dbmalloptarg *v){    char *s;    unsigned long n;    int r;    if (!malloc_initialised)        __mp_init_dbmalloc();    r = 0;    switch (c)    {      case MALLOC_ERRFILE:        if (strcmp(v->str, "-") == 0)            s = "stderr";        else            s = v->str;        r = __mp_setoption(MP_OPT_LOGFILE, (unsigned long) s);        break;      case MALLOC_CKCHAIN:        if (v->i != 0)            n = (unsigned long) -1;        else            n = 0;        if (((r = __mp_setoption(MP_OPT_CHECKLOWER, n)) == 0) &&            ((r = __mp_setoption(MP_OPT_CHECKUPPER, n)) == 0))            r = __mp_setoption(MP_OPT_CHECKFREQ, 1);        break;      case MALLOC_FILLAREA:        if (v->i == 0)            n = 0;        else if (!__mp_getoption(MP_OPT_OFLOWSIZE, &n) || (n == 0))            n = 1;        if ((r = __mp_setoption(MP_OPT_OFLOWSIZE, n)) == 0)        {            if ((v->i >= 0) && (v->i <= 2))                c = MP_OPT_SETFLAGS;            else                c = MP_OPT_UNSETFLAGS;            r = __mp_setoption(c, MP_FLG_PRESERVE);        }        break;      case MALLOC_REUSE:        if (v->i != 0)            n = 0;        else            n = ~0L;        r = __mp_setoption(MP_OPT_NOFREE, n);        break;      case MALLOC_DETAIL:        malloc_detail = v->i;        break;      case MALLOC_ZERO:        if (v->i != 0)            c = MP_OPT_SETFLAGS;        else            c = MP_OPT_UNSETFLAGS;        if (__mp_setoption(c, MP_FLG_CHECKALLOCS))            r = 1;        break;      default:        r = 1;        break;    }    return r;}/* Display a malloc library error message. */void__mpt_dbmallocperror(MP_CONST char *s){    if ((s != NULL) && (*s != '\0'))        fprintf(stderr, "%s: ", s);    if ((s = __mp_strerror(__mp_errno)) == NULL)        s = "unknown error";    fprintf(stderr, "%s\n", s);}/* Verify that the malloc chain is still intact and the heap has not been * corrupted. */int__mpt_dbmallocchaincheck(int f, MP_CONST char *s, MP_CONST char *t,                         unsigned long u){    if (!malloc_initialised)        __mp_init_dbmalloc();    __mp_checkheap(s, t, u);    return 0;}/* Display all of the heap allocations and their associated data. */void__mpt_dbmallocdump(int f){    listinfo i;    if (!malloc_initialised)        __mp_init_dbmalloc();    i.file = f;    i.event = __mp_snapshot();    i.header = 0;    i.dump = 1;    __mp_iterate(callback, &i, 0);    if (f > 0)        write(f, "\n", 1);    else if (i.header)        __mp_printf("\n");}/* Display some of the heap allocations and their associated data. */void__mpt_dbmalloclist(int f, unsigned long l, unsigned long u){    listinfo i;    if (!malloc_initialised)        __mp_init_dbmalloc();    i.file = f;    if (l <= u)        i.event = u;    else    {        i.event = l;        l = u;        u = i.event;    }    i.header = 0;    i.dump = 0;    __mp_iterate(callback, &i, l);    if (f > 0)        write(f, "\n", 1);    else if (i.header)        __mp_printf("\n");}/* Return the number of bytes of heap memory currently in use and optionally * return the current malloc history id. */unsigned long__mpt_dbmallocinuse(unsigned long *h){    __mp_heapinfo i;    unsigned long t;    if (!malloc_initialised)        __mp_init_dbmalloc();    if (__mp_stats(&i))        t = i.atotal - i.mtotal;    else        t = 0;    if (h != NULL)        *h = __mp_snapshot();    return t;}/* Return the size in bytes of the memory allocation that contains a specified * address. */size_t__mpt_dbmallocsize(MP_CONST void *p){    __mp_allocinfo i;    size_t t;    if (!malloc_initialised)        __mp_init_dbmalloc();    if (__mp_info(p, &i) && i.allocated && !i.freed)        t = i.size;    else        t = (size_t) -1;    return t;}/* Initialise the dbmalloc module. */void__mp_init_dbmalloc(void){    char *v;    union dbmalloptarg a;    long n;    if (!malloc_initialised)    {        malloc_initialised = 1;        malloc_detail = 0;        if ((v = getenv("MALLOC_BOUNDSIZE")) && (*v != '\0'))        {            if ((n = strtol(v, NULL, 10)) < 1)                n = 1;            __mp_setoption(MP_OPT_OFLOWSIZE, n);        }        if ((v = getenv("MALLOC_FILLBYTE")) && (*v != '\0'))        {            if (((n = strtol(v, NULL, 10)) < 0) || (n > 255))                n = 1;            __mp_setoption(MP_OPT_ALLOCBYTE, n);        }        if ((v = getenv("MALLOC_FREEBYTE")) && (*v != '\0'))        {            if (((n = strtol(v, NULL, 10)) < 0) || (n > 255))                n = 2;            __mp_setoption(MP_OPT_FREEBYTE, n);        }        if ((v = getenv("MALLOC_WARN")) && (*v != '\0'))        {            a.i = strtol(v, NULL, 10);            __mpt_dbmallocoption(MALLOC_WARN, &a);        }        if ((v = getenv("MALLOC_FATAL")) && (*v != '\0'))        {            a.i = strtol(v, NULL, 10);            __mpt_dbmallocoption(MALLOC_FATAL, &a);        }        if ((v = getenv("MALLOC_ERRFILE")) && (*v != '\0'))        {            a.str = v;            __mpt_dbmallocoption(MALLOC_ERRFILE, &a);        }        if ((v = getenv("MALLOC_CKCHAIN")) && (*v != '\0'))        {            a.i = strtol(v, NULL, 10);            __mpt_dbmallocoption(MALLOC_CKCHAIN, &a);        }        if ((v = getenv("MALLOC_FILLAREA")) && (*v != '\0'))        {            a.i = strtol(v, NULL, 10);            __mpt_dbmallocoption(MALLOC_FILLAREA, &a);        }        if ((v = getenv("MALLOC_LOWFRAG")) && (*v != '\0'))        {            a.i = strtol(v, NULL, 10);            __mpt_dbmallocoption(MALLOC_LOWFRAG, &a);        }        if ((v = getenv("MALLOC_CKDATA")) && (*v != '\0'))        {            a.i = strtol(v, NULL, 10);            __mpt_dbmallocoption(MALLOC_CKDATA, &a);        }        if ((v = getenv("MALLOC_REUSE")) && (*v != '\0'))        {            a.i = strtol(v, NULL, 10);            __mpt_dbmallocoption(MALLOC_REUSE, &a);        }        if ((v = getenv("MALLOC_SHOWLINKS")) && (*v != '\0'))        {            a.i = strtol(v, NULL, 10);            __mpt_dbmallocoption(MALLOC_SHOWLINKS, &a);        }        if ((v = getenv("MALLOC_DETAIL")) && (*v != '\0'))        {            a.i = strtol(v, NULL, 10);            __mpt_dbmallocoption(MALLOC_DETAIL, &a);        }        if ((v = getenv("MALLOC_FREEMARK")) && (*v != '\0'))        {            a.i = strtol(v, NULL, 10);            __mpt_dbmallocoption(MALLOC_FREEMARK, &a);        }        if ((v = getenv("MALLOC_ZERO")) && (*v != '\0'))        {            a.i = strtol(v, NULL, 10);            __mpt_dbmallocoption(MALLOC_ZERO, &a);        }    }}#ifdef __cplusplus}#endif /* __cplusplus */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -