OSDN Git Service

* python/python-internal.h (struct language_defn): Declare.
authoruweigand <uweigand>
Thu, 2 Jul 2009 17:04:17 +0000 (17:04 +0000)
committeruweigand <uweigand>
Thu, 2 Jul 2009 17:04:17 +0000 (17:04 +0000)
(python_gdbarch, python_language): Likewise.
(ensure_python_env): Add prototype.
(make_cleanup_py_restore_gil): Remove prototype.

* python/python.c: Include "arch-utils.h", "value.h" and "language.h".
(python_gdbarch, python_language): New global variables.
(struct python_env): New data type.
(ensure_python_env, restore_python_env): New functions.
(eval_python_from_control_command): Call ensure_python_env to
install current architecture and language.
(python_command, gdbpy_new_objfile): Likewise.
* python/python-cmd.c: Include "arch-utils.h" and "language.h".
(cmdpy_destroyer, cmdpy_function, cmdpy_completer): Call
ensure_python_env.
* python/python-type.c (clean_up_objfile_types): Likewise.
* python/python-objfile.c: Include "language.h".
(clean_up_objfile): Call ensure_python_env.
* python/python-prettyprint.c (apply_val_pretty_printer): Likewise.
(apply_varobj_pretty_printer): Do not call PyGILState_Ensure.
* varobj.c (varobj_ensure_python_env): New helper function.
(varobj_get_display_hint, update_dynamic_varobj_children,
install_default_visualizer, varobj_set_visualizer, free_variable,
value_get_print_value): Call it.
(value_get_print_value): Add varobj argument instead of pretty
printer argument.  Update all callers.

* python/python-utils.c (py_gil_restore, make_cleanup_py_restore_gil):
Remove.

* value.h (internal_function_fn): Add GDBARCH and LANGUAGE argument.
(call_internal_function): Likewise.
* value.c (call_internal_function): Likewise.  Pass to handler.
* eval.c (evaluate_subexp_standard): Update call.
* python/python-function.c: Include "language.h".
(fnpy_call): Add GDBARCH and LANGAUAGE arguments and call
make_cleanup_python_env.

* python/python-value.c (builtin_type_pyint, builtin_type_pyfloat,
builtin_type_pylong, builtin_type_pybool, builtin_type_pychar,
valpy_str): Use python_gdbarch and python_language instead of
current_gdbarch and current_language.
* python/python-type.c (typy_lookup_typename): Likewise.

14 files changed:
gdb/ChangeLog
gdb/eval.c
gdb/python/python-cmd.c
gdb/python/python-function.c
gdb/python/python-internal.h
gdb/python/python-objfile.c
gdb/python/python-prettyprint.c
gdb/python/python-type.c
gdb/python/python-utils.c
gdb/python/python-value.c
gdb/python/python.c
gdb/value.c
gdb/value.h
gdb/varobj.c

index 4c7df3e..335b939 100644 (file)
@@ -1,5 +1,51 @@
 2009-07-02  Ulrich Weigand  <uweigand@de.ibm.com>
 
+       * python/python-internal.h (struct language_defn): Declare.
+       (python_gdbarch, python_language): Likewise.
+       (ensure_python_env): Add prototype.
+       (make_cleanup_py_restore_gil): Remove prototype.
+
+       * python/python.c: Include "arch-utils.h", "value.h" and "language.h".
+       (python_gdbarch, python_language): New global variables.
+       (struct python_env): New data type.
+       (ensure_python_env, restore_python_env): New functions.
+       (eval_python_from_control_command): Call ensure_python_env to
+       install current architecture and language.
+       (python_command, gdbpy_new_objfile): Likewise.
+       * python/python-cmd.c: Include "arch-utils.h" and "language.h".
+       (cmdpy_destroyer, cmdpy_function, cmdpy_completer): Call
+       ensure_python_env.
+       * python/python-type.c (clean_up_objfile_types): Likewise.
+       * python/python-objfile.c: Include "language.h".
+       (clean_up_objfile): Call ensure_python_env.
+       * python/python-prettyprint.c (apply_val_pretty_printer): Likewise.
+       (apply_varobj_pretty_printer): Do not call PyGILState_Ensure.
+       * varobj.c (varobj_ensure_python_env): New helper function.
+       (varobj_get_display_hint, update_dynamic_varobj_children,
+       install_default_visualizer, varobj_set_visualizer, free_variable,
+       value_get_print_value): Call it.
+       (value_get_print_value): Add varobj argument instead of pretty
+       printer argument.  Update all callers.
+
+       * python/python-utils.c (py_gil_restore, make_cleanup_py_restore_gil):
+       Remove.
+
+       * value.h (internal_function_fn): Add GDBARCH and LANGUAGE argument.
+       (call_internal_function): Likewise.
+       * value.c (call_internal_function): Likewise.  Pass to handler.
+       * eval.c (evaluate_subexp_standard): Update call.
+       * python/python-function.c: Include "language.h".
+       (fnpy_call): Add GDBARCH and LANGAUAGE arguments and call
+       make_cleanup_python_env.
+
+       * python/python-value.c (builtin_type_pyint, builtin_type_pyfloat,
+       builtin_type_pylong, builtin_type_pybool, builtin_type_pychar,
+       valpy_str): Use python_gdbarch and python_language instead of
+       current_gdbarch and current_language.
+       * python/python-type.c (typy_lookup_typename): Likewise.
+
+2009-07-02  Ulrich Weigand  <uweigand@de.ibm.com>
+
        * arch-utils.c (selected_byte_order): Return target_byte_order_user.
        (show_endian): Use target_byte_order_user if specified; otherwise
        use get_current_arch () instead of current_gdbarch.
