2009-08-10 Paul Pluzhnikov <ppluzhnikov@google.com>
[deliverable/binutils-gdb.git] / gdb / varobj.c
index 9729766e468c878e9052d0afd6138d790441d74a..4a94988b5727cfe0827c3efe10b4c9eb54ee3968 100644 (file)
@@ -257,7 +257,7 @@ static char *my_value_of_variable (struct varobj *var,
 
 static char *value_get_print_value (struct value *value,
                                    enum varobj_display_formats format,
-                                   PyObject *value_formatter);
+                                   struct varobj *var);
 
 static int varobj_value_is_changeable_p (struct varobj *var);
 
@@ -424,7 +424,6 @@ static int format_code[] = { 0, 't', 'd', 'x', 'o' };
 
 /* Header of the list of root variable objects */
 static struct varobj_root *rootlist;
-static int rootcount = 0;      /* number of root varobjs in the list */
 
 /* Prime number indicating the number of buckets in the hash table */
 /* A prime large enough to avoid too many colisions */
@@ -445,6 +444,17 @@ is_root_p (struct varobj *var)
   return (var->root->rootvar == var);
 }
 
+#ifdef HAVE_PYTHON
+/* Helper function to install a Python environment suitable for
+   use during operations on VAR.  */
+struct cleanup *
+varobj_ensure_python_env (struct varobj *var)
+{
+  return ensure_python_env (var->root->exp->gdbarch,
+                           var->root->exp->language_defn);
+}
+#endif
+
 /* Creates a varobj (not its children) */
 
 /* Return the full FRAME which corresponds to the given CORE_ADDR
@@ -462,7 +472,16 @@ find_frame_addr_in_frame_chain (CORE_ADDR frame_addr)
        frame != NULL;
        frame = get_prev_frame (frame))
     {
-      if (get_frame_base_address (frame) == frame_addr)
+      /* The CORE_ADDR we get as argument was parsed from a string GDB
+        output as $fp.  This output got truncated to gdbarch_addr_bit.
+        Truncate the frame base address in the same manner before
+        comparing it against our argument.  */
+      CORE_ADDR frame_base = get_frame_base_address (frame);
+      int addr_bit = gdbarch_addr_bit (get_frame_arch (frame));
+      if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT))
+       frame_base &= ((CORE_ADDR) 1 << addr_bit) - 1;
+
+      if (frame_base == frame_addr)
        return frame;
     }
 
@@ -577,7 +596,7 @@ varobj_create (char *objname,
       var->root->rootvar = var;
 
       /* Reset the selected frame */
-      if (fi != NULL)
+      if (old_fi != NULL)
        select_frame (old_fi);
     }
 
@@ -755,8 +774,7 @@ varobj_set_display_format (struct varobj *var,
       && var->value && !value_lazy (var->value))
     {
       xfree (var->print_value);
-      var->print_value = value_get_print_value (var->value, var->format,
-                                               var->pretty_printer);
+      var->print_value = value_get_print_value (var->value, var->format, var);
     }
 
   return var->format;
@@ -774,10 +792,12 @@ varobj_get_display_hint (struct varobj *var)
   char *result = NULL;
 
 #if HAVE_PYTHON
-  PyGILState_STATE state = PyGILState_Ensure ();
+  struct cleanup *back_to = varobj_ensure_python_env (var);
+
   if (var->pretty_printer)
     result = gdbpy_get_display_hint (var->pretty_printer);
-  PyGILState_Release (state);
+
+  do_cleanups (back_to);
 #endif
 
   return result;
