diff --git a/Source/Core/Core/Boot/Boot.h b/Source/Core/Core/Boot/Boot.h index d280cc0785..f892ee7c75 100644 --- a/Source/Core/Core/Boot/Boot.h +++ b/Source/Core/Core/Boot/Boot.h @@ -159,7 +159,6 @@ public: static bool BootUp(Core::System& system, const Core::CPUThreadGuard& guard, std::unique_ptr boot); - private: static bool DVDRead(Core::System& system, const DiscIO::VolumeDisc& disc, u64 dvd_offset, u32 output_address, u32 length, const DiscIO::Partition& partition); diff --git a/Source/Core/Core/PowerPC/PPCSymbolDB.cpp b/Source/Core/Core/PowerPC/PPCSymbolDB.cpp index 4a3ac6084a..e6077f6174 100644 --- a/Source/Core/Core/PowerPC/PPCSymbolDB.cpp +++ b/Source/Core/Core/PowerPC/PPCSymbolDB.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -135,6 +136,13 @@ void PPCSymbolDB::DetermineNoteLayers() Common::Symbol* PPCSymbolDB::GetSymbolFromAddr(u32 addr) { + // If m_functions is changing, there should be a PPCSymbolsChanged signal afterward. The signal + // will re-update persistent symbol displays by calling this function. Only one-off calls to this + // function, such as printing the symbol to console, should be affected by leaving early. + std::unique_lock lock(m_write_lock, std::try_to_lock); + if (!lock.owns_lock() || m_functions.empty()) + return nullptr; + auto it = m_functions.lower_bound(addr); if (it != m_functions.end()) @@ -156,7 +164,8 @@ Common::Symbol* PPCSymbolDB::GetSymbolFromAddr(u32 addr) Common::Note* PPCSymbolDB::GetNoteFromAddr(u32 addr) { - if (m_notes.empty()) + std::unique_lock lock(m_write_lock, std::try_to_lock); + if (!lock.owns_lock() || m_notes.empty()) return nullptr; auto itn = m_notes.lower_bound(addr); @@ -203,6 +212,10 @@ std::string_view PPCSymbolDB::GetDescription(u32 addr) void PPCSymbolDB::FillInCallers() { + std::unique_lock lock(m_write_lock, std::try_to_lock); + if (!lock.owns_lock()) + return; + for (auto& p : m_functions) { p.second.callers.clear(); @@ -303,6 +316,10 @@ bool PPCSymbolDB::FindMapFile(std::string* existing_map_file, std::string* writa bool PPCSymbolDB::LoadMapOnBoot(const Core::CPUThreadGuard& guard) { + // Loads from emuthread and can crash with main thread accessing the map. Any other loads will be + // done on the main thread and should be safe. Returns true if m_functions was changed. + std::lock_guard lock(m_write_lock); + std::string existing_map_file; if (!PPCSymbolDB::FindMapFile(&existing_map_file, nullptr)) return Clear(); diff --git a/Source/Core/Core/PowerPC/PPCSymbolDB.h b/Source/Core/Core/PowerPC/PPCSymbolDB.h index 2da3ce8474..6e51392195 100644 --- a/Source/Core/Core/PowerPC/PPCSymbolDB.h +++ b/Source/Core/Core/PowerPC/PPCSymbolDB.h @@ -3,6 +3,7 @@ #pragma once +#include #include #include @@ -48,4 +49,7 @@ public: void LogFunctionCall(u32 addr); static bool FindMapFile(std::string* existing_map_file, std::string* writable_map_file); + +private: + std::mutex m_write_lock; };