]> xenbits.xensource.com Git - libvirt.git/commitdiff
Generic OOM testing hooks
authorDaniel P. Berrange <berrange@redhat.com>
Thu, 29 May 2008 15:13:07 +0000 (15:13 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Thu, 29 May 2008 15:13:07 +0000 (15:13 +0000)
ChangeLog
configure.in
src/memory.c
src/memory.h

index 50505ae84fe6204cc0774a1010fc8e06cc763f38..080e32fb892ed434cb9d52d50ba849111b2b9a56 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+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
index 8ba3cdce18c234c8069a85d1097339c48b046b12..e8d3f065debf56ed431f3fbb7a1d3a3570a3ea7e 100644 (file)
@@ -883,14 +883,15 @@ AC_MSG_RESULT($RUNNING_XEND)
 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])
@@ -898,6 +899,25 @@ if test "${enableval}" = yes; then
   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],
@@ -1042,6 +1062,11 @@ else
 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])
index 1eb1be3c3d30b5f48f57d7b8d770c83429dc0517..5a55f2acd4d43444b2a5e4a50d8b2d29e9d6746c 100644 (file)
 #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;
@@ -83,6 +139,13 @@ int virAlloc(void *ptrptr, size_t size)
  */
 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;
@@ -111,6 +174,11 @@ int virAllocN(void *ptrptr, size_t size, size_t count)
 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;
index 872fd8cc7a6686c0324f589a275b2bea182a31ba..2331b11c1144d47e50c44d5ddfc4c762b935c642 100644 (file)
@@ -31,7 +31,6 @@ int virAllocN(void *ptrptr, size_t size, size_t count) ATTRIBUTE_RETURN_CHECK;
 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
@@ -79,4 +78,14 @@ void virFree(void *ptrptr);
  */
 #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_ */