@@ -832,10 +852,8 @@ update_dynamic_varobj_children (struct varobj *var,
   int i;
   int children_changed = 0;
   PyObject *printer = var->pretty_printer;
-  PyGILState_STATE state;
 
-  state = PyGILState_Ensure ();
-  back_to = make_cleanup_py_restore_gil (&state);
+  back_to = varobj_ensure_python_env (var);
 
   *cchanged = 0;
   if (!PyObject_HasAttr (printer, gdbpy_children_cst))
@@ -1021,29 +1039,13 @@ varobj_add_child (struct varobj *var, const char *name, struct value *value)
 char *
 varobj_get_type (struct varobj *var)
 {
-  struct value *val;
-  struct cleanup *old_chain;
-  struct ui_file *stb;
-  char *thetype;
-  long length;
-
   /* For the "fake" variables, do not return a type. (It's type is
      NULL, too.)
      Do not return a type for invalid variables as well.  */
   if (CPLUS_FAKE_CHILD (var) || !var->root->is_valid)
     return NULL;
 
-  stb = mem_fileopen ();
-  old_chain = make_cleanup_ui_file_delete (stb);
-
-  /* To print the type, we simply create a zero ``struct value *'' and
-     cast it to our type. We then typeprint this variable. */
-  val = value_zero (var->type, not_lval);
-  type_print (value_type (val), "", stb, -1);
-
-  thetype = ui_file_xstrdup (stb, &length);
-  do_cleanups (old_chain);
-  return thetype;
+  return type_to_string (var->type);
 }
 
 /* Obtain the type of an object variable.  */
@@ -1166,37 +1168,6 @@ varobj_set_value (struct varobj *var, char *expression)
   return 1;
 }
 
-/* Returns a malloc'ed list with all root variable objects */
-int
-varobj_list (struct varobj ***varlist)
-{
-  struct varobj **cv;
-  struct varobj_root *croot;
-  int mycount = rootcount;
-
-  /* Alloc (rootcount + 1) entries for the result */
-  *varlist = xmalloc ((rootcount + 1) * sizeof (struct varobj *));
-
-  cv = *varlist;
-  croot = rootlist;
-  while ((croot != NULL) && (mycount > 0))
-    {
-      *cv = croot->rootvar;
-      mycount--;
-      cv++;
-      croot = croot->next;
-    }
-  /* Mark the end of the list */
-  *cv = NULL;
-
-  if (mycount || (croot != NULL))
-    warning
-      ("varobj_list: assertion failed - wrong tally of root vars (%d:%d)",
-       rootcount, mycount);
-
-  return rootcount;
-}
-
 /* Assign a new value to a variable object.  If INITIAL is non-zero,
    this is the first assignement after the variable object was just
    created, or changed type.  In that case, just assign the value 
@@ -1288,8 +1259,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
      lazy -- if it is, the code above has decided that the value
      should not be fetched.  */
   if (value && !value_lazy (value))
-    print_value = value_get_print_value (value, var->format, 
-                                        var->pretty_printer);
+    print_value = value_get_print_value (value, var->format, var);
 
   /* If the type is changeable, compare the old and the new values.
      If this is the initial assignment, we don't have any old value
@@ -1392,11 +1362,9 @@ install_default_visualizer (struct varobj *var)
 {
 #if HAVE_PYTHON
   struct cleanup *cleanup;
-  PyGILState_STATE state;
   PyObject *pretty_printer = NULL;
 
-  state = PyGILState_Ensure ();
-  cleanup = make_cleanup_py_restore_gil (&state);
+  cleanup = varobj_ensure_python_env (var);
 
   if (var->value)
     {
@@ -1427,11 +1395,8 @@ varobj_set_visualizer (struct varobj *var, const char *visualizer)
 #if HAVE_PYTHON
   PyObject *mainmod, *globals, *pretty_printer, *constructor;
   struct cleanup *back_to, *value;
-  PyGILState_STATE state;
 
-
-  state = PyGILState_Ensure ();
-  back_to = make_cleanup_py_restore_gil (&state);
+  back_to = varobj_ensure_python_env (var);
 
   mainmod = PyImport_AddModule ("__main__");
   globals = PyModule_GetDict (mainmod);
@@ -1749,7 +1714,6 @@ install_variable (struct varobj *var)
       else
        var->root->next = rootlist;
       rootlist = var->root;
-      rootcount++;
     }
 
   return 1;                    /* OK */
@@ -1826,7 +1790,6 @@ uninstall_variable (struct varobj *var)
          else
            prer->next = cr->next;
        }
-      rootcount--;
     }
 
 }
