From f29564da699c1a39cf5e194c7201a715ac23157d Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Sat, 6 Oct 2012 14:18:49 +0200 Subject: [PATCH] better xmalloc from midish --- sndiod/abuf.c | 2 +- sndiod/dev.c | 6 +-- sndiod/file.c | 2 +- sndiod/midi.c | 2 +- sndiod/miofile.c | 2 +- sndiod/siofile.c | 2 +- sndiod/sock.c | 4 +- sndiod/utils.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++ sndiod/utils.h | 9 +++- 9 files changed, 151 insertions(+), 11 deletions(-) diff --git a/sndiod/abuf.c b/sndiod/abuf.c index 7ec99ce..d19a74a 100644 --- a/sndiod/abuf.c +++ b/sndiod/abuf.c @@ -64,7 +64,7 @@ abuf_done(struct abuf *buf) } } #endif - free(buf->data); + xfree(buf->data); buf->data = (void *)0xdeadbeef; } diff --git a/sndiod/dev.c b/sndiod/dev.c index 8c8c5d9..c39c169 100644 --- a/sndiod/dev.c +++ b/sndiod/dev.c @@ -1231,7 +1231,7 @@ dev_del(struct dev *d) #endif } *p = d->next; - free(d); + xfree(d); } unsigned int @@ -1464,7 +1464,7 @@ slot_new(struct dev *d, char *who, struct slotops *ops, void *arg, int mode) } /* - * find a free controller slot with the same name/unit + * find a xfree controller slot with the same name/unit */ for (i = 0, s = d->slot; i < DEV_NSLOT; i++, s++) { if (s->ops == NULL && @@ -1482,7 +1482,7 @@ slot_new(struct dev *d, char *who, struct slotops *ops, void *arg, int mode) } /* - * couldn't find a matching slot, pick oldest free slot + * couldn't find a matching slot, pick oldest xfree slot * and set its name/unit */ bestser = 0; diff --git a/sndiod/file.c b/sndiod/file.c index 1d175c4..8a9afe7 100644 --- a/sndiod/file.c +++ b/sndiod/file.c @@ -289,7 +289,7 @@ file_poll(void) while ((f = *pf) != NULL) { if (f->state == FILE_ZOMB) { *pf = f->next; - free(f); + xfree(f); } else pf = &f->next; } diff --git a/sndiod/midi.c b/sndiod/midi.c index 80e93e6..cc15356 100644 --- a/sndiod/midi.c +++ b/sndiod/midi.c @@ -430,7 +430,7 @@ port_del(struct port *c) #endif } *p = c->next; - free(c); + xfree(c); } /* diff --git a/sndiod/miofile.c b/sndiod/miofile.c index 8b9bb9a..46ab34a 100644 --- a/sndiod/miofile.c +++ b/sndiod/miofile.c @@ -71,7 +71,7 @@ miofile_del(struct miofile *f) { file_del(f->file); mio_close(f->hdl); - free(f); + xfree(f); } int diff --git a/sndiod/siofile.c b/sndiod/siofile.c index 2957077..d4eac38 100644 --- a/sndiod/siofile.c +++ b/sndiod/siofile.c @@ -277,7 +277,7 @@ siofile_del(struct siofile *f) #endif file_del(f->file); sio_close(f->hdl); - free(f); + xfree(f); } void diff --git a/sndiod/sock.c b/sndiod/sock.c index 5811dd4..52b1617 100644 --- a/sndiod/sock.c +++ b/sndiod/sock.c @@ -154,7 +154,7 @@ sock_close(struct sock *f) } file_del(f->file); close(f->fd); - free(f); + xfree(f); } void @@ -295,7 +295,7 @@ sock_new(int fd) f->file = file_new(&sock_fileops, f, "sock", 1); f->fd = fd; if (f->file == NULL) { - free(f); + xfree(f); return NULL; } f->next = sock_list; diff --git a/sndiod/utils.c b/sndiod/utils.c index c55372a..d0861f2 100644 --- a/sndiod/utils.c +++ b/sndiod/utils.c @@ -136,6 +136,7 @@ panic(void) abort(); } +#if 0 /* * allocate memory, and abort on error */ @@ -151,6 +152,7 @@ xmalloc(size_t size) } return p; } +#endif /* * return a random number, will be used to randomize memory bocks @@ -172,3 +174,134 @@ memrnd(void *addr, size_t size) while (size-- > 0) *(p++) = rnd() >> 24; } + +/* + * header of a memory block + */ +struct mem_hdr { + char *owner; /* who allocaed the block ? */ + unsigned words; /* data chunk size expressed in sizeof(int) */ +#define MAGIC_FREE 0xa55f9811 /* a (hopefully) ``rare'' number */ + unsigned magic; /* random number, but not MAGIC_FREE */ +}; + +unsigned mem_nalloc = 0, mem_nfree = 0, mem_debug = 0; + +/* + * return a random number, will be used to randomize memory bocks + */ +unsigned +mem_rnd(void) +{ + static unsigned seed = 1989123; + + seed = (seed * 1664525) + 1013904223; + return seed; +} + +/* + * allocate 'n' bytes of memory (with n > 0). This functions never + * fails (and never returns NULL), if there isn't enough memory then + * we abord the program. The memory block is randomized to break code + * that doesn't initialize the block. We also add a footer and a + * trailer to detect writes outside the block boundaries. + */ +void * +mem_alloc(unsigned bytes, char *owner) +{ + unsigned words, i, *p; + struct mem_hdr *hdr; + + if (bytes == 0) { + log_puts(owner); + log_puts(": mem_alloc: nbytes = 0\n"); + panic(); + } + + /* + * calculates the number of ints corresponding to ``bytes'' + */ + words = (bytes + sizeof(int) - 1) / sizeof(int); + + /* + * allocate the header, the data chunk and the trailer + */ + hdr = malloc(sizeof(struct mem_hdr) + (words + 1) * sizeof(int)); + if (hdr == NULL) { + log_puts(owner); + log_puts(": mem_alloc: failed to allocate "); + log_putx(words); + log_puts(" words\n"); + panic(); + } + + /* + * find a random magic, but not MAGIC_FREE + */ + do { + hdr->magic = mem_rnd(); + } while (hdr->magic == MAGIC_FREE); + + /* + * randomize data chunk + */ + p = (unsigned *)(hdr + 1); + for (i = words; i > 0; i--) + *p++ = mem_rnd(); + + /* + * trailer is equal to the magic + */ + *p = hdr->magic; + + hdr->owner = owner; + hdr->words = words; + mem_nalloc++; + return hdr + 1; +} + +/* + * free a memory block. Also check that the header and the trailer + * werent changed and randomise the block, so that the block is not + * usable once freed + */ +void +mem_free(void *mem) +{ + struct mem_hdr *hdr; + unsigned i, *p; + + hdr = (struct mem_hdr *)mem - 1; + p = (unsigned *)mem; + + if (hdr->magic == MAGIC_FREE) { + log_puts("mem_free: block seems already freed\n"); + panic(); + } + if (hdr->magic != p[hdr->words]) { + log_puts("mem_free: block corrupted\n"); + panic(); + } + + /* + * randomize block, so it's not usable + */ + for (i = hdr->words; i > 0; i--) + *p++ = mem_rnd(); + + hdr->magic = MAGIC_FREE; + mem_nfree++; + free(hdr); +} + +void +mem_stats(void) +{ + if (mem_debug) { + log_puts("mem_stats: used="); + log_putu(mem_nalloc - mem_nfree); + log_puts(", alloc="); + log_putu(mem_nalloc); + log_puts("\n"); + } +} diff --git a/sndiod/utils.h b/sndiod/utils.h index d2bcb36..66c347c 100644 --- a/sndiod/utils.h +++ b/sndiod/utils.h @@ -24,7 +24,14 @@ void log_puti(long); void panic(void); void log_flush(void); -void *xmalloc(size_t); +//void *xmalloc(size_t); +void *mem_alloc(unsigned, char *); +void mem_free(void *); +void mem_stats(void); + +#define xmalloc(s) (mem_alloc((s), (char *)__func__)) +#define xfree(p) (mem_free((p))) + void memrnd(void *, size_t); extern unsigned int log_sync;