Jan Kratochvil fbf39fd
http://sourceware.org/ml/gdb-patches/2012-04/msg00058.html
Jan Kratochvil fbf39fd
Subject: [downstream patch FYI] workaround stale frame_info * (PR 13866)
Jan Kratochvil fbf39fd
Jan Kratochvil fbf39fd
Hi,
Jan Kratochvil fbf39fd
Jan Kratochvil fbf39fd
I did not look at which commit caused this regression but apparently it was
Jan Kratochvil fbf39fd
introduced at least with multi-inferiors.
Jan Kratochvil fbf39fd
Jan Kratochvil fbf39fd
I understand this fix is not right fix of the crash; but in most GDB cases one
Jan Kratochvil fbf39fd
does not use multi-inferior so why to regress single-inferior by it.
Jan Kratochvil fbf39fd
Some more simple solutions still fix the single-inferior mode but they
Jan Kratochvil fbf39fd
regressed the multi-inferior mode
Jan Kratochvil fbf39fd
	gdb.threads/no-unwaited-for-left.exp
Jan Kratochvil fbf39fd
	gdb.multi/base.exp
Jan Kratochvil fbf39fd
so I had to put there that sorting magic.
Jan Kratochvil fbf39fd
Jan Kratochvil fbf39fd
With proper C++ sanity check of stale live frame_info references the testcase
Jan Kratochvil fbf39fd
would be simple without the "frame_garbage_collection" reproducer below.
Jan Kratochvil fbf39fd
It is also reproducible just with valgrind but regularly running the whole
Jan Kratochvil fbf39fd
testsuite under valgrind I did not find feasible.
Jan Kratochvil fbf39fd
Jan Kratochvil fbf39fd
No regressions on {x86_64,x86_64-m32,i686}-fedora17-linux-gnu.
Jan Kratochvil fbf39fd
Jan Kratochvil fbf39fd
Jan Kratochvil fbf39fd
Thanks,
Jan Kratochvil fbf39fd
Jan
Jan Kratochvil fbf39fd
Jan Kratochvil fbf39fd
Jan Kratochvil fbf39fd
gdb/
Jan Kratochvil fbf39fd
2012-04-04  Jan Kratochvil  <jan.kratochvil@redhat.com>
Jan Kratochvil fbf39fd
Jan Kratochvil fbf39fd
	Workaround PR backtrace/13866.
Jan Kratochvil fbf39fd
	* progspace.c (switch_to_program_space_and_thread): Try not to call
Jan Kratochvil fbf39fd
	switch_to_thread.
Jan Kratochvil fbf39fd
Jan Kratochvil fbf39fd
--- a/gdb/progspace.c
Jan Kratochvil fbf39fd
+++ b/gdb/progspace.c
Jan Kratochvil fbf39fd
@@ -481,17 +481,28 @@ save_current_space_and_thread (void)
Jan Kratochvil fbf39fd
 void
Jan Kratochvil fbf39fd
 switch_to_program_space_and_thread (struct program_space *pspace)
