diff options
author | Tom Tromey <tom@tromey.com> | 2024-10-17 17:16:54 -0600 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2024-10-24 14:17:47 -0600 |
commit | ce61f407ac3b509e5b5a16bb79f6848f2de3695f (patch) | |
tree | f9ce9f6df433abee62ee835aa0fe69b396a70fb7 | |
parent | abbc4d4435aade0773974f05acaff2fab67dbf78 (diff) | |
download | gdb-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.c | 23 |
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); |