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