From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14761 invoked by alias); 19 Apr 2013 14:38:36 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 14749 invoked by uid 89); 19 Apr 2013 14:38:35 -0000 X-Spam-SWARE-Status: No, score=-6.8 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,RCVD_IN_DNSWL_HI,RCVD_IN_HOSTKARMA_W,RP_MATCHES_RCVD,SPF_HELO_PASS,TW_BJ autolearn=ham version=3.3.1 Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Fri, 19 Apr 2013 14:38:34 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r3JEcXGd012265 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 19 Apr 2013 10:38:33 -0400 Received: from barimba (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id r3JEcUrP030411 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Fri, 19 Apr 2013 10:38:31 -0400 From: Tom Tromey To: gdb-patches@sourceware.org Subject: [PATCH 18/28] check gdb_python_initialized everywhere References: <87ehe638ww.fsf@fleche.redhat.com> Date: Fri, 19 Apr 2013 15:40:00 -0000 In-Reply-To: <87ehe638ww.fsf@fleche.redhat.com> (Tom Tromey's message of "Fri, 19 Apr 2013 08:13:51 -0600") Message-ID: <87vc7iy49l.fsf@fleche.redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-SW-Source: 2013-04/txt/msg00601.txt.bz2 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 #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 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