Doxygen Source Code Documentation
Main Page Alphabetical List Data Structures File List Data Fields Globals Search
dmalloc.c
Go to the documentation of this file.00001 #include <stdio.h>
00002 #include <stdlib.h>
00003
00004 typedef struct bucket {
00005 size_t size;
00006 const char *file;
00007 int line;
00008 struct bucket *next;
00009 } bucket;
00010
00011 #define NBUCK 5779
00012 static bucket *buckets[NBUCK];
00013 static int event_number;
00014 static FILE *verbose_out = 0;
00015
00016 size_t dmalloc_live_memory;
00017
00018
00019 void *
00020 debug_malloc_id(size_t k, const char *file, int line)
00021 {
00022 void *p = malloc(k + sizeof(bucket));
00023 bucket *b = (bucket *)p;
00024 int bnum = (((long)p) >> 4) % NBUCK;
00025
00026 if (p == 0) {
00027 fprintf(stderr, "dmalloc:%s:%d: virtual memory exhausted (wanted %d)\n",
00028 file, line, k);
00029 abort();
00030 }
00031
00032 b->size = k;
00033 b->next = buckets[bnum];
00034 b->file = file;
00035 b->line = line;
00036 buckets[bnum] = b;
00037 dmalloc_live_memory += k;
00038 p = (void *)(((char *)p) + sizeof(bucket));
00039
00040 if (verbose_out)
00041 fprintf(verbose_out, "%5d: %p +%-7d (%s:%d) ++ %d\n", event_number,
00042 p, b->size, file, line, dmalloc_live_memory);
00043 event_number++;
00044 return p;
00045 }
00046
00047 void *
00048 debug_realloc_id(void *p, size_t k, const char *file, int line)
00049 {
00050 bucket *b_in = (bucket *)(((char *)p) - sizeof(bucket));
00051 bucket *b;
00052 bucket *prev;
00053 bucket *new_b;
00054 int bnum = (((long)b_in) >> 4) % NBUCK;
00055 if (p == 0) return debug_malloc_id(k, file, line);
00056
00057 for (b = buckets[bnum], prev = 0; b && b != b_in; prev = b, b = b->next)
00058 ;
00059 if (b == 0) {
00060 fprintf(stderr, "debug_realloc given bad pointer %p\n", p);
00061 abort();
00062 }
00063
00064 dmalloc_live_memory += k - b->size;
00065 if (verbose_out)
00066 fprintf(verbose_out, "%5d: %p +%-7d (%s:%d) >> ", event_number,
00067 p, b->size, b->file, b->line);
00068
00069 new_b = (bucket *)realloc(b, k + sizeof(bucket));
00070 if (new_b == 0) {
00071 fprintf(stderr, "dmalloc:%s:%d: virtual memory exhausted (wanted %d)\n",
00072 file, line, k);
00073 abort();
00074 }
00075
00076 new_b->size = k;
00077 if (new_b != b) {
00078 if (prev) prev->next = new_b->next;
00079 else buckets[bnum] = new_b->next;
00080
00081 bnum = (((long)new_b) >> 4) % NBUCK;
00082 new_b->next = buckets[bnum];
00083 buckets[bnum] = new_b;
00084
00085 p = (void *)(((char *)new_b) + sizeof(bucket));
00086 }
00087
00088 if (verbose_out)
00089 fprintf(verbose_out, "%p +%-7d (%s:%d)\n", p, k, file, line);
00090 event_number++;
00091 return p;
00092 }
00093
00094
00095 void
00096 debug_free_id(void *p, const char *file, int line)
00097 {
00098 bucket *b_in = (bucket *)(((char *)p) - sizeof(bucket));
00099 bucket *b;
00100 bucket *prev;
00101 int chain_length = 0;
00102 int bnum = (((long)b_in) >> 4) % NBUCK;
00103 if (p == 0) return;
00104
00105 for (b = buckets[bnum], prev = 0; b && b != b_in; prev = b, b = b->next)
00106 chain_length++;
00107 if (b == 0) {
00108 fprintf(stderr, "my_free given bad pointer %p\n", p);
00109 abort();
00110 }
00111
00112 dmalloc_live_memory -= b->size;
00113 if (prev) prev->next = b->next;
00114 else buckets[bnum] = b->next;
00115
00116 if (verbose_out)
00117 fprintf(verbose_out, "%5d: %p +%-7d (%s:%d) -- %s:%d %d\n", event_number,
00118 p, b->size, b->file, b->line, file, line, dmalloc_live_memory);
00119 event_number++;
00120 free(b_in);
00121 }
00122
00123
00124 #undef debug_malloc
00125 #undef debug_realloc
00126 #undef debug_free
00127
00128 void *
00129 debug_malloc(size_t k)
00130 {
00131 return debug_malloc_id(k, "<UNKNOWN>", 0);
00132 }
00133
00134 void *
00135 debug_realloc(void *p, size_t k)
00136 {
00137 return debug_realloc_id(p, k, "<UNKNOWN>", 0);
00138 }
00139
00140 void
00141 debug_free(void *p)
00142 {
00143 debug_free_id(p, "<UNKNOWN>", 0);
00144 }
00145
00146
00147 void
00148 dmalloc_info(void *p)
00149 {
00150 bucket *b_in = (bucket *)(((char *)p) - sizeof(bucket));
00151 bucket *b;
00152 int bnum = (((long)b_in) >> 4) % NBUCK;
00153 if (p == 0)
00154 fprintf(stderr, "dmalloc: 0x0\n");
00155 else {
00156 for (b = buckets[bnum]; b && b != b_in; b = b->next)
00157 ;
00158 if (b == 0) {
00159 fprintf(stderr, "dmalloc: %p: not my pointer\n", p);
00160 } else {
00161 fprintf(stderr, "dmalloc: %p +%-7d (%s:%d)\n",
00162 p, b->size, b->file, b->line);
00163 }
00164 }
00165 }
00166
00167
00168 void
00169 dmalloc_report(void)
00170 {
00171 int i;
00172 bucket *b;
00173 fprintf(stderr, "dmalloc: %d bytes allocated\n", dmalloc_live_memory);
00174 for (i = 0; i < NBUCK; i++)
00175 for (b = buckets[i]; b; b = b->next)
00176 fprintf(stderr, "dmalloc: %p +%-7d (%s:%d)\n",
00177 (void *)(((char *)b) + sizeof(bucket)), b->size,
00178 b->file, b->line);
00179 }
00180
00181
00182 void
00183 dmalloc_verbose(const char *out_name)
00184 {
00185 if (out_name)
00186 verbose_out = fopen(out_name, "w");
00187 else
00188 verbose_out = stdout;
00189 }