Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Simon Marchi <simon.marchi@efficios.com>
To: gdb-patches@sourceware.org
Cc: Simon Marchi <simon.marchi@efficios.com>
Subject: [PATCH] gdb/dwarf2: don't search included symtabs recursively
Date: Tue,  3 Feb 2026 12:36:27 -0500	[thread overview]
Message-ID: <20260203173640.215967-1-simon.marchi@efficios.com> (raw)
In-Reply-To: <20260130025546.322629-3-simon.marchi@polymtl.ca>

This patch depends on this mini-series that converts
compunit_symtab::includes to a vector:

  https://inbox.sourceware.org/gdb-patches/20260130025546.322629-1-simon.marchi@polymtl.ca/

The compunit_symtab::includes field says that it contains the flattened
list of all recursively included symtabs:

  /* Vector of included compunit symtabs.  When searching the static or global
     block of this compunit, the corresponding block of all
     included compunits will also be searched.  Note that this
     list must be flattened -- the symbol reader is responsible for
     ensuring that this vector contains the transitive closure of all
     included compunits.  */
  std::vector<compunit_symtab *> includes;

The DWARF reader appears to do exactly that, see
recursively_compute_inclusions.

It therefore seems unnecessary to do a recursive search, in
recursively_find_pc_sect_compunit_symtab, it will search some symtabs
multiple times.  I confirmed this by hacking the function to print the
searched CUs and to never find anything:

    diff --git i/gdb/dwarf2/read.c w/gdb/dwarf2/read.c
    index aeed0fa13a46..098fecb06cd9 100644
    --- i/gdb/dwarf2/read.c
    +++ w/gdb/dwarf2/read.c
    @@ -2114,8 +2114,7 @@ static struct compunit_symtab *
     recursively_find_pc_sect_compunit_symtab (struct compunit_symtab *cust,
     					  CORE_ADDR pc)
     {
    -  if (cust->blockvector () != nullptr && cust->blockvector ()->contains (pc))
    -    return cust;
    +  printf ("\nSearch CU %p\n", cust);

       for (compunit_symtab *include : cust->includes)
         if (compunit_symtab *found

And then:

    $ ./gdb -nx  --data-directory=data-directory ~/build/babeltrace/src/lib/.libs/libbabeltrace2.so.0.0.0 -ex "p bt_common_assert_failed" -batch | grep 'Search CU' | sort | uniq -c
          1 Search CU 0x7c83249e44b0
          1 Search CU 0x7c83249e4690
          1 Search CU 0x7c83249e4870
          1 Search CU 0x7c83249e4960
          1 Search CU 0x7c83249e4b40
          1 Search CU 0x7c83249e4d20
          1 Search CU 0x7c83249e4f00
          2 Search CU 0x7c83249e4ff0
          2 Search CU 0x7c83249e50e0
          4 Search CU 0x7c83249e51d0
          2 Search CU 0x7c83249e52c0
          2 Search CU 0x7c83249e53b0
          4 Search CU 0x7c83249e54a0

Change recursively_find_pc_sect_compunit_symtab to only search the
flattened list, and rename it accordingly.

With the patch, the same hack (putting the print in the "is_the_one"
lambda) and command as above shows that all CUs are searched exactly
once:

      1 Search CU 0x7cc78ffe44b0
      1 Search CU 0x7cc78ffe4690
      1 Search CU 0x7cc78ffe4870
      1 Search CU 0x7cc78ffe4960
      1 Search CU 0x7cc78ffe4b40
      1 Search CU 0x7cc78ffe4d20
      1 Search CU 0x7cc78ffe4f00
      1 Search CU 0x7cc78ffe4ff0
      1 Search CU 0x7cc78ffe50e0
      1 Search CU 0x7cc78ffe51d0
      1 Search CU 0x7cc78ffe52c0
      1 Search CU 0x7cc78ffe53b0
      1 Search CU 0x7cc78ffe54a0

I am not sure how blockvectors work exactly, whether the blockvector of
the includer CU is a superset of the blockvectors of the includees.  I
ask that because it seems like in practice, the requested PC always
seems to be found in the first searched CU.  I haven't investigated this
point more than that though.

Change-Id: I4064f9ddf6131226593ac864f0f804460201502e
---
 gdb/dwarf2/read.c | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index aeed0fa13a46..75fd737f6a66 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -2110,18 +2110,21 @@ dw_search_file_matcher
 /* A helper for dw2_find_pc_sect_compunit_symtab which finds the most specific
    symtab.  */
 
-static struct compunit_symtab *
-recursively_find_pc_sect_compunit_symtab (struct compunit_symtab *cust,
-					  CORE_ADDR pc)
+static compunit_symtab *
+find_pc_sect_compunit_symtab_includes (compunit_symtab *cust, CORE_ADDR pc)
 {
-  if (cust->blockvector () != nullptr && cust->blockvector ()->contains (pc))
+  auto is_the_one = [pc] (compunit_symtab *one_cust)
+    {
+      return (one_cust->blockvector () != nullptr
+	      && one_cust->blockvector ()->contains (pc));
+    };
+
+  if (is_the_one (cust))
     return cust;
 
   for (compunit_symtab *include : cust->includes)
-    if (compunit_symtab *found
-	  = recursively_find_pc_sect_compunit_symtab (include, pc);
-	found != nullptr)
-      return found;
+    if (is_the_one (include))
+      return include;
 
   return nullptr;
 }
@@ -2134,8 +2137,6 @@ dwarf2_base_index_functions::find_pc_sect_compunit_symtab
       struct obj_section *section,
       int warn_if_readin)
 {
-  struct compunit_symtab *result;
-
   dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
   dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
 
@@ -2152,7 +2153,7 @@ dwarf2_base_index_functions::find_pc_sect_compunit_symtab
     warning (_("(Internal error: pc %s in read in CU, but not in symtab.)"),
 	     paddress (objfile->arch (), pc));
 
-  result = recursively_find_pc_sect_compunit_symtab
+  compunit_symtab *result = find_pc_sect_compunit_symtab_includes
     (dw2_instantiate_symtab (data, per_objfile, false), pc);
 
   if (warn_if_readin && result == nullptr)

base-commit: 637751817dd2e9a5dff9fc03b5917ecc4faeaf4a
-- 
2.53.0


  reply	other threads:[~2026-02-03 17:37 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-30  2:55 [PATCH 1/3] gdb/block: make find_iterator_compunit_symtab a method of block_iterator simon.marchi
2026-01-30  2:55 ` [PATCH 2/3] gdb/symtab: make compunit_symtab::includes a std::vector simon.marchi
2026-02-05 18:38   ` Tom Tromey
2026-01-30  2:55 ` [PATCH 3/3] gdb/block: bool-ify some parameters simon.marchi
2026-02-03 17:36   ` Simon Marchi [this message]
2026-02-05 18:53     ` [PATCH] gdb/dwarf2: don't search included symtabs recursively Tom Tromey
2026-02-05 19:36       ` Simon Marchi
2026-02-05 18:38   ` [PATCH 3/3] gdb/block: bool-ify some parameters Tom Tromey
2026-02-05 17:41 ` [PATCH 1/3] gdb/block: make find_iterator_compunit_symtab a method of block_iterator Tom Tromey
2026-02-05 19:33   ` Simon Marchi
2026-02-05 18:46 ` Tom Tromey
2026-02-05 19:17   ` Simon Marchi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260203173640.215967-1-simon.marchi@efficios.com \
    --to=simon.marchi@efficios.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox