From: Tom Tromey Date: Thu, 17 Oct 2024 23:16:54 +0000 (-0600) Subject: Add locking when reading BFD sections X-Git-Tag: gdb-16-branchpoint~603 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ce61f407ac3b509e5b5a16bb79f6848f2de3695f;p=thirdparty%2Fbinutils-gdb.git 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 --- diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c index b142f985dcd..fff71d0c3bd 100644 --- a/gdb/gdb_bfd.c +++ b/gdb/gdb_bfd.c @@ -144,6 +144,19 @@ struct gdb_bfd_data /* The registry. */ registry 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 * @@ -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 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 guard (gdata->per_bfd_mutex); +#endif + bfd_size_type section_size = bfd_section_size (section); contents->resize (section_size);