Annotation of sys/dev/raidframe/rf_debugMem.c, Revision 1.1
1.1 ! nbrk 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: }
CVSweb