+Thu May 29 11:12:00 EST 2008 Daniel P. Berrange <berrange@redhat.com>
+
+ * src/memory.c, src/memory.h, configure.ac: Add generics hooks
+ for out-of-memory testing
+
Thu May 29 10:55:00 EST 2008 Daniel P. Berrange <berrange@redhat.com>
* src/virsh.c: Don't add trailing blanks in dominfo output
AM_CONDITIONAL([ENABLE_XEN_TESTS], [test "$RUNNING_XEN" != "no" -a "$RUNNING_XEND" != "no"])
AC_ARG_ENABLE([test-coverage],
-[ --enable-test-coverage turn on code coverage instrumentation],
+[ --enable-test-coverage turn on code coverage instrumentation],
[case "${enableval}" in
yes|no) ;;
*) AC_MSG_ERROR([bad value ${enableval} for test-coverage option]) ;;
esac],
[enableval=no])
+enable_coverage=$enableval
-if test "${enableval}" = yes; then
+if test "${enable_coverage}" = yes; then
gl_COMPILER_FLAGS(-fprofile-arcs)
gl_COMPILER_FLAGS(-ftest-coverage)
AC_SUBST([COVERAGE_CFLAGS], [$COMPILER_FLAGS])
COMPILER_FLAGS=
fi
+AC_ARG_ENABLE([test-oom],
+[ --enable-test-oom memory allocation failure checking],
+[case "${enableval}" in
+ yes|no) ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for test-oom option]) ;;
+ esac],
+ [enableval=no])
+enable_oom=$enableval
+
+if test "${enable_oom}" = yes; then
+ have_trace=yes
+ AC_CHECK_HEADER([execinfo.h],[],[have_trace=no])
+ AC_CHECK_FUNC([backtrace],[],[have_trace=no])
+ if test "$have_trace" = "yes"; then
+ AC_DEFINE([TEST_OOM_TRACE], 1, [Whether backtrace() is available])
+ fi
+ AC_DEFINE([TEST_OOM], 1, [Whether malloc OOM checking is enabled])
+fi
+
dnl Enable building the proxy?
AC_ARG_WITH([xen-proxy],
AC_MSG_NOTICE([ numactl: no])
fi
AC_MSG_NOTICE([])
+AC_MSG_NOTICE([Test suite])
+AC_MSG_NOTICE([])
+AC_MSG_NOTICE([ Coverage: $enable_coverage])
+AC_MSG_NOTICE([ Alloc OOM: $enable_oom])
+AC_MSG_NOTICE([])
AC_MSG_NOTICE([Miscellaneous])
AC_MSG_NOTICE([])
AC_MSG_NOTICE([ Debug: $enable_debug])
#include "memory.h"
+#if TEST_OOM
+static int testMallocNext = 0;
+static int testMallocFailFirst = 0;
+static int testMallocFailLast = 0;
+static void (*testMallocHook)(void*) = NULL;
+static void *testMallocHookData = NULL;
+
+void virAllocTestInit(void)
+{
+ testMallocNext = 1;
+ testMallocFailFirst = 0;
+ testMallocFailLast = 0;
+}
+
+int virAllocTestCount(void)
+{
+ return testMallocNext - 1;
+}
+
+void virAllocTestHook(void (*func)(void*), void *data)
+{
+ testMallocHook = func;
+ testMallocHookData = data;
+}
+
+void virAllocTestOOM(int n, int m)
+{
+ testMallocNext = 1;
+ testMallocFailFirst = n;
+ testMallocFailLast = n + m - 1;
+}
+
+static int virAllocTestFail(void)
+{
+ int fail = 0;
+ if (testMallocNext == 0)
+ return 0;
+
+ fail =
+ testMallocNext >= testMallocFailFirst &&
+ testMallocNext <= testMallocFailLast;
+
+ if (fail && testMallocHook)
+ (testMallocHook)(testMallocHookData);
+
+ testMallocNext++;
+ return fail;
+}
+#endif
+
+
/* Return 1 if an array of N objects, each of size S, cannot exist due
to size arithmetic overflow. S must be positive and N must be
nonnegative. This is a macro, not an inline function, so that it
*/
int virAlloc(void *ptrptr, size_t size)
{
+#if TEST_OOM
+ if (virAllocTestFail()) {
+ *(void **)ptrptr = NULL;
+ return -1;
+ }
+#endif
+
if (size == 0) {
*(void **)ptrptr = NULL;
return 0;
}
-
-
*(void **)ptrptr = calloc(1, size);
if (*(void **)ptrptr == NULL)
return -1;
*/
int virAllocN(void *ptrptr, size_t size, size_t count)
{
+#if TEST_OOM
+ if (virAllocTestFail()) {
+ *(void **)ptrptr = NULL;
+ return -1;
+ }
+#endif
+
if (size == 0 || count == 0) {
*(void **)ptrptr = NULL;
return 0;
int virReallocN(void *ptrptr, size_t size, size_t count)
{
void *tmp;
+#if TEST_OOM
+ if (virAllocTestFail())
+ return -1;
+#endif
+
if (size == 0 || count == 0) {
free(*(void **)ptrptr);
*(void **)ptrptr = NULL;
int virReallocN(void *ptrptr, size_t size, size_t count) ATTRIBUTE_RETURN_CHECK;
void virFree(void *ptrptr);
-
/**
* VIR_ALLOC:
* @ptr: pointer to hold address of allocated memory
*/
#define VIR_FREE(ptr) virFree(&(ptr));
+
+#if TEST_OOM
+void virAllocTestInit(void);
+int virAllocTestCount(void);
+void virAllocTestOOM(int n, int m);
+void virAllocTestHook(void (*func)(void*), void *data);
+#endif
+
+
+
#endif /* __VIR_MEMORY_H_ */