@@ -1927,6 +1890,15 @@ new_root_variable (void)
 static void
 free_variable (struct varobj *var)
 {
+#if HAVE_PYTHON
+  if (var->pretty_printer)
+    {
+      struct cleanup *cleanup = varobj_ensure_python_env (var);
+      Py_DECREF (var->pretty_printer);
+      do_cleanups (cleanup);
+    }
+#endif
+
   value_free (var->value);
 
   /* Free the expression if this is a root variable. */
@@ -1936,14 +1908,6 @@ free_variable (struct varobj *var)
       xfree (var->root);
     }
 
-#if HAVE_PYTHON
-  {
-    PyGILState_STATE state = PyGILState_Ensure ();
-    Py_XDECREF (var->pretty_printer);
-    PyGILState_Release (state);
-  }
-#endif
-
   xfree (var->name);
   xfree (var->obj_name);
   xfree (var->print_value);
@@ -2218,26 +2182,30 @@ my_value_of_variable (struct varobj *var, enum varobj_display_formats format)
 
 static char *
 value_get_print_value (struct value *value, enum varobj_display_formats format,
-                      PyObject *value_formatter)
+                      struct varobj *var)
 {
   long dummy;
   struct ui_file *stb;
   struct cleanup *old_chain;
-  char *thevalue = NULL;
+  gdb_byte *thevalue = NULL;
   struct value_print_options opts;
+  int len = 0;
 
   if (value == NULL)
     return NULL;
 
 #if HAVE_PYTHON
   {
-    PyGILState_STATE state = PyGILState_Ensure ();
+    struct cleanup *back_to = varobj_ensure_python_env (var);
+    PyObject *value_formatter = var->pretty_printer;
+
     if (value_formatter && PyObject_HasAttr (value_formatter,
                                             gdbpy_to_string_cst))
       {
        char *hint;
        struct value *replacement;
        int string_print = 0;
+       PyObject *output = NULL;
 
        hint = gdbpy_get_display_hint (value_formatter);
        if (hint)
@@ -2247,17 +2215,29 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
            xfree (hint);
          }
 
-       thevalue = apply_varobj_pretty_printer (value_formatter,
-                                               &replacement);
+       output = apply_varobj_pretty_printer (value_formatter,
+                                             &replacement);
+       if (output)
+         {
+           PyObject *py_str = python_string_to_target_python_string (output);
+           if (py_str)
+             {
+               char *s = PyString_AsString (py_str);
+               len = PyString_Size (py_str);
+               thevalue = xmemdup (s, len + 1, len + 1);
+               Py_DECREF (py_str);
+             }
+           Py_DECREF (output);
+         }
        if (thevalue && !string_print)
          {
-           PyGILState_Release (state);
+           do_cleanups (back_to);
            return thevalue;
          }
        if (replacement)
          value = replacement;
       }
-    PyGILState_Release (state);
+    do_cleanups (back_to);
   }
 #endif
 
@@ -2269,10 +2249,10 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
   opts.raw = 1;
   if (thevalue)
     {
+      struct gdbarch *gdbarch = get_type_arch (value_type (value));
       make_cleanup (xfree, thevalue);
-      LA_PRINT_STRING (stb, builtin_type (current_gdbarch)->builtin_char,
-                      (gdb_byte *) thevalue, strlen (thevalue),
-                      0, &opts);
+      LA_PRINT_STRING (stb, builtin_type (gdbarch)->builtin_char,
+                      thevalue, len, 0, &opts);
     }
   else
     common_val_print (value, stb, 0, &opts, current_language);
@@ -2547,9 +2527,7 @@ c_describe_child (struct varobj *parent, int index,
       if (cvalue && value)
        {
          int real_index = index + TYPE_LOW_BOUND (TYPE_INDEX_TYPE (type));
-         struct value *indval = 
-           value_from_longest (builtin_type_int32, (LONGEST) real_index);
-         gdb_value_subscript (value, indval, cvalue);
+         gdb_value_subscript (value, real_index, cvalue);
        }
 
       if (ctype)
@@ -2781,8 +2759,7 @@ c_value_of_variable (struct varobj *var, enum varobj_display_formats format)
            if (format == var->format)
              return xstrdup (var->print_value);
            else
-             return value_get_print_value (var->value, format, 
-                                           var->pretty_printer);
+             return value_get_print_value (var->value, format, var);
          }
       }
     }
