From: Wouter Wijngaards Date: Tue, 9 Mar 2010 16:26:53 +0000 (+0000) Subject: --enable-alloc-lite X-Git-Tag: release-1.4.3~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0000843c32f1cb78d9435a06d6ff8b27797aa07a;p=thirdparty%2Funbound.git --enable-alloc-lite git-svn-id: file:///svn/unbound/trunk@2014 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/config.h.in b/config.h.in index 200fa3861..99f8cbc6d 100644 --- a/config.h.in +++ b/config.h.in @@ -420,6 +420,9 @@ /* default username */ #undef UB_USERNAME +/* use to enable lightweight alloc assertions, for debug use */ +#undef UNBOUND_ALLOC_LITE + /* use statistics for allocs and frees, for debug use */ #undef UNBOUND_ALLOC_STATS @@ -832,7 +835,9 @@ void unbound_stat_free_log(void *ptr, const char* file, int line, const char* func); void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file, int line, const char* func); -#endif /* UNBOUND_ALLOC_STATS */ +#elif defined(UNBOUND_ALLOC_LITE) +# include "util/alloc.h" +#endif /* UNBOUND_ALLOC_LITE and UNBOUND_ALLOC_STATS */ /** default port for DNS traffic. */ #define UNBOUND_DNS_PORT 53 diff --git a/configure b/configure index 221499049..81e21a87e 100755 --- a/configure +++ b/configure @@ -932,6 +932,7 @@ with_libevent enable_staticexe enable_lock_checks enable_alloc_checks +enable_alloc_lite enable_largefile with_ldns with_ldns_builtin @@ -1587,7 +1588,9 @@ Optional Features: event, ldns libs, for debug purposes --enable-lock-checks enable to check lock and unlock calls, for debug purposes - --enable-alloc-checks enable to check memory allocation, for debug + --enable-alloc-checks enable to memory allocation statistics, for debug + purposes + --enable-alloc-lite enable for lightweight alloc assertions, for debug purposes --disable-largefile omit support for large files @@ -7290,13 +7293,13 @@ if test "${lt_cv_nm_interface+set}" = set; then else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:7293: $ac_compile\"" >&5) + (eval echo "\"\$as_me:7296: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:7296: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:7299: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:7299: output\"" >&5) + (eval echo "\"\$as_me:7302: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -8501,7 +8504,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 8504 "configure"' > conftest.$ac_ext + echo '#line 8507 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -9868,11 +9871,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:9871: $lt_compile\"" >&5) + (eval echo "\"\$as_me:9874: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:9875: \$? = $ac_status" >&5 + echo "$as_me:9878: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -10207,11 +10210,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:10210: $lt_compile\"" >&5) + (eval echo "\"\$as_me:10213: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:10214: \$? = $ac_status" >&5 + echo "$as_me:10217: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -10312,11 +10315,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:10315: $lt_compile\"" >&5) + (eval echo "\"\$as_me:10318: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:10319: \$? = $ac_status" >&5 + echo "$as_me:10322: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -10367,11 +10370,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:10370: $lt_compile\"" >&5) + (eval echo "\"\$as_me:10373: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:10374: \$? = $ac_status" >&5 + echo "$as_me:10377: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -13170,7 +13173,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 13173 "configure" +#line 13176 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -13266,7 +13269,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 13269 "configure" +#line 13272 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -19265,6 +19268,11 @@ if test "${enable_alloc_checks+set}" = set; then enableval=$enable_alloc_checks; fi +# Check whether --enable-alloc-lite was given. +if test "${enable_alloc_lite+set}" = set; then + enableval=$enable_alloc_lite; +fi + if test x_$enable_alloc_checks = x_yes; then cat >>confdefs.h <<\_ACEOF @@ -19272,6 +19280,13 @@ cat >>confdefs.h <<\_ACEOF _ACEOF else + if test x_$enable_alloc_lite = x_yes; then + +cat >>confdefs.h <<\_ACEOF +#define UNBOUND_ALLOC_LITE 1 +_ACEOF + + else for ac_header in stdlib.h @@ -19525,6 +19540,7 @@ _ACEOF fi + fi fi diff --git a/configure.ac b/configure.ac index e33c4217c..9ade3efb6 100644 --- a/configure.ac +++ b/configure.ac @@ -516,12 +516,19 @@ fi # set memory allocation checking if requested AC_ARG_ENABLE(alloc-checks, AC_HELP_STRING([--enable-alloc-checks], - [ enable to check memory allocation, for debug purposes ]), + [ enable to memory allocation statistics, for debug purposes ]), + , ) +AC_ARG_ENABLE(alloc-lite, AC_HELP_STRING([--enable-alloc-lite], + [ enable for lightweight alloc assertions, for debug purposes ]), , ) if test x_$enable_alloc_checks = x_yes; then AC_DEFINE(UNBOUND_ALLOC_STATS, 1, [use statistics for allocs and frees, for debug use]) else - ACX_FUNC_MALLOC([unbound]) + if test x_$enable_alloc_lite = x_yes; then + AC_DEFINE(UNBOUND_ALLOC_LITE, 1, [use to enable lightweight alloc assertions, for debug use]) + else + ACX_FUNC_MALLOC([unbound]) + fi fi AC_FUNC_CHOWN @@ -771,7 +778,9 @@ void unbound_stat_free_log(void *ptr, const char* file, int line, const char* func); void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file, int line, const char* func); -#endif /* UNBOUND_ALLOC_STATS */ +#elif defined(UNBOUND_ALLOC_LITE) +# include "util/alloc.h" +#endif /* UNBOUND_ALLOC_LITE and UNBOUND_ALLOC_STATS */ /** default port for DNS traffic. */ #define UNBOUND_DNS_PORT 53 diff --git a/doc/Changelog b/doc/Changelog index e5a2504a1..64c6fb682 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,6 +1,7 @@ 9 March 2010: Wouter - tag 1.4.2 created. - trunk is 1.4.3 in development. + - --enable-alloc-lite debug option. 8 March 2010: Wouter - iana portlist updated. diff --git a/testcode/ldns-testpkts.c b/testcode/ldns-testpkts.c index 9dcb79b1d..a00389d02 100644 --- a/testcode/ldns-testpkts.c +++ b/testcode/ldns-testpkts.c @@ -31,8 +31,9 @@ struct sockaddr_storage; /** string to show in warnings and errors */ static const char* prog_name = "ldns-testpkts"; +enum verbosity_value; /** logging routine, provided by caller */ -void verbose(int lvl, const char* msg, ...); +void verbose(enum verbosity_value lvl, const char* msg, ...) ATTR_FORMAT(printf, 2, 3); /** print error and exit */ static void error(const char* msg, ...) diff --git a/util/alloc.c b/util/alloc.c index 3fe09f790..d530aa4ff 100644 --- a/util/alloc.c +++ b/util/alloc.c @@ -472,3 +472,121 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file, } #endif /* UNBOUND_ALLOC_STATS */ +#ifdef UNBOUND_ALLOC_LITE +#undef malloc +#undef calloc +#undef free +#undef realloc +/** length of prefix and suffix */ +static size_t lite_pad = 16; +/** prefix value to check */ +static char* lite_pre = "checkfront123456"; +/** suffix value to check */ +static char* lite_post= "checkafter123456"; + +void *unbound_stat_malloc_lite(size_t size, const char* file, int line, + const char* func) +{ + /* [prefix .. len .. actual data .. suffix] */ + void* res = malloc(size+lite_pad*2+sizeof(size_t)); + if(!res) return NULL; + memmove(res, lite_pre, lite_pad); + memmove(res+lite_pad, &size, sizeof(size_t)); + memset(res+lite_pad+sizeof(size_t), 0x1a, size); /* init the memory */ + memmove(res+lite_pad+size+sizeof(size_t), lite_post, lite_pad); + return res+lite_pad+sizeof(size_t); +} + +void *unbound_stat_calloc_lite(size_t nmemb, size_t size, const char* file, + int line, const char* func) +{ + size_t req = nmemb * size; + void* res = malloc(req+lite_pad*2+sizeof(size_t)); + if(!res) return NULL; + memmove(res, lite_pre, lite_pad); + memmove(res+lite_pad, &req, sizeof(size_t)); + memset(res+lite_pad+sizeof(size_t), 0, req); + memmove(res+lite_pad+req+sizeof(size_t), lite_post, lite_pad); + return res+lite_pad+sizeof(size_t); +} + +void unbound_stat_free_lite(void *ptr, const char* file, int line, + const char* func) +{ + void* real; + size_t orig = 0; + if(!ptr) return; + real = ptr-lite_pad-sizeof(size_t); + if(memcmp(real, lite_pre, lite_pad) != 0) { + log_err("free(): prefix failed %s:%d %s", file, line, func); + log_hex("prefix here", real, lite_pad); + log_hex(" should be", lite_pre, lite_pad); + fatal_exit("alloc assertion failed"); + } + memmove(&orig, real+lite_pad, sizeof(size_t)); + if(memcmp(real+lite_pad+orig+sizeof(size_t), lite_post, lite_pad)!=0){ + log_err("free(): suffix failed %s:%d %s", file, line, func); + log_err("alloc size is %d", (int)orig); + log_hex("suffix here", real+lite_pad+orig+sizeof(size_t), + lite_pad); + log_hex(" should be", lite_post, lite_pad); + fatal_exit("alloc assertion failed"); + } + memset(real, 0xdd, orig+lite_pad*2+sizeof(size_t)); /* mark it */ + free(real); +} + +void *unbound_stat_realloc_lite(void *ptr, size_t size, const char* file, + int line, const char* func) +{ + /* always free and realloc (no growing) */ + void* real, *newa; + size_t orig = 0; + if(!ptr) { + /* like malloc() */ + return unbound_stat_malloc_lite(size, file, line, func); + } + if(!size) { + /* like free() */ + unbound_stat_free_lite(ptr, file, line, func); + return NULL; + } + /* change allocation size and copy */ + real = ptr-lite_pad-sizeof(size_t); + if(memcmp(real, lite_pre, lite_pad) != 0) { + log_err("realloc(): prefix failed %s:%d %s", file, line, func); + log_hex("prefix here", real, lite_pad); + log_hex(" should be", lite_pre, lite_pad); + fatal_exit("alloc assertion failed"); + } + memmove(&orig, real+lite_pad, sizeof(size_t)); + if(memcmp(real+lite_pad+orig+sizeof(size_t), lite_post, lite_pad)!=0){ + log_err("realloc(): suffix failed %s:%d %s", file, line, func); + log_err("alloc size is %d", (int)orig); + log_hex("suffix here", real+lite_pad+orig+sizeof(size_t), + lite_pad); + log_hex(" should be", lite_post, lite_pad); + fatal_exit("alloc assertion failed"); + } + /* new alloc and copy over */ + newa = unbound_stat_malloc_lite(size, file, line, func); + if(!newa) + return NULL; + if(orig < size) + memmove(newa, ptr, orig); + else memmove(newa, ptr, size); + free(real); + return newa; +} + +char* unbound_strdup_lite(const char* s, const char* file, int line, + const char* func) +{ + /* this routine is made to make sure strdup() uses the malloc_lite */ + size_t l = strlen(s)+1; + char* n = (char*)unbound_stat_malloc_lite(l, file, line, func); + if(!n) return NULL; + memmove(n, s, l); + return n; +} +#endif /* UNBOUND_ALLOC_LITE */ diff --git a/util/alloc.h b/util/alloc.h index 6b54a9dfc..e0810afaa 100644 --- a/util/alloc.h +++ b/util/alloc.h @@ -176,4 +176,25 @@ void alloc_reg_release(struct alloc_cache* alloc, struct regional* r); void alloc_set_id_cleanup(struct alloc_cache* alloc, void (*cleanup)(void*), void* arg); +#ifdef UNBOUND_ALLOC_LITE +# define malloc(s) unbound_stat_malloc_lite(s, __FILE__, __LINE__, __func__) +# define calloc(n,s) unbound_stat_calloc_lite(n, s, __FILE__, __LINE__, __func__) +# define free(p) unbound_stat_free_lite(p, __FILE__, __LINE__, __func__) +# define realloc(p,s) unbound_stat_realloc_lite(p, s, __FILE__, __LINE__, __func__) +void *unbound_stat_malloc_lite(size_t size, const char* file, int line, + const char* func); +void *unbound_stat_calloc_lite(size_t nmemb, size_t size, const char* file, + int line, const char* func); +void unbound_stat_free_lite(void *ptr, const char* file, int line, + const char* func); +void *unbound_stat_realloc_lite(void *ptr, size_t size, const char* file, + int line, const char* func); +# ifdef strdup +# undef strdup +# endif +# define strdup(s) unbound_strdup_lite(s, __FILE__, __LINE__, __func__) +char* unbound_strdup_lite(const char* s, const char* file, int line, + const char* func); +#endif /* UNBOUND_ALLOC_LITE */ + #endif /* UTIL_ALLOC_H */