/* 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
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
enable_staticexe
enable_lock_checks
enable_alloc_checks
+enable_alloc_lite
enable_largefile
with_ldns
with_ldns_builtin
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
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"
;;
*-*-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=$?
-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.
-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.
-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
-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
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
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
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
_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
fi
+ fi
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
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
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.
/** 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, ...)
}
#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 */
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 */