Author: Lirong Yuan Date: 2022-01-10T14:33:09-08:00 New Revision: 1267506ea54a62e0c728215c033b256ce856db30
URL: https://github.com/llvm/llvm-project/commit/1267506ea54a62e0c728215c033b256ce856db30 DIFF: https://github.com/llvm/llvm-project/commit/1267506ea54a62e0c728215c033b256ce856db30.diff LOG: [lldb] fix memory leak in "GetGDBServerRegisterInfoXMLAndProcess" While running heap checker on a test that uses LLDB API, the following memory leak is found: RAW: HeapChecker started... RAW: Leak check _main_ detected leaks of 34 bytes in 4 objects RAW: The 2 largest leaks: RAW: Leak of 17 bytes in 2 objects allocated from: @ 0x7fb93bd20166 NewHook() @ 0x7fb929372a73 absl::base_internal::MallocHook::InvokeNewHookSlow() @ 0x5600d1046093 libc_malloc @ 0x7fb974529c03 xmlStrdup @ 0x7fb9744c2a0b xmlGetProp @ 0x7fb9749d9ed6 lldb_private::XMLNode::GetAttributeValue() @ 0x7fb979043001 std::u::function::policy_invoker<>::__call_impl<>() @ 0x7fb9749da06d lldb_private::XMLNode::ForEachChildElement() @ 0x7fb97903c54d lldb_private::process_gdb_remote::ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess() @ 0x7fb97902cfe4 lldb_private::process_gdb_remote::ProcessGDBRemote::GetGDBServerRegisterInfo() @ 0x7fb97902c1d0 lldb_private::process_gdb_remote::ProcessGDBRemote::BuildDynamicRegisterInfo() @ 0x7fb97902e92a lldb_private::process_gdb_remote::ProcessGDBRemote::SetThreadStopInfo() @ 0x7fb97902db18 lldb_private::process_gdb_remote::ProcessGDBRemote::DoConnectRemote() @ 0x7fb97584965e lldb_private::Process::ConnectRemote() @ 0x7fb975839fa6 lldb_private::Platform::DoConnectProcess() @ 0x7fb97583a39e lldb_private::Platform::ConnectProcessSynchronous() @ 0x7fb97545b28b CommandObjectProcessConnect::DoExecute() @ 0x7fb9755a70c9 lldb_private::CommandObjectParsed::Execute() @ 0x7fb97559c0e9 lldb_private::CommandInterpreter::HandleCommand() @ 0x7fb975460145 lldb_private::CommandObjectRegexCommand::DoExecute() @ 0x7fb9755a72d2 lldb_private::CommandObjectRaw::Execute() @ 0x7fb97559c0e9 lldb_private::CommandInterpreter::HandleCommand() @ 0x7fb997a5f22e lldb::SBCommandInterpreter::HandleCommand() @ 0x7fb997a5ef9b lldb::SBCommandInterpreter::HandleCommand() This change fixes the memory leaks by freeing memory after it is no longer in use. Tested with "ninja check-lldb". Differential revision: https://reviews.llvm.org/D116707 Added: Modified: lldb/include/lldb/Host/XML.h lldb/source/Host/common/XML.cpp lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Removed: ################################################################################ diff --git a/lldb/include/lldb/Host/XML.h b/lldb/include/lldb/Host/XML.h index 9edf46bf09df5..da0f9cd7aa8c0 100644 --- a/lldb/include/lldb/Host/XML.h +++ b/lldb/include/lldb/Host/XML.h @@ -76,8 +76,8 @@ class XMLNode { XMLNode GetChild() const; - llvm::StringRef GetAttributeValue(const char *name, - const char *fail_value = nullptr) const; + std::string GetAttributeValue(const char *name, + const char *fail_value = nullptr) const; bool GetAttributeValueAsUnsigned(const char *name, uint64_t &value, uint64_t fail_value = 0, int base = 0) const; diff --git a/lldb/source/Host/common/XML.cpp b/lldb/source/Host/common/XML.cpp index 79128b98dc38d..2d48175a82346 100644 --- a/lldb/source/Host/common/XML.cpp +++ b/lldb/source/Host/common/XML.cpp @@ -130,22 +130,25 @@ XMLNode XMLNode::GetChild() const { #endif } -llvm::StringRef XMLNode::GetAttributeValue(const char *name, - const char *fail_value) const { - const char *attr_value = nullptr; +std::string XMLNode::GetAttributeValue(const char *name, + const char *fail_value) const { + std::string attr_value; #if LLDB_ENABLE_LIBXML2 - - if (IsValid()) - attr_value = (const char *)xmlGetProp(m_node, (const xmlChar *)name); - else - attr_value = fail_value; + if (IsValid()) { + xmlChar *value = xmlGetProp(m_node, (const xmlChar *)name); + if (value) { + attr_value = (const char *)value; + xmlFree(value); + } + } else { + if (fail_value) + attr_value = fail_value; + } #else - attr_value = fail_value; + if (fail_value) + attr_value = fail_value; #endif - if (attr_value) - return llvm::StringRef(attr_value); - else - return llvm::StringRef(); + return attr_value; } bool XMLNode::GetAttributeValueAsUnsigned(const char *name, uint64_t &value, diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index cb5ec7f18d190..dfc1c4a200689 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -4351,9 +4351,9 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess( } else if (name == "osabi") { node.GetElementText(target_info.osabi); } else if (name == "xi:include" || name == "include") { - llvm::StringRef href = node.GetAttributeValue("href"); + std::string href = node.GetAttributeValue("href"); if (!href.empty()) - target_info.includes.push_back(href.str()); + target_info.includes.push_back(href); } else if (name == "feature") { feature_nodes.push_back(node); } else if (name == "groups") { @@ -4392,9 +4392,9 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess( const XMLNode &node) -> bool { llvm::StringRef name = node.GetName(); if (name == "xi:include" || name == "include") { - llvm::StringRef href = node.GetAttributeValue("href"); + std::string href = node.GetAttributeValue("href"); if (!href.empty()) - target_info.includes.push_back(href.str()); + target_info.includes.push_back(href); } return true; }); @@ -4530,7 +4530,7 @@ llvm::Expected<LoadedModuleInfoList> ProcessGDBRemote::GetLoadedModuleList() { "Error finding library-list-svr4 xml element"); // main link map structure - llvm::StringRef main_lm = root_element.GetAttributeValue("main-lm"); + std::string main_lm = root_element.GetAttributeValue("main-lm"); // FIXME: we're silently ignoring invalid data here if (!main_lm.empty()) llvm::to_integer(main_lm, list.m_link_map); @@ -4618,15 +4618,15 @@ llvm::Expected<LoadedModuleInfoList> ProcessGDBRemote::GetLoadedModuleList() { "library", [log, &list](const XMLNode &library) -> bool { LoadedModuleInfoList::LoadedModuleInfo module; - llvm::StringRef name = library.GetAttributeValue("name"); - module.set_name(name.str()); + std::string name = library.GetAttributeValue("name"); + module.set_name(name); // The base address of a given library will be the address of its // first section. Most remotes send only one section for Windows // targets for example. const XMLNode §ion = library.FindFirstChildElementWithName("section"); - llvm::StringRef address = section.GetAttributeValue("address"); + std::string address = section.GetAttributeValue("address"); uint64_t address_value = LLDB_INVALID_ADDRESS; llvm::to_integer(address, address_value); module.set_base(address_value); _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits