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 18/28] check gdb_python_initialized everywhere


This patch changes the rest of gdb to use gdb_python_initialized.  It
also changes ensure_python_env to throw an exception if Python is not
initialized.  In some spots no other checks were needed -- there is no
way to reach some of the calls to ensure_python_env unless some
previous call into Python was made.

value_get_print_value had to be reindented, which is why that part of
the patch looks odd.

While sending out the series I realized I had meant to write a test case
for this patch but forgot to.  I will hold on to this one until I write
it.

	* mi/mi-main.c: Include python-internal.h.
	(mi_cmd_list_features): Check gdb_python_initialized.
	* python/py-inferior.c (python_on_normal_stop, python_on_resume)
	(python_inferior_exit, python_new_objfile, add_thread_object)
	(delete_thread_object, py_free_inferior): Check
	gdb_python_initialized.
	* python/py-prettyprint.c (apply_val_pretty_printer): Check
	gdb_python_initialized.
	* python/py-type.c (save_objfile_types): Check
	gdb_python_initialized.
	* python/python-internal.h (gdb_python_initialized): Declare.
	* python/python.c (ensure_python_env): Throw exception if
	Python not initialized.
	(before_prompt_hook, source_python_script_for_objfile)
	(start_type_printers, apply_type_printers,
	free_type_printers): Check gdb_python_initialized.
	* varobj.c (varobj_get_display_hint)
	(dynamic_varobj_has_child_method, update_dynamic_varobj_children)
	(install_new_value_visualizer, varobj_set_visualizer)
	(value_get_print_value): Check gdb_python_initialized.
---
 gdb/mi/mi-main.c             |   6 +-
 gdb/python/py-inferior.c     |  21 +++++
 gdb/python/py-prettyprint.c  |   3 +
 gdb/python/py-type.c         |   3 +
 gdb/python/python-internal.h |   2 +
 gdb/python/python.c          |  19 +++++
 gdb/varobj.c                 | 182 ++++++++++++++++++++++++-------------------
 7 files changed, 153 insertions(+), 83 deletions(-)

diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index 94fda8f..9428e8c 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -52,6 +52,9 @@
 #include "ctf.h"
 #include "ada-lang.h"
 #include "linespec.h"
+#ifdef HAVE_PYTHON
+#include "python/python-internal.h"
+#endif
 
 #include <ctype.h>
 #include <sys/time.h>
@@ -1757,7 +1760,8 @@ mi_cmd_list_features (char *command, char **argv, int argc)
       ui_out_field_string (uiout, NULL, "ada-task-info");
       
 #if HAVE_PYTHON
-      ui_out_field_string (uiout, NULL, "python");
+      if (gdb_python_initialized)
+	ui_out_field_string (uiout, NULL, "python");
 #endif
       
       do_cleanups (cleanup);
diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c
index b11d786..1ab58e6 100644
--- a/gdb/python/py-inferior.c
+++ b/gdb/python/py-inferior.c
@@ -85,6 +85,9 @@ python_on_normal_stop (struct bpstats *bs, int print_frame)
   struct cleanup *cleanup;
   enum gdb_signal stop_signal;
 
+  if (!gdb_python_initialized)
+    return;
+
   if (!find_thread_ptid (inferior_ptid))
       return;
 