Jan Kratochvil fbf39fd
 {
Jan Kratochvil fbf39fd
-  struct inferior *inf;
Jan Kratochvil fbf39fd
+  struct inferior *inf = current_inferior ();
Jan Kratochvil fbf39fd
 
Jan Kratochvil fbf39fd
-  inf = find_inferior_for_program_space (pspace);
Jan Kratochvil fbf39fd
+  if (inf->pspace != pspace)
Jan Kratochvil fbf39fd
+    inf = find_inferior_for_program_space (pspace);
Jan Kratochvil fbf39fd
   if (inf != NULL)
Jan Kratochvil fbf39fd
     {
Jan Kratochvil fbf39fd
-      struct thread_info *tp;
Jan Kratochvil fbf39fd
+      struct thread_info *tp, *current_tp = NULL;
Jan Kratochvil fbf39fd
+
Jan Kratochvil fbf39fd
+      if (ptid_get_pid (inferior_ptid) == inf->pid)
Jan Kratochvil fbf39fd
+	current_tp = find_thread_ptid (inferior_ptid);
Jan Kratochvil fbf39fd
 
Jan Kratochvil fbf39fd
       tp = any_live_thread_of_process (inf->pid);
Jan Kratochvil fbf39fd
       if (tp != NULL)
Jan Kratochvil fbf39fd
 	{
Jan Kratochvil fbf39fd
-	  switch_to_thread (tp->ptid);
Jan Kratochvil fbf39fd
+	  /* Prefer primarily thread not THREAD_EXITED and secondarily thread
Jan Kratochvil fbf39fd
+	     not EXECUTING.  */
Jan Kratochvil fbf39fd
+	  if (current_tp == NULL
Jan Kratochvil fbf39fd
+	      || (tp->state != THREAD_EXITED
Jan Kratochvil fbf39fd
+		  && current_tp->state == THREAD_EXITED)
Jan Kratochvil fbf39fd
+	      || (!tp->executing && current_tp->executing))
Jan Kratochvil fbf39fd
+	    switch_to_thread (tp->ptid);
Jan Kratochvil fbf39fd
+
Jan Kratochvil fbf39fd
 	  /* Switching thread switches pspace implicitly.  We're
Jan Kratochvil fbf39fd
 	     done.  */
Jan Kratochvil fbf39fd
 	  return;
Jan Kratochvil fbf39fd
Jan Kratochvil fbf39fd
Jan Kratochvil fbf39fd
Reproducer with:
Jan Kratochvil fbf39fd
./gdb -nx ~/t/thread -ex 'b 24' -ex r -ex 'until 25'
Jan Kratochvil fbf39fd
Breakpoint 1, main () at /home/jkratoch/t/thread.c:24
Jan Kratochvil fbf39fd
24	  v++;
Jan Kratochvil fbf39fd
Segmentation fault (core dumped)
Jan Kratochvil fbf39fd
Jan Kratochvil fbf39fd
#include <pthread.h>
Jan Kratochvil fbf39fd
#include <assert.h>
Jan Kratochvil fbf39fd
#include <unistd.h>
Jan Kratochvil fbf39fd
Jan Kratochvil fbf39fd
static int v;
Jan Kratochvil fbf39fd
Jan Kratochvil fbf39fd
static void *start (void *arg)
Jan Kratochvil fbf39fd
{
Jan Kratochvil fbf39fd
  v++;
Jan Kratochvil fbf39fd
  v++;
Jan Kratochvil fbf39fd
  v++;
Jan Kratochvil fbf39fd
  v++;
Jan Kratochvil fbf39fd
  sleep (100);
Jan Kratochvil fbf39fd
  return arg;
Jan Kratochvil fbf39fd
}
Jan Kratochvil fbf39fd
Jan Kratochvil fbf39fd
int main (void)
Jan Kratochvil fbf39fd
{
Jan Kratochvil fbf39fd
  pthread_t thread1;
Jan Kratochvil fbf39fd
  int i;
Jan Kratochvil fbf39fd
Jan Kratochvil fbf39fd
  i = pthread_create (&thread1, NULL, start, NULL);
Jan Kratochvil fbf39fd
  assert (i == 0);
Jan Kratochvil fbf39fd
  v++;
Jan Kratochvil fbf39fd
  v++;
Jan Kratochvil fbf39fd
  v++;
Jan Kratochvil fbf39fd
  v++;
Jan Kratochvil fbf39fd
  i = pthread_join (thread1, NULL);
Jan Kratochvil fbf39fd
  assert (i == 0);
Jan Kratochvil fbf39fd
Jan Kratochvil fbf39fd
  return 0;
Jan Kratochvil fbf39fd
}
Jan Kratochvil fbf39fd
### --- a/gdb/frame.c
Jan Kratochvil fbf39fd
### +++ b/gdb/frame.c
Jan Kratochvil fbf39fd
### @@ -1522,12 +1522,30 @@ frame_observer_target_changed (struct target_ops *target)
Jan Kratochvil fbf39fd
###    reinit_frame_cache ();
Jan Kratochvil fbf39fd
###  }
Jan Kratochvil fbf39fd
###  
Jan Kratochvil fbf39fd
### +typedef struct obstack obstack_s;
Jan Kratochvil fbf39fd
### +DEF_VEC_O (obstack_s);
Jan Kratochvil fbf39fd
### +static VEC (obstack_s) *frame_poison_vec;
Jan Kratochvil fbf39fd
### +
Jan Kratochvil fbf39fd
### +void frame_garbage_collection (void);
Jan Kratochvil fbf39fd
### +void
Jan Kratochvil fbf39fd
### +frame_garbage_collection (void)
Jan Kratochvil fbf39fd
### +{
Jan Kratochvil fbf39fd
### +  struct obstack *obstack_p;
Jan Kratochvil fbf39fd
### +  int ix;
Jan Kratochvil fbf39fd
### +
Jan Kratochvil fbf39fd
### +  for (ix = 0; VEC_iterate (obstack_s, frame_poison_vec, ix, obstack_p); ix++)
Jan Kratochvil fbf39fd
### +    obstack_free (obstack_p, 0);
Jan Kratochvil fbf39fd
### +
Jan Kratochvil fbf39fd
### +  VEC_free (obstack_s, frame_poison_vec);
Jan Kratochvil fbf39fd
### +  frame_poison_vec = NULL;
Jan Kratochvil fbf39fd
### +}
Jan Kratochvil fbf39fd
### +
Jan Kratochvil fbf39fd
###  /* Flush the entire frame cache.  */
Jan Kratochvil fbf39fd
###  
Jan Kratochvil fbf39fd
###  void
Jan Kratochvil fbf39fd
###  reinit_frame_cache (void)
Jan Kratochvil fbf39fd
###  {
Jan Kratochvil fbf39fd
### -  struct frame_info *fi;
Jan Kratochvil fbf39fd
### +  struct frame_info *fi, *fi_prev;
Jan Kratochvil fbf39fd
###  
Jan Kratochvil fbf39fd
###    /* Tear down all frame caches.  */
Jan Kratochvil fbf39fd
###    for (fi = current_frame; fi != NULL; fi = fi->prev)
Jan Kratochvil fbf39fd
### @@ -1538,8 +1556,14 @@ reinit_frame_cache (void)
Jan Kratochvil fbf39fd
###  	fi->base->unwind->dealloc_cache (fi, fi->base_cache);
Jan Kratochvil fbf39fd
###      }
Jan Kratochvil fbf39fd
###  
Jan Kratochvil fbf39fd
### +  for (fi = current_frame; fi != NULL; fi = fi_prev)
Jan Kratochvil fbf39fd
### +    {
Jan Kratochvil fbf39fd
### +      fi_prev = fi->prev;
Jan Kratochvil fbf39fd
### +      memset (fi, 0, sizeof (*fi));
Jan Kratochvil fbf39fd
### +    }
Jan Kratochvil fbf39fd
### +  VEC_safe_push (obstack_s, frame_poison_vec, &frame_cache_obstack);
Jan Kratochvil fbf39fd
### +
Jan Kratochvil fbf39fd
###    /* Since we can't really be sure what the first object allocated was.  */
Jan Kratochvil fbf39fd
### -  obstack_free (&frame_cache_obstack, 0);
Jan Kratochvil fbf39fd
###    obstack_init (&frame_cache_obstack);
Jan Kratochvil fbf39fd
###  
Jan Kratochvil fbf39fd
###    if (current_frame != NULL)
Jan Kratochvil fbf39fd
### --- a/gdb/top.c
Jan Kratochvil fbf39fd
### +++ b/gdb/top.c
Jan Kratochvil fbf39fd
### @@ -359,6 +359,11 @@ prepare_execute_command (void)
Jan Kratochvil fbf39fd
###    if (non_stop)
Jan Kratochvil fbf39fd
###      target_dcache_invalidate ();
Jan Kratochvil fbf39fd
###  
Jan Kratochvil fbf39fd
### +  {
Jan Kratochvil fbf39fd
### +    extern void frame_garbage_collection (void);
Jan Kratochvil fbf39fd
### +    frame_garbage_collection ();
Jan Kratochvil fbf39fd
### +  }
Jan Kratochvil fbf39fd
### +
Jan Kratochvil fbf39fd
###    return cleanup;
Jan Kratochvil fbf39fd
###  }
Jan Kratochvil fbf39fd
###