From bb50f5958ee965b37cf04720111921f55636818f Mon Sep 17 00:00:00 2001 From: Alper Akcan Date: Thu, 28 Mar 2013 20:39:34 +0200 Subject: [PATCH] corruption check interval tests --- src/hmemory.c | 57 ++++++++++++++++++++++++++++++++++++++++++++--- src/hmemory.h | 5 +++++ test/Makefile | 3 +++ test/README | 18 +++++++++++++++ test/fail-43.c | 30 +++++++++++++++++++++++++ test/fail-44.c | 30 +++++++++++++++++++++++++ test/fail-45.c | 30 +++++++++++++++++++++++++ test/success-43.c | 30 +++++++++++++++++++++++++ test/success-44.c | 30 +++++++++++++++++++++++++ test/success-45.c | 30 +++++++++++++++++++++++++ 10 files changed, 260 insertions(+), 3 deletions(-) create mode 100644 test/fail-43.c create mode 100644 test/fail-44.c create mode 100644 test/fail-45.c create mode 100644 test/success-43.c create mode 100644 test/success-44.c create mode 100644 test/success-45.c diff --git a/src/hmemory.c b/src/hmemory.c index cbeee36..8b73178 100644 --- a/src/hmemory.c +++ b/src/hmemory.c @@ -520,7 +520,7 @@ static int debug_memory_add (const char *name, void *address, size_t size, const return 0; } -static int debug_memory_check (void *address, const char *command, const char *func, const char *file, const int line) +static int debug_memory_check_actual (void *address, const char *command, const char *func, const char *file, const int line) { int rcu; int rco; @@ -528,7 +528,6 @@ static int debug_memory_check (void *address, const char *command, const char *f if (address == NULL) { return 0; } - hmemory_lock(); HASH_FIND_PTR(debug_memory, &address, m); if (m != NULL) { goto found_m; @@ -544,7 +543,6 @@ static int debug_memory_check (void *address, const char *command, const char *f hinfof(" at: alper.akcan@gmail.com"); hdebug_unlock(); hassert((m != NULL) && "invalid address"); - hmemory_unlock(); return -1; found_m: hdebug_lock(); @@ -562,6 +560,13 @@ static int debug_memory_check (void *address, const char *command, const char *f } hdebug_unlock(); hassert(((rcu == 0) && (rco == 0)) && "memory corruption"); + return 0; +} + +static int debug_memory_check (void *address, const char *command, const char *func, const char *file, const int line) +{ + hmemory_lock(); + debug_memory_check_actual(address, command, func, file, line); hmemory_unlock(); return 0; } @@ -599,8 +604,48 @@ static int debug_memory_del (void *address, const char *command, const char *fun return 0; } +static int hmemory_worker_started = 0; +static int hmemory_worker_running = 0; +static pthread_t hmemory_thread; + +static void * hmemory_worker (void *arg) +{ + unsigned int v; + struct hmemory_memory *m; + struct hmemory_memory *nm; + (void) arg; + while (1) { + v = hmemory_getenv_int(HMEMORY_CORRUPTION_CHECK_INTERVAL_NAME); + if (v == (unsigned int) -1) { + v = HMEMORY_CORRUPTION_CHECK_INTERVAL; + } + usleep(v * 1000); + hmemory_lock(); + if (hmemory_worker_running == 0) { + hmemory_unlock(); + break; + } + HASH_ITER(hh, debug_memory, m, nm) { + debug_memory_check_actual(m->address, "worker check", __FUNCTION__, __FILE__, __LINE__); + } + hmemory_unlock(); + } + return NULL; +} + static void __attribute__ ((constructor)) hmemory_init (void) { + int rc; + hmemory_lock(); + hmemory_worker_started = 1; + hmemory_worker_running = 1; + rc = pthread_create(&hmemory_thread, NULL, hmemory_worker, NULL); + if (rc != 0) { + herrorf("failed to create worker"); + hmemory_worker_started = 0; + hmemory_worker_running = 0; + } + hmemory_unlock(); } static void __attribute__ ((destructor)) hmemory_fini (void) @@ -608,6 +653,12 @@ static void __attribute__ ((destructor)) hmemory_fini (void) struct hmemory_memory *m; struct hmemory_memory *nm; hmemory_lock(); + if (hmemory_worker_running == 1) { + hmemory_worker_running = 0; + } + hmemory_unlock(); + pthread_join(hmemory_thread, NULL); + hmemory_lock(); hdebug_lock(); hinfof("memory information:") hinfof(" current: %llu bytes (%.02f mb)", memory_current, ((double) memory_current) / (1024.00 * 1024.00)); diff --git a/src/hmemory.h b/src/hmemory.h index f3884bf..287e078 100644 --- a/src/hmemory.h +++ b/src/hmemory.h @@ -34,6 +34,11 @@ #endif #define HMEMORY_ASSERT_ON_ERROR_NAME "hmemory_assert_on_error" +#if !defined(HMEMORY_CORRUPTION_CHECK_INTERVAL) +#define HMEMORY_CORRUPTION_CHECK_INTERVAL 500 +#endif +#define HMEMORY_CORRUPTION_CHECK_INTERVAL_NAME "hmemory_corruption_check_interval" + #if defined(HMEMORY_DEBUG) && (HMEMORY_DEBUG == 1) #if !defined(HMEMORY_INTERNAL) || (HMEMORY_INTERNAL == 0) diff --git a/test/Makefile b/test/Makefile index 6e1f011..8bd570a 100644 --- a/test/Makefile +++ b/test/Makefile @@ -40,6 +40,9 @@ define test-debug-defaults $1_includes-y = \ ../src + $1_ldflags-y += \ + -lpthread + $1_ldflags-${HMEMORY_ENABLE_CALLSTACK} += \ -rdynamic \ -ldl \ diff --git a/test/README b/test/README index 330eee3..0adb2db 100644 --- a/test/README +++ b/test/README @@ -61,4 +61,22 @@ unit tests behaviours and expected results memset: rc, 0, 1024 memset: rc - 10, 0, 1044 free: rc free: rc exit ** memory corruption ** + +43 rc = malloc: 1024 rc = malloc: 1024 + memset: rc, 0, 1024 memset: rc, 0, 1025 + sleep: 3 sleep: 3 + free: rc ** memory corruption ** + exit + +44 rc = malloc: 1024 rc = malloc: 1024 + memset: rc, 0, 1024 memset: rc - 10, 0, 1024 + sleep: 3 sleep: 3 + free: rc ** memory corruption ** + exit + +45 rc = malloc: 1024 rc = malloc: 1024 + memset: rc, 0, 1024 memset: rc - 10, 0, 1044 + sleep: 3 sleep: 3 + free: rc ** memory corruption ** + exit \ No newline at end of file diff --git a/test/fail-43.c b/test/fail-43.c new file mode 100644 index 0000000..a589927 --- /dev/null +++ b/test/fail-43.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2008-2013 Alper Akcan + * + * This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://www.wtfpl.net/ for more details. + */ + +#include +#include +#include +#include + +int main (int argc, char *argv[]) +{ + void *rc; + (void) argc; + (void) argv; + rc = malloc(1024); + if (rc == NULL) { + fprintf(stderr, "malloc failed\n"); + exit(-1); + } + memset(rc + 10, 0, 1024); + sleep(1); + free(rc); + return 0; +} diff --git a/test/fail-44.c b/test/fail-44.c new file mode 100644 index 0000000..af0a48c --- /dev/null +++ b/test/fail-44.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2008-2013 Alper Akcan + * + * This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://www.wtfpl.net/ for more details. + */ + +#include +#include +#include +#include + +int main (int argc, char *argv[]) +{ + void *rc; + (void) argc; + (void) argv; + rc = malloc(1024); + if (rc == NULL) { + fprintf(stderr, "malloc failed\n"); + exit(-1); + } + memset(rc - 10, 0, 1024); + sleep(1); + free(rc); + return 0; +} diff --git a/test/fail-45.c b/test/fail-45.c new file mode 100644 index 0000000..b68e069 --- /dev/null +++ b/test/fail-45.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2008-2013 Alper Akcan + * + * This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://www.wtfpl.net/ for more details. + */ + +#include +#include +#include +#include + +int main (int argc, char *argv[]) +{ + void *rc; + (void) argc; + (void) argv; + rc = malloc(1024); + if (rc == NULL) { + fprintf(stderr, "malloc failed\n"); + exit(-1); + } + memset(rc - 10, 0, 1044); + sleep(1); + free(rc); + return 0; +} diff --git a/test/success-43.c b/test/success-43.c new file mode 100644 index 0000000..57a012b --- /dev/null +++ b/test/success-43.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2008-2013 Alper Akcan + * + * This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://www.wtfpl.net/ for more details. + */ + +#include +#include +#include +#include + +int main (int argc, char *argv[]) +{ + void *rc; + (void) argc; + (void) argv; + rc = malloc(1024); + if (rc == NULL) { + fprintf(stderr, "malloc failed\n"); + exit(-1); + } + memset(rc, 0, 1024); + sleep(1); + free(rc); + return 0; +} diff --git a/test/success-44.c b/test/success-44.c new file mode 100644 index 0000000..57a012b --- /dev/null +++ b/test/success-44.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2008-2013 Alper Akcan + * + * This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://www.wtfpl.net/ for more details. + */ + +#include +#include +#include +#include + +int main (int argc, char *argv[]) +{ + void *rc; + (void) argc; + (void) argv; + rc = malloc(1024); + if (rc == NULL) { + fprintf(stderr, "malloc failed\n"); + exit(-1); + } + memset(rc, 0, 1024); + sleep(1); + free(rc); + return 0; +} diff --git a/test/success-45.c b/test/success-45.c new file mode 100644 index 0000000..57a012b --- /dev/null +++ b/test/success-45.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2008-2013 Alper Akcan + * + * This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://www.wtfpl.net/ for more details. + */ + +#include +#include +#include +#include + +int main (int argc, char *argv[]) +{ + void *rc; + (void) argc; + (void) argv; + rc = malloc(1024); + if (rc == NULL) { + fprintf(stderr, "malloc failed\n"); + exit(-1); + } + memset(rc, 0, 1024); + sleep(1); + free(rc); + return 0; +}