[PATCH 2/3] gdb/varobj: Reset varobj after relocations have been computed
Tom de Vries
tdevries@suse.de
Tue Aug 9 10:55:37 GMT 2022
On 8/4/22 15:02, Lancelot SIX wrote:
> From: Tom de Vries <tdevries@suse.de>
>
> [This patch is a followup to the discussion in
> https://sourceware.org/pipermail/gdb-patches/2022-August/191188.html]
>
> PR/29426 shows failures when running the gdb.mi/mi-var-invalidate-shlib
> test when using a compiler which does not produce a PIE executable by
> default.
>
> In the testcase, a varobj is created to track a global variable, and
> then the main binary is reloaded in GDB (using the file command).
>
> During the load of the new binary, GDB tries to recreate the varobj to
> track the global in the new binary (varobj_invalidate_iter). At this
> point, the old process is still in flight. So when we try to access to
> the value of the global, in a PIE executable we only have access to the
> unrelocated address (the objfile's text_section_offset () is 0). As a
> consequence down the line read_value_memory fails to read the unrelated
> address, so cannot evaluate the value of the global. Note that the
> expression used to access to the global’s value is valid, so the varobj
> can be created. When using a non PIE executable, the address of the
> global GDB knows about at this point does not need relocation, so
> read_value_memory can access the (old binary’s) value.
>
> So at this point, in the case of a non-PIE executable the value field is
> set, while it is cleared in the case of PIE executable. Later when the
> test issues a "-var-update global_var", the command sees no change in
> the case of the non-PIE executable, while in the case of the PIE
> executable install_new_value sees that value changes, leading to a
> different output.
>
> This patch makes sure that, as we do for breakpoints, we wait until
> relocation has happened before we try to recreate varobjs. This way we
> have a consistent behavior between PIE and non-PIE binaries.
>
> Tested on x86_64-linux.
>
LGTM.
Thanks,
- Tom
> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29426
> Co-authored-by: Lancelot SIX <lancelot.six@amd.com>
> ---
> gdb/symfile.c | 6 ++---
> .../gdb.mi/mi-var-invalidate-shlib.exp | 2 +-
> gdb/varobj.c | 22 +++++++------------
> gdb/varobj.h | 5 ++++-
> 4 files changed, 16 insertions(+), 19 deletions(-)
>
> diff --git a/gdb/symfile.c b/gdb/symfile.c
> index aea8c762ee6..f61235dd271 100644
> --- a/gdb/symfile.c
> +++ b/gdb/symfile.c
> @@ -1656,6 +1656,9 @@ symbol_file_command (const char *args, int from_tty)
>
> /* Now it's safe to re-add the breakpoints. */
> breakpoint_re_set ();
> +
> + /* Also, it's safe to re-add varobjs. */
> + varobj_re_set ();
> }
> }
>
> @@ -2870,9 +2873,6 @@ clear_symtab_users (symfile_add_flags add_flags)
> clear_pc_function_cache ();
> gdb::observers::new_objfile.notify (NULL);
>
> - /* Varobj may refer to old symbols, perform a cleanup. */
> - varobj_invalidate ();
> -
> /* Now that the various caches have been cleared, we can re_set
> our breakpoints without risking it using stale data. */
> if ((add_flags & SYMFILE_DEFER_BP_RESET) == 0)
> diff --git a/gdb/testsuite/gdb.mi/mi-var-invalidate-shlib.exp b/gdb/testsuite/gdb.mi/mi-var-invalidate-shlib.exp
> index 9ba5af0c028..fdf80b79741 100644
> --- a/gdb/testsuite/gdb.mi/mi-var-invalidate-shlib.exp
> +++ b/gdb/testsuite/gdb.mi/mi-var-invalidate-shlib.exp
> @@ -99,7 +99,7 @@ proc do_test { separate_debuginfo } {
> # When reloading the symbol file, only the var for the global in the main
> # executable is re-created.
> mi_gdb_test "-var-update global_var" \
> - "\\^done,changelist=\\\[{name=\"global_var\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"}\\\]" \
> + "\\^done,changelist=\\\[\\\]" \
> "global_var recreated"
> mi_gdb_test "-var-update global_shlib_var" \
> "\\^done,changelist=\\\[{name=\"global_shlib_var\",in_scope=\"invalid\",has_more=\"0\"}\\\]" \
> diff --git a/gdb/varobj.c b/gdb/varobj.c
> index a142bb02e03..55a7bd97f43 100644
> --- a/gdb/varobj.c
> +++ b/gdb/varobj.c
> @@ -2353,18 +2353,14 @@ all_root_varobjs (gdb::function_view<void (struct varobj *var)> func)
> }
> }
>
> -/* Invalidate varobj VAR if it is tied to locals and re-create it if it is
> - defined on globals. It is a helper for varobj_invalidate.
> -
> - This function is called after changing the symbol file, in this case the
> - pointers to "struct type" stored by the varobj are no longer valid. All
> - varobj must be either re-evaluated, or marked as invalid here. */
> +/* Try to recreate the varobj VAR if it is a global or floating. This is a
> + helper function for varobj_re_set. */
>
> static void
> -varobj_invalidate_iter (struct varobj *var)
> +varobj_re_set_iter (struct varobj *var)
> {
> - /* global and floating var must be re-evaluated. */
> - if (var->root->floating || var->root->global)
> + /* Invalidated globals and floating var must be re-evaluated. */
> + if (var->root->global || var->root->floating)
> {
> struct varobj *tmp_var;
>
> @@ -2389,14 +2385,12 @@ varobj_invalidate_iter (struct varobj *var)
> }
> }
>
> -/* Invalidate the varobjs that are tied to locals and re-create the ones that
> - are defined on globals.
> - Invalidated varobjs will be always printed in_scope="invalid". */
> +/* See varobj.h. */
>
> void
> -varobj_invalidate (void)
> +varobj_re_set (void)
> {
> - all_root_varobjs (varobj_invalidate_iter);
> + all_root_varobjs (varobj_re_set_iter);
> }
>
> /* Ensure that no varobj keep references to OBJFILE. */
> diff --git a/gdb/varobj.h b/gdb/varobj.h
> index 073da60d772..0c92d67e4f4 100644
> --- a/gdb/varobj.h
> +++ b/gdb/varobj.h
> @@ -314,7 +314,10 @@ extern void all_root_varobjs (gdb::function_view<void (struct varobj *var)>);
> extern std::vector<varobj_update_result>
> varobj_update (struct varobj **varp, bool is_explicit);
>
> -extern void varobj_invalidate (void);
> +/* Try to recreate any global or floating varobj. This is called after
> + changing symbol files. */
> +
> +extern void varobj_re_set (void);
>
> extern bool varobj_editable_p (const struct varobj *var);
>
More information about the Gdb-patches
mailing list