From patchwork Sun Dec 8 18:29:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 36624 Received: (qmail 105650 invoked by alias); 8 Dec 2019 18:31:18 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 101847 invoked by uid 89); 8 Dec 2019 18:30:32 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-21.3 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS autolearn=ham version=3.3.1 spammy=sideeffects, side-effects, nonzero X-HELO: gateway36.websitewelcome.com Received: from gateway36.websitewelcome.com (HELO gateway36.websitewelcome.com) (192.185.187.5) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 08 Dec 2019 18:30:25 +0000 Received: from cm14.websitewelcome.com (cm14.websitewelcome.com [100.42.49.7]) by gateway36.websitewelcome.com (Postfix) with ESMTP id C61BA4028F159 for ; Sun, 8 Dec 2019 11:40:33 -0600 (CST) Received: from box5379.bluehost.com ([162.241.216.53]) by cmsmtp with SMTP id e1JtiZZEg4kpje1Jti9VAw; Sun, 08 Dec 2019 12:30:13 -0600 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=tromey.com; s=default; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Sender:Reply-To:MIME-Version:Content-Type:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=IBUkroRiXeyjP7Ox8q2prx+eQeBteY+5BhYka/np5es=; b=Y4CJRDLetqCZNAGPEOnWkg0bo8 /pDlh9veOZlYnbC1U6v/7pREPkjQhmxCDm2xjnOWIAVNhXAeIkksw/Im17vU6WuNIRVmxRws2ig3p D+HPBfESh2Ywvdt4pFea/mbjI; Received: from 75-166-123-50.hlrn.qwest.net ([75.166.123.50]:53632 helo=bapiya.Home) by box5379.bluehost.com with esmtpa (Exim 4.92) (envelope-from ) id 1ie1Jt-0045O4-6B; Sun, 08 Dec 2019 11:30:13 -0700 From: Tom Tromey To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH 54/55] Change extension language pretty-printers to use value API Date: Sun, 8 Dec 2019 11:29:57 -0700 Message-Id: <20191208182958.10181-55-tom@tromey.com> In-Reply-To: <20191208182958.10181-1-tom@tromey.com> References: <20191208182958.10181-1-tom@tromey.com> This changes the extension language pretty-printers to use the value API. Note that new functions were needed, for both Guile and Python. Currently both languages always wrap values by removing the values from the value chain. This makes sense to avoid strange behavior with watchpoints, and to avoid excessive memory use. However, when printing, it's important to leave the passed-in value untouched, in case pretty-printing does nothing -- that way the caller can still access it. gdb/ChangeLog 2019-12-08 Tom Tromey * valprint.c (do_val_print): Update. * python/python-internal.h (gdbpy_apply_val_pretty_printer): Take a struct value. (value_to_value_object_no_release): Declare. * python/py-value.c (value_to_value_object_no_release): New function. * python/py-prettyprint.c (gdbpy_apply_val_pretty_printer): Take a struct value. * guile/scm-value.c (vlscm_scm_from_value_no_release): New function. * guile/scm-pretty-print.c (gdbscm_apply_val_pretty_printer): Take a struct value. * guile/guile-internal.h (vlscm_scm_from_value_no_release): Declare. (gdbscm_apply_val_pretty_printer): Take a struct value. * extension.h (apply_ext_lang_val_pretty_printer): Take a struct value. * extension.c (apply_ext_lang_val_pretty_printer): Take a struct value. * extension-priv.h (struct extension_language_ops) : Take a struct value. * cp-valprint.c (cp_print_value): Create a struct value. (cp_print_value): Update. Change-Id: I49245df133fd0ab82d072c0b0479d38b600d0eda --- gdb/ChangeLog | 26 ++++++++++++++++++++++++++ gdb/cp-valprint.c | 28 +++++++++++++++------------- gdb/extension-priv.h | 17 ++++++----------- gdb/extension.c | 19 ++++++------------- gdb/extension.h | 6 ++---- gdb/guile/guile-internal.h | 5 ++--- gdb/guile/scm-pretty-print.c | 16 ++++++---------- gdb/guile/scm-value.c | 18 ++++++++++++++++++ gdb/python/py-prettyprint.c | 17 ++++++----------- gdb/python/py-value.c | 21 +++++++++++++++++++++ gdb/python/python-internal.h | 5 ++--- gdb/valprint.c | 17 +++++++++-------- 12 files changed, 119 insertions(+), 76 deletions(-) diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c index 143d77cb223..282eb0864a7 100644 --- a/gdb/cp-valprint.c +++ b/gdb/cp-valprint.c @@ -841,13 +841,15 @@ cp_print_value (struct type *type, struct type *real_type, /* Attempt to run an extension language pretty-printer on the baseclass if possible. */ if (!options->raw) - result - = apply_ext_lang_val_pretty_printer (baseclass, - thisoffset + boffset, - value_address (base_val), - stream, recurse, - base_val, options, - current_language); + { + struct value *v + = value_from_component (base_val, baseclass, + thisoffset + boffset); + result + = apply_ext_lang_val_pretty_printer (v, stream, recurse, + options, + current_language); + } if (!result) cp_print_value_fields (baseclass, thistype, @@ -999,19 +1001,19 @@ cp_print_value (struct value *val, struct ui_file *stream, } else { + struct value *baseclass_val = value_primitive_field (val, 0, + i, type); + /* Attempt to run an extension language pretty-printer on the baseclass if possible. */ if (!options->raw) result - = apply_ext_lang_val_pretty_printer (baseclass, boffset, - value_address (base_val), - stream, recurse, - base_val, options, + = apply_ext_lang_val_pretty_printer (baseclass_val, stream, + recurse, options, current_language); if (!result) - cp_print_value_fields (value_primitive_field (val, 0, i, type), - stream, recurse, options, + cp_print_value_fields (baseclass_val, stream, recurse, options, ((struct type **) obstack_base (&dont_print_vb_obstack)), 0); diff --git a/gdb/extension-priv.h b/gdb/extension-priv.h index 97594f853a2..694df278aad 100644 --- a/gdb/extension-priv.h +++ b/gdb/extension-priv.h @@ -152,19 +152,14 @@ struct extension_language_ops void (*free_type_printers) (const struct extension_language_defn *, struct ext_lang_type_printers *); - /* Try to pretty-print a value of type TYPE located at VAL's contents - buffer + EMBEDDED_OFFSET, which came from the inferior at address - ADDRESS + EMBEDDED_OFFSET, onto stdio stream STREAM according to - OPTIONS. - VAL is the whole object that came from ADDRESS. - Returns EXT_LANG_RC_OK upon success, EXT_LANG_RC_NOP if the value - is not recognized, and EXT_LANG_RC_ERROR if an error was encountered. */ + /* Try to pretty-print a value, onto stdio stream STREAM according + to OPTIONS. VAL is the object to print. Returns EXT_LANG_RC_OK + upon success, EXT_LANG_RC_NOP if the value is not recognized, and + EXT_LANG_RC_ERROR if an error was encountered. */ enum ext_lang_rc (*apply_val_pretty_printer) (const struct extension_language_defn *, - struct type *type, - LONGEST embedded_offset, CORE_ADDR address, - struct ui_file *stream, int recurse, - struct value *val, const struct value_print_options *options, + struct value *val, struct ui_file *stream, int recurse, + const struct value_print_options *options, const struct language_defn *language); /* GDB access to the "frame filter" feature. diff --git a/gdb/extension.c b/gdb/extension.c index 1fb4b48003a..4ece206cc37 100644 --- a/gdb/extension.c +++ b/gdb/extension.c @@ -470,12 +470,9 @@ ext_lang_type_printers::~ext_lang_type_printers () } } -/* Try to pretty-print a value of type TYPE located at VAL's contents - buffer + EMBEDDED_OFFSET, which came from the inferior at address - ADDRESS + EMBEDDED_OFFSET, onto stdio stream STREAM according to - OPTIONS. - VAL is the whole object that came from ADDRESS. - Returns non-zero if the value was successfully pretty-printed. +/* Try to pretty-print a value onto stdio stream STREAM according to + OPTIONS. VAL is the object to print. Returns non-zero if the + value was successfully pretty-printed. Extension languages are tried in the order specified by extension_languages. The first one to provide a pretty-printed @@ -488,10 +485,8 @@ ext_lang_type_printers::~ext_lang_type_printers () errors that trigger an exception in the extension language. */ int -apply_ext_lang_val_pretty_printer (struct type *type, - LONGEST embedded_offset, CORE_ADDR address, +apply_ext_lang_val_pretty_printer (struct value *val, struct ui_file *stream, int recurse, - struct value *val, const struct value_print_options *options, const struct language_defn *language) { @@ -504,10 +499,8 @@ apply_ext_lang_val_pretty_printer (struct type *type, if (extlang->ops->apply_val_pretty_printer == NULL) continue; - rc = extlang->ops->apply_val_pretty_printer (extlang, type, - embedded_offset, address, - stream, recurse, val, - options, language); + rc = extlang->ops->apply_val_pretty_printer (extlang, val, stream, + recurse, options, language); switch (rc) { case EXT_LANG_RC_OK: diff --git a/gdb/extension.h b/gdb/extension.h index fc8e3e2c0ba..bf6fd3e3e58 100644 --- a/gdb/extension.h +++ b/gdb/extension.h @@ -282,10 +282,8 @@ extern char *apply_ext_lang_type_printers (struct ext_lang_type_printers *, struct type *); extern int apply_ext_lang_val_pretty_printer - (struct type *type, - LONGEST embedded_offset, CORE_ADDR address, - struct ui_file *stream, int recurse, - struct value *val, const struct value_print_options *options, + (struct value *value, struct ui_file *stream, int recurse, + const struct value_print_options *options, const struct language_defn *language); extern enum ext_lang_bt_status apply_ext_lang_frame_filter diff --git a/gdb/guile/guile-internal.h b/gdb/guile/guile-internal.h index 3ae6618a7bc..3444c406d55 100644 --- a/gdb/guile/guile-internal.h +++ b/gdb/guile/guile-internal.h @@ -579,6 +579,7 @@ extern struct value *vlscm_scm_to_value (SCM scm); extern int vlscm_is_value (SCM scm); extern SCM vlscm_scm_from_value (struct value *value); +extern SCM vlscm_scm_from_value_no_release (struct value *value); extern struct value *vlscm_convert_typed_value_from_scheme (const char *func_name, int obj_arg_pos, SCM obj, @@ -602,10 +603,8 @@ extern void gdbscm_preserve_values extern enum ext_lang_rc gdbscm_apply_val_pretty_printer (const struct extension_language_defn *, - struct type *type, - LONGEST embedded_offset, CORE_ADDR address, - struct ui_file *stream, int recurse, struct value *val, + struct ui_file *stream, int recurse, const struct value_print_options *options, const struct language_defn *language); diff --git a/gdb/guile/scm-pretty-print.c b/gdb/guile/scm-pretty-print.c index 630a062148e..e7289a71786 100644 --- a/gdb/guile/scm-pretty-print.c +++ b/gdb/guile/scm-pretty-print.c @@ -943,36 +943,32 @@ ppscm_print_children (SCM printer, enum display_hint hint, enum ext_lang_rc gdbscm_apply_val_pretty_printer (const struct extension_language_defn *extlang, - struct type *type, - LONGEST embedded_offset, CORE_ADDR address, + struct value *value, struct ui_file *stream, int recurse, - struct value *val, const struct value_print_options *options, const struct language_defn *language) { + struct type *type = value_type (value); struct gdbarch *gdbarch = get_type_arch (type); SCM exception = SCM_BOOL_F; SCM printer = SCM_BOOL_F; SCM val_obj = SCM_BOOL_F; - struct value *value; enum display_hint hint; enum ext_lang_rc result = EXT_LANG_RC_NOP; enum string_repr_result print_result; - if (value_lazy (val)) - value_fetch_lazy (val); + if (value_lazy (value)) + value_fetch_lazy (value); /* No pretty-printer support for unavailable values. */ - if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type))) + if (!value_bytes_available (value, 0, TYPE_LENGTH (type))) return EXT_LANG_RC_NOP; if (!gdb_scheme_initialized) return EXT_LANG_RC_NOP; /* Instantiate the printer. */ - value = value_from_component (val, type, embedded_offset); - - val_obj = vlscm_scm_from_value (value); + val_obj = vlscm_scm_from_value_no_release (value); if (gdbscm_is_exception (val_obj)) { exception = val_obj; diff --git a/gdb/guile/scm-value.c b/gdb/guile/scm-value.c index 8aa4cfa345b..7398a2d8332 100644 --- a/gdb/guile/scm-value.c +++ b/gdb/guile/scm-value.c @@ -261,6 +261,24 @@ vlscm_scm_from_value (struct value *value) return v_scm; } +/* Create a new object that encapsulates VALUE. + The value is not released from the all_values chain. */ + +SCM +vlscm_scm_from_value_no_release (struct value *value) +{ + /* N.B. It's important to not cause any side-effects until we know the + conversion worked. */ + SCM v_scm = vlscm_make_value_smob (); + value_smob *v_smob = (value_smob *) SCM_SMOB_DATA (v_scm); + + value_incref (value); + v_smob->value = value; + vlscm_remember_scheme_value (v_smob); + + return v_scm; +} + /* Returns the object in SELF. Throws an exception if SELF is not a object. */ diff --git a/gdb/python/py-prettyprint.c b/gdb/python/py-prettyprint.c index a4df48fe19a..a5aed9c91ac 100644 --- a/gdb/python/py-prettyprint.c +++ b/gdb/python/py-prettyprint.c @@ -558,22 +558,20 @@ print_children (PyObject *printer, const char *hint, enum ext_lang_rc gdbpy_apply_val_pretty_printer (const struct extension_language_defn *extlang, - struct type *type, - LONGEST embedded_offset, CORE_ADDR address, + struct value *value, struct ui_file *stream, int recurse, - struct value *val, const struct value_print_options *options, const struct language_defn *language) { + struct type *type = value_type (value); struct gdbarch *gdbarch = get_type_arch (type); - struct value *value; enum string_repr_result print_result; - if (value_lazy (val)) - value_fetch_lazy (val); + if (value_lazy (value)) + value_fetch_lazy (value); /* No pretty-printer support for unavailable values. */ - if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type))) + if (!value_bytes_available (value, 0, TYPE_LENGTH (type))) return EXT_LANG_RC_NOP; if (!gdb_python_initialized) @@ -581,10 +579,7 @@ gdbpy_apply_val_pretty_printer (const struct extension_language_defn *extlang, gdbpy_enter enter_py (gdbarch, language); - /* Instantiate the printer. */ - value = value_from_component (val, type, embedded_offset); - - gdbpy_ref<> val_obj (value_to_value_object (value)); + gdbpy_ref<> val_obj (value_to_value_object_no_release (value)); if (val_obj == NULL) { print_stack_unless_memory_error (stream); diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c index 1ca2dc5c719..5a967329f2d 100644 --- a/gdb/python/py-value.c +++ b/gdb/python/py-value.c @@ -1788,6 +1788,27 @@ value_to_value_object (struct value *val) return (PyObject *) val_obj; } +/* Returns an object for a value, but without releasing it from the + all_values chain. */ +PyObject * +value_to_value_object_no_release (struct value *val) +{ + value_object *val_obj; + + val_obj = PyObject_New (value_object, &value_object_type); + if (val_obj != NULL) + { + value_incref (val); + val_obj->value = val; + val_obj->address = NULL; + val_obj->type = NULL; + val_obj->dynamic_type = NULL; + note_value (val_obj); + } + + return (PyObject *) val_obj; +} + /* Returns a borrowed reference to the struct value corresponding to the given value object. */ struct value * diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index 703c60032c0..a60af21458e 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -391,10 +391,8 @@ extern int gdbpy_auto_load_enabled (const struct extension_language_defn *); extern enum ext_lang_rc gdbpy_apply_val_pretty_printer (const struct extension_language_defn *, - struct type *type, - LONGEST embedded_offset, CORE_ADDR address, + struct value *value, struct ui_file *stream, int recurse, - struct value *val, const struct value_print_options *options, const struct language_defn *language); extern enum ext_lang_bt_status gdbpy_apply_frame_filter @@ -454,6 +452,7 @@ PyObject *symbol_to_symbol_object (struct symbol *sym); PyObject *block_to_block_object (const struct block *block, struct objfile *objfile); PyObject *value_to_value_object (struct value *v); +PyObject *value_to_value_object_no_release (struct value *v); PyObject *type_to_type_object (struct type *); PyObject *frame_info_to_frame_object (struct frame_info *frame); PyObject *symtab_to_linetable_object (PyObject *symtab); diff --git a/gdb/valprint.c b/gdb/valprint.c index 251eae2d844..56f06be6b9c 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -1253,9 +1253,13 @@ do_val_print (struct value *full_value, if (!options->raw) { - ret = apply_ext_lang_val_pretty_printer (type, embedded_offset, - address, stream, recurse, - val, options, language); + struct value *v = full_value; + + if (v == nullptr) + v = value_from_component (val, type, embedded_offset); + + ret = apply_ext_lang_val_pretty_printer (v, stream, recurse, options, + language); if (ret) return; } @@ -1451,11 +1455,8 @@ value_print (struct value *val, struct ui_file *stream, if (!options->raw) { int r - = apply_ext_lang_val_pretty_printer (value_type (val), - value_embedded_offset (val), - value_address (val), - stream, 0, - val, options, current_language); + = apply_ext_lang_val_pretty_printer (val, stream, 0, options, + current_language); if (r) return;