index e028e89..7e41d39 100644 (file)
@@ -1522,7 +1522,8 @@ evaluate_subexp_standard (struct type *expect_type,
            error (_("Expression of type other than \"Function returning ...\" used as function"));
        }
       if (TYPE_CODE (value_type (argvec[0])) == TYPE_CODE_INTERNAL_FUNCTION)
-       return call_internal_function (argvec[0], nargs, argvec + 1);
+       return call_internal_function (exp->gdbarch, exp->language_defn,
+                                      argvec[0], nargs, argvec + 1);
 
       return call_function_by_hand (argvec[0], nargs, argvec + 1);
       /* pai: FIXME save value from call_function_by_hand, then adjust pc by adjust_fn_pc if +ve  */
index 8f59a22..528aca6 100644 (file)
@@ -19,6 +19,7 @@
 
 
 #include "defs.h"
+#include "arch-utils.h"
 #include "value.h"
 #include "exceptions.h"
 #include "python-internal.h"
@@ -26,6 +27,7 @@
 #include "gdbcmd.h"
 #include "cli/cli-decode.h"
 #include "completer.h"
+#include "language.h"
 
 /* Struct representing built-in completion types.  */
 struct cmdpy_completer
@@ -90,9 +92,9 @@ static void
 cmdpy_destroyer (struct cmd_list_element *self, void *context)
 {
   cmdpy_object *cmd;
-  PyGILState_STATE state;
+  struct cleanup *cleanup;
 
-  state = PyGILState_Ensure ();
+  cleanup = ensure_python_env (get_current_arch (), current_language);
 
   /* Release our hold on the command object.  */
   cmd = (cmdpy_object *) context;
@@ -105,7 +107,7 @@ cmdpy_destroyer (struct cmd_list_element *self, void *context)
   xfree (self->doc);
   xfree (self->prefixname);
 
-  PyGILState_Release (state);
+  do_cleanups (cleanup);
 }
 
 /* Called by gdb to invoke the command.  */
@@ -115,10 +117,8 @@ cmdpy_function (struct cmd_list_element *command, char *args, int from_tty)
   cmdpy_object *obj = (cmdpy_object *) get_cmd_context (command);
   PyObject *argobj, *ttyobj, *result;
   struct cleanup *cleanup;
-  PyGILState_STATE state;
 
-  state = PyGILState_Ensure ();
-  cleanup = make_cleanup_py_restore_gil (&state);
+  cleanup = ensure_python_env (get_current_arch (), current_language);
 
   if (! obj)
     error (_("Invalid invocation of Python command object."));
@@ -182,10 +182,8 @@ cmdpy_completer (struct cmd_list_element *command, char *text, char *word)
   PyObject *textobj, *wordobj, *resultobj = NULL;
   char **result = NULL;
   struct cleanup *cleanup;
-  PyGILState_STATE state;
 
-  state = PyGILState_Ensure ();
-  cleanup = make_cleanup_py_restore_gil (&state);
+  cleanup = ensure_python_env (get_current_arch (), current_language);
 
   if (! obj)
     error (_("Invalid invocation of Python command object."));
index 4a85a33..8a5abaf 100644 (file)
@@ -27,6 +27,7 @@
 #include "cli/cli-decode.h"
 #include "completer.h"
 #include "expression.h"
