From 0646da15da19313ef79611081904ce5e723b0646 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Mon, 20 May 2013 20:29:44 +0000 Subject: [PATCH] * 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/ChangeLog | 23 +++++ 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 +++++++++++++++++++---------------- 8 files changed, 176 insertions(+), 83 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e2e73ac2627..19707154dfe 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,26 @@ +2013-05-20 Tom Tromey + + * 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. + 2013-05-20 Tom Tromey * python/py-arch.c (gdbpy_initialize_arch): Return 'int'. diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c index 94fda8f63b2..9428e8c8df4 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 #include @@ -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 18ddecde47b..edbad9e0248 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)); @@ -726,6 +744,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 b50e757a018..aa9476ed06c 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 05e251b023c..dd3a7518d38 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 695bcd3627b..f434b667ca4 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -189,6 +189,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 5b5afcfd8ef..e8a70da8f28 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 467e59ae0b3..70ed28fc03d 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]); -- 2.30.2