diff mbox

[5/6] oslib-posix: add a configure switch to debug stack usage

Message ID 1467272240-32123-6-git-send-email-pl@kamp.de (mailing list archive)
State New, archived
Headers show

Commit Message

Peter Lieven June 30, 2016, 7:37 a.m. UTC
this adds a knob to track the maximum stack usage of stacks
created by qemu_alloc_stack.

Signed-off-by: Peter Lieven <pl@kamp.de>
---
 configure          | 15 +++++++++++++++
 util/oslib-posix.c | 35 ++++++++++++++++++++++++++++++++++-
 2 files changed, 49 insertions(+), 1 deletion(-)

Comments

Richard Henderson July 1, 2016, 8:55 p.m. UTC | #1
On 06/30/2016 12:37 AM, Peter Lieven wrote:
> +    for (ptr2 = ptr; ptr2 < ptr + sz; ptr2 += sizeof(u_int32_t)) {
> +        *(u_int32_t *)ptr2 = 0xdeadbeaf;
> +    }

s/u_int32_t/uint32_t/g


r~
diff mbox

Patch

diff --git a/configure b/configure
index 5929aba..ba66916 100755
--- a/configure
+++ b/configure
@@ -296,6 +296,7 @@  libiscsi=""
 libnfs=""
 coroutine=""
 coroutine_pool=""
+debug_stack_usage="no"
 seccomp=""
 glusterfs=""
 glusterfs_xlator_opt="no"
@@ -1004,6 +1005,8 @@  for opt do
   ;;
   --enable-coroutine-pool) coroutine_pool="yes"
   ;;
+  --enable-debug-stack-usage) debug_stack_usage="yes"
+  ;;
   --disable-docs) docs="no"
   ;;
   --enable-docs) docs="yes"
@@ -4298,6 +4301,13 @@  fi
 if test "$coroutine" = "gthread" -a "$coroutine_pool" = "yes"; then
   error_exit "'gthread' coroutine backend does not support pool (use --disable-coroutine-pool)"
 fi
+if test "$debug_stack_usage" = "yes"; then
+  if test "$coroutine_pool" = "yes"; then
+    echo "WARN: disabling coroutine pool for stack usage debugging"
+    coroutine_pool=no
+  fi
+fi
+
 
 ##########################################
 # check if we have open_by_handle_at
@@ -4866,6 +4876,7 @@  echo "QGA MSI support   $guest_agent_msi"
 echo "seccomp support   $seccomp"
 echo "coroutine backend $coroutine"
 echo "coroutine pool    $coroutine_pool"
+echo "debug stack usage $debug_stack_usage"
 echo "GlusterFS support $glusterfs"
 echo "Archipelago support $archipelago"
 echo "gcov              $gcov_tool"
@@ -5336,6 +5347,10 @@  else
   echo "CONFIG_COROUTINE_POOL=0" >> $config_host_mak
 fi
 
+if test "$debug_stack_usage" = "yes" ; then
+  echo "CONFIG_DEBUG_STACK_USAGE=y" >> $config_host_mak
+fi
+
 if test "$open_by_handle_at" = "yes" ; then
   echo "CONFIG_OPEN_BY_HANDLE=y" >> $config_host_mak
 fi
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index a567a7d..0a9f2b2 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -50,6 +50,10 @@ 
 
 #include <qemu/mmap-alloc.h>
 
+#ifdef CONFIG_DEBUG_STACK_USAGE
+#include "qemu/error-report.h"
+#endif
+
 int qemu_get_thread_id(void)
 {
 #if defined(__linux__)
@@ -500,6 +504,9 @@  pid_t qemu_fork(Error **errp)
 
 void *qemu_alloc_stack(size_t sz)
 {
+#ifdef CONFIG_DEBUG_STACK_USAGE
+    void *ptr2;
+#endif
     /* allocate sz bytes plus one extra page for a guard
      * page at the bottom of the stack */
     void *ptr = mmap(NULL, sz + getpagesize(), PROT_NONE,
@@ -511,11 +518,37 @@  void *qemu_alloc_stack(size_t sz)
         MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0) == MAP_FAILED) {
         abort();
     }
-    return ptr + getpagesize();
+    ptr += getpagesize();
+#ifdef CONFIG_DEBUG_STACK_USAGE
+    for (ptr2 = ptr; ptr2 < ptr + sz; ptr2 += sizeof(u_int32_t)) {
+        *(u_int32_t *)ptr2 = 0xdeadbeaf;
+    }
+#endif
+    return ptr;
 }
 
+#ifdef CONFIG_DEBUG_STACK_USAGE
+static __thread unsigned int max_stack_usage;
+#endif
+
 void qemu_free_stack(void *stack, size_t sz)
 {
+#ifdef CONFIG_DEBUG_STACK_USAGE
+    void *ptr;
+    unsigned int usage;
+    for (ptr = stack; ptr < stack + sz; ptr += sizeof(u_int32_t)) {
+        if (*(u_int32_t *)ptr != 0xdeadbeaf) {
+            break;
+        }
+    }
+    usage = sz - (uintptr_t) (ptr - stack);
+    if (usage > max_stack_usage) {
+        error_report("thread %d max stack usage increased from %u to %u",
+                     qemu_get_thread_id(), max_stack_usage, usage);
+        max_stack_usage = usage;
+    }
+#endif
+
     /* unmap the stack plus the extra guard page */
     munmap(stack - getpagesize(), sz + getpagesize());
 }