* varobj.c (struct varobj_root): New component thread_id.
authorVladimir Prus <vladimir@codesourcery.com>
Mon, 24 Mar 2008 17:33:30 +0000 (17:33 +0000)
committerVladimir Prus <vladimir@codesourcery.com>
Mon, 24 Mar 2008 17:33:30 +0000 (17:33 +0000)
        (varobj_get_thread_id, check_scope): New functions.
        (c_value_of_root): Use check_scope.  Switch to the
proper thread if necessary.

        * varobj.h (varobj_get_thread_id): New extern.

        * mi/mi-cmd-var.c (print_varobj): Add thread-id field.

gdb/ChangeLog
gdb/mi/mi-cmd-var.c
gdb/varobj.c
gdb/varobj.h

index ed25beba430398543ed1678d00cb4cc8befc7549..16a6c62f6ae5913bbccabb14378509ae70982391 100644 (file)
@@ -1,3 +1,15 @@
+2008-03-24  Nick Roberts  <nickrob@snap.net.nz>
+           Vladimir Prus  <vladimir@codesourcery.com>
+
+        * varobj.c  (struct varobj_root): New component thread_id.
+        (varobj_get_thread_id, check_scope): New functions.
+        (c_value_of_root): Use check_scope.  Switch to the
+       proper thread if necessary.
+
+        * varobj.h (varobj_get_thread_id): New extern.
+
+        * mi/mi-cmd-var.c (print_varobj): Add thread-id field.
+
 2008-03-23  Daniel Jacobowitz  <dan@codesourcery.com>
 
        PR gdb/544
index 7dfa1f0af64b708853dace5d8e03c3edd79a041e..dc873cacc43245cca7599b6823d56ddccf36889c 100644 (file)
@@ -50,6 +50,7 @@ print_varobj (struct varobj *var, enum print_values print_values,
 {
   struct type *gdb_type;
   char *type;
+  int thread_id;
 
   ui_out_field_string (uiout, "name", varobj_get_objname (var));
   if (print_expression)
@@ -66,6 +67,10 @@ print_varobj (struct varobj *var, enum print_values print_values,
       xfree (type);
     }
 
+  thread_id = varobj_get_thread_id (var);
+  if (thread_id > 0)
+    ui_out_field_int (uiout, "thread-id", thread_id);
+
   if (varobj_get_frozen (var))
     ui_out_field_int (uiout, "frozen", 1);
 }
index 3f08dfc6a1e1bcc857edd3690e0d36537b0d657e..c8d85a9bbdc336cd60fc2fdcc08ef2efafe99d70 100644 (file)
@@ -68,6 +68,13 @@ struct varobj_root
      not NULL.  */
   struct frame_id frame;
 
+  /* The thread ID that this varobj_root belong to.  This field
+     is only valid if valid_block is not NULL.  
+     When not 0, indicates which thread 'frame' belongs to.
+     When 0, indicates that the thread list was empty when the varobj_root
+     was created.  */
+  int thread_id;
+
   /* If 1, "update" always recomputes the frame & valid block
      using the currently selected frame. */
   int use_selected_frame;
@@ -503,8 +510,9 @@ varobj_create (char *objname,
       if (innermost_block && fi != NULL)
        {
          var->root->frame = get_frame_id (fi);
+         var->root->thread_id = pid_to_thread_id (inferior_ptid);
          old_fi = get_selected_frame (NULL);
-         select_frame (fi);
+         select_frame (fi);     
        }
 
       /* We definitely need to catch errors here.
@@ -692,6 +700,19 @@ varobj_get_display_format (struct varobj *var)
   return var->format;
 }
 
+/* If the variable object is bound to a specific thread, that
+   is its evaluation can always be done in context of a frame
+   inside that thread, returns GDB id of the thread -- which
+   is always positive.  Otherwise, returns -1. */
+int
+varobj_get_thread_id (struct varobj *var)
+{
+  if (var->root->valid_block && var->root->thread_id > 0)
+    return var->root->thread_id;
+  else
+    return -1;
+}
+
 void
 varobj_set_frozen (struct varobj *var, int frozen)
 {
@@ -2138,13 +2159,36 @@ c_path_expr_of_child (struct varobj *child)
   return child->path_expr;
 }
 
+/* If frame associated with VAR can be found, switch
+   to it and return 1.  Otherwise, return 0.  */
+static int
+check_scope (struct varobj *var)
+{
+  struct frame_info *fi;
+  int scope;
+
+  fi = frame_find_by_id (var->root->frame);
+  scope = fi != NULL;
+
+  if (fi)
+    {
+      CORE_ADDR pc = get_frame_pc (fi);
+      if (pc <  BLOCK_START (var->root->valid_block) ||
+         pc >= BLOCK_END (var->root->valid_block))
+       scope = 0;
+      else
+       select_frame (fi);
+    }
+  return scope;
+}
+
 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;
-  int within_scope;
+  int within_scope = 0;
   struct cleanup *back_to;
                                                                 
   /*  Only root variables can be updated... */
@@ -2158,20 +2202,22 @@ c_value_of_root (struct varobj **var_handle)
   /* Determine whether the variable is still around. */
   if (var->root->valid_block == NULL || var->root->use_selected_frame)
     within_scope = 1;
+  else if (var->root->thread_id == 0)
+    {
+      /* The program was single-threaded when the variable object was
+        created.  Technically, it's possible that the program became
+        multi-threaded since then, but we don't support such
+        scenario yet.  */
+      within_scope = check_scope (var);          
+    }
   else
     {
-      fi = frame_find_by_id (var->root->frame);
-      within_scope = fi != NULL;
-      /* FIXME: select_frame could fail */
-      if (fi)
+      ptid_t ptid = thread_id_to_pid (var->root->thread_id);
+      if (in_thread_list (ptid))
        {
-         CORE_ADDR pc = get_frame_pc (fi);
-         if (pc <  BLOCK_START (var->root->valid_block) ||
-             pc >= BLOCK_END (var->root->valid_block))
-           within_scope = 0;
-         else
-           select_frame (fi);
-       }         
+         switch_to_thread (ptid);
+         within_scope = check_scope (var);
+       }
     }
 
   if (within_scope)
index e0a5c170fbeb58b43fb95b648e813e1cf3242cb0..4033b4b955e34e3a4b3c4fd9cb1e1cab504f3184 100644 (file)
@@ -89,6 +89,8 @@ extern enum varobj_display_formats varobj_set_display_format (
 extern enum varobj_display_formats varobj_get_display_format (
                                                        struct varobj *var);
 
+extern int varobj_get_thread_id (struct varobj *var);
+
 extern void varobj_set_frozen (struct varobj *var, int frozen);
 
 extern int varobj_get_frozen (struct varobj *var);
This page took 0.043442 seconds and 4 git commands to generate.