diff options
author | Pedro Alves <palves@redhat.com> | 2017-09-20 16:12:54 +0100 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2017-09-20 16:12:54 +0100 |
commit | e5f25bc5d6dba5a5c4dd36e08afd57e918c63dea (patch) | |
tree | 8a2b690a4cbd7af63cce3f8b276f32a8454a6218 /gdb/linespec.c | |
parent | 1b7fa39ed9678fded7264636c1e5cc14c6d6ebc6 (diff) | |
download | gdb-e5f25bc5d6dba5a5c4dd36e08afd57e918c63dea.zip gdb-e5f25bc5d6dba5a5c4dd36e08afd57e918c63dea.tar.gz gdb-e5f25bc5d6dba5a5c4dd36e08afd57e918c63dea.tar.bz2 |
Fix "list ambiguous_variable"
The "list" command allows specifying the name of variables as
argument, not just functions, so that users can type "list
a_global_variable".
That support is a broken when it comes to ambiguous locations though.
If there's more than one such global variable in the program, e.g.,
static globals in different compilation units, GDB ends up listing the
source of the first variable it finds, only.
linespec.c does find both symbol and minsym locations for all the
globals. The problem is that it ends up merging all the resulting
sals into one, because they all have address, zero. I.e., all sals
end up with sal.pc == 0, so maybe_add_address returns false for all
but the first.
The zero addresses appear because:
- in the minsyms case, linespec.c:minsym_found incorrectly treats all
minsyms as if they were function/text symbols. In list mode we can
end up with data symbols there, and we shouldn't be using
find_pc_sect_line on data symbols.
- in the debug symbols case, symbol_to_sal misses recording an address
(sal.pc) for non-block, non-label symbols.
gdb/ChangeLog:
2017-09-20 Pedro Alves <palves@redhat.com>
* linespec.c (minsym_found): Handle non-text minsyms.
(symbol_to_sal): Record a sal.pc for non-block, non-label symbols.
gdb/testsuite/ChangeLog:
2017-09-20 Pedro Alves <palves@redhat.com>
* gdb.base/list-ambiguous.exp (test_list_ambiguous_function):
Rename to ...
(test_list_ambiguous_symbol): ... this and add a symbol name
parameter. Adjust.
(test_list_ambiguous_function): Reimplement on top of
test_list_ambiguous_symbol and also test listing ambiguous
variables.
* gdb.base/list-ambiguous0.c (ambiguous): Rename to ...
(ambiguous_fun): ... this.
(ambiguous_var): New.
* gdb.base/list-ambiguous1.c (ambiguous): Rename to ...
(ambiguous_fun): ... this.
(ambiguous_var): New.
Diffstat (limited to 'gdb/linespec.c')
-rw-r--r-- | gdb/linespec.c | 64 |
1 files changed, 38 insertions, 26 deletions
diff --git a/gdb/linespec.c b/gdb/linespec.c index b69ab62..35ef159 100644 --- a/gdb/linespec.c +++ b/gdb/linespec.c @@ -4313,35 +4313,46 @@ minsym_found (struct linespec_state *self, struct objfile *objfile, CORE_ADDR pc; struct symtab_and_line sal; - sal = find_pc_sect_line (MSYMBOL_VALUE_ADDRESS (objfile, msymbol), - (struct obj_section *) 0, 0); - sal.section = MSYMBOL_OBJ_SECTION (objfile, msymbol); - - /* The minimal symbol might point to a function descriptor; - resolve it to the actual code address instead. */ - pc = gdbarch_convert_from_func_ptr_addr (gdbarch, sal.pc, ¤t_target); - if (pc != sal.pc) - sal = find_pc_sect_line (pc, NULL, 0); - - if (self->funfirstline) + if (msymbol_is_text (msymbol)) { - if (sal.symtab != NULL - && (COMPUNIT_LOCATIONS_VALID (SYMTAB_COMPUNIT (sal.symtab)) - || SYMTAB_LANGUAGE (sal.symtab) == language_asm)) + sal = find_pc_sect_line (MSYMBOL_VALUE_ADDRESS (objfile, msymbol), + (struct obj_section *) 0, 0); + sal.section = MSYMBOL_OBJ_SECTION (objfile, msymbol); + + /* The minimal symbol might point to a function descriptor; + resolve it to the actual code address instead. */ + pc = gdbarch_convert_from_func_ptr_addr (gdbarch, sal.pc, + ¤t_target); + if (pc != sal.pc) + sal = find_pc_sect_line (pc, NULL, 0); + + if (self->funfirstline) { - /* If gdbarch_convert_from_func_ptr_addr does not apply then - sal.SECTION, sal.LINE&co. will stay correct from above. - If gdbarch_convert_from_func_ptr_addr applies then - sal.SECTION is cleared from above and sal.LINE&co. will - stay correct from the last find_pc_sect_line above. */ - sal.pc = MSYMBOL_VALUE_ADDRESS (objfile, msymbol); - sal.pc = gdbarch_convert_from_func_ptr_addr (gdbarch, sal.pc, - ¤t_target); - if (gdbarch_skip_entrypoint_p (gdbarch)) - sal.pc = gdbarch_skip_entrypoint (gdbarch, sal.pc); + if (sal.symtab != NULL + && (COMPUNIT_LOCATIONS_VALID (SYMTAB_COMPUNIT (sal.symtab)) + || SYMTAB_LANGUAGE (sal.symtab) == language_asm)) + { + /* If gdbarch_convert_from_func_ptr_addr does not apply then + sal.SECTION, sal.LINE&co. will stay correct from above. + If gdbarch_convert_from_func_ptr_addr applies then + sal.SECTION is cleared from above and sal.LINE&co. will + stay correct from the last find_pc_sect_line above. */ + sal.pc = MSYMBOL_VALUE_ADDRESS (objfile, msymbol); + sal.pc = gdbarch_convert_from_func_ptr_addr (gdbarch, sal.pc, + ¤t_target); + if (gdbarch_skip_entrypoint_p (gdbarch)) + sal.pc = gdbarch_skip_entrypoint (gdbarch, sal.pc); + } + else + skip_prologue_sal (&sal); } - else - skip_prologue_sal (&sal); + } + else + { + sal.objfile = objfile; + sal.pc = MSYMBOL_VALUE_ADDRESS (objfile, msymbol); + sal.pspace = current_program_space; + sal.section = MSYMBOL_OBJ_SECTION (objfile, msymbol); } if (maybe_add_address (self->addr_set, objfile->pspace, sal.pc)) @@ -4628,6 +4639,7 @@ symbol_to_sal (struct symtab_and_line *result, *result = {}; result->symtab = symbol_symtab (sym); result->line = SYMBOL_LINE (sym); + result->pc = SYMBOL_VALUE_ADDRESS (sym); result->pspace = SYMTAB_PSPACE (result->symtab); return 1; } |