From dbcd4b5e0c47a8fb8e398431fccb290526303608 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Tue, 14 Dec 2021 11:45:01 +0200 Subject: [PATCH] forgot to add the chkalloc files --- src/chkalloc.c | 239 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/chkalloc.h | 26 ++++++ 2 files changed, 265 insertions(+) create mode 100644 src/chkalloc.c create mode 100644 src/chkalloc.h diff --git a/src/chkalloc.c b/src/chkalloc.c new file mode 100644 index 0000000..70f3dfc --- /dev/null +++ b/src/chkalloc.c @@ -0,0 +1,239 @@ +#ifdef CHECK_ALLOC + +#include +#include +#include +#include "chkalloc.h" +#include "util.h" + +#define OFFSET 512 + +struct allocation { + char *ptr; + char *file; + int fullsz, sz; + int lineno; + struct allocation *next; +}; + +static FILE *logfile; +static struct allocation *alist, *atail; + +static void init_once(void) +{ + static int init_once_done; + if(!init_once_done) { + init_once_done = 1; + remove("chk.log"); + } +} + +static FILE *openlog(void) +{ + if(logfile) return logfile; + return (logfile = fopen("chk.log", "a")); +} + +static void closelog(void) +{ + fclose(logfile); + logfile = 0; +} + +static void mark_alloc(struct allocation *a) +{ + uintptr_t *left, *right, *end; + + left = (uintptr_t*)(a + 1); + right = (uintptr_t*)((char*)a + a->fullsz) - 1; + end = (uintptr_t*)(a->ptr + a->sz); + + while(left + 1 < (void*)a->ptr) { + *left = (uintptr_t)left; + left++; + } + while(right >= end) { + *right = (uintptr_t)right; + right--; + } +} + +static int check_alloc(struct allocation *a, const char *reason) +{ + int i; + uintptr_t *left = (uintptr_t*)(a + 1); + uintptr_t *right = (uintptr_t*)((char*)a + a->fullsz) - 1; + void *end = a->ptr + a->sz; + int trash_left = 0, trash_right = 0; + char *last_trash_left = 0, *first_trash_right = 0; + char *first_trash_left = 0, *last_trash_right = 0; + + init_once(); + if(!openlog()) return -1; + + while(left + 1 < (void*)a->ptr) { + if(*left != (uintptr_t)left) { + fprintf(logfile, "@%p: %p\n", left, (void*)*left); + } + for(i=0; i> s) & 0xff) != (((uintptr_t)left >> s) & 0xff)) { + if(!first_trash_left) first_trash_left = (char*)left; + trash_left++; + last_trash_left = (char*)left + i; + } + } + left++; + } + while(right >= end) { + if(*right != (uintptr_t)right) { + fprintf(logfile, "@%p: %p\n", right, (void*)*right); + } + for(i=0; i> s) & 0xff) != (((uintptr_t)right >> s) & 0xff)) { + if(!last_trash_right) last_trash_right = (char*)right; + trash_right++; + first_trash_right = (char*)right + i; + } + } + right--; + } + + if(!(trash_left | trash_right)) return 0; + + fprintf(logfile, "corrupted memory allocated from: %s:%d\n", a->file, a->lineno); + if(trash_left) { + fprintf(logfile, " %d bytes at offset %d before start (%p)\n", + (int)(last_trash_left - first_trash_left), + (int)(a->ptr - last_trash_left), a->ptr); + } + if(trash_right) { + fprintf(logfile, " %d bytes at offset %d after end (%p)\n", + (int)(last_trash_right - first_trash_right), + (int)(first_trash_right - end), end); + } + fprintf(logfile, " check due to %s\n", reason); + closelog(); + return -1; +} + +void chk_check(void) +{ + struct allocation *anode = alist; + while(anode) { + check_alloc(anode, "explicit check call"); + anode = anode->next; + } +} + +void *chk_malloc_impl(int sz, char *file, int line) +{ + int fullsz; + struct allocation *a; + + init_once(); + + fullsz = sz + OFFSET * 2; + if(!(a = malloc(fullsz))) { + return 0; + } + + a->ptr = (char*)a + OFFSET; + a->file = file; + a->lineno = line; + a->fullsz = fullsz; + a->sz = sz; + a->next = 0; + + if(alist) { + atail->next = a; + atail = a; + } else { + alist = atail = a; + } + + mark_alloc(a); + + if(openlog()) { + fprintf(logfile, "alloc(%d) from %s:%d\n", sz, a->file, a->lineno); + closelog(); + } + return a->ptr; +} + +void *chk_realloc_impl(void *ptr, int sz, char *file, int line) +{ + int fullsz; + struct allocation *newptr; + struct allocation *a = (struct allocation*)((char*)ptr - OFFSET); + struct allocation *prev, dummy; + + init_once(); + if(ptr) { + check_alloc(a, "realloc"); + } + + fullsz = sz + OFFSET * 2; + if(!(newptr = realloc(a, fullsz))) { + return 0; + } + + dummy.next = alist; + prev = &dummy; + while(prev->next) { + if(prev->next == a) { + prev->next = newptr; + break; + } + prev = prev->next; + } + alist = dummy.next; + + a = newptr; + a->ptr = (char*)a + OFFSET; + a->sz = sz; + a->fullsz = fullsz; + a->file = file; + a->lineno = line; + + mark_alloc(a); + + if(openlog()) { + fprintf(logfile, "realloc(%d) from %s:%d\n", sz, a->file, a->lineno); + closelog(); + } + return a->ptr; +} + +void chk_free(void *p) +{ + struct allocation dummy, *prev, *a; + + init_once(); + + if(!p) return; + + a = (struct allocation*)((char*)p - OFFSET); + if(openlog()) { + fprintf(logfile, "free() %d allocated from %s:%d\n", a->sz, a->file, a->lineno); + closelog(); + } + + dummy.next = alist; + prev = &dummy; + while(prev->next) { + if(prev->next->ptr == p) { + a = prev->next; + prev->next = a->next; + + check_alloc(a, "free"); + free(a); + break; + } + prev = prev->next; + } + alist = dummy.next; +} + +#endif /* CHECK_ALLOC */ diff --git a/src/chkalloc.h b/src/chkalloc.h new file mode 100644 index 0000000..4375d2c --- /dev/null +++ b/src/chkalloc.h @@ -0,0 +1,26 @@ +#ifndef CHKALLOC_H_ +#define CHKALLOC_H_ + +#ifdef CHECK_ALLOC + +void chk_check(void); + +#define chk_malloc(sz) chk_malloc_impl(sz, __FILE__, __LINE__) +#define chk_realloc(p, sz) chk_realloc_impl(p, sz, __FILE__, __LINE__) + +void *chk_malloc_impl(int sz, char *file, int line); +void *chk_realloc_impl(void *ptr, int sz, char *file, int line); +void chk_free(void *p); + +#else /* !CHECK_ALLOC */ + +#include + +#define chk_check() +#define chk_malloc(sz) malloc(sz) +#define chk_realloc(p, sz) realloc(p, sz) +#define chk_free(p) free(p) + +#endif /* CHECK_ALLOC */ + +#endif /* CHKALLOC_H_ */ -- 1.7.10.4