diff options
author | Tom Tromey <tom@tromey.com> | 2025-02-21 09:18:28 -0700 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2025-03-07 17:15:20 -0700 |
commit | aab2ac34d7f78f0b7a42cef0187dc6e4d7ec4f02 (patch) | |
tree | 3fa71586b82374b5d2cb0a24ff5fd998ecbc1044 | |
parent | d519282866163864fff3fe0ab7227ff0339cad67 (diff) | |
download | binutils-aab2ac34d7f78f0b7a42cef0187dc6e4d7ec4f02.zip binutils-aab2ac34d7f78f0b7a42cef0187dc6e4d7ec4f02.tar.gz binutils-aab2ac34d7f78f0b7a42cef0187dc6e4d7ec4f02.tar.bz2 |
Avoid excessive CU expansion on failed matches
PR symtab/31010 points out that something like "ptype INT" will expand
all CUs in a typical program. The OP further points out that the
original patch for PR symtab/30520:
https://sourceware.org/pipermail/gdb-patches/2024-January/205924.html
... did solve the problem, but the patch changed after (my) review and
reintroduced the bug.
In cooked_index_functions::expand_symtabs_matching, the final
component of a split name is compared with the entry's name using the
usual method of calling get_symbol_name_matcher.
This code iterates over languages and tries to split the original name
according to each style. But, the Ada splitter uses the decoded name
-- "int". This causes every C or C++ CU to be expanded.
Clearly this is wrong. And, it seems to me that looping over
languages and trying to guess the splitting style for the input text
is probably bad. However, fixing the problem is not so easy (again
due to Ada). I've filed a follow-up bug, PR symtab/32733, for this.
Meanwhile, this patch changes the code to be closer to the
originally-submitted patch. This works because the comparison is now
done between the full name and the "lookup_name_without_params"
object, which is a less adulterated variant of the original input.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31010
Tested-By: Simon Marchi <simon.marchi@efficios.com>
-rw-r--r-- | gdb/dwarf2/read.c | 46 | ||||
-rw-r--r-- | gdb/testsuite/gdb.dwarf2/no-expand-mixed-case.exp | 42 |
2 files changed, 66 insertions, 22 deletions
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 202f05f..41532c8 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -14926,31 +14926,33 @@ cooked_index_functions::expand_symtabs_matching /* Might have been looking for "a::b" and found "x::a::b". */ - if (symbol_matcher == nullptr) - { - if ((match_type == symbol_name_match_type::FULL - || (lang != language_ada - && match_type == symbol_name_match_type::EXPRESSION))) - { - if (parent != nullptr) - continue; + if (((match_type == symbol_name_match_type::FULL + || (lang != language_ada + && match_type == symbol_name_match_type::EXPRESSION))) + && parent != nullptr) + continue; - if (entry->lang != language_unknown) - { - symbol_name_matcher_ftype *name_matcher - = lang_def->get_symbol_name_matcher - (segment_lookup_names.back ()); - if (!name_matcher (entry->canonical, - segment_lookup_names.back (), nullptr)) - continue; - } - } - } - else + /* Check that the full name matches -- either by matching + the lookup name ourselves, or by passing the full name to + the symbol matcher. The former is a bit of a hack: it + seems like the loop above could just examine every + element of the name, avoiding the need to check here; but + this is hard. See PR symtab/32733. */ + if (symbol_matcher != nullptr || entry->lang != language_unknown) { auto_obstack temp_storage; - const char *full_name = entry->full_name (&temp_storage); - if (!symbol_matcher (full_name)) + const char *full_name = entry->full_name (&temp_storage, + false, true); + if (symbol_matcher == nullptr) + { + symbol_name_matcher_ftype *name_matcher + = (lang_def->get_symbol_name_matcher + (lookup_name_without_params)); + if (!name_matcher (full_name, lookup_name_without_params, + nullptr)) + continue; + } + else if (!symbol_matcher (full_name)) continue; } diff --git a/gdb/testsuite/gdb.dwarf2/no-expand-mixed-case.exp b/gdb/testsuite/gdb.dwarf2/no-expand-mixed-case.exp new file mode 100644 index 0000000..7359eea --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/no-expand-mixed-case.exp @@ -0,0 +1,42 @@ +# Copyright 2025 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Searching for "INT" should not cause CU expansion in a C program. +# PR symtab/31010. + +require !readnow + +standard_testfile main.c + +if {[prepare_for_testing "failed to prepare" $testfile \ + $srcfile {debug}]} { + return +} + +# Check that no CUs have been expanded yet. +gdb_test_no_output "maint info symtabs" \ + "no symtabs before lookup" + +# The bug was that this caused CU expansion even though the type does +# not exist. +gdb_test "whatis INT" "No symbol \"INT\" in current context." + +# Check that no CUs were expanded by the lookup. This fails with +# .gdb_index. +if {[have_index $binfile] == "gdb_index"} { + setup_kfail symtab/31363 *-*-* +} +gdb_test_no_output "maint info symtabs" \ + "no symtabs after lookup" |