aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2
diff options
context:
space:
mode:
authorTom de Vries <tdevries@suse.de>2024-09-24 10:24:22 +0200
committerTom de Vries <tdevries@suse.de>2024-09-24 10:24:22 +0200
commit00105aa1c4d9933fe3cfe9bc1be0daefe9f8ca36 (patch)
treedd077abbf5a07581e38eb098133690987dc4ae4b /gdb/dwarf2
parent7d5702b8fdee17a5b4597b2b03c93e97d5b4c136 (diff)
downloadgdb-00105aa1c4d9933fe3cfe9bc1be0daefe9f8ca36.zip
gdb-00105aa1c4d9933fe3cfe9bc1be0daefe9f8ca36.tar.gz
gdb-00105aa1c4d9933fe3cfe9bc1be0daefe9f8ca36.tar.bz2
[gdb/symtab] Don't expand non-Ada CUs for info exceptions
I noticed when running test-case gdb.ada/info_exc.exp with glibc debug info installed, that the "info exceptions" command that lists all Ada exceptions also expands non-Ada CUs, which includes CUs in /lib64/ld-linux-x86-64.so.2 and /lib64/libc.so.6. Fix this by: - adding a new lang_matcher parameter to the expand_symtabs_matching function, and - using that new parameter in the expand_symtabs_matching call in ada_add_global_exceptions. The new parameter is a hint, meaning implementations are free to ignore it and expand CUs with any language. This is the case for partial symtabs, I'm not sure whether it makes sense to implement support for this there. Conversely, when processing a CU with language C and name "<artificial>" (as produced by GCC LTO), the CU may not really have a single language and we should ignore the lang_matcher. See also commit d2f67711730 ("Fix 'catch exception' with -flto"). Now that we have lang_matcher available, also use it to limit name splitting styles and symbol matchers to those applicable to the matched languages. Without this patch we have (with a gdb build with -O0): ... $ time gdb -q -batch -x outputs/gdb.ada/info_exc/gdb.in.1 > /dev/null real 0m1.866s user 0m2.089s sys 0m0.120s ... and with this patch we have: ... $ time gdb -q -batch -x outputs/gdb.ada/info_exc/gdb.in.1 > /dev/null real 0m0.469s user 0m0.777s sys 0m0.051s ... Or, to put it in terms of number of CUs, we have 1853 CUs: ... $ gdb -q -batch -readnow outputs/gdb.ada/info_exc/foo \ -ex start \ -ex "maint info symtabs" \ | grep -c " name " 1853 ... Without this patch, we have: ... $ gdb -q -batch outputs/gdb.ada/info_exc/foo \ -ex start \ -ex "info exceptions" \ -ex "maint info symtabs" \ | grep -c " name " 1393 ... so ~75% of the CUs is expanded, and with this patch we have: ... $ gdb <same-as-above> 20 ... so ~1% of the CUs is expanded. Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com> PR symtab/32182 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32182
Diffstat (limited to 'gdb/dwarf2')
-rw-r--r--gdb/dwarf2/cooked-index.h4
-rw-r--r--gdb/dwarf2/read-gdb-index.c20
-rw-r--r--gdb/dwarf2/read.c116
-rw-r--r--gdb/dwarf2/read.h31
4 files changed, 146 insertions, 25 deletions
diff --git a/gdb/dwarf2/cooked-index.h b/gdb/dwarf2/cooked-index.h
index 802e856..0873e7d 100644
--- a/gdb/dwarf2/cooked-index.h
+++ b/gdb/dwarf2/cooked-index.h
@@ -778,7 +778,9 @@ struct cooked_index_functions : public dwarf2_base_index_functions
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
block_search_flags search_flags,
- domain_search_flags domain) override;
+ domain_search_flags domain,
+ gdb::function_view<expand_symtabs_lang_matcher_ftype> lang_matcher)
+ override;
struct compunit_symtab *find_pc_sect_compunit_symtab
(struct objfile *objfile, bound_minimal_symbol msymbol,
diff --git a/gdb/dwarf2/read-gdb-index.c b/gdb/dwarf2/read-gdb-index.c
index 8cd665c..701cdec 100644
--- a/gdb/dwarf2/read-gdb-index.c
+++ b/gdb/dwarf2/read-gdb-index.c
@@ -158,7 +158,9 @@ struct dwarf2_gdb_index : public dwarf2_base_index_functions
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
block_search_flags search_flags,
- domain_search_flags domain) override;
+ domain_search_flags domain,
+ gdb::function_view<expand_symtabs_lang_matcher_ftype> lang_matcher)
+ override;
};
/* This dumps minimal information about the index.
@@ -187,7 +189,8 @@ dw2_expand_marked_cus
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
block_search_flags search_flags,
- domain_search_flags kind)
+ domain_search_flags kind,
+ gdb::function_view<expand_symtabs_lang_matcher_ftype> lang_matcher)
{
offset_type vec_len, vec_idx;
bool global_seen = false;
@@ -268,7 +271,7 @@ dw2_expand_marked_cus
dwarf2_per_cu_data *per_cu = per_objfile->per_bfd->get_cu (cu_index);
if (!dw2_expand_symtabs_matching_one (per_cu, per_objfile, file_matcher,
- expansion_notify))
+ expansion_notify, lang_matcher))
return false;
}
@@ -283,7 +286,8 @@ dwarf2_gdb_index::expand_symtabs_matching
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
block_search_flags search_flags,
- domain_search_flags domain)
+ domain_search_flags domain,
+ gdb::function_view<expand_symtabs_lang_matcher_ftype> lang_matcher)
{
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
@@ -300,7 +304,8 @@ dwarf2_gdb_index::expand_symtabs_matching
if (!dw2_expand_symtabs_matching_one (per_cu, per_objfile,
file_matcher,
- expansion_notify))
+ expansion_notify,
+ lang_matcher))
return false;
}
return true;
@@ -316,10 +321,11 @@ dwarf2_gdb_index::expand_symtabs_matching
[&] (offset_type idx)
{
if (!dw2_expand_marked_cus (per_objfile, idx, file_matcher,
- expansion_notify, search_flags, domain))
+ expansion_notify, search_flags, domain,
+ lang_matcher))
return false;
return true;
- }, per_objfile);
+ }, per_objfile, lang_matcher);
return result;
}
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index bbd6bfb..ca27391 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1644,7 +1644,9 @@ struct readnow_functions : public dwarf2_base_index_functions
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
block_search_flags search_flags,
- domain_search_flags domain) override
+ domain_search_flags domain,
+ gdb::function_view<expand_symtabs_lang_matcher_ftype> lang_matcher)
+ override
{
return true;
}
@@ -2296,7 +2298,8 @@ dw2_expand_symtabs_matching_symbol
const lookup_name_info &lookup_name_in,
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
gdb::function_view<bool (offset_type)> match_callback,
- dwarf2_per_objfile *per_objfile)
+ dwarf2_per_objfile *per_objfile,
+ gdb::function_view<expand_symtabs_lang_matcher_ftype> lang_matcher)
{
lookup_name_info lookup_name_without_params
= lookup_name_in.make_ignore_params ();
@@ -2332,6 +2335,8 @@ dw2_expand_symtabs_matching_symbol
for (int i = 0; i < nr_languages; i++)
{
enum language lang_e = (enum language) i;
+ if (lang_matcher != nullptr && !lang_matcher (lang_e))
+ continue;
const language_defn *lang = language_def (lang_e);
symbol_name_matcher_ftype *name_matcher
@@ -2489,7 +2494,7 @@ check_match (const char *file, int line,
if (expected_str == NULL || strcmp (expected_str, matched_name) != 0)
mismatch (expected_str, matched_name);
return true;
- }, per_objfile);
+ }, per_objfile, nullptr);
const char *expected_str
= expected_it == expected_end ? NULL : *expected_it++;
@@ -2850,19 +2855,29 @@ dw2_expand_symtabs_matching_one
(dwarf2_per_cu_data *per_cu,
dwarf2_per_objfile *per_objfile,
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
- gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify)
+ gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
+ gdb::function_view<expand_symtabs_lang_matcher_ftype> lang_matcher)
{
- if (file_matcher == NULL || per_cu->mark)
+ if (file_matcher != nullptr && !per_cu->mark)
+ return true;
+
+ if (lang_matcher != nullptr)
{
- bool symtab_was_null = !per_objfile->symtab_set_p (per_cu);
+ /* Try to skip CUs with non-matching language. */
+ per_cu->ensure_lang (per_objfile);
+ if (!per_cu->maybe_multi_language ()
+ && !lang_matcher (per_cu->lang ()))
+ return true;
+ }
- compunit_symtab *symtab
- = dw2_instantiate_symtab (per_cu, per_objfile, false);
- gdb_assert (symtab != nullptr);
+ bool symtab_was_null = !per_objfile->symtab_set_p (per_cu);
+ compunit_symtab *symtab
+ = dw2_instantiate_symtab (per_cu, per_objfile, false);
+ gdb_assert (symtab != nullptr);
+
+ if (expansion_notify != NULL && symtab_was_null)
+ return expansion_notify (symtab);
- if (expansion_notify != NULL && symtab_was_null)
- return expansion_notify (symtab);
- }
return true;
}
@@ -16619,7 +16634,8 @@ cooked_index_functions::expand_symtabs_matching
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
block_search_flags search_flags,
- domain_search_flags domain)
+ domain_search_flags domain,
+ gdb::function_view<expand_symtabs_lang_matcher_ftype> lang_matcher)
{
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
@@ -16638,7 +16654,8 @@ cooked_index_functions::expand_symtabs_matching
if (!dw2_expand_symtabs_matching_one (per_cu, per_objfile,
file_matcher,
- expansion_notify))
+ expansion_notify,
+ lang_matcher))
return false;
}
return true;
@@ -16663,8 +16680,42 @@ cooked_index_functions::expand_symtabs_matching
symbol_name_match_type match_type
= lookup_name_without_params.match_type ();
+ std::bitset<nr_languages> unique_styles_used;
+ if (lang_matcher != nullptr)
+ for (unsigned iter = 0; iter < nr_languages; ++iter)
+ {
+ enum language lang = (enum language) iter;
+ if (!lang_matcher (lang))
+ continue;
+
+ switch (lang)
+ {
+ case language_cplus:
+ case language_rust:
+ unique_styles_used[language_cplus] = true;
+ break;
+ case language_d:
+ case language_go:
+ unique_styles_used[language_d] = true;
+ break;
+ case language_ada:
+ unique_styles_used[language_ada] = true;
+ break;
+ default:
+ unique_styles_used[language_c] = true;
+ }
+
+ if (unique_styles_used.count ()
+ == sizeof (unique_styles) / sizeof (unique_styles[0]))
+ break;
+ }
+
for (enum language lang : unique_styles)
{
+ if (lang_matcher != nullptr
+ && !unique_styles_used.test (lang))
+ continue;
+
std::vector<std::string_view> name_vec
= lookup_name_without_params.split_name (lang);
std::vector<std::string> name_str_vec (name_vec.begin (), name_vec.end ());
@@ -16695,6 +16746,15 @@ cooked_index_functions::expand_symtabs_matching
|| !entry->matches (domain))
continue;
+ if (lang_matcher != nullptr)
+ {
+ /* Try to skip CUs with non-matching language. */
+ entry->per_cu->ensure_lang (per_objfile);
+ if (!entry->per_cu->maybe_multi_language ()
+ && !lang_matcher (entry->per_cu->lang ()))
+ continue;
+ }
+
/* We've found the base name of the symbol; now walk its
parentage chain, ensuring that each component
matches. */
@@ -16763,7 +16823,7 @@ cooked_index_functions::expand_symtabs_matching
if (!dw2_expand_symtabs_matching_one (entry->per_cu, per_objfile,
file_matcher,
- expansion_notify))
+ expansion_notify, nullptr))
return false;
}
}
@@ -21463,6 +21523,24 @@ dwarf2_per_cu_data::set_lang (enum language lang,
gdb_assert (old_dw == 0 || old_dw == dw_lang);
}
+/* See read.h. */
+
+void
+dwarf2_per_cu_data::ensure_lang (dwarf2_per_objfile *per_objfile)
+{
+ if (lang (false) != language_unknown)
+ return;
+
+ cutu_reader reader (this, per_objfile);
+ if (reader.dummy_p)
+ {
+ set_lang (language_minimal, (dwarf_source_language)0);
+ return;
+ }
+
+ prepare_one_comp_unit (reader.cu, reader.comp_unit_die, language_minimal);
+}
+
/* A helper function for dwarf2_find_containing_comp_unit that returns
the index of the result, and that searches a vector. It will
return a result even if the offset in question does not actually
@@ -21626,6 +21704,14 @@ prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die,
cu->language_defn = language_def (lang);
+ /* Initialize the lto_artificial field. */
+ attr = dwarf2_attr (comp_unit_die, DW_AT_name, cu);
+ if (attr != nullptr
+ && cu->producer != nullptr
+ && strcmp (attr->as_string (), "<artificial>") == 0
+ && producer_is_gcc (cu->producer, nullptr, nullptr))
+ cu->per_cu->lto_artificial = true;
+
switch (comp_unit_die->tag)
{
case DW_TAG_compile_unit:
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index b23972b..7c42017 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -102,6 +102,7 @@ struct dwarf2_per_cu_data
is_dwz (false),
reading_dwo_directly (false),
tu_read (false),
+ lto_artificial (false),
queued (false),
m_header_read_in (false),
mark (false),
@@ -148,6 +149,11 @@ public:
This flag is only valid if is_debug_types is true. */
unsigned int tu_read : 1;
+ /* Non-zero if the CU is produced by GCC and has name "<artificial>". GCC
+ uses this to indicate that the CU does not correspond to a single source
+ file. GCC produces this type of CU during LTO. */
+ unsigned int lto_artificial : 1;
+
/* Wrap the following in struct packed instead of bitfields to avoid
data races when the bitfields end up on the same memory location
(per C++ memory model). */
@@ -324,6 +330,9 @@ public:
return l;
}
+ /* Make sure that m_lang != language_unknown. */
+ void ensure_lang (dwarf2_per_objfile *per_objfile);
+
/* Return the language of this CU, as a DWARF DW_LANG_* value. This
may be 0 in some situations. */
dwarf_source_language dw_lang () const
@@ -335,6 +344,22 @@ public:
situation LANG would be set by the importing CU. */
void set_lang (enum language lang, dwarf_source_language dw_lang);
+ /* Return true if the CU may be a multi-language CU. */
+
+ bool maybe_multi_language () const
+ {
+ enum language lang = this->lang ();
+
+ if (!lto_artificial)
+ /* Assume multi-language CUs are generated only by GCC LTO. */
+ return false;
+
+ /* If GCC mixes different languages in an artificial LTO CU, it labels it C.
+ The exception to this is when it mixes C and C++, which it labels it C++.
+ For now, we don't consider the latter a multi-language CU. */
+ return lang == language_c;
+ }
+
/* Free any cached file names. */
void free_cached_file_names ();
};
@@ -867,7 +892,8 @@ extern bool dw2_expand_symtabs_matching_one
(dwarf2_per_cu_data *per_cu,
dwarf2_per_objfile *per_objfile,
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
- gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify);
+ gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
+ gdb::function_view<expand_symtabs_lang_matcher_ftype> lang_matcher);
/* Helper for dw2_expand_symtabs_matching that works with a
mapped_index_base instead of the containing objfile. This is split
@@ -881,7 +907,8 @@ extern bool dw2_expand_symtabs_matching_symbol
const lookup_name_info &lookup_name_in,
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
gdb::function_view<bool (offset_type)> match_callback,
- dwarf2_per_objfile *per_objfile);
+ dwarf2_per_objfile *per_objfile,
+ gdb::function_view<expand_symtabs_lang_matcher_ftype> lang_matcher);
/* If FILE_MATCHER is non-NULL, set all the
dwarf2_per_cu_quick_data::MARK of the current DWARF2_PER_OBJFILE