[PATCH] Add proper handling for non-local references in nested subprograms

Pierre-Marie de Rodat derodat@adacore.com
Mon Mar 2 14:36:00 GMT 2015


GDB's current behavior when dealing with non-local references in the
context of nested subprograms is approximative:

   - code using valops.c:value_of_variable read the first available stack
     frame that holds the corresponding variable (whereas there can be
     multiple candidates for this);

   - code directly relying on read_var_value will instead read non-local
     variables in frames where they are not even defined.

This change adds necessary information to symbols (the block they belong
to) and to blocks (the static link property, if any) so that GDB can
make the proper decisions when dealing with non-local variables.

Regtested on x86_64-linux with both GCC 4.9.2 and a patched GCC (see 
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53927>).

PS: I'm aware that this patches increases the size of two critical data 
structures (namely struct block and struct symbol) and I'm completely 
open to suggestions. :-)

     Since I'm not sure of how this issue should be solved, I'm 
nevertheless posting this patch here so this matter can be discussed. In 
the context of this feature, I think we need a backlink from all symbols 
to the corresponding embedding block but on the other hand only a few 
blocks have static link: maybe we could turn this static_link field into 
a objfile-based hashtable lookup. Thoughts?

Thank you in advance!

gdb/ChangeLog:
2015-03-02  Pierre-Marie de Rodat  <derodat@adacore.com>

         * ada-lang.c (get_var_value): Update call to value_of_variable.
         * block.h (struct block): Add a static_link field.
         (BLOCK_STATIC_LINK): New accessor.
         * buildsym.c (finish_block_internal): Add a static_link
         argument.  Associate each symbol to the new block.  Initialize
         the static_link field in blocks.
         (finish_block): Add a static link argument and update call to
         finish_block_internal.
         (end_symtab_get_static_block): Update calls to finish_block.
         (end_symtab_with_blockvector): Update call to
         finish_block_internal.
         * buildsym.h: Pull gdbtypes.h.
         (struct context_stack): Add a static_link field.
         (finish_block): Add a static link argument.
         * coffread.c (coff_symtab_read): Update calls to finish_block.
         * dbxread.c (process_one_symbol): Likewise.
         * xcoffread.c (read_xcoff_symtab): Likewise.
         * jit.c (finalize_symtab): Initialize to NULL the static link
         field for the new block.
         * dwarf2loc.c (block_op_get_frame_base): New.
         (dwarf2_block_frame_base_locexpr_funcs): Implement the
         get_frame_base method.
         (dwarf2_block_frame_base_loclist_funcs): Likewise.
         (dwarf2locexpr_baton_eval): Add a frame argument and use it
         instead of the selected frame in order to evaluate the
         expression.
         (dwarf2_evaluate_property): Add a frame argument.  Update call
         to dwarf2_locexpr_baton_eval to provide a frame in available and
         to handle the absence of address stack.
         * dwarf2loc.h (dwarf2_evaluate_property): Add a frame argument.
         * dwarf2read.c (attr_to_dynamic_prop): Add a forward
         declaration.
         (read_func_scope): Record any available static link description.
         Update call to finish_block.
         (read_lexical_block_scope): Update call to finish_block.
         * eval.c (evaluate_subexp_standard): Update calls to
         value_of_variable.
         (evaluate_subexp_for_address): Likewise.
         (evaluate_subexp_with_coercion): Likewise.
         * f-valprint.c (info_common_command_for_block): Likewise.
         * findvar.c (follow_static_link): New.
         (get_hosting_frame): New.
         (default_read_var_value): Use get_hosting_frame to handle
         non-local references.
         * gdbtypes.c (resolve_dynamic_range): Update calls to
         dwarf2_evaluate_property.
         (resolve_dynamic_type_internal): Likewise.
         * python/py-type.c (typy_template_argument): Update call to
         value_of_variable.
         * symtab.h (struct symbol_block_ops): Add a get_frame_base
         method.
         (struct symbol): Add a block field.
         (SYMBOL_BLOCK): New accessor.
         * valarith.c (value_user_defined_cpp_op): Update call to
         value_of_variable.
         * valops.c (find_function_in_inferior): Likewise.
         (value_of_variable): Remove the block argument and remove
         frame/block handling (read_var_value does this, now).
         (address_of_variable): Remove the block argument and update call
         to value_of_variable.
         (value_maybe_namespace_elt): Update call to value_of_variable.
         * value.c (value_static_field): Likewise.
         * value.h (value_of_variable): Remove the block argument.
         (address_of_variable): Likewise.

gdb/testsuite/ChangeLog:
2015-03-02  Pierre-Marie de Rodat  <derodat@adacore.com>

         * gdb.base/nested-subp1.exp: New file.
         * gdb.base/nested-subp1.c: New file.
         * gdb.base/nested-subp2.exp: New file.
         * gdb.base/nested-subp2.c: New file.
         * gdb.base/nested-subp3.exp: New file.
         * gdb.base/nested-subp3.c: New file.

-- 
Pierre-Marie de Rodat
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Add-proper-handling-for-non-local-references-in-nest.patch
Type: text/x-diff
Size: 49316 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/gdb-patches/attachments/20150302/9809c804/attachment.bin>


More information about the Gdb-patches mailing list