+#include "language.h"
 
 static PyTypeObject fnpy_object_type;
 
@@ -53,16 +54,15 @@ convert_values_to_python (int argc, struct value **argv)
 /* Call a Python function object's invoke method.  */
 
 static struct value *
-fnpy_call (void *cookie, int argc, struct value **argv)
+fnpy_call (struct gdbarch *gdbarch, const struct language_defn *language,
+          void *cookie, int argc, struct value **argv)
 {
   int i;
   struct value *value = NULL;
   PyObject *result, *callable, *args;
   struct cleanup *cleanup;
-  PyGILState_STATE state;
 
-  state = PyGILState_Ensure ();
-  cleanup = make_cleanup_py_restore_gil (&state);
+  cleanup = ensure_python_env (gdbarch, language);
 
   args = convert_values_to_python (argc, argv);
 
index 35d3870..39d37e1 100644 (file)
@@ -62,6 +62,7 @@ typedef int Py_ssize_t;
 #endif
 
 struct value;
+struct language_defn;
 
 extern PyObject *gdb_module;
 extern PyTypeObject value_object_type;
@@ -89,7 +90,12 @@ void gdbpy_initialize_functions (void);
 void gdbpy_initialize_objfile (void);
 
 struct cleanup *make_cleanup_py_decref (PyObject *py);
-struct cleanup *make_cleanup_py_restore_gil (PyGILState_STATE *state);
+
+struct cleanup *ensure_python_env (struct gdbarch *gdbarch,
+                                  const struct language_defn *language);
+
+extern struct gdbarch *python_gdbarch;
+extern const struct language_defn *python_language;
 
 /* Use this after a TRY_EXCEPT to throw the appropriate Python
    exception.  */
index b70a006..a483d33 100644 (file)
@@ -21,6 +21,7 @@
 #include "python-internal.h"
 #include "charset.h"
 #include "objfiles.h"
+#include "language.h"
 
 typedef struct
 {
@@ -119,13 +120,13 @@ objfpy_set_printers (PyObject *o, PyObject *value, void *ignore)
 static void
 clean_up_objfile (struct objfile *objfile, void *datum)
 {
-  PyGILState_STATE state;
+  struct cleanup *cleanup;
   objfile_object *object = datum;
 
-  state = PyGILState_Ensure ();
+  cleanup = ensure_python_env (get_objfile_arch (objfile), current_language);
   object->objfile = NULL;
   Py_DECREF ((PyObject *) object);
-  PyGILState_Release (state);
+  do_cleanups (cleanup);
 }
 
 /* Return a borrowed reference to the Python object of type Objfile
index 09ef261..57e517a 100644 (file)
@@ -474,10 +474,8 @@ apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
   char *hint = NULL;
   struct cleanup *cleanups;
   int result = 0;
-  PyGILState_STATE state;
 
-  state = PyGILState_Ensure ();
-  cleanups = make_cleanup_py_restore_gil (&state);
+  cleanups = ensure_python_env (gdbarch, language);
 
   /* Instantiate the printer.  */
   if (valaddr)
@@ -526,13 +524,11 @@ apply_varobj_pretty_printer (PyObject *printer_obj,
                             struct value **replacement)
 {
   char *result;
-  PyGILState_STATE state = PyGILState_Ensure ();
 
   *replacement = NULL;
   result = pretty_print_one_value (printer_obj, replacement);
   if (result == NULL);
     gdbpy_print_stack ();
-  PyGILState_Release (state);
 
   return result;
 }
index 0874a99..e185112 100644 (file)
@@ -374,7 +374,7 @@ typy_lookup_typename (char *type_name)
       else if (!strncmp (type_name, "enum ", 5))
        type = lookup_enum (type_name + 5, NULL);
       else
-       type = lookup_typename (current_language, current_gdbarch,
+       type = lookup_typename (python_language, python_gdbarch,
                                type_name, NULL, 0);
     }
   if (except.reason < 0)
@@ -532,12 +532,10 @@ clean_up_objfile_types (struct objfile *objfile, void *datum)
   type_object *obj = datum;
   htab_t copied_types;
   struct cleanup *cleanup;
-  PyGILState_STATE state;
 
   /* This prevents another thread from freeing the objects we're
      operating on.  */
-  state = PyGILState_Ensure ();
-  cleanup = make_cleanup_py_restore_gil (&state);
+  cleanup = ensure_python_env (get_objfile_arch (objfile), current_language);
 
   copied_types = create_copied_types_hash (objfile);
 
index ddac2f5..9f6fe07 100644 (file)
@@ -46,23 +46,6 @@ make_cleanup_py_decref (PyObject *py)
   return make_cleanup (py_decref, (void *) py);
 }
 
-/* A cleanup function to restore the thread state.  */
-
-static void
-py_gil_restore (void *p)
-{
-  PyGILState_STATE *state = p;
-  PyGILState_Release (*state);
-}
-
-/* Return a new cleanup which will restore the Python GIL state.  */
-
-struct cleanup *
-make_cleanup_py_restore_gil (PyGILState_STATE *state)
-{
-  return make_cleanup (py_gil_restore, state);
-}
-
 /* Converts a Python 8-bit string to a unicode string object.  Assumes the
    8-bit string is in the host charset.  If an error occurs during conversion,
    returns NULL with a python exception set.
index ebc15dc..d4353f7 100644 (file)
@@ -44,19 +44,19 @@ struct value *values_in_python = NULL;
    GDB (which uses target arithmetic).  */
 
 /* Python's integer type corresponds to C's long type.  */
-#define builtin_type_pyint builtin_type (current_gdbarch)->builtin_long
+#define builtin_type_pyint builtin_type (python_gdbarch)->builtin_long
 
 /* Python's float type corresponds to C's double type.  */
-#define builtin_type_pyfloat builtin_type (current_gdbarch)->builtin_double
+#define builtin_type_pyfloat builtin_type (python_gdbarch)->builtin_double
 
 /* Python's long type corresponds to C's long long type.  */
-#define builtin_type_pylong builtin_type (current_gdbarch)->builtin_long_long
+#define builtin_type_pylong builtin_type (python_gdbarch)->builtin_long_long
 
 #define builtin_type_pybool \
-  language_bool_type (current_language, current_gdbarch)
+  language_bool_type (python_language, python_gdbarch)
 
 #define builtin_type_pychar \
-  language_string_char_type (current_language, current_gdbarch)
+  language_string_char_type (python_language, python_gdbarch)
 
 typedef struct {
   PyObject_HEAD
@@ -333,7 +333,7 @@ valpy_str (PyObject *self)
   TRY_CATCH (except, RETURN_MASK_ALL)
     {
       common_val_print (((value_object *) self)->value, stb, 0,
-                       &opts, current_language);
+                       &opts, python_language);
       s = ui_file_xstrdup (stb, &dummy);
     }
   GDB_PY_HANDLE_EXCEPTION (except);
index 3ad69d4..254bd28 100644 (file)
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
+#include "arch-utils.h"
 #include "command.h"
 #include "ui-out.h"
 #include "cli/cli-script.h"
 #include "gdbcmd.h"
 #include "objfiles.h"
 #include "observer.h"
+#include "value.h"
+#include "language.h"
 
 #include <ctype.h>
 
@@ -58,6 +61,52 @@ PyObject *gdbpy_children_cst;
 PyObject *gdbpy_display_hint_cst;
 PyObject *gdbpy_doc_cst;
 
+
+/* Architecture and language to be used in callbacks from
+   the Python interpreter.  */
+struct gdbarch *python_gdbarch;
+const struct language_defn *python_language;
+
+/* Restore global language and architecture and Python GIL state
+   when leaving the Python interpreter.  */
+
+struct python_env
+{
+  PyGILState_STATE state;
+  struct gdbarch *gdbarch;
+  const struct language_defn *language;
+};
+
+static void
+restore_python_env (void *p)
+{
+  struct python_env *env = (struct python_env *)p;
+  PyGILState_Release (env->state);
+  python_gdbarch = env->gdbarch;
+  python_language = env->language;
+  xfree (env);
+}
+
+/* Called before entering the Python interpreter to install the
+   current language and architecture to be used for Python values.  */
+
+struct cleanup *
+ensure_python_env (struct gdbarch *gdbarch,
+                   const struct language_defn *language)
+{
+  struct python_env *env = xmalloc (sizeof *env);
+
+  env->state = PyGILState_Ensure ();
+  env->gdbarch = python_gdbarch;
+  env->language = python_language;
+
+  python_gdbarch = gdbarch;
+  python_language = language;
+
+  return make_cleanup (restore_python_env, env);
+}
+
+
 /* Given a command_line, return a command string suitable for passing
    to Python.  Lines in the string are separated by newlines.  The
    return value is allocated using xmalloc and the caller is
@@ -96,13 +145,11 @@ eval_python_from_control_command (struct command_line *cmd)
   int ret;
   char *script;
   struct cleanup *cleanup;
-  PyGILState_STATE state;
 
   if (cmd->body_count != 1)
     error (_("Invalid \"python\" block structure."));
 
-  state = PyGILState_Ensure ();
-  cleanup = make_cleanup_py_restore_gil (&state);
+  cleanup = ensure_python_env (get_current_arch (), current_language);
 
   script = compute_python_string (cmd->body_list[0]);
   ret = PyRun_SimpleString (script);
@@ -122,10 +169,7 @@ static void
 python_command (char *arg, int from_tty)
 {
   struct cleanup *cleanup;
-  PyGILState_STATE state;
-
-  state = PyGILState_Ensure ();
-  cleanup = make_cleanup_py_restore_gil (&state);
+  cleanup = ensure_python_env (get_current_arch (), current_language);
 
   while (arg && *arg && isspace (*arg))
     ++arg;
@@ -330,13 +374,12 @@ gdbpy_new_objfile (struct objfile *objfile)
   char *filename, *debugfile;
   int len;
   FILE *input;
-  PyGILState_STATE state;
   struct cleanup *cleanups;
 
   if (!gdbpy_auto_load || !objfile || !objfile->name)
     return;
 
-  state = PyGILState_Ensure ();
+  cleanups = ensure_python_env (get_objfile_arch (objfile), current_language);
 
   gdbpy_current_objfile = objfile;
 
@@ -349,7 +392,7 @@ gdbpy_new_objfile (struct objfile *objfile)
   input = fopen (filename, "r");
   debugfile = filename;
 
-  cleanups = make_cleanup (xfree, filename);
+  make_cleanup (xfree, filename);
   make_cleanup (xfree, realname);
 
   if (!input && debug_file_directory)
@@ -391,8 +434,6 @@ gdbpy_new_objfile (struct objfile *objfile)
 
   do_cleanups (cleanups);
   gdbpy_current_objfile = NULL;
-
-  PyGILState_Release (state);
 }
 
 /* Return the current Objfile, or None if there isn't one.  */
index 4632ae4..dc2e8bc 100644 (file)
@@ -1326,7 +1326,9 @@ value_internal_function_name (struct value *val)
 }
 
 struct value *
