Back to index

plt-scheme  4.2.1
checkm.c
Go to the documentation of this file.
00001 
00002 /* Slow, but effective, memory debugging for Unix. */
00003 /* Run checkmem() to test memory consistency and get allocated bytes. */
00004 
00005 /* Replace GC routines, too? (Don't link with libgc.a.) */
00006 #define GC_too 0
00007 
00008 typedef long SPACE;
00009 #define SPACE_VAL 0x77777777
00010 #define CHAR_SPACE_VAL ((unsigned char)0x99)
00011 #define FREED_VAL 0x55555555
00012 
00013 static long total_allocated;
00014 
00015 typedef struct HEADER {
00016   struct HEADER *prev;
00017   struct HEADER *next;
00018   unsigned long exact_len; /* 0 => free */
00019   unsigned long len;
00020   SPACE s;
00021 } HEADER;
00022 
00023 HEADER *chain_start, *chain_end;
00024 
00025 static long looking_for;
00026 
00027 void *malloc(unsigned long len)
00028 {
00029   long pos, d, exact_len = len;
00030   HEADER *h;
00031 
00032   total_allocated += exact_len;
00033 
00034   d = len % sizeof(long);
00035   if (d)
00036     len += (sizeof(long) - d);
00037 
00038   pos = sbrk(len + sizeof(HEADER) + sizeof(SPACE));
00039 
00040   if (pos == looking_for) {
00041     /* Found it ... */
00042     looking_for = 0;
00043   }
00044 
00045   h = (HEADER *)pos;
00046   if (chain_end)
00047     chain_end->next = h;
00048   else
00049     chain_start = h;
00050   h->prev = chain_end;
00051   h->len = len;
00052   h->exact_len = exact_len;
00053 
00054   h->s = SPACE_VAL;
00055   
00056   *(SPACE *)(pos + sizeof(HEADER) + len) = SPACE_VAL;
00057   while (exact_len < len) {
00058     *(unsigned char *)(pos + sizeof(HEADER) + exact_len) = CHAR_SPACE_VAL;
00059     exact_len++;
00060   }
00061 
00062   chain_end = h;
00063 
00064   return (void *)(pos + sizeof(HEADER));
00065 }
00066 
00067 void *realloc(void *p, unsigned long len)
00068 {
00069   void *n;
00070   unsigned long olen;
00071 
00072   olen = ((HEADER *)((long)p - sizeof(HEADER)))->len;
00073   if (olen > len)
00074     return p;
00075 
00076   n = malloc(len);
00077 
00078   memcpy(n, p, olen);
00079 
00080   free(p);
00081 
00082   return n;
00083 }
00084 
00085 void *calloc(unsigned long len0, unsigned long len)
00086 {
00087   void *v;
00088 
00089   len *= len0;
00090   v = malloc(len);
00091   memset(v, 0, len);
00092   return v;
00093 }
00094 
00095 void free(void *p)
00096 {
00097   HEADER *h = (HEADER *)(((long)p) - sizeof(HEADER));
00098   SPACE v;
00099 
00100   if (!p)
00101     return;
00102 
00103   if (!h->exact_len) {
00104     printf("%lx: double-free (%lx)\n", h, h->len);
00105   } else {
00106     int i;
00107 
00108     if (h->s != SPACE_VAL)
00109       printf("%lx: bad start for free (%lx)\n", h, h->s);
00110 
00111     if (h->exact_len < h->len) {
00112       for (i = h->exact_len; i < h->len; i++) {
00113        v = (*(unsigned char *)((long)h + sizeof(HEADER) + i));
00114        if (v != CHAR_SPACE_VAL)
00115          printf("%lx: bad inexact end for free (%lx)\n", h, v);
00116       }
00117     }
00118 
00119     v = (*(SPACE *)((long)h + sizeof(HEADER) + h->len));
00120     if (v != SPACE_VAL)
00121       printf("%lx: bad end for free (%lx)\n", h, v);
00122 
00123     for (i = h->len; i; ) {
00124       i -= sizeof(long);
00125       (*(long *)((long)h + sizeof(HEADER) + i)) = FREED_VAL;
00126     }
00127   }
00128 
00129   total_allocated -= h->exact_len;
00130 
00131   h->exact_len = 0;
00132 }
00133 
00134 unsigned long checkmem(void)
00135 {
00136   HEADER *h, *prev = 0;
00137   SPACE v;
00138   unsigned long total_use = 0;
00139 
00140   for (h = chain_start; h; prev = h, h = h->next) {
00141     if (h->s != SPACE_VAL)
00142       printf("%lx [after %lx]: bad start (%lx)\n", h, prev, h->s);
00143 
00144     if (h->exact_len) {
00145       total_use += h->exact_len;
00146 
00147       if (h->exact_len < h->len) {
00148        int i;
00149        for (i = h->exact_len; i < h->len; i++) {
00150          v = (*(unsigned char *)((long)h + sizeof(HEADER) + i));
00151          if (v != CHAR_SPACE_VAL)
00152            printf("%lx: bad inexact end (%lx)\n", h, v);
00153        }
00154       }
00155     } else {
00156       int i;
00157       for (i = h->len; i; ) {
00158        i -= sizeof(long);
00159        v = (*(long *)((long)h + sizeof(HEADER) + i));
00160        if (v != FREED_VAL)
00161          printf("%lx: bad freed val (%lx)\n", h, v);
00162       }
00163     }
00164 
00165     v = (*(SPACE *)((long)h + sizeof(HEADER) + h->len));
00166     if (v != SPACE_VAL)
00167       printf("%lx: bad end (%lx)\n", h, v);
00168   }
00169 
00170   return total_use;
00171 }
00172 
00173 long get_total(void)
00174 {
00175   return total_allocated;
00176 }
00177 
00178 #if GC_too
00179 
00180 void (*GC_collect_start_callback)(void);
00181 void (*GC_collect_end_callback)(void);
00182 void (*GC_out_of_memory)(void);
00183 
00184 long GC_dl_entries;
00185 long GC_fo_entries;
00186 void *GC_changing_list_start, *GC_changing_list_current;
00187 
00188 void *GC_malloc(unsigned long len)
00189 {
00190   return malloc(len);
00191 }
00192 
00193 void *GC_malloc_atomic(unsigned long len)
00194 {
00195   return malloc(len);
00196 }
00197 
00198 void *GC_malloc_stubborn(unsigned long len)
00199 {
00200   return malloc(len);
00201 }
00202 
00203 void *GC_malloc_uncollectable(unsigned long len)
00204 {
00205   return malloc(len);
00206 }
00207 
00208 void GC_free(void *p)
00209 {
00210 }
00211 
00212 void GC_end_stubborn_change(void *p)
00213 {
00214 }
00215 
00216 void *GC_base(void *p)
00217 {
00218   return 0;
00219 }
00220 
00221 void GC_general_register_disappearing_link(void)
00222 {
00223 }
00224 
00225 void GC_register_finalizer_ignore_self(void)
00226 {
00227 }
00228 
00229 void GC_register_finalizer(void)
00230 {
00231 }
00232 
00233 void GC_gcollect(void)
00234 {
00235 }
00236 
00237 void GC_dump(void)
00238 {
00239 }
00240 
00241 long GC_get_heap_size(void)
00242 {
00243   return 0;
00244 }
00245 
00246 void GC_add_roots(void)
00247 {
00248 }
00249 
00250 void GC_set_warn_proc(void)
00251 {
00252 }
00253 
00254 void *GC_get_stack_base(void)
00255 {
00256   void *dummy;
00257 
00258   return (void *)(((char *)(&dummy)) + 3000);
00259 }
00260 
00261 #endif