mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-11 18:13:04 +00:00
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:
@@ -188,6 +188,8 @@ dwarf2_read_dwz_file (dwarf2_per_objfile *per_objfile)
|
|||||||
only be run in the main thread. */
|
only be run in the main thread. */
|
||||||
gdb_assert (is_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. */
|
/* Set this early, so that on error it remains NULL. */
|
||||||
per_bfd->dwz_file.emplace (nullptr);
|
per_bfd->dwz_file.emplace (nullptr);
|
||||||
|
|
||||||
@@ -281,14 +283,9 @@ dwarf2_read_dwz_file (dwarf2_per_objfile *per_objfile)
|
|||||||
struct dwz_file *
|
struct dwz_file *
|
||||||
dwarf2_get_dwz_file (dwarf2_per_bfd *per_bfd, bool require)
|
dwarf2_get_dwz_file (dwarf2_per_bfd *per_bfd, bool require)
|
||||||
{
|
{
|
||||||
gdb_assert (!require || per_bfd->dwz_file.has_value ());
|
gdb_assert (per_bfd->dwz_file.has_value ());
|
||||||
|
dwz_file *result = per_bfd->dwz_file->get ();
|
||||||
dwz_file *result = nullptr;
|
if (require && result == nullptr)
|
||||||
if (per_bfd->dwz_file.has_value ())
|
error (_("could not read '.gnu_debugaltlink' section"));
|
||||||
{
|
|
||||||
result = per_bfd->dwz_file->get ();
|
|
||||||
if (require && result == nullptr)
|
|
||||||
error (_("could not read '.gnu_debugaltlink' section"));
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1366,6 +1366,7 @@ dwarf2_has_info (struct objfile *objfile,
|
|||||||
if (per_objfile == NULL)
|
if (per_objfile == NULL)
|
||||||
{
|
{
|
||||||
dwarf2_per_bfd *per_bfd;
|
dwarf2_per_bfd *per_bfd;
|
||||||
|
bool just_created = false;
|
||||||
|
|
||||||
/* We can share a "dwarf2_per_bfd" with other objfiles if the
|
/* We can share a "dwarf2_per_bfd" with other objfiles if the
|
||||||
BFD doesn't require relocations.
|
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,
|
per_bfd = new dwarf2_per_bfd (objfile->obfd.get (), names,
|
||||||
can_copy);
|
can_copy);
|
||||||
dwarf2_per_bfd_bfd_data_key.set (objfile->obfd.get (), per_bfd);
|
dwarf2_per_bfd_bfd_data_key.set (objfile->obfd.get (), per_bfd);
|
||||||
|
just_created = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1392,9 +1394,25 @@ dwarf2_has_info (struct objfile *objfile,
|
|||||||
/* No sharing possible, create one specifically for this objfile. */
|
/* No sharing possible, create one specifically for this objfile. */
|
||||||
per_bfd = new dwarf2_per_bfd (objfile->obfd.get (), names, can_copy);
|
per_bfd = new dwarf2_per_bfd (objfile->obfd.get (), names, can_copy);
|
||||||
dwarf2_per_bfd_objfile_data_key.set (objfile, per_bfd);
|
dwarf2_per_bfd_objfile_data_key.set (objfile, per_bfd);
|
||||||
|
just_created = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
per_objfile = dwarf2_objfile_data_key.emplace (objfile, objfile, per_bfd);
|
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
|
return (!per_objfile->per_bfd->info.is_virtual
|
||||||
@@ -3202,17 +3220,6 @@ dwarf2_initialize_objfile (struct objfile *objfile,
|
|||||||
|
|
||||||
dwarf_read_debug_printf ("called");
|
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
|
/* 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
|
indices. In this case we also don't care if some other debug
|
||||||
format is making psymtabs, because they are all about to be
|
format is making psymtabs, because they are all about to be
|
||||||
|
|||||||
Reference in New Issue
Block a user