@@ -103,6 +106,9 @@ python_on_resume (ptid_t ptid)
 {
   struct cleanup *cleanup;
 
+  if (!gdb_python_initialized)
+    return;
+
   cleanup = ensure_python_env (target_gdbarch (), current_language);
 
   if (emit_continue_event (ptid) < 0)
@@ -117,6 +123,9 @@ python_inferior_exit (struct inferior *inf)
   struct cleanup *cleanup;
   const LONGEST *exit_code = NULL;
 
+  if (!gdb_python_initialized)
+    return;
+
   cleanup = ensure_python_env (target_gdbarch (), current_language);
 
   if (inf->has_exit_code)
@@ -139,6 +148,9 @@ python_new_objfile (struct objfile *objfile)
   if (objfile == NULL)
     return;
 
+  if (!gdb_python_initialized)
+    return;
+
   cleanup = ensure_python_env (get_objfile_arch (objfile), current_language);
 
   if (emit_new_objfile_event (objfile) < 0)
@@ -231,6 +243,9 @@ add_thread_object (struct thread_info *tp)
   inferior_object *inf_obj;
   struct threadlist_entry *entry;
 
+  if (!gdb_python_initialized)
+    return;
+
   cleanup = ensure_python_env (python_gdbarch, python_language);
 
   thread_obj = create_thread_object (tp);
@@ -260,6 +275,9 @@ delete_thread_object (struct thread_info *tp, int ignore)
   inferior_object *inf_obj;
   struct threadlist_entry **entry, *tmp;
   
+  if (!gdb_python_initialized)
+    return;
+
   cleanup = ensure_python_env (python_gdbarch, python_language);
 
   inf_obj = (inferior_object *) find_inferior_object (PIDGET(tp->ptid));
@@ -728,6 +746,9 @@ py_free_inferior (struct inferior *inf, void *datum)
   inferior_object *inf_obj = datum;
   struct threadlist_entry *th_entry, *th_tmp;
 
+  if (!gdb_python_initialized)
+    return;
+
   cleanup = ensure_python_env (python_gdbarch, python_language);
 
   inf_obj->inferior = NULL;
diff --git a/gdb/python/py-prettyprint.c b/gdb/python/py-prettyprint.c
index dbf6c22..c337334 100644
--- a/gdb/python/py-prettyprint.c
+++ b/gdb/python/py-prettyprint.c
@@ -708,6 +708,9 @@ apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
   if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type)))
     return 0;
 
+  if (!gdb_python_initialized)
+    return 0;
+
   cleanups = ensure_python_env (gdbarch, language);
 
   /* Instantiate the printer.  */
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 05e251b..dd3a751 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -1192,6 +1192,9 @@ save_objfile_types (struct objfile *objfile, void *datum)
   htab_t copied_types;
   struct cleanup *cleanup;
 
+  if (!gdb_python_initialized)
+    return;
+
   /* This prevents another thread from freeing the objects we're
      operating on.  */
   cleanup = ensure_python_env (get_objfile_arch (objfile), current_language);
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 63d020d..4a9405f 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -183,6 +183,8 @@ struct program_space;
 struct bpstats;
 struct inferior;
 
