aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2024-10-17 17:16:54 -0600
committerTom Tromey <tom@tromey.com>2024-10-24 14:17:47 -0600
commitce61f407ac3b509e5b5a16bb79f6848f2de3695f (patch)
treef9ce9f6df433abee62ee835aa0fe69b396a70fb7
parentabbc4d4435aade0773974f05acaff2fab67dbf78 (diff)
downloadgdb-ce61f407ac3b509e5b5a16bb79f6848f2de3695f.zip
gdb-ce61f407ac3b509e5b5a16bb79f6848f2de3695f.tar.gz
gdb-ce61f407ac3b509e5b5a16bb79f6848f2de3695f.tar.bz2
Add locking when reading BFD sections
This adds some per-BFD locking to gdb_bfd_map_section and gdb_bfd_get_full_section_contents. It turned out that the background DWARF reader could race with the auto-load code, because the reader might try to mmap a section when the main thread was trying to read in .debug_gdb_scripts. The current BFD threading model is that only BFD globals will be locked, so any multi-threaded use of a BFD has to be handled specially by the application. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31626 Reviewed-by: Kevin Buettner <kevinb@redhat.com>
-rw-r--r--gdb/gdb_bfd.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c
index b142f98..fff71d0 100644
--- a/gdb/gdb_bfd.c
+++ b/gdb/gdb_bfd.c
@@ -144,6 +144,19 @@ struct gdb_bfd_data
/* The registry. */
registry<bfd> registry_fields;
+
+#if CXX_STD_THREAD
+ /* Most of the locking needed for multi-threaded operation is
+ handled by BFD itself. However, the current BFD model is that
+ locking is only needed for global operations -- but it turned out
+ that the background DWARF reader could race with the auto-load
+ code reading the .debug_gdb_scripts section from the same BFD.
+
+ This lock is the fix: wrappers for important BFD functions will
+ acquire this lock before performing operations that might modify
+ the state of this BFD. */
+ std::mutex per_bfd_mutex;
+#endif
};
registry<bfd> *
@@ -777,6 +790,11 @@ gdb_bfd_map_section (asection *sectp, bfd_size_type *size)
abfd = sectp->owner;
+#if CXX_STD_THREAD
+ gdb_bfd_data *gdata = (gdb_bfd_data *) bfd_usrdata (abfd);
+ std::lock_guard<std::mutex> guard (gdata->per_bfd_mutex);
+#endif
+
descriptor = get_section_descriptor (sectp);
/* If the data was already read for this BFD, just reuse it. */
@@ -1108,6 +1126,11 @@ bool
gdb_bfd_get_full_section_contents (bfd *abfd, asection *section,
gdb::byte_vector *contents)
{
+#if CXX_STD_THREAD
+ gdb_bfd_data *gdata = (gdb_bfd_data *) bfd_usrdata (abfd);
+ std::lock_guard<std::mutex> guard (gdata->per_bfd_mutex);
+#endif
+
bfd_size_type section_size = bfd_section_size (section);
contents->resize (section_size);