Skip to content

Commit 05e3335

Browse files
committed
[SharedCache] Add mutex to guard m_namedSymbols
It is modified on a worker thread so if a user tries to call `GetSymbolWithName` after view init but before the processing on the worker thread finishes, there would have been issues!
1 parent 833375c commit 05e3335

File tree

2 files changed

+8
-3
lines changed

2 files changed

+8
-3
lines changed

view/sharedcache/core/SharedCache.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ SharedCache::SharedCache(uint64_t addressSize)
149149
{
150150
m_addressSize = addressSize;
151151
m_vm = std::make_shared<VirtualMemory>();
152+
m_namedSymMutex = std::make_unique<std::shared_mutex>();
152153
}
153154

154155

@@ -437,6 +438,7 @@ void SharedCache::ProcessEntrySlideInfo(const CacheEntry& entry) const
437438

438439
void SharedCache::ProcessSymbols()
439440
{
441+
std::unique_lock<std::shared_mutex> lock(*m_namedSymMutex);
440442
// Populate the named symbols from the regular symbols map.
441443
m_namedSymbols.reserve(m_symbols.size());
442444
for (const auto& [address, symbol] : m_symbols)
@@ -520,8 +522,9 @@ std::optional<CacheSymbol> SharedCache::GetSymbolAt(uint64_t address) const
520522
return it->second;
521523
}
522524

523-
std::optional<CacheSymbol> SharedCache::GetSymbolWithName(const std::string& name) const
525+
std::optional<CacheSymbol> SharedCache::GetSymbolWithName(const std::string& name)
524526
{
527+
std::shared_lock<std::shared_mutex> lock(*m_namedSymMutex);
525528
const auto it = m_namedSymbols.find(name);
526529
if (it == m_namedSymbols.end())
527530
return std::nullopt;

view/sharedcache/core/SharedCache.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,9 @@ class SharedCache
203203
// Quickly lookup a symbol by name, populated by `FinalizeSymbols`.
204204
// `m_namedSymbols` is modified in a worker thread spawned by view init so we must not get a symbol until its populated.
205205
std::unordered_map<std::string, uint64_t> m_namedSymbols {};
206+
// Used to guard `m_namedSymbols` as it's accessed on multiple threads.
207+
// NOTE: Wrapped in unique_ptr to keep SharedCache movable.
208+
std::unique_ptr<std::shared_mutex> m_namedSymMutex;
206209

207210
bool ProcessEntryImage(const std::string& path, const dyld_cache_image_info& info);
208211

@@ -225,7 +228,6 @@ class SharedCache
225228
const AddressRangeMap<CacheRegion>& GetRegions() const { return m_regions; }
226229
const std::unordered_map<uint64_t, CacheImage>& GetImages() const { return m_images; }
227230
const std::unordered_map<uint64_t, CacheSymbol>& GetSymbols() const { return m_symbols; }
228-
const std::unordered_map<std::string, uint64_t>& GetNamedSymbols() const { return m_namedSymbols; }
229231

230232
void AddImage(CacheImage&& image);
231233

@@ -266,7 +268,7 @@ class SharedCache
266268

267269
std::optional<CacheSymbol> GetSymbolAt(uint64_t address) const;
268270

269-
std::optional<CacheSymbol> GetSymbolWithName(const std::string& name) const;
271+
std::optional<CacheSymbol> GetSymbolWithName(const std::string& name);
270272
};
271273

272274
// This constructs a Cache, give it a file path, and it will add all relevant cache entries.

0 commit comments

Comments
 (0)