root/dev/raidframe/rf_debugMem.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rf_record_malloc
  2. rf_unrecord_malloc
  3. rf_print_unfreed
  4. rf_ConfigureDebugMem
  5. rf_memory_hash_insert
  6. rf_memory_hash_remove

    1 /*      $OpenBSD: rf_debugMem.c,v 1.5 2002/12/16 07:01:03 tdeval Exp $  */
    2 /*      $NetBSD: rf_debugMem.c,v 1.7 2000/01/07 03:40:59 oster Exp $    */
    3 
    4 /*
    5  * Copyright (c) 1995 Carnegie-Mellon University.
    6  * All rights reserved.
    7  *
    8  * Author: Daniel Stodolsky, Mark Holland, Jim Zelenka
    9  *
   10  * Permission to use, copy, modify and distribute this software and
   11  * its documentation is hereby granted, provided that both the copyright
   12  * notice and this permission notice appear in all copies of the
   13  * software, derivative works or modified versions, and any portions
   14  * thereof, and that both notices appear in supporting documentation.
   15  *
   16  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   17  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
   18  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   19  *
   20  * Carnegie Mellon requests users of this software to return to
   21  *
   22  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   23  *  School of Computer Science
   24  *  Carnegie Mellon University
   25  *  Pittsburgh PA 15213-3890
   26  *
   27  * any improvements or extensions that they make and grant Carnegie the
   28  * rights to redistribute these changes.
   29  */
   30 
   31 /*
   32  * debugMem.c:  Memory usage debugging stuff.
   33  *
   34  * Malloc, Calloc, and Free are #defined everywhere
   35  * to do_malloc, do_calloc, and do_free.
   36  *
   37  * If RF_UTILITY is nonzero, it means we are compiling one of the
   38  * RAIDframe utility programs, such as rfctrl or smd. In this
   39  * case, we eliminate all references to the threads package
   40  * and to the allocation list stuff.
   41  */
   42 
   43 #include "rf_types.h"
   44 #include "rf_threadstuff.h"
   45 #include "rf_options.h"
   46 #include "rf_debugMem.h"
   47 #include "rf_general.h"
   48 
   49 static long tot_mem_in_use = 0;
   50 
   51 /* Hash table of information about memory allocations. */
   52 #define RF_MH_TABLESIZE         1000
   53 
   54 struct mh_struct {
   55         void            *address;
   56         int              size;
   57         int              line;
   58         char            *filen;
   59         char             allocated;
   60         struct mh_struct *next;
   61 };
   62 
   63 static struct mh_struct *mh_table[RF_MH_TABLESIZE];
   64 
   65 RF_DECLARE_MUTEX(rf_debug_mem_mutex);
   66 static int mh_table_initialized = 0;
   67 
   68 void rf_memory_hash_insert(void *, int, int, char *);
   69 int  rf_memory_hash_remove(void *, int);
   70 
   71 void
   72 rf_record_malloc(void *p, int size, int line, char *filen)
   73 {
   74         RF_ASSERT(size != 0);
   75 
   76         /*RF_LOCK_MUTEX(rf_debug_mem_mutex);*/
   77         rf_memory_hash_insert(p, size, line, filen);
   78         tot_mem_in_use += size;
   79         /*RF_UNLOCK_MUTEX(rf_debug_mem_mutex);*/
   80 
   81         if ((long) p == rf_memDebugAddress) {
   82                 printf("Allocate: debug address allocated from line %d file"
   83                     " %s\n", line, filen);
   84         }
   85 }
   86 
   87 void
   88 rf_unrecord_malloc(void *p, int sz)
   89 {
   90         int size;
   91 
   92         /*RF_LOCK_MUTEX(rf_debug_mem_mutex);*/
   93         size = rf_memory_hash_remove(p, sz);
   94         tot_mem_in_use -= size;
   95         /*RF_UNLOCK_MUTEX(rf_debug_mem_mutex);*/
   96         if ((long) p == rf_memDebugAddress) {
   97                 /* This is really only a flag line for gdb. */
   98                 printf("Free: Found debug address\n");
   99         }
  100 }
  101 
  102 void
  103 rf_print_unfreed(void)
  104 {
  105         int i, foundone = 0;
  106         struct mh_struct *p;
  107 
  108         for (i = 0; i < RF_MH_TABLESIZE; i++) {
  109                 for (p = mh_table[i]; p; p = p->next)
  110                         if (p->allocated) {
  111                                 if (!foundone)
  112                                         printf("\n\nThere are unfreed"
  113                                             " memory locations at"
  114                                             " program shutdown:\n");
  115                                 foundone = 1;
  116                                 printf("Addr 0x%lx Size %d line %d file %s\n",
  117                                     (long) p->address, p->size, p->line,
  118                                     p->filen);
  119                         }
  120         }
  121         if (tot_mem_in_use) {
  122                 printf("%ld total bytes in use\n", tot_mem_in_use);
  123         }
  124 }
  125 
  126 int
  127 rf_ConfigureDebugMem(RF_ShutdownList_t **listp)
  128 {
  129         int i, rc;
  130 
  131         rc = rf_create_managed_mutex(listp, &rf_debug_mem_mutex);
  132         if (rc) {
  133                 RF_ERRORMSG3("Unable to init mutex file %s line %d rc=%d\n",
  134                     __FILE__, __LINE__, rc);
  135                 return (rc);
  136         }
  137         if (rf_memDebug) {
  138                 for (i = 0; i < RF_MH_TABLESIZE; i++)
  139                         mh_table[i] = NULL;
  140                 mh_table_initialized = 1;
  141         }
  142         return (0);
  143 }
  144 
  145 #define HASHADDR(_a_)   ( (((unsigned long) _a_)>>3) % RF_MH_TABLESIZE )
  146 
  147 void
  148 rf_memory_hash_insert(void *addr, int size, int line, char *filen)
  149 {
  150         unsigned long bucket = HASHADDR(addr);
  151         struct mh_struct *p;
  152 
  153         RF_ASSERT(mh_table_initialized);
  154 
  155         /* Search for this address in the hash table. */
  156         for (p = mh_table[bucket]; p && (p->address != addr); p = p->next);
  157         if (!p) {
  158                 RF_Malloc(p, sizeof(struct mh_struct), (struct mh_struct *));
  159                 RF_ASSERT(p);
  160                 p->next = mh_table[bucket];
  161                 mh_table[bucket] = p;
  162                 p->address = addr;
  163                 p->allocated = 0;
  164         }
  165         if (p->allocated) {
  166                 printf("ERROR:  Reallocated address 0x%lx from line %d,"
  167                     " file %s without intervening free\n", (long) addr,
  168                     line, filen);
  169                 printf("        Last allocated from line %d file %s\n",
  170                     p->line, p->filen);
  171                 RF_ASSERT(0);
  172         }
  173         p->size = size;
  174         p->line = line;
  175         p->filen = filen;
  176         p->allocated = 1;
  177 }
  178 
  179 int
  180 rf_memory_hash_remove(void *addr, int sz)
  181 {
  182         unsigned long bucket = HASHADDR(addr);
  183         struct mh_struct *p;
  184 
  185         RF_ASSERT(mh_table_initialized);
  186         for (p = mh_table[bucket]; p && (p->address != addr); p = p->next);
  187         if (!p) {
  188                 printf("ERROR:  Freeing never-allocated address 0x%lx\n",
  189                     (long) addr);
  190                 RF_PANIC();
  191         }
  192         if (!p->allocated) {
  193                 printf("ERROR:  Freeing unallocated address 0x%lx."
  194                     "  Last allocation line %d file %s\n", (long) addr,
  195                     p->line, p->filen);
  196                 RF_PANIC();
  197         }
  198         if (sz > 0 && p->size != sz) {
  199                 /*
  200                  * This error can be suppressed by using a negative value
  201                  * as the size to free.
  202                  */
  203                 printf("ERROR:  Incorrect size at free for address 0x%lx:"
  204                     " is %d should be %d.  Alloc at line %d of file %s\n",
  205                     (unsigned long) addr, sz, p->size, p->line, p->filen);
  206                 RF_PANIC();
  207         }
  208         p->allocated = 0;
  209         return (p->size);
  210 }

/* [<][>][^][v][top][bottom][index][help] */