-call_internal_function (struct value *func, int argc, struct value **argv)
+call_internal_function (struct gdbarch *gdbarch,
+                       const struct language_defn *language,
+                       struct value *func, int argc, struct value **argv)
 {
   struct internal_function *ifn;
   int result;
@@ -1335,7 +1337,7 @@ call_internal_function (struct value *func, int argc, struct value **argv)
   result = get_internalvar_function (VALUE_INTERNALVAR (func), &ifn);
   gdb_assert (result);
 
-  return (*ifn->handler) (ifn->cookie, argc, argv);
+  return (*ifn->handler) (gdbarch, language, ifn->cookie, argc, argv);
 }
 
 /* The 'function' command.  This does nothing -- it is just a
index 42a1827..8fe2f40 100644 (file)
@@ -674,7 +674,9 @@ extern struct value *value_subscripted_rvalue (struct value *array,
 
 /* User function handler.  */
 
-typedef struct value *(*internal_function_fn) (void *cookie,
+typedef struct value *(*internal_function_fn) (struct gdbarch *gdbarch,
+                                              const struct language_defn *language,
+                                              void *cookie,
                                               int argc,
                                               struct value **argv);
 
@@ -682,7 +684,9 @@ void add_internal_function (const char *name, const char *doc,
                            internal_function_fn handler,
                            void *cookie);
 
-struct value *call_internal_function (struct value *function,
+struct value *call_internal_function (struct gdbarch *gdbarch,
+                                     const struct language_defn *language,
+                                     struct value *function,
                                      int argc, struct value **argv);
 
 char *value_internal_function_name (struct value *);
index e6cae7f..db27a4b 100644 (file)
@@ -258,7 +258,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);
 
@@ -446,6 +446,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
@@ -765,8 +776,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;
@@ -784,10 +794,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;
@@ -842,10 +854,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))
@@ -1282,8 +1292,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
@@ -1386,11 +1395,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)
     {
@@ -1421,11 +1428,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);
@@ -1921,6 +1925,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. */
@@ -1930,14 +1943,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);
@@ -2212,7 +2217,7 @@ 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;
@@ -2225,7 +2230,9 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
 
 #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))
       {
@@ -2245,13 +2252,13 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
                                                &replacement);
        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
 
@@ -2774,8 +2781,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);
          }
       }
     }