aadsm updated this revision to Diff 210422. aadsm added a comment. Missed one function
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D64013/new/ https://reviews.llvm.org/D64013 Files: lldb/include/lldb/Target/Process.h lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
Index: lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h =================================================================== --- lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -200,9 +200,9 @@ llvm::VersionTuple GetHostOSVersion() override; - size_t LoadModules(LoadedModuleInfoList &module_list) override; + llvm::Error LoadModules() override; - size_t LoadModules() override; + llvm::Expected<LoadedModuleInfoList> GetLoadedModuleList() override; Status GetFileLoadAddress(const FileSpec &file, bool &is_loaded, lldb::addr_t &load_addr) override; @@ -386,9 +386,6 @@ // Query remote GDBServer for register information bool GetGDBServerRegisterInfo(ArchSpec &arch); - // Query remote GDBServer for a detailed loaded library list - Status GetLoadedModuleList(LoadedModuleInfoList &); - lldb::ModuleSP LoadModuleAtAddress(const FileSpec &file, lldb::addr_t link_map, lldb::addr_t base_addr, Index: lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp =================================================================== --- lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -2375,7 +2375,14 @@ ostr.Printf("%" PRIu64 " %" PRIu32, wp_addr, wp_index); description = ostr.GetString(); } else if (key.compare("library") == 0) { - LoadModules(); + auto error = LoadModules(); + if (error) { + Log *log( + ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); + LLDB_LOG_ERROR(log, std::move(error), + "ProcessGDBRemote::{1} failed to load modules: {0}", + __FUNCTION__); + } } else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1])) { uint32_t reg = UINT32_MAX; if (!key.getAsInteger(16, reg)) @@ -2728,9 +2735,15 @@ // the loaded module list can also provides a link map address if (addr == LLDB_INVALID_ADDRESS) { - LoadedModuleInfoList list; - if (GetLoadedModuleList(list).Success()) - addr = list.m_link_map; + llvm::Expected<LoadedModuleInfoList> list = GetLoadedModuleList(); + if (!list) { + Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); + LLDB_LOG_ERROR(log, list.takeError(), + "ProcessGDBRemote::{1} failed to read module list: {0}", + __FUNCTION__); + } else { + addr = list->m_link_map; + } } return addr; @@ -4648,28 +4661,29 @@ return m_register_info.GetNumRegisters() > 0; } -Status ProcessGDBRemote::GetLoadedModuleList(LoadedModuleInfoList &list) { +llvm::Expected<LoadedModuleInfoList> ProcessGDBRemote::GetLoadedModuleList() { // Make sure LLDB has an XML parser it can use first if (!XMLDocument::XMLEnabled()) - return Status(0, ErrorType::eErrorTypeGeneric); + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "XML parsing not available"); Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS); if (log) log->Printf("ProcessGDBRemote::%s", __FUNCTION__); + LoadedModuleInfoList list; GDBRemoteCommunicationClient &comm = m_gdb_comm; // check that we have extended feature read support if (comm.GetQXferLibrariesSVR4ReadSupported()) { - list.clear(); - // request the loaded library list std::string raw; lldb_private::Status lldberr; if (!comm.ReadExtFeature(ConstString("libraries-svr4"), ConstString(""), raw, lldberr)) - return Status(0, ErrorType::eErrorTypeGeneric); + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Error in libraries-svr4 packet"); // parse the xml file in memory if (log) @@ -4677,11 +4691,14 @@ XMLDocument doc; if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml")) - return Status(0, ErrorType::eErrorTypeGeneric); + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Error reading noname.xml"); XMLNode root_element = doc.GetRootElement("library-list-svr4"); if (!root_element) - return Status(); + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Error finding library-list-svr4 xml element"); // main link map structure llvm::StringRef main_lm = root_element.GetAttributeValue("main-lm"); @@ -4747,27 +4764,29 @@ if (log) log->Printf("found %" PRId32 " modules in total", (int)list.m_list.size()); + return list; } else if (comm.GetQXferLibrariesReadSupported()) { - list.clear(); - // request the loaded library list std::string raw; lldb_private::Status lldberr; if (!comm.ReadExtFeature(ConstString("libraries"), ConstString(""), raw, lldberr)) - return Status(0, ErrorType::eErrorTypeGeneric); + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Error in libraries packet"); if (log) log->Printf("parsing: %s", raw.c_str()); XMLDocument doc; if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml")) - return Status(0, ErrorType::eErrorTypeGeneric); + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Error reading noname.xml"); XMLNode root_element = doc.GetRootElement("library-list"); if (!root_element) - return Status(); + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Error finding library-list xml element"); root_element.ForEachChildElementWithName( "library", [log, &list](const XMLNode &library) -> bool { @@ -4807,11 +4826,11 @@ if (log) log->Printf("found %" PRId32 " modules in total", (int)list.m_list.size()); + return list; } else { - return Status(0, ErrorType::eErrorTypeGeneric); + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Remote libraries not supported"); } - - return Status(); } lldb::ModuleSP ProcessGDBRemote::LoadModuleAtAddress(const FileSpec &file, @@ -4826,17 +4845,18 @@ value_is_offset); } -size_t ProcessGDBRemote::LoadModules(LoadedModuleInfoList &module_list) { +llvm::Error ProcessGDBRemote::LoadModules() { using lldb_private::process_gdb_remote::ProcessGDBRemote; // request a list of loaded libraries from GDBServer - if (GetLoadedModuleList(module_list).Fail()) - return 0; + llvm::Expected<LoadedModuleInfoList> module_list = GetLoadedModuleList(); + if (!module_list) + return module_list.takeError(); // get a list of all the modules ModuleList new_modules; - for (LoadedModuleInfoList::LoadedModuleInfo &modInfo : module_list.m_list) { + for (LoadedModuleInfoList::LoadedModuleInfo &modInfo : module_list->m_list) { std::string mod_name; lldb::addr_t mod_base; lldb::addr_t link_map; @@ -4903,12 +4923,7 @@ m_process->GetTarget().ModulesDidLoad(new_modules); } - return new_modules.GetSize(); -} - -size_t ProcessGDBRemote::LoadModules() { - LoadedModuleInfoList module_list; - return LoadModules(module_list); + return llvm::ErrorSuccess(); } Status ProcessGDBRemote::GetFileLoadAddress(const FileSpec &file, Index: lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h =================================================================== --- lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h +++ lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h @@ -222,16 +222,20 @@ /// Updates the current set of SOEntries, the set of added entries, and the /// set of removed entries. - bool UpdateSOEntries(bool fromRemote = false); + bool UpdateSOEntries(); + + /// Same as UpdateSOEntries but it gets the list of loaded modules from the + /// remote debug server (faster when supported). + bool UpdateSOEntriesFromRemote(); bool FillSOEntryFromModuleInfo( LoadedModuleInfoList::LoadedModuleInfo const &modInfo, SOEntry &entry); - bool SaveSOEntriesFromRemote(LoadedModuleInfoList &module_list); + bool SaveSOEntriesFromRemote(const LoadedModuleInfoList &module_list); - bool AddSOEntriesFromRemote(LoadedModuleInfoList &module_list); + bool AddSOEntriesFromRemote(const LoadedModuleInfoList &module_list); - bool RemoveSOEntriesFromRemote(LoadedModuleInfoList &module_list); + bool RemoveSOEntriesFromRemote(const LoadedModuleInfoList &module_list); bool AddSOEntries(); @@ -248,6 +252,17 @@ enum PThreadField { eSize, eNElem, eOffset }; bool FindMetadata(const char *name, PThreadField field, uint32_t &value); + + enum RendezvousAction { + eNoAction, + eTakeSnapshot, + eAddModules, + eRemoveModules + }; + + /// Returns the current action to be taken given the current and previous + /// state + RendezvousAction GetAction() const; }; #endif Index: lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp =================================================================== --- lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp +++ lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp @@ -168,7 +168,10 @@ m_previous = m_current; m_current = info; - if (UpdateSOEntries(true)) + if (m_current.map_addr == 0) + return false; + + if (UpdateSOEntriesFromRemote()) return true; return UpdateSOEntries(); @@ -178,53 +181,87 @@ return m_rendezvous_addr != LLDB_INVALID_ADDRESS; } -bool DYLDRendezvous::UpdateSOEntries(bool fromRemote) { - SOEntry entry; - LoadedModuleInfoList module_list; - - // If we can't get the SO info from the remote, return failure. - if (fromRemote && m_process->LoadModules(module_list) == 0) - return false; - - if (!fromRemote && m_current.map_addr == 0) - return false; +DYLDRendezvous::RendezvousAction DYLDRendezvous::GetAction() const { + switch (m_current.state) { + + case eConsistent: + switch (m_previous.state) { + // When the previous and current states are consistent this is the first + // time we have been asked to update. Just take a snapshot of the + // currently loaded modules. + case eConsistent: + return eTakeSnapshot; + // If we are about to add or remove a shared object clear out the current + // state and take a snapshot of the currently loaded images. + case eAdd: + return eAddModules; + case eDelete: + return eRemoveModules; + } + break; - // When the previous and current states are consistent this is the first time - // we have been asked to update. Just take a snapshot of the currently - // loaded modules. - if (m_previous.state == eConsistent && m_current.state == eConsistent) - return fromRemote ? SaveSOEntriesFromRemote(module_list) - : TakeSnapshot(m_soentries); - - // If we are about to add or remove a shared object clear out the current - // state and take a snapshot of the currently loaded images. - if (m_current.state == eAdd || m_current.state == eDelete) { - // Some versions of the android dynamic linker might send two notifications - // with state == eAdd back to back. Ignore them until we get an eConsistent - // notification. + case eAdd: + case eDelete: + // Some versions of the android dynamic linker might send two + // notifications with state == eAdd back to back. Ignore them until we + // get an eConsistent notification. if (!(m_previous.state == eConsistent || (m_previous.state == eAdd && m_current.state == eDelete))) - return false; + return eNoAction; - m_soentries.clear(); - if (fromRemote) - return SaveSOEntriesFromRemote(module_list); + return eTakeSnapshot; + } + + return eNoAction; +} + +bool DYLDRendezvous::UpdateSOEntriesFromRemote() { + auto action = GetAction(); + if (action == eNoAction) + return false; + + if (action == eTakeSnapshot) { m_added_soentries.clear(); m_removed_soentries.clear(); - return TakeSnapshot(m_soentries); + // We already have the loaded list from the previous update so no need to + // find all the modules again. + if (!m_loaded_modules.m_list.empty()) + return true; } - assert(m_current.state == eConsistent); - // Otherwise check the previous state to determine what to expect and update - // accordingly. - if (m_previous.state == eAdd) - return fromRemote ? AddSOEntriesFromRemote(module_list) : AddSOEntries(); - else if (m_previous.state == eDelete) - return fromRemote ? RemoveSOEntriesFromRemote(module_list) - : RemoveSOEntries(); + llvm::Expected<LoadedModuleInfoList> module_list = + m_process->GetLoadedModuleList(); + if (!module_list) + return false; + + switch (action) { + case eTakeSnapshot: + m_soentries.clear(); + return SaveSOEntriesFromRemote(*module_list); + case eAddModules: + return AddSOEntriesFromRemote(*module_list); + case eRemoveModules: + return RemoveSOEntriesFromRemote(*module_list); + case eNoAction: + return false; + } +} - return false; +bool DYLDRendezvous::UpdateSOEntries() { + switch(GetAction()) { + case eTakeSnapshot: + m_soentries.clear(); + m_added_soentries.clear(); + m_removed_soentries.clear(); + return TakeSnapshot(m_soentries); + case eAddModules: + return AddSOEntries(); + case eRemoveModules: + return RemoveSOEntries(); + case eNoAction: + return false; + } } bool DYLDRendezvous::FillSOEntryFromModuleInfo( @@ -255,7 +292,7 @@ } bool DYLDRendezvous::SaveSOEntriesFromRemote( - LoadedModuleInfoList &module_list) { + const LoadedModuleInfoList &module_list) { for (auto const &modInfo : module_list.m_list) { SOEntry entry; if (!FillSOEntryFromModuleInfo(modInfo, entry)) @@ -270,7 +307,8 @@ return true; } -bool DYLDRendezvous::AddSOEntriesFromRemote(LoadedModuleInfoList &module_list) { +bool DYLDRendezvous::AddSOEntriesFromRemote( + const LoadedModuleInfoList &module_list) { for (auto const &modInfo : module_list.m_list) { bool found = false; for (auto const &existing : m_loaded_modules.m_list) { @@ -288,8 +326,10 @@ return false; // Only add shared libraries and not the executable. - if (!SOEntryIsMainExecutable(entry)) + if (!SOEntryIsMainExecutable(entry)) { m_soentries.push_back(entry); + m_added_soentries.push_back(entry); + } } m_loaded_modules = module_list; @@ -297,7 +337,7 @@ } bool DYLDRendezvous::RemoveSOEntriesFromRemote( - LoadedModuleInfoList &module_list) { + const LoadedModuleInfoList &module_list) { for (auto const &existing : m_loaded_modules.m_list) { bool found = false; for (auto const &modInfo : module_list.m_list) { @@ -321,6 +361,7 @@ return false; m_soentries.erase(pos); + m_removed_soentries.push_back(entry); } } Index: lldb/include/lldb/Target/Process.h =================================================================== --- lldb/include/lldb/Target/Process.h +++ lldb/include/lldb/Target/Process.h @@ -680,10 +680,19 @@ /// shared library load state. /// /// \return - /// The number of shared libraries that were loaded - virtual size_t LoadModules() { return 0; } + /// A status object indicating if the operation was sucessful or not. + virtual llvm::Error LoadModules() { + return llvm::make_error<llvm::StringError>("Not implemented.", + llvm::inconvertibleErrorCode()); + } - virtual size_t LoadModules(LoadedModuleInfoList &) { return 0; } + /// Query remote GDBServer for a detailed loaded library list + /// \return + /// The list of modules currently loaded by the process, or an error. + virtual llvm::Expected<LoadedModuleInfoList> GetLoadedModuleList() { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Not implemented"); + } protected: virtual JITLoaderList &GetJITLoaders();
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits