Skip to content

Commit a76cf1f

Browse files
committed
Fix regresssion(internal-error) printing subprogram argument (PR gdb/22670)
At <https://sourceware.org/ml/gdb-patches/2017-12/msg00298.html>, Joel wrote: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider the following code which first declares a tagged type (the equivalent of a class in Ada), and then a procedure which takes a pointer (access) to this type's 'Class. package Pck is type Top_T is tagged record N : Integer := 1; end record; procedure Inspect (Obj: access Top_T'Class); end Pck; Putting a breakpoint in that procedure and then running to it triggers an internal error: (gdb) break inspect (gdb) continue Breakpoint 1, pck.inspect (obj=0x63e010 /[...]/gdb/stack.c:621: internal-error: void print_frame_args(symbol*, frame_info*, int, ui_file*): Assertion `nsym != NULL' failed. What's special about this subprogram is that it takes an access to what we call a 'Class type, and for implementation reasons, the compiler adds an extra argument named "objL". If you are curious why, it allows the compiler for perform dynamic accessibility checks that are mandated by the language. If we look at the location where we get the internal error (in stack.c), we find that we are looping over the symbol of each parameter, and for each parameter, we do: /* We have to look up the symbol because arguments can have two entries (one a parameter, one a local) and the one we want is the local, which lookup_symbol will find for us. [...] nsym = lookup_symbol (SYMBOL_LINKAGE_NAME (sym), b, VAR_DOMAIN, NULL).symbol; gdb_assert (nsym != NULL); The lookup_symbol goes through the lookup structure, which means the symbol's linkage name ("objL") gets transformed into a lookup_name_info object (in block_lookup_symbol), before it gets fed to the block symbol dictionary iterators. This, in turn, triggers the symbol matching by comparing the "lookup" name which, for Ada, means among other things, lowercasing the given name to "objl". It is this transformation that causes the lookup find no matches, and therefore trip this assertion. Going back to the "offending" call to lookup_symbol in stack.c, what we are trying to do, here, is do a lookup by linkage name. So, I think what we mean to be doing is a completely literal symbol lookup, so maybe not even strcmp_iw, but actually just plain strcmp??? In the past, in practice, you could get that effect by doing a lookup using the C language. But that doesn't work, because we still end up somehow using Ada's lookup_name routine which transforms "objL". So, ideally, as I hinted before, I think what we need is a way to perform a literal lookup so that searches by linkage names like the above can be performed. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This commit fixes the problem by implementing something similar to Joel's literal idea, but with some important differences. I considered adding a symbol_name_match_type::LINKAGE and supporting searching by linkage name for any language, but the problem with that is that the dictionaries only work with SYMBOL_SEARCH_NAME, because that's what is used for hashing. We'd need separate dictionaries for hashed linkage names. So with the current symbol tables infrastructure, it's not literal linkage names that we want to pass down, but instead literal _search_ names (SYMBOL_SEARCH_NAME, etc.). However, psymbols have no overload/function parameter info in C++, so a straight strcmp doesn't work properly for C++ name matching. So what we do is be a little less aggressive then and add a new symbol_name_match_type::SEARCH_SYMBOL instead that takes as input a non-user-input search symbol, and then we skip any decoding/demangling steps and make: - Ada treat that as a verbatim match, - other languages treat it as symbol_name_match_type::FULL. This also fixes the new '"maint check-psymtabs" for Ada' testcase for me (gdb.ada/maint_with_ada.exp). I've not removed the kfail yet because Joel still sees that testcase failing with this patch. That'll be fixed in follow up patches. gdb/ChangeLog: 2018-01-05 Pedro Alves <palves@redhat.com> PR gdb/22670 * ada-lang.c (literal_symbol_name_matcher): New function. (ada_get_symbol_name_matcher): Use it for symbol_name_match_type::SEARCH_NAME. * block.c (block_lookup_symbol): New parameter 'match_type'. Pass it down instead of assuming symbol_name_match_type::FULL. * block.h (block_lookup_symbol): New parameter 'match_type'. * c-valprint.c (print_unpacked_pointer): Use lookup_symbol_search_name instead of lookup_symbol. * compile/compile-object-load.c (get_out_value_type): Pass down symbol_name_match_type::SEARCH_NAME. * cp-namespace.c (cp_basic_lookup_symbol): Pass down symbol_name_match_type::FULL. * cp-support.c (cp_get_symbol_name_matcher): Handle symbol_name_match_type::SEARCH_NAME. * infrun.c (insert_exception_resume_breakpoint): Use lookup_symbol_search_name. * p-valprint.c (pascal_val_print): Use lookup_symbol_search_name. * psymtab.c (maintenance_check_psymtabs): Use symbol_name_match_type::SEARCH_NAME and SYMBOL_SEARCH_NAME. * stack.c (print_frame_args): Use lookup_symbol_search_name and SYMBOL_SEARCH_NAME. * symtab.c (lookup_local_symbol): Don't demangle the lookup name if symbol_name_match_type::SEARCH_NAME. (lookup_symbol_in_language): Pass down symbol_name_match_type::FULL. (lookup_symbol_search_name): New. (lookup_language_this): Pass down symbol_name_match_type::SEARCH_NAME. (lookup_symbol_aux, lookup_local_symbol): New parameter 'match_type'. Pass it down. * symtab.h (symbol_name_match_type::SEARCH_NAME): New enumerator. (lookup_symbol_search_name): New declaration. (lookup_symbol_in_block): New 'match_type' parameter. gdb/testsuite/ChangeLog: 2018-01-05 Joel Brobecker <brobecker@adacore.com> PR gdb/22670 * gdb.ada/access_tagged_param.exp: New file. * gdb.ada/access_tagged_param/foo.adb: New file.
1 parent 7a19098 commit a76cf1f

File tree

19 files changed

+271
-31
lines changed

19 files changed

+271
-31
lines changed

gdb/ChangeLog

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,40 @@
1+
2018-01-05 Pedro Alves <palves@redhat.com>
2+
3+
PR gdb/22670
4+
* ada-lang.c (literal_symbol_name_matcher): New function.
5+
(ada_get_symbol_name_matcher): Use it for
6+
symbol_name_match_type::SEARCH_NAME.
7+
* block.c (block_lookup_symbol): New parameter 'match_type'. Pass
8+
it down instead of assuming symbol_name_match_type::FULL.
9+
* block.h (block_lookup_symbol): New parameter 'match_type'.
10+
* c-valprint.c (print_unpacked_pointer): Use
11+
lookup_symbol_search_name instead of lookup_symbol.
12+
* compile/compile-object-load.c (get_out_value_type): Pass down
13+
symbol_name_match_type::SEARCH_NAME.
14+
* cp-namespace.c (cp_basic_lookup_symbol): Pass down
15+
symbol_name_match_type::FULL.
16+
* cp-support.c (cp_get_symbol_name_matcher): Handle
17+
symbol_name_match_type::SEARCH_NAME.
18+
* infrun.c (insert_exception_resume_breakpoint): Use
19+
lookup_symbol_search_name.
20+
* p-valprint.c (pascal_val_print): Use lookup_symbol_search_name.
21+
* psymtab.c (maintenance_check_psymtabs): Use
22+
symbol_name_match_type::SEARCH_NAME and SYMBOL_SEARCH_NAME.
23+
* stack.c (print_frame_args): Use lookup_symbol_search_name and
24+
SYMBOL_SEARCH_NAME.
25+
* symtab.c (lookup_local_symbol): Don't demangle the lookup name
26+
if symbol_name_match_type::SEARCH_NAME.
27+
(lookup_symbol_in_language): Pass down
28+
symbol_name_match_type::FULL.
29+
(lookup_symbol_search_name): New.
30+
(lookup_language_this): Pass down
31+
symbol_name_match_type::SEARCH_NAME.
32+
(lookup_symbol_aux, lookup_local_symbol): New parameter
33+
'match_type'. Pass it down.
34+
* symtab.h (symbol_name_match_type::SEARCH_NAME): New enumerator.
35+
(lookup_symbol_search_name): New declaration.
36+
(lookup_symbol_in_block): New 'match_type' parameter.
37+
138
2018-01-05 Pedro Alves <palves@redhat.com>
239

340
PR gdb/22670

gdb/ada-lang.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14404,12 +14404,38 @@ ada_symbol_name_matches (const char *symbol_search_name,
1440414404
comp_match_res);
1440514405
}
1440614406

14407+
/* A name matcher that matches the symbol name exactly, with
14408+
strcmp. */
14409+
14410+
static bool
14411+
literal_symbol_name_matcher (const char *symbol_search_name,
14412+
const lookup_name_info &lookup_name,
14413+
completion_match_result *comp_match_res)
14414+
{
14415+
const std::string &name = lookup_name.name ();
14416+
14417+
int cmp = (lookup_name.completion_mode ()
14418+
? strncmp (symbol_search_name, name.c_str (), name.size ())
14419+
: strcmp (symbol_search_name, name.c_str ()));
14420+
if (cmp == 0)
14421+
{
14422+
if (comp_match_res != NULL)
14423+
comp_match_res->set_match (symbol_search_name);
14424+
return true;
14425+
}
14426+
else
14427+
return false;
14428+
}
14429+
1440714430
/* Implement the "la_get_symbol_name_matcher" language_defn method for
1440814431
Ada. */
1440914432

1441014433
static symbol_name_matcher_ftype *
1441114434
ada_get_symbol_name_matcher (const lookup_name_info &lookup_name)
1441214435
{
14436+
if (lookup_name.match_type () == symbol_name_match_type::SEARCH_NAME)
14437+
return literal_symbol_name_matcher;
14438+
1441314439
if (lookup_name.completion_mode ())
1441414440
return ada_symbol_name_matches;
1441514441
else

gdb/block.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -673,12 +673,13 @@ block_iter_match_next (const lookup_name_info &name,
673673

674674
struct symbol *
675675
block_lookup_symbol (const struct block *block, const char *name,
676+
symbol_name_match_type match_type,
676677
const domain_enum domain)
677678
{
678679
struct block_iterator iter;
679680
struct symbol *sym;
680681

681-
lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
682+
lookup_name_info lookup_name (name, match_type);
682683

683684
if (!BLOCK_FUNCTION (block))
684685
{

gdb/block.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ extern struct symbol *block_iter_match_next
258258

259259
extern struct symbol *block_lookup_symbol (const struct block *block,
260260
const char *name,
261+
symbol_name_match_type match_type,
261262
const domain_enum domain);
262263

263264
/* Search BLOCK for symbol NAME in DOMAIN but only in primary symbol table of

gdb/c-valprint.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,14 +198,17 @@ print_unpacked_pointer (struct type *type, struct type *elttype,
198198
struct symbol *wsym = NULL;
199199
struct type *wtype;
200200
struct block *block = NULL;
201-
struct field_of_this_result is_this_fld;
202201

203202
if (want_space)
204203
fputs_filtered (" ", stream);
205204

206205
if (msymbol.minsym != NULL)
207-
wsym = lookup_symbol (MSYMBOL_LINKAGE_NAME(msymbol.minsym), block,
208-
VAR_DOMAIN, &is_this_fld).symbol;
206+
{
207+
const char *search_name
208+
= MSYMBOL_SEARCH_NAME (msymbol.minsym);
209+
wsym = lookup_symbol_search_name (search_name, block,
210+
VAR_DOMAIN).symbol;
211+
}
209212

210213
if (wsym)
211214
{

gdb/compile/compile-object-load.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,10 @@ get_out_value_type (struct symbol *func_sym, struct objfile *objfile,
439439
block = BLOCKVECTOR_BLOCK (bv, block_loop);
440440
if (BLOCK_FUNCTION (block) != NULL)
441441
continue;
442-
gdb_val_sym = block_lookup_symbol (block, COMPILE_I_EXPR_VAL, VAR_DOMAIN);
442+
gdb_val_sym = block_lookup_symbol (block,
443+
COMPILE_I_EXPR_VAL,
444+
symbol_name_match_type::SEARCH_NAME,
445+
VAR_DOMAIN);
443446
if (gdb_val_sym == NULL)
444447
continue;
445448

@@ -466,6 +469,7 @@ get_out_value_type (struct symbol *func_sym, struct objfile *objfile,
466469
gdb_type = check_typedef (gdb_type);
467470

468471
gdb_ptr_type_sym = block_lookup_symbol (block, COMPILE_I_EXPR_PTR_TYPE,
472+
symbol_name_match_type::SEARCH_NAME,
469473
VAR_DOMAIN);
470474
if (gdb_ptr_type_sym == NULL)
471475
error (_("No \"%s\" symbol found"), COMPILE_I_EXPR_PTR_TYPE);

gdb/cp-namespace.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,9 @@ cp_basic_lookup_symbol (const char *name, const struct block *block,
141141

142142
if (global_block != NULL)
143143
{
144-
sym.symbol = lookup_symbol_in_block (name, global_block, domain);
144+
sym.symbol = lookup_symbol_in_block (name,
145+
symbol_name_match_type::FULL,
146+
global_block, domain);
145147
sym.block = global_block;
146148
}
147149
}

gdb/cp-support.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1793,6 +1793,7 @@ cp_get_symbol_name_matcher (const lookup_name_info &lookup_name)
17931793
{
17941794
case symbol_name_match_type::FULL:
17951795
case symbol_name_match_type::EXPRESSION:
1796+
case symbol_name_match_type::SEARCH_NAME:
17961797
return cp_fq_symbol_name_matches;
17971798
case symbol_name_match_type::WILD:
17981799
return cp_symbol_name_matches;

gdb/infrun.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7489,7 +7489,8 @@ insert_exception_resume_breakpoint (struct thread_info *tp,
74897489
CORE_ADDR handler;
74907490
struct breakpoint *bp;
74917491

7492-
vsym = lookup_symbol (SYMBOL_LINKAGE_NAME (sym), b, VAR_DOMAIN, NULL);
7492+
vsym = lookup_symbol_search_name (SYMBOL_SEARCH_NAME (sym),
7493+
b, VAR_DOMAIN);
74937494
value = read_var_value (vsym.symbol, vsym.block, frame);
74947495
/* If the value was optimized out, revert to the old behavior. */
74957496
if (! value_optimized_out (value))

gdb/p-valprint.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -246,15 +246,17 @@ pascal_val_print (struct type *type,
246246
struct symbol *wsym = NULL;
247247
struct type *wtype;
248248
struct block *block = NULL;
249-
struct field_of_this_result is_this_fld;
250249

251250
if (want_space)
252251
fputs_filtered (" ", stream);
253252

254253
if (msymbol.minsym != NULL)
255-
wsym = lookup_symbol (MSYMBOL_LINKAGE_NAME (msymbol.minsym),
256-
block,
257-
VAR_DOMAIN, &is_this_fld).symbol;
254+
{
255+
const char *search_name
256+
= MSYMBOL_SEARCH_NAME (msymbol.minsym);
257+
wsym = lookup_symbol_search_name (search_name, block,
258+
VAR_DOMAIN).symbol;
259+
}
258260

259261
if (wsym)
260262
{

0 commit comments

Comments
 (0)