+extern int gdb_python_initialized;
+
 extern PyObject *gdb_module;
 extern PyObject *gdb_python_module;
 extern PyTypeObject value_object_type
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 51f8cd5..a7b1b44 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -150,6 +150,10 @@ ensure_python_env (struct gdbarch *gdbarch,
 {
   struct python_env *env = xmalloc (sizeof *env);
 
+  /* We should not ever enter Python unless initialized.  */
+  if (!gdb_python_initialized)
+    error (_("Python not initialized"));
+
   env->state = PyGILState_Ensure ();
   env->gdbarch = python_gdbarch;
   env->language = python_language;
@@ -896,6 +900,9 @@ before_prompt_hook (const char *current_gdb_prompt)
   struct cleanup *cleanup;
   char *prompt = NULL;
 
+  if (!gdb_python_initialized)
+    return;
+
   cleanup = ensure_python_env (get_current_arch (), current_language);
 
   if (gdb_python_module
@@ -1159,6 +1166,9 @@ source_python_script_for_objfile (struct objfile *objfile, FILE *file,
 {
   struct cleanup *cleanups;
 
+  if (!gdb_python_initialized)
+    return;
+
   cleanups = ensure_python_env (get_objfile_arch (objfile), current_language);
   gdbpy_current_objfile = objfile;
 
@@ -1220,6 +1230,9 @@ start_type_printers (void)
   struct cleanup *cleanups;
   PyObject *type_module, *func, *result_obj = NULL;
 
+  if (!gdb_python_initialized)
+    return NULL;
+
   cleanups = ensure_python_env (get_current_arch (), current_language);
 
   type_module = PyImport_ImportModule ("gdb.types");
@@ -1266,6 +1279,9 @@ apply_type_printers (void *printers, struct type *type)
   if (printers_obj == NULL)
     return NULL;
 
+  if (!gdb_python_initialized)
+    return NULL;
+
   cleanups = ensure_python_env (get_current_arch (), current_language);
 
   type_obj = type_to_type_object (type);
@@ -1324,6 +1340,9 @@ free_type_printers (void *arg)
   if (printers == NULL)
     return;
 
+  if (!gdb_python_initialized)
+    return;
+
   cleanups = ensure_python_env (get_current_arch (), current_language);
   Py_DECREF (printers);
   do_cleanups (cleanups);
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 467e59a..70ed28f 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -935,7 +935,12 @@ varobj_get_display_hint (struct varobj *var)
   char *result = NULL;
 
 #if HAVE_PYTHON
-  struct cleanup *back_to = varobj_ensure_python_env (var);
+  struct cleanup *back_to;
+
+  if (!gdb_python_initialized)
+    return NULL;
+
+  back_to = varobj_ensure_python_env (var);
 
   if (var->pretty_printer)
     result = gdbpy_get_display_hint (var->pretty_printer);
@@ -1067,6 +1072,9 @@ dynamic_varobj_has_child_method (struct varobj *var)
   PyObject *printer = var->pretty_printer;
   int result;
 
+  if (!gdb_python_initialized)
+    return 0;
+
   back_to = varobj_ensure_python_env (var);
   result = PyObject_HasAttr (printer, gdbpy_children_cst);
   do_cleanups (back_to);
@@ -1092,6 +1100,9 @@ update_dynamic_varobj_children (struct varobj *var,
   int i;
   PyObject *printer = var->pretty_printer;
 
+  if (!gdb_python_initialized)
+    return 0;
+
   back_to = varobj_ensure_python_env (var);
 
   *cchanged = 0;
@@ -1623,6 +1634,9 @@ install_new_value_visualizer (struct varobj *var)
 #if HAVE_PYTHON
   /* If the constructor is None, then we want the raw value.  If VAR
      does not have a value, just skip this.  */
+  if (!gdb_python_initialized)
+    return;
+
   if (var->constructor != Py_None && var->value)
     {
       struct cleanup *cleanup;
@@ -1899,6 +1913,9 @@ varobj_set_visualizer (struct varobj *var, const char *visualizer)
   PyObject *mainmod, *globals, *constructor;
   struct cleanup *back_to;
 
+  if (!gdb_python_initialized)
+    return;
+
   back_to = varobj_ensure_python_env (var);
 
   mainmod = PyImport_AddModule ("__main__");
@@ -2862,92 +2879,93 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
 
   gdbarch = get_type_arch (value_type (value));
 #if HAVE_PYTHON
-  {
-    PyObject *value_formatter = var->pretty_printer;
+  if (gdb_python_initialized)
+    {
+      PyObject *value_formatter = var->pretty_printer;
 
-    varobj_ensure_python_env (var);
+      varobj_ensure_python_env (var);
 
-    if (value_formatter)
-      {
-	/* First check to see if we have any children at all.  If so,
-	   we simply return {...}.  */
-	if (dynamic_varobj_has_child_method (var))
-	  {
-	    do_cleanups (old_chain);
-	    return xstrdup ("{...}");
-	  }
+      if (value_formatter)
+	{
+	  /* First check to see if we have any children at all.  If so,
+	     we simply return {...}.  */
+	  if (dynamic_varobj_has_child_method (var))
+	    {
+	      do_cleanups (old_chain);
+	      return xstrdup ("{...}");
+	    }
 
-	if (PyObject_HasAttr (value_formatter, gdbpy_to_string_cst))
-	  {
-	    struct value *replacement;
-	    PyObject *output = NULL;
+	  if (PyObject_HasAttr (value_formatter, gdbpy_to_string_cst))
+	    {
+	      struct value *replacement;
+	      PyObject *output = NULL;
 
-	    output = apply_varobj_pretty_printer (value_formatter,
-						  &replacement,
-						  stb);
+	      output = apply_varobj_pretty_printer (value_formatter,
+						    &replacement,
+						    stb);
 
-	    /* If we have string like output ...  */
-	    if (output)
-	      {
-		make_cleanup_py_decref (output);
-
-		/* If this is a lazy string, extract it.  For lazy
-		   strings we always print as a string, so set
-		   string_print.  */
-		if (gdbpy_is_lazy_string (output))
-		  {
-		    gdbpy_extract_lazy_string (output, &str_addr, &type,
-					       &len, &encoding);
-		    make_cleanup (free_current_contents, &encoding);
-		    string_print = 1;
-		  }
-		else
-		  {
-		    /* If it is a regular (non-lazy) string, extract
-		       it and copy the contents into THEVALUE.  If the
-		       hint says to print it as a string, set
-		       string_print.  Otherwise just return the extracted
-		       string as a value.  */
-
-		    char *s = python_string_to_target_string (output);
-
-		    if (s)
-		      {
-			char *hint;
-
-			hint = gdbpy_get_display_hint (value_formatter);
-			if (hint)
-			  {
-			    if (!strcmp (hint, "string"))
-			      string_print = 1;
-			    xfree (hint);
-			  }
-
-			len = strlen (s);
-			thevalue = xmemdup (s, len + 1, len + 1);
-			type = builtin_type (gdbarch)->builtin_char;
-			xfree (s);
-
-			if (!string_print)
-			  {
-			    do_cleanups (old_chain);
-			    return thevalue;
-			  }
-
-			make_cleanup (xfree, thevalue);
-		      }
-		    else
-		      gdbpy_print_stack ();
-		  }
-	      }
-	    /* If the printer returned a replacement value, set VALUE
-	       to REPLACEMENT.  If there is not a replacement value,
-	       just use the value passed to this function.  */
-	    if (replacement)
-	      value = replacement;
-	  }
-      }
-  }
+	      /* If we have string like output ...  */
+	      if (output)
+		{
+		  make_cleanup_py_decref (output);
+
+		  /* If this is a lazy string, extract it.  For lazy
+		     strings we always print as a string, so set
+		     string_print.  */
+		  if (gdbpy_is_lazy_string (output))
+		    {
+		      gdbpy_extract_lazy_string (output, &str_addr, &type,
+						 &len, &encoding);
+		      make_cleanup (free_current_contents, &encoding);
+		      string_print = 1;
+		    }
+		  else
+		    {
+		      /* If it is a regular (non-lazy) string, extract
+			 it and copy the contents into THEVALUE.  If the
+			 hint says to print it as a string, set
+			 string_print.  Otherwise just return the extracted
+			 string as a value.  */
+
+		      char *s = python_string_to_target_string (output);
+
+		      if (s)
+			{
+			  char *hint;
+
+			  hint = gdbpy_get_display_hint (value_formatter);
+			  if (hint)
+			    {
+			      if (!strcmp (hint, "string"))
+				string_print = 1;
+			      xfree (hint);
+			    }
+
+			  len = strlen (s);
+			  thevalue = xmemdup (s, len + 1, len + 1);
+			  type = builtin_type (gdbarch)->builtin_char;
+			  xfree (s);
+
+			  if (!string_print)
+			    {
+			      do_cleanups (old_chain);
+			      return thevalue;
+			    }
+
+			  make_cleanup (xfree, thevalue);
+			}
+		      else
+			gdbpy_print_stack ();
+		    }
+		}
+	      /* If the printer returned a replacement value, set VALUE
+		 to REPLACEMENT.  If there is not a replacement value,
+		 just use the value passed to this function.  */
+	      if (replacement)
+		value = replacement;
+	    }
+	}
+    }
 #endif
 
   get_formatted_print_options (&opts, format_code[(int) format]);
-- 
1.8.1.4



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