int markblock(ulong from, ulong fromval, Block *b) { Data *d; ulong top; Block *nb; USED(from, fromval); //print("trace 0x%.8lux from 0x%.8lux (%d)\n", b->addr, from, b->mark); if(b->free){ // fprint(2, "possible dangling pointer *0x%.8lux = 0x%.8lux\n", from, fromval); return 0; } if(b->mark) return 0; b->mark = 1; nmark++; if(d = finddata(b->addr)) { assert(d->addr >= b->addr); b->d = d; top = b->addr+b->size; for(; d < edata && d->addr < top; d++) { assert(d->b == 0); d->b = b; if((nb = findblock(d->val-8)) || (nb = findblock(d->val-8-8))) markblock(d->addr, d->val, nb); } return 1; } return 0; }
static void test567(int testno, unsigned long seed) { static const int sizes[8] = { 13, 17, 69, 176, 433, 871, 1150, 6060 }; void *ptrs[32]; int psizes[32]; int i, n, size, failed=0; srandom(seed); printf("Seeded random number generator with %lu.\n", seed); for (i=0; i<32; i++) { ptrs[i] = NULL; psizes[i] = 0; } for (i=0; i<100000; i++) { n = random()%32; if (ptrs[n] == NULL) { size = sizes[random()%8]; ptrs[n] = malloc(size); psizes[n] = size; if (ptrs[n] == NULL) { printf("\nmalloc %u failed\n", size); failed = 1; break; } markblock(ptrs[n], size, n, 0); } else { size = psizes[n]; if (checkblock(ptrs[n], size, n, 0)) { failed = 1; break; } free(ptrs[n]); ptrs[n] = NULL; psizes[n] = 0; } if (i%256==0) { printf("."); } } printf("\n"); for (i=0; i<32; i++) { if (ptrs[i] != NULL) { free(ptrs[i]); } } if (failed) { printf("FAILED malloc test %d\n", testno); } else { printf("Passed malloc test %d\n", testno); } }
static void test2(void) { volatile unsigned *x; size_t size; printf("Entering malloc test 2.\n"); printf("Make sure you read and understand the comment in malloctest.c " "that\nexplains the conditions this test assumes.\n\n"); printf("Testing how much memory we can allocate:\n"); for (size = HUGESIZE; (x = malloc(size))==NULL; size = size/2) { printf(" %9lu bytes: failed\n", (unsigned long) size); } printf(" %9lu bytes: succeeded\n", (unsigned long) size); printf("Passed part 1\n"); printf("Touching all the words in the block.\n"); markblock(x, size, 0, 1); printf("Validating the words in the block.\n"); if (checkblock(x, size, 0, 1)) { printf("FAILED: data corrupt\n"); return; } printf("Passed part 2\n"); printf("Freeing the block\n"); free((void *)x); printf("Passed part 3\n"); printf("Allocating another block\n"); x = malloc(size); if (x==NULL) { printf("FAILED: free didn't return the memory?\n"); return; } free((void *)x); printf("Passed malloc test 2.\n"); }
static void test1(void) { volatile unsigned *x; printf("*** Malloc test 1 ***\n"); printf("Allocating %u bytes\n", BIGSIZE); x = malloc(BIGSIZE); if (x==NULL) { printf("FAILED: malloc failed\n"); return; } markblock(x, BIGSIZE, 0, 0); if (checkblock(x, BIGSIZE, 0, 0)) { printf("FAILED: data corrupt\n"); return; } free((void *)x); printf("Passed malloc test 1.\n"); }
void main(int argc, char **argv) { Biobuf bio; char *p, *f[10]; int bitmap, c, nf, resolution, n8, n16, hdr, nhdr, nlhdr, nleak, x, y, nb; ulong allocstart, allocend, len, u; Data *d, *ed; Block *b, *eb; bitmap = 0; resolution = 8; x = 512; ARGBEGIN{ case 'b': bitmap=1; break; case 'r': resolution = atoi(EARGF(sysfatal("usage"))); break; case 'x': x = atoi(EARGF(sysfatal("usage"))); break; }ARGEND n8 = n16 = 0; allocstart = allocend = 0; Binit(&bio, 0, OREAD); while(p=Brdline(&bio, '\n')) { p[Blinelen(&bio)-1] = '\0'; nf = tokenize(p, f, nelem(f)); if(nf >= 4 && strcmp(f[0], "data") == 0) { if(ndata%64==0) data = erealloc(data, (ndata+64)*sizeof(Data)); data[ndata].addr = strtoul(f[1], nil, 0); data[ndata].val = strtoul(f[2], nil, 0); data[ndata].type = f[3][0]; data[ndata].b = 0; ndata++; } if(nf >= 5 && (strcmp(f[0], "block") == 0 || strcmp(f[0], "free") == 0)) { if(nblock%64 == 0) block = erealloc(block, (nblock+64)*sizeof(Block)); block[nblock].addr = strtoul(f[1], nil, 0); block[nblock].size = strtoul(f[2], nil, 0); block[nblock].w0 = strtoul(f[3], nil, 0); block[nblock].w1 = strtoul(f[4], nil, 0); if (nf >= 7) { block[nblock].s0 = estrdup(f[5]); block[nblock].s1 = estrdup(f[6]); } else { block[nblock].s0 = ""; block[nblock].s1 = ""; } block[nblock].mark = 0; block[nblock].d = 0; block[nblock].free = strcmp(f[0], "free") == 0; nblock++; } if(nf >= 4 && strcmp(f[0], "range") == 0 && strcmp(f[1], "alloc") == 0) { allocstart = strtoul(f[2], 0, 0)&~15; allocend = strtoul(f[3], 0, 0); } } qsort(block, nblock, sizeof(Block), addrcmp); qsort(data, ndata, sizeof(Data), addrcmp); ed = edata = data+ndata; for(d=data; d<ed; d++) { if(d->type == 'a') continue; if(b = findblock(d->val-8)) // pool header 2 words n8 += markblock(d->addr, d->val, b); else if(b = findblock(d->val-8-8)) // sometimes malloc header 2 words n16 += markblock(d->addr, d->val, b); else {}//print("noblock %.8lux\n", d->val); } Binit(&bio, 1, OWRITE); if(bitmap){ if(n8 > n16) // guess size of header hdr = 8; else hdr = 16; for(d=data; d<ed; d++) if(d->type=='a') break; if(d==ed) sysfatal("no allocated data region"); len = (allocend-allocstart+resolution-1)/resolution; y = (len+x-1)/x; Bprint(&bio, "%11s %11d %11d %11d %11d ", "m8", 0, 0, x, y); //fprint(2, "alloc %lux %lux x %d y %d res %d\n", allocstart, allocend, x, y, resolution); b = block; eb = block+nblock; for(u = allocstart; u<allocend; u+=resolution){ //fprint(2, "u %lux %lux baddr %lux\n", u, u+resolution, b->addr); while(b->addr+b->size <= u && b < eb) //{ //fprint(2, "\tskip %lux %lux\n", b->addr, b->addr+b->size); b++; //} nhdr = 0; nleak = 0; nb = 0; nlhdr = 0; if(block < b && u < (b-1)->addr+(b-1)->size) b--; for(; b->addr < u+resolution && b < eb; b++){ //fprint(2, "\tblock %lux %lux %d\n", b->addr, b->addr+b->size, b->mark); if(rXr(b->addr, b->addr+hdr, u, u+resolution) || rXr(b->addr+b->size-8, b->addr+b->size, u, u+resolution)){ if(b->mark == 0 && !b->free) nlhdr++; else nhdr++; } if(b->mark == 0 && !b->free) nleak++; nb++; } if(nhdr) c = HdrColor; else if(nlhdr) c = LeakHdrColor; else if(nleak) c = LeakColor; else if(nb) c = AllocColor; else c = FreeColor; //fprint(2, "\t%d\n", c); Bputc(&bio, c); } allocend = allocstart+x*y*resolution; for(; u < allocend; u+=resolution) Bputc(&bio, NoColor); }else{ eb = block+nblock; for(b=block; b<eb; b++) if(b->mark == 0 && !b->free) Bprint(&bio, "block 0x%.8lux 0x%.8lux 0x%.8lux 0x%.8lux %s %s\n", b->addr, b->size, b->w0, b->w1, b->s0, b->s1); } Bterm(&bio); }
static void test3(void) { struct test3 *list = NULL, *tmp; size_t tot=0; int ct=0, failed=0; void *x; printf("Entering malloc test 3.\n"); printf("Make sure you read and understand the comment in malloctest.c " "that\nexplains the conditions this test assumes.\n\n"); printf("Testing how much memory we can allocate:\n"); while ((tmp = malloc(sizeof(struct test3))) != NULL) { tmp->next = list; list = tmp; tot += sizeof(struct test3); markblock(list->junk, sizeof(list->junk), (uintptr_t)list, 0); ct++; if (ct%128==0) { printf("."); } } printf("Allocated %lu bytes\n", (unsigned long) tot); printf("Trying some more allocations which I expect to fail...\n"); x = malloc(SMALLSIZE); if (x != NULL) { printf("FAILED: malloc(%u) succeeded\n", SMALLSIZE); return; } x = malloc(MEDIUMSIZE); if (x != NULL) { printf("FAILED: malloc(%u) succeeded\n", MEDIUMSIZE); return; } x = malloc(BIGSIZE); if (x != NULL) { printf("FAILED: malloc(%u) succeeded\n", BIGSIZE); return; } printf("Ok, now I'm going to free everything...\n"); while (list != NULL) { tmp = list->next; if (checkblock(list->junk, sizeof(list->junk), (uintptr_t)list, 0)) { failed = 1; } free(list); list = tmp; } if (failed) { printf("FAILED: data corruption\n"); return; } printf("Let me see if I can allocate some more now...\n"); x = malloc(MEDIUMSIZE); if (x == NULL) { printf("FAIL: Nope, I couldn't.\n"); return; } free(x); printf("Passed malloc test 3\n"); }