1f061d
commit 2b49317b4f237ea5f648d8b958f96cd03fcabc7d
1f061d
Author: philippe <philippe@a5019735-40e9-0310-863c-91ae7b9d1cf9>
1f061d
Date:   Mon Nov 28 19:34:06 2016 +0000
1f061d
1f061d
    Fix 373046 - Stacks registered by core are never deregistered
1f061d
    
1f061d
    
1f061d
    git-svn-id: svn://svn.valgrind.org/valgrind/trunk@16159 a5019735-40e9-0310-863c-91ae7b9d1cf9
1f061d
1f061d
diff --git a/coregrind/m_scheduler/scheduler.c b/coregrind/m_scheduler/scheduler.c
1f061d
index 0363898..49f51d6 100644
1f061d
--- a/coregrind/m_scheduler/scheduler.c
1f061d
+++ b/coregrind/m_scheduler/scheduler.c
1f061d
@@ -488,6 +488,7 @@ static void os_state_clear(ThreadState *tst)
1f061d
 {
1f061d
    tst->os_state.lwpid       = 0;
1f061d
    tst->os_state.threadgroup = 0;
1f061d
+   tst->os_state.stk_id = NULL_STK_ID;
1f061d
 #  if defined(VGO_linux)
1f061d
    /* no other fields to clear */
1f061d
 #  elif defined(VGO_darwin)
1f061d
@@ -504,7 +505,6 @@ static void os_state_clear(ThreadState *tst)
1f061d
 #  if defined(VGP_x86_solaris)
1f061d
    tst->os_state.thrptr = 0;
1f061d
 #  endif
1f061d
-   tst->os_state.stk_id = (UWord)-1;
1f061d
    tst->os_state.ustack = NULL;
1f061d
    tst->os_state.in_door_return = False;
1f061d
    tst->os_state.door_return_procedure = 0;
1f061d
diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c
1f061d
index 6ef6a90..28972ae 100644
1f061d
--- a/coregrind/m_syswrap/syswrap-generic.c
1f061d
+++ b/coregrind/m_syswrap/syswrap-generic.c
1f061d
@@ -84,11 +84,14 @@ void ML_(guess_and_register_stack) (Addr sp, ThreadState* tst)
1f061d
       tst->client_stack_highest_byte = (Addr)VG_PGROUNDUP(sp)-1;
1f061d
       tst->client_stack_szB = tst->client_stack_highest_byte - seg->start + 1;
1f061d
 
1f061d
-      VG_(register_stack)(seg->start, tst->client_stack_highest_byte);
1f061d
+      tst->os_state.stk_id 
1f061d
+         = VG_(register_stack)(seg->start, tst->client_stack_highest_byte);
1f061d
 
1f061d
       if (debug)
1f061d
-	 VG_(printf)("tid %u: guessed client stack range [%#lx-%#lx]\n",
1f061d
-		     tst->tid, seg->start, tst->client_stack_highest_byte);
1f061d
+	 VG_(printf)("tid %u: guessed client stack range [%#lx-%#lx]"
1f061d
+                     " as stk_id %lu\n",
1f061d
+		     tst->tid, seg->start, tst->client_stack_highest_byte,
1f061d
+                     tst->os_state.stk_id);
1f061d
    } else {
1f061d
       VG_(message)(Vg_UserMsg,
1f061d
                    "!? New thread %u starts with SP(%#lx) unmapped\n",
1f061d
diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c
1f061d
index af10b92..725ad78 100644
1f061d
--- a/coregrind/m_syswrap/syswrap-linux.c
1f061d
+++ b/coregrind/m_syswrap/syswrap-linux.c
1f061d
@@ -52,6 +52,7 @@
1f061d
 #include "pub_core_options.h"
1f061d
 #include "pub_core_scheduler.h"
1f061d
 #include "pub_core_signals.h"
1f061d
+#include "pub_core_stacks.h"
1f061d
 #include "pub_core_syscall.h"
1f061d
 #include "pub_core_syswrap.h"
1f061d
 #include "pub_core_inner.h"
1f061d
@@ -162,6 +163,10 @@ static void run_a_thread_NORETURN ( Word tidW )
1f061d
    c = VG_(count_living_threads)();
1f061d
    vg_assert(c >= 1); /* stay sane */
1f061d
 
1f061d
+   /* Deregister thread's stack. */
1f061d
+   if (tst->os_state.stk_id != NULL_STK_ID)
1f061d
+      VG_(deregister_stack)(tst->os_state.stk_id);
1f061d
+
1f061d
    // Tell the tool this thread is exiting
1f061d
    VG_TRACK( pre_thread_ll_exit, tid );
1f061d
 
1f061d
diff --git a/coregrind/pub_core_threadstate.h b/coregrind/pub_core_threadstate.h
1f061d
index f3d956c..3307e75 100644
1f061d
--- a/coregrind/pub_core_threadstate.h
1f061d
+++ b/coregrind/pub_core_threadstate.h
1f061d
@@ -114,6 +114,8 @@ typedef
1f061d
    ThreadArchState;
1f061d
 
1f061d
 
1f061d
+#define NULL_STK_ID (~(UWord)0)
1f061d
+
1f061d
 /* OS-specific thread state.  IMPORTANT: if you add fields to this,
1f061d
    you _must_ add code to os_state_clear() to initialise those
1f061d
    fields. */
1f061d
@@ -129,6 +131,12 @@ typedef
1f061d
       Addr valgrind_stack_base;    // Valgrind's stack (VgStack*)
1f061d
       Addr valgrind_stack_init_SP; // starting value for SP
1f061d
 
1f061d
+      /* Client stack is registered as stk_id (on linux/darwin, by
1f061d
+         ML_(guess_and_register_stack)).
1f061d
+         Stack id NULL_STK_ID means that the user stack is not (yet)
1f061d
+         registered. */
1f061d
+      UWord stk_id;
1f061d
+
1f061d
       /* exit details */
1f061d
       Word exitcode; // in the case of exitgroup, set by someone else
1f061d
       Int  fatalsig; // fatal signal
1f061d
@@ -281,10 +289,6 @@ typedef
1f061d
          the 64-bit offset associated with a %fs value of zero. */
1f061d
 #     endif
1f061d
 
1f061d
-      /* Stack id (value (UWord)(-1) means that there is no stack). This
1f061d
-         tracks a stack that is set in restore_stack(). */
1f061d
-      UWord stk_id;
1f061d
-
1f061d
       /* Simulation of the kernel's lwp->lwp_ustack. Set in the PRE wrapper
1f061d
          of the getsetcontext syscall, for SETUSTACK. Used in
1f061d
          VG_(save_context)(), VG_(restore_context)() and