[lldb] Fix unsafe map mutation in ProcessElfCore::FindModuleUUID (#159444)

The `ProcessElfCore::FindModuleUUID` function can be called by multiple
threads at the same time when `target.parallel-module-load` is true. We
were using the `operator[]` to lookup the UUID which will mutate the map
when the key is not present. This is unsafe in a multi-threaded contex
so we now use a read-only `find` operation and explicitly return an
invalid UUID when the key is not present.

The `m_uuids` map can follow a create-then-query pattern. It is
populated in the `DoLoadCore` function which looks like it is only
called in a single-threaded context so we do not need extra locking as
long as we keep the other accesses read-only.

Other fixes I considered

* Use a lock to protect access - We don't need to modify the map after
creation so we can allow concurrent read-only access.
* Store the map in a const pointer container to prevent accidental
mutation in other places.
     - Only accessed in one place currently so just added a comment.
* Store the UUID in the NT_FILE_Entry after building the mapping
correctly in `UpdateBuildIdForNTFileEntries`. - The map lets us avoid a
linear search in `FindModuleUUID`.

This commit also reverts the temporary workaround from #159395 which
disabled parallel module loading to avoid the test failure.

Fixes #159377
This commit is contained in:
David Peixotto 2025-09-18 08:20:09 -07:00 committed by GitHub
parent 6e47bff24d
commit 44a1f7e7ca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 7 additions and 3 deletions

View File

@ -308,7 +308,13 @@ llvm::StringRef ProcessElfCore::GetMainExecutablePath() {
}
UUID ProcessElfCore::FindModuleUUID(const llvm::StringRef path) {
return m_uuids[std::string(path)];
// Lookup the UUID for the given path in the map.
// Note that this could be called by multiple threads so make sure
// we access the map in a thread safe way (i.e. don't use operator[]).
auto it = m_uuids.find(std::string(path));
if (it != m_uuids.end())
return it->second;
return UUID();
}
lldb_private::DynamicLoader *ProcessElfCore::GetDynamicLoader() {

View File

@ -117,8 +117,6 @@ class NetBSDCoreCommonTestCase(TestBase):
)
def do_test(self, filename, pid, region_count):
# Temporary workaround for https://github.com/llvm/llvm-project/issues/159377
self.runCmd("settings set target.parallel-module-load false")
target = self.dbg.CreateTarget(filename)
process = target.LoadCore(filename + ".core")