[RFC][gdb/symtab] Lazy expansion of full symbol table
Tom de Vries
tdevries@suse.de
Sun Jun 20 09:41:16 GMT 2021
On 6/19/21 9:36 PM, Tom de Vries wrote:
> On 6/18/21 4:30 AM, Tom Tromey wrote:
>> Tom> I did an overnight build and test with the updated branch (5bc56d745fd)
>> Tom> and ran into some trouble. The first internal-error I investigated
>> Tom> happens when parsing the libstdc++ .debug package (so, it was not
>> Tom> specific to the test-case). It seems the branch has some trouble with
>> Tom> the dwz layout where an abbrev entry is shared between different CUs:
>>
>> Thank you for trying this, it uncovered several bugs.
>> As you can see I haven't gotten to the dwz testing yet... one of the
>> issues with DWARF, btw, is that there are just so many modes.
>> I.e., I haven't tried DWO or .debug_types yet either.
>>
>
> Yeah, very true.
>
>> I pushed some patches to fix the crashes but the result is so fast that
>> I suspect it is incorrect:
>>
>> (gdb) file libstdc++.so.6.0.28-10.2.1+git583-lp152.4.1.x86_64.debug
>> 2021-06-17 20:25:34.361 - command started
>> Reading symbols from libstdc++.so.6.0.28-10.2.1+git583-lp152.4.1.x86_64.debug...
>> 2021-06-17 20:25:34.406 - command finished
>> Command execution time: 0.075291 (cpu), 0.045521 (wall)
>>
>> (Though /bin/gdb is also pretty fast here, maybe I'm doing something
>> else wrong.)
>>
>> So, at least it doesn't crash, but more investigation is needed.
>> I'll probably add some code to make it easy to dump the index so it's
>> easier to see what the scanner recorded.
>
> Tried the updated branch and ran into a race condition, fixed in
> attached patch.
Another thing I ran into is a not 100% reproducible segfault.
It triggered in gdb.base/advance-until-multiple-locations.exp, when
trying to find "test" in the libc debug package.
The segfault happens in cooked_index_entry::matches due to the entry
parameter being invalid, which is set in this loop:
...
for (const cooked_index_entry *entry
: per_objfile->per_bfd->cooked_index_table->find (name_vec.back
()))
{
if (!entry->matches (search_flags)
|| !entry->matches (domain)
|| !entry->matches (kind))
continue;
...
I could reproduce the segfault with maint set worker-thread 1.
Using this debugging code:
...
diff --git a/gdb/dwarf2/cooked-index.c b/gdb/dwarf2/cooked-index.c
index 7358352fb0b..c75531ac548 100644
--- a/gdb/dwarf2/cooked-index.c
+++ b/gdb/dwarf2/cooked-index.c
@@ -133,6 +133,43 @@ cooked_index_vector::find (gdb::string_view name)
{
range result;
+#if 1
+ auto it = m_entries.begin ();
+ const char *prev_c = nullptr;
+ bool prev = true;
+ for (; it != m_entries.end (); ++it)
+ {
+ auto val = *it;
+ bool res = strncasecmp (val->canonical, name.data (), name.length
()) < 0;
+ if (res && !prev)
+ {
+ fprintf (stderr, "PREV_IT: %s\n", prev_c);
+ fprintf (stderr, "IT: %s\n", (*it)->canonical);
+ fprintf (stderr, "PREV_IT: %d\n",
+ strncasecmp (prev_c, name.data (), name.length ()));
+ fprintf (stderr, "IT: %d\n",
+ strncasecmp ((*it)->canonical, name.data (),
name.length ()));
+ gdb_assert_not_reached ("");
+ }
+ prev = res;
+ prev_c = val->canonical;
+ }
+#endif
...
I found out that the precondition for using std::lower_bound of the
vector being sorted in a certain way is not valid:
...
PREV_IT: uint32_t
IT: tcbhead_t
PREV_IT: 1
IT: -2
<gdb_assert>
...
so my hypothesis is that this causes the segfault somehow.
The test passes reliable when sorting at the entry of
cooked_index_vector::find (which is of course inefficient).
Thanks,
- Tom
More information about the Gdb-patches
mailing list