Avoid race when reading dwz file
PR gdb/31260 points out a race introduced by the background reading changes. If a given objfile is re-opened when it is already being read, dwarf2_initialize_objfile will call dwarf2_read_dwz_file again, causing the 'dwz_file' to be reset. This patch fixes the problem by arranging to open the dwz just once: when the dwarf2_per_bfd object is created. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31260
This commit is contained in:
parent
cdabd12b18
commit
e9b738dfbd
2 changed files with 24 additions and 20 deletions
|
@ -188,6 +188,8 @@ dwarf2_read_dwz_file (dwarf2_per_objfile *per_objfile)
|
|||
only be run in the main thread. */
|
||||
gdb_assert (is_main_thread ());
|
||||
|
||||
/* This should only be called once. */
|
||||
gdb_assert (!per_bfd->dwz_file.has_value ());
|
||||
/* Set this early, so that on error it remains NULL. */
|
||||
per_bfd->dwz_file.emplace (nullptr);
|
||||
|
||||
|
@ -281,14 +283,9 @@ dwarf2_read_dwz_file (dwarf2_per_objfile *per_objfile)
|
|||
struct dwz_file *
|
||||
dwarf2_get_dwz_file (dwarf2_per_bfd *per_bfd, bool require)
|
||||
{
|
||||
gdb_assert (!require || per_bfd->dwz_file.has_value ());
|
||||
|
||||
dwz_file *result = nullptr;
|
||||
if (per_bfd->dwz_file.has_value ())
|
||||
{
|
||||
result = per_bfd->dwz_file->get ();
|
||||
if (require && result == nullptr)
|
||||
error (_("could not read '.gnu_debugaltlink' section"));
|
||||
}
|
||||
gdb_assert (per_bfd->dwz_file.has_value ());
|
||||
dwz_file *result = per_bfd->dwz_file->get ();
|
||||
if (require && result == nullptr)
|
||||
error (_("could not read '.gnu_debugaltlink' section"));
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -1366,6 +1366,7 @@ dwarf2_has_info (struct objfile *objfile,
|
|||
if (per_objfile == NULL)
|
||||
{
|
||||
dwarf2_per_bfd *per_bfd;
|
||||
bool just_created = false;
|
||||
|
||||
/* We can share a "dwarf2_per_bfd" with other objfiles if the
|
||||
BFD doesn't require relocations.
|
||||
|
@ -1385,6 +1386,7 @@ dwarf2_has_info (struct objfile *objfile,
|
|||
per_bfd = new dwarf2_per_bfd (objfile->obfd.get (), names,
|
||||
can_copy);
|
||||
dwarf2_per_bfd_bfd_data_key.set (objfile->obfd.get (), per_bfd);
|
||||
just_created = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1392,9 +1394,25 @@ dwarf2_has_info (struct objfile *objfile,
|
|||
/* No sharing possible, create one specifically for this objfile. */
|
||||
per_bfd = new dwarf2_per_bfd (objfile->obfd.get (), names, can_copy);
|
||||
dwarf2_per_bfd_objfile_data_key.set (objfile, per_bfd);
|
||||
just_created = true;
|
||||
}
|
||||
|
||||
per_objfile = dwarf2_objfile_data_key.emplace (objfile, objfile, per_bfd);
|
||||
|
||||
if (just_created)
|
||||
{
|
||||
/* Try to fetch any potential dwz file early, while still on
|
||||
the main thread. Also, be sure to do it just once per
|
||||
BFD, to avoid races. */
|
||||
try
|
||||
{
|
||||
dwarf2_read_dwz_file (per_objfile);
|
||||
}
|
||||
catch (const gdb_exception_error &err)
|
||||
{
|
||||
warning (_("%s"), err.what ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (!per_objfile->per_bfd->info.is_virtual
|
||||
|
@ -3202,17 +3220,6 @@ dwarf2_initialize_objfile (struct objfile *objfile,
|
|||
|
||||
dwarf_read_debug_printf ("called");
|
||||
|
||||
/* Try to fetch any potential dwz file early, while still on the
|
||||
main thread. */
|
||||
try
|
||||
{
|
||||
dwarf2_read_dwz_file (per_objfile);
|
||||
}
|
||||
catch (const gdb_exception_error &err)
|
||||
{
|
||||
warning (_("%s"), err.what ());
|
||||
}
|
||||
|
||||
/* If we're about to read full symbols, don't bother with the
|
||||
indices. In this case we also don't care if some other debug
|
||||
format is making psymtabs, because they are all about to be
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue