This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Variable objects in multi-threaded programs


Currently GDB thinks variable objects have gone out of scope if the thread
changes.  This patch corrects that.

---
Nick                                           http://www.inet.net.nz/~nickrob


2008-01-24  Nick Roberts  <nickrob@snap.net.nz>

	* thread.c (make_cleanup_restore_current_thread)
	(do_restore_current_thread_cleanup): Don't make static
	(struct current_thread_cleanup): Move to gdbthread.h

	* gdbthread.h: Declare above functions as externs here.

	* varobj.c (look_for_frame): New function.
	(c_value_of_root): Use it to iterate over threads.



*** varobj.c.~1.99.~	2008-01-04 10:24:29.000000000 +1300
--- varobj.c	2008-01-24 16:42:41.000000000 +1300
***************
*** 24,30 ****
--- 24,32 ----
  #include "language.h"
  #include "wrapper.h"
  #include "gdbcmd.h"
+ #include "gdbthread.h"
  #include "block.h"
+ #include "inferior.h"
  
  #include "gdb_assert.h"
  #include "gdb_string.h"
*************** c_path_expr_of_child (struct varobj *chi
*** 2153,2164 ****
--- 2155,2181 ----
    return child->path_expr;
  }
  
+ static int
+ look_for_frame (struct thread_info *thr, void* arg)
+ {
+   struct frame_id *id = arg;
+   struct frame_info *fi;
+   switch_to_thread (thr->ptid);
+   fi = frame_find_by_id (*id);
+   if (fi)
+     return 1;
+   else
+     return 0;
+ }
+ 
  static struct value *
  c_value_of_root (struct varobj **var_handle)
  {
    struct value *new_val = NULL;
    struct varobj *var = *var_handle;
    struct frame_info *fi;
+   struct frame_id saved_frame_id;
+   struct cleanup *old_cleanups = NULL;
    int within_scope;
  
    /*  Only root variables can be updated... */
*************** c_value_of_root (struct varobj **var_han
*** 2172,2179 ****
      within_scope = 1;
    else
      {
        fi = frame_find_by_id (var->root->frame);
!       within_scope = fi != NULL;
        /* FIXME: select_frame could fail */
        if (fi)
  	{
--- 2189,2203 ----
      within_scope = 1;
    else
      {
+       saved_frame_id = get_frame_id (get_selected_frame (NULL));
+       old_cleanups
+ 	= make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
+ 
+       if (iterate_over_threads (look_for_frame, &var->root->frame))
+ 	within_scope = 1;
+ 
        fi = frame_find_by_id (var->root->frame);
! 
        /* FIXME: select_frame could fail */
        if (fi)
  	{
*************** c_value_of_root (struct varobj **var_han
*** 2194,2199 ****
--- 2218,2225 ----
        return new_val;
      }
  
+   do_cleanups (old_cleanups);
+ 
    return NULL;
  }
  

*** thread.c.~1.59.~	2008-01-24 09:47:31.000000000 +1300
--- thread.c	2008-01-24 15:38:41.000000000 +1300
*************** static void info_threads_command (char *
*** 60,67 ****
  static void thread_apply_command (char *, int);
  static void restore_current_thread (ptid_t);
  static void prune_threads (void);
- static struct cleanup *make_cleanup_restore_current_thread (ptid_t,
-                                                             struct frame_id);
  
  void
  delete_step_resume_breakpoint (void *arg)
--- 60,65 ----
*************** restore_selected_frame (struct frame_id 
*** 496,508 ****
      }
  }
  
! struct current_thread_cleanup
! {
!   ptid_t inferior_ptid;
!   struct frame_id selected_frame_id;
! };
! 
! static void
  do_restore_current_thread_cleanup (void *arg)
  {
    struct current_thread_cleanup *old = arg;
--- 494,500 ----
      }
  }
  
! void
  do_restore_current_thread_cleanup (void *arg)
  {
    struct current_thread_cleanup *old = arg;
*************** do_restore_current_thread_cleanup (void 
*** 511,517 ****
    xfree (old);
  }
  
! static struct cleanup *
  make_cleanup_restore_current_thread (ptid_t inferior_ptid, 
                                       struct frame_id a_frame_id)
  {
--- 503,509 ----
    xfree (old);
  }
  
! struct cleanup *
  make_cleanup_restore_current_thread (ptid_t inferior_ptid, 
                                       struct frame_id a_frame_id)
  {


*** gdbthread.h.~1.19.~	2008-01-24 09:47:30.000000000 +1300
--- gdbthread.h	2008-01-24 15:37:19.000000000 +1300
*************** extern void load_infrun_state (ptid_t pt
*** 143,148 ****
--- 143,159 ----
  /* Switch from one thread to another.  */
  extern void switch_to_thread (ptid_t ptid);
  
+ struct current_thread_cleanup
+ {
+   ptid_t inferior_ptid;
+   struct frame_id selected_frame_id;
+ };
+ 
+ extern void do_restore_current_thread_cleanup (void *arg);
+ 
+ extern struct cleanup * make_cleanup_restore_current_thread
+                           (ptid_t inferior_ptid, struct frame_id a_frame_id);
+ 
  /* Commands with a prefix of `thread'.  */
  extern struct cmd_list_element *thread_cmd_list;
  


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]