@@ -3195,6 +3172,24 @@ java_value_of_variable (struct varobj *var, enum varobj_display_formats format)
 {
   return cplus_value_of_variable (var, format);
 }
+
+/* Iterate all the existing _root_ VAROBJs and call the FUNC callback for them
+   with an arbitrary caller supplied DATA pointer.  */
+
+void
+all_root_varobjs (void (*func) (struct varobj *var, void *data), void *data)
+{
+  struct varobj_root *var_root, *var_root_next;
+
+  /* Iterate "safely" - handle if the callee deletes its passed VAROBJ.  */
+
+  for (var_root = rootlist; var_root != NULL; var_root = var_root_next)
+    {
+      var_root_next = var_root->next;
+
+      (*func) (var_root->rootvar, data);
+    }
+}
 \f
 extern void _initialize_varobj (void);
 void
@@ -3215,51 +3210,45 @@ When non-zero, varobj debugging is enabled."),
                            &setlist, &showlist);
 }
 
-/* Invalidate the varobjs that are tied to locals and re-create the ones that
-   are defined on globals.
-   Invalidated varobjs will be always printed in_scope="invalid".  */
+/* Invalidate varobj VAR if it is tied to locals and re-create it if it is
+   defined on globals.  It is a helper for varobj_invalidate.  */
 
-void 
-varobj_invalidate (void)
+static void
+varobj_invalidate_iter (struct varobj *var, void *unused)
 {
-  struct varobj **all_rootvarobj;
-  struct varobj **varp;
+  /* Floating varobjs are reparsed on each stop, so we don't care if the
+     presently parsed expression refers to something that's gone.  */
+  if (var->root->floating)
+    return;
 
-  if (varobj_list (&all_rootvarobj) > 0)
+  /* global var must be re-evaluated.  */     
+  if (var->root->valid_block == NULL)
     {
-      varp = all_rootvarobj;
-      while (*varp != NULL)
-       {
-         /* Floating varobjs are reparsed on each stop, so we don't care if
-            the presently parsed expression refers to something that's gone.
-            */
-         if ((*varp)->root->floating)
-           continue;
-
-         /* global var must be re-evaluated.  */     
-         if ((*varp)->root->valid_block == NULL)
-           {
-             struct varobj *tmp_var;
-
-             /* Try to create a varobj with same expression.  If we succeed
-                replace the old varobj, otherwise invalidate it.  */
-             tmp_var = varobj_create (NULL, (*varp)->name, (CORE_ADDR) 0,
-                                      USE_CURRENT_FRAME);
-             if (tmp_var != NULL) 
-               { 
-                 tmp_var->obj_name = xstrdup ((*varp)->obj_name);
-                 varobj_delete (*varp, NULL, 0);
-                 install_variable (tmp_var);
-               }
-             else
-               (*varp)->root->is_valid = 0;
-           }
-         else /* locals must be invalidated.  */
-           (*varp)->root->is_valid = 0;
+      struct varobj *tmp_var;
 
-         varp++;
+      /* Try to create a varobj with same expression.  If we succeed
+        replace the old varobj, otherwise invalidate it.  */
+      tmp_var = varobj_create (NULL, var->name, (CORE_ADDR) 0,
+                              USE_CURRENT_FRAME);
+      if (tmp_var != NULL) 
+       { 
+         tmp_var->obj_name = xstrdup (var->obj_name);
+         varobj_delete (var, NULL, 0);
+         install_variable (tmp_var);
        }
+      else
+       var->root->is_valid = 0;
     }
-  xfree (all_rootvarobj);
-  return;
+  else /* locals must be invalidated.  */
+    var->root->is_valid = 0;
+}
+
+/* Invalidate the varobjs that are tied to locals and re-create the ones that
+   are defined on globals.
+   Invalidated varobjs will be always printed in_scope="invalid".  */
+
+void 
+varobj_invalidate (void)
+{
+  all_root_varobjs (varobj_invalidate_iter, NULL);
 }
This page took 0.028272 seconds and 4 git commands to generate.