home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1996 May / PCOnline_05_1996.bin / linux / source / n / bind / bind-4.001 / bind-4~ / bind-4.9.3-BETA9 / named / dmalloc.c < prev    next >
C/C++ Source or Header  |  1994-07-02  |  8KB  |  313 lines

  1. /* dmalloc - debugging layer on top of malloc
  2.  * vix 25mar92 [fixed bug in round-up calcs in alloc()]
  3.  * vix 24mar92 [added size calcs, improved printout]
  4.  * vix 22mar92 [original work]
  5.  *
  6.  * $Id: dmalloc.c,v 4.9.1.3 1994/07/02 16:28:11 vixie Exp $
  7.  */
  8.  
  9. /*
  10.  * ++Copyright++ 1993
  11.  * -
  12.  * Copyright (c) 1993
  13.  *    The Regents of the University of California.  All rights reserved.
  14.  * 
  15.  * Redistribution and use in source and binary forms, with or without
  16.  * modification, are permitted provided that the following conditions
  17.  * are met:
  18.  * 1. Redistributions of source code must retain the above copyright
  19.  *    notice, this list of conditions and the following disclaimer.
  20.  * 2. Redistributions in binary form must reproduce the above copyright
  21.  *    notice, this list of conditions and the following disclaimer in the
  22.  *    documentation and/or other materials provided with the distribution.
  23.  * 3. All advertising materials mentioning features or use of this software
  24.  *    must display the following acknowledgement:
  25.  *     This product includes software developed by the University of
  26.  *     California, Berkeley and its contributors.
  27.  * 4. Neither the name of the University nor the names of its contributors
  28.  *    may be used to endorse or promote products derived from this software
  29.  *    without specific prior written permission.
  30.  * 
  31.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  32.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  33.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  34.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  35.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  39.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  40.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  41.  * SUCH DAMAGE.
  42.  * -
  43.  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
  44.  * 
  45.  * Permission to use, copy, modify, and distribute this software for any
  46.  * purpose with or without fee is hereby granted, provided that the above
  47.  * copyright notice and this permission notice appear in all copies, and that
  48.  * the name of Digital Equipment Corporation not be used in advertising or
  49.  * publicity pertaining to distribution of the document or software without
  50.  * specific, written prior permission.
  51.  * 
  52.  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  53.  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  54.  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
  55.  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  56.  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  57.  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  58.  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  59.  * SOFTWARE.
  60.  * -
  61.  * --Copyright--
  62.  */
  63.  
  64. #include <stdio.h>
  65. #include <signal.h>
  66. #include "../conf/portability.h"
  67. #include "../conf/options.h"
  68.  
  69. #ifdef DMALLOC
  70.  
  71. #define TRUE 1
  72. #define FALSE 0
  73. typedef    unsigned bool;
  74.  
  75. #define    MAX_MEMORY    65536    /* must fit in typeof(datum.size) */
  76. #define    MAX_CALLERS    256    /* must be **2 */
  77.  
  78. typedef struct caller {
  79.     struct caller    *next;
  80.     struct filenam    *file;
  81.     struct calltab    *frees;
  82.     unsigned    line;
  83.     unsigned    calls;
  84.     unsigned    blocks;
  85.     unsigned    bytes;
  86. } caller;
  87.  
  88. typedef    struct filenam {
  89.     struct filenam    *next;
  90.     char        *name;
  91. } filenam;
  92.  
  93. typedef    struct calltab {
  94.     struct caller    *callers[MAX_CALLERS];
  95. } calltab;
  96.  
  97. typedef struct datum {
  98.     unsigned    size;        /* size of malloc'd item */
  99.     unsigned    caller;        /* offset into memory[] */
  100.     /* user data follows */
  101. } datum;
  102.  
  103. static    char    memory[MAX_MEMORY];
  104. static    char    *nextmem = memory;
  105. static    char    *alloc(size) unsigned size; {
  106.             char *thismem = nextmem;
  107.             int oddness = (size % sizeof(char*));
  108.             if (oddness)
  109.                 size += (sizeof(char*) - oddness);
  110.             nextmem += size;
  111.             if (nextmem >= &memory[MAX_MEMORY]) {
  112.                 fprintf(stderr, "dmalloc.alloc: out of mem\n");
  113.                 kill(0, SIGBUS);
  114.             }
  115.             return thismem;
  116.         }
  117.  
  118. static    filenam    *Files;
  119. static    calltab    Callers;
  120.  
  121. /*--------------------------------------------------- imports
  122.  */
  123.  
  124. #undef    malloc
  125. #undef    calloc
  126. #undef    realloc
  127. #undef    free
  128.  
  129. char    *malloc(), *calloc(), *realloc();
  130.  
  131. #if    defined(sun)
  132. int    free();
  133. #else
  134. void    free();
  135. #endif
  136.  
  137. /*--------------------------------------------------- private
  138.  */
  139.  
  140. #define    STR_EQ(l,r)    (((l)[0] == (r)[0]) && !strcmp(l, r))
  141.  
  142. static filenam *
  143. findFile(file, addflag)
  144.     char *file;
  145.     bool addflag;
  146. {
  147.     filenam    *f;
  148.  
  149.     for (f = Files;  f;  f = f->next)
  150.         if (STR_EQ(file, f->name))
  151.             return f;
  152.     if (!addflag)
  153.         return NULL;
  154.     f = (filenam*) alloc(sizeof(filenam));
  155.     f->next = Files;
  156.     Files = f;
  157.     f->name = alloc(strlen(file) + 1);
  158.     strcpy(f->name, file);
  159.     return f;
  160. }
  161.  
  162. static caller *
  163. findCaller(ctab, file, line, addflag)
  164.     calltab *ctab;
  165.     char *file;
  166.     unsigned line;
  167.     bool addflag;
  168. {
  169.     unsigned hash = line & (MAX_CALLERS - 1);
  170.     caller *c;
  171.  
  172.     for (c = ctab->callers[hash];  c;  c = c->next)
  173.         if ((c->line == line) && STR_EQ(c->file->name, file))
  174.             return c;
  175.     if (!addflag)
  176.         return NULL;
  177.     c = (caller*) alloc(sizeof(caller));
  178.     c->next = ctab->callers[hash];
  179.     c->file = findFile(file, TRUE);
  180.     c->line = line;
  181.     c->calls = 0;
  182.     c->frees = (calltab *) alloc(sizeof(calltab));
  183.     ctab->callers[hash] = c;
  184.     return c;
  185. }
  186.  
  187. /*--------------------------------------------------- public
  188.  */
  189.  
  190. char *
  191. dmalloc(file, line, size)
  192.     char *file;
  193.     unsigned line;
  194.     unsigned size;
  195. {
  196.     caller *c;
  197.     datum *d;
  198.  
  199.     c = findCaller(&Callers, file, line, TRUE);
  200.     d = (datum *) malloc(sizeof(datum) + size);
  201.     d->size = size;
  202.     d->caller = ((char *)c) - memory;
  203.     c->calls++;
  204.     c->blocks++;
  205.     c->bytes += size;
  206.     return (char *) (d+1);
  207. }
  208.  
  209. void
  210. dfree(file, line, ptr)
  211.     char *file;
  212.     unsigned line;
  213.     char *ptr;
  214. {
  215.     caller *c, *a;
  216.     datum *d;
  217.  
  218.     d = (datum *) ptr;  d--;
  219.     a = (caller *) (memory + d->caller);
  220.     a->bytes -= d->size;
  221.     a->blocks--;
  222.     c = findCaller(a->frees, file, line, TRUE);
  223.     c->calls++;
  224.     free((char*) d);
  225. }
  226.  
  227. char *
  228. dcalloc(file, line, nelems, elsize)
  229.     char *file;
  230.     unsigned line;
  231.     unsigned nelems, elsize;
  232. {
  233.     unsigned size = (nelems * elsize);
  234.     char *ptr;
  235.  
  236.     ptr = dmalloc(file, line, size);
  237.     bzero(ptr, size);
  238.     return ptr;
  239. }
  240.  
  241. char *
  242. drealloc(file, line, ptr, size)
  243.     char *file;
  244.     unsigned line;
  245.     char *ptr;
  246.     unsigned size;
  247. {
  248.     caller *c, *a;
  249.     datum *d;
  250.  
  251.     d = (datum *) ptr;  d--;
  252.     /* fix up stats from allocation */
  253.     a = (caller *) (memory + d->caller);
  254.     a->bytes -= d->size;
  255.     a->blocks--;
  256.     /* we are a "freer" of this allocation */
  257.     c = findCaller(a->frees, file, line, TRUE);
  258.     c->calls++;
  259.     /* get new allocation and stat it */
  260.     c = findCaller(&Callers, file, line, TRUE);
  261.     d = (datum *) realloc((char *) d, sizeof(datum) + size);
  262.     d->size = size;
  263.     d->caller = ((char *)c) - memory;
  264.     c->calls++;
  265.     c->blocks++;
  266.     c->bytes += size;
  267.     return (char *) (d+1);
  268. }
  269.  
  270. static void
  271. dmalloccallers(outf, prefix, ctab)
  272.     FILE *outf;
  273.     char *prefix;
  274.     calltab *ctab;
  275. {
  276.     /* this bizarre logic is to print all of a file's entries together */
  277.     filenam    *f;
  278.  
  279.     for (f = Files;  f;  f = f->next) {
  280.         int    i;
  281.  
  282.         for (i = MAX_CALLERS-1;  i >= 0;  i--) {
  283.             caller *c;
  284.  
  285.             for (c = ctab->callers[i];  c;  c = c->next) {
  286.                 if (f != c->file)
  287.                     continue;
  288.                 fprintf(outf, "%s\"%s\":%u calls=%u",
  289.                     prefix, c->file->name, c->line,
  290.                     c->calls);
  291.                 if (c->blocks || c->bytes)
  292.                     fprintf(outf, " blocks=%u bytes=%u",
  293.                         c->blocks, c->bytes);
  294.                 fputc('\n', outf);
  295.                 if (c->frees)
  296.                     dmalloccallers(outf,
  297.                                "\t\t", c->frees);
  298.             }
  299.         }
  300.     }
  301. }
  302.  
  303. void
  304. dmallocstats(outf)
  305.     FILE *outf;
  306. {
  307.     fprintf(outf, "dallocstats [ private mem used=%u, avail=%u ]\n",
  308.         nextmem - memory, &memory[MAX_MEMORY] - nextmem);
  309.     dmalloccallers(outf, "\t", &Callers);
  310. }
  311.  
  312. #endif /*DMALLOC*/
  313.