diff options
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote')
6 files changed, 244 insertions, 155 deletions
diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index 5c7f6ca..c0ea9cc 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -101,6 +101,8 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() : m_supports_QEnvironment (true), m_supports_QEnvironmentHexEncoded (true), m_supports_qSymbol (true), + m_qSymbol_requests_done (false), + m_supports_qModuleInfo (true), m_supports_jThreadsInfo (true), m_curr_pid (LLDB_INVALID_PROCESS_ID), m_curr_tid (LLDB_INVALID_THREAD_ID), @@ -376,6 +378,8 @@ GDBRemoteCommunicationClient::ResetDiscoverableSettings (bool did_exec) m_supports_QEnvironment = true; m_supports_QEnvironmentHexEncoded = true; m_supports_qSymbol = true; + m_qSymbol_requests_done = false; + m_supports_qModuleInfo = true; m_host_arch.Clear(); m_os_version_major = UINT32_MAX; m_os_version_minor = UINT32_MAX; @@ -4284,6 +4288,9 @@ GDBRemoteCommunicationClient::GetModuleInfo (const FileSpec& module_file_spec, const lldb_private::ArchSpec& arch_spec, ModuleSpec &module_spec) { + if (!m_supports_qModuleInfo) + return false; + std::string module_path = module_file_spec.GetPath (false); if (module_path.empty ()) return false; @@ -4299,8 +4306,14 @@ GDBRemoteCommunicationClient::GetModuleInfo (const FileSpec& module_file_spec, if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) != PacketResult::Success) return false; - if (response.IsErrorResponse () || response.IsUnsupportedResponse ()) + if (response.IsErrorResponse ()) + return false; + + if (response.IsUnsupportedResponse ()) + { + m_supports_qModuleInfo = false; return false; + } std::string name; std::string value; @@ -4432,11 +4445,42 @@ GDBRemoteCommunicationClient::ReadExtFeature (const lldb_private::ConstString ob // qSymbol:<sym_name> The target requests the value of symbol sym_name (hex encoded). // LLDB may provide the value by sending another qSymbol packet // in the form of"qSymbol:<sym_value>:<sym_name>". +// +// Three examples: +// +// lldb sends: qSymbol:: +// lldb receives: OK +// Remote gdb stub does not need to know the addresses of any symbols, lldb does not +// need to ask again in this session. +// +// lldb sends: qSymbol:: +// lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473 +// lldb sends: qSymbol::64697370617463685f71756575655f6f666673657473 +// lldb receives: OK +// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb does not know +// the address at this time. lldb needs to send qSymbol:: again when it has more +// solibs loaded. +// +// lldb sends: qSymbol:: +// lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473 +// lldb sends: qSymbol:2bc97554:64697370617463685f71756575655f6f666673657473 +// lldb receives: OK +// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb says that it +// is at address 0x2bc97554. Remote gdb stub sends 'OK' indicating that it does not +// need any more symbols. lldb does not need to ask again in this session. void GDBRemoteCommunicationClient::ServeSymbolLookups(lldb_private::Process *process) { - if (m_supports_qSymbol) + // Set to true once we've resolved a symbol to an address for the remote stub. + // If we get an 'OK' response after this, the remote stub doesn't need any more + // symbols and we can stop asking. + bool symbol_response_provided = false; + + // Is this the inital qSymbol:: packet? + bool first_qsymbol_query = true; + + if (m_supports_qSymbol && m_qSymbol_requests_done == false) { Mutex::Locker locker; if (GetSequenceMutex(locker, "GDBRemoteCommunicationClient::ServeSymbolLookups() failed due to not getting the sequence mutex")) @@ -4448,9 +4492,15 @@ GDBRemoteCommunicationClient::ServeSymbolLookups(lldb_private::Process *process) { if (response.IsOKResponse()) { + if (symbol_response_provided || first_qsymbol_query) + { + m_qSymbol_requests_done = true; + } + // We are done serving symbols requests return; } + first_qsymbol_query = false; if (response.IsUnsupportedResponse()) { @@ -4530,7 +4580,14 @@ GDBRemoteCommunicationClient::ServeSymbolLookups(lldb_private::Process *process) packet.Clear(); packet.PutCString("qSymbol:"); if (symbol_load_addr != LLDB_INVALID_ADDRESS) + { packet.Printf("%" PRIx64, symbol_load_addr); + symbol_response_provided = true; + } + else + { + symbol_response_provided = false; + } packet.PutCString(":"); packet.PutBytesAsRawHex8(symbol_name.data(), symbol_name.size()); continue; // go back to the while loop and send "packet" and wait for another response diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h index d2df214..311b0f3 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -619,6 +619,8 @@ protected: m_supports_QEnvironment:1, m_supports_QEnvironmentHexEncoded:1, m_supports_qSymbol:1, + m_qSymbol_requests_done:1, + m_supports_qModuleInfo:1, m_supports_jThreadsInfo:1; lldb::pid_t m_curr_pid; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index bb528eb..6bee4e1 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -172,118 +172,6 @@ namespace { } // anonymous namespace end -class ProcessGDBRemote::GDBLoadedModuleInfoList -{ -public: - - class LoadedModuleInfo - { - public: - - enum e_data_point - { - e_has_name = 0, - e_has_base , - e_has_dynamic , - e_has_link_map , - e_num - }; - - LoadedModuleInfo () - { - for (uint32_t i = 0; i < e_num; ++i) - m_has[i] = false; - } - - void set_name (const std::string & name) - { - m_name = name; - m_has[e_has_name] = true; - } - bool get_name (std::string & out) const - { - out = m_name; - return m_has[e_has_name]; - } - - void set_base (const lldb::addr_t base) - { - m_base = base; - m_has[e_has_base] = true; - } - bool get_base (lldb::addr_t & out) const - { - out = m_base; - return m_has[e_has_base]; - } - - void set_base_is_offset (bool is_offset) - { - m_base_is_offset = is_offset; - } - bool get_base_is_offset(bool & out) const - { - out = m_base_is_offset; - return m_has[e_has_base]; - } - - void set_link_map (const lldb::addr_t addr) - { - m_link_map = addr; - m_has[e_has_link_map] = true; - } - bool get_link_map (lldb::addr_t & out) const - { - out = m_link_map; - return m_has[e_has_link_map]; - } - - void set_dynamic (const lldb::addr_t addr) - { - m_dynamic = addr; - m_has[e_has_dynamic] = true; - } - bool get_dynamic (lldb::addr_t & out) const - { - out = m_dynamic; - return m_has[e_has_dynamic]; - } - - bool has_info (e_data_point datum) - { - assert (datum < e_num); - return m_has[datum]; - } - - protected: - - bool m_has[e_num]; - std::string m_name; - lldb::addr_t m_link_map; - lldb::addr_t m_base; - bool m_base_is_offset; - lldb::addr_t m_dynamic; - }; - - GDBLoadedModuleInfoList () - : m_list () - , m_link_map (LLDB_INVALID_ADDRESS) - {} - - void add (const LoadedModuleInfo & mod) - { - m_list.push_back (mod); - } - - void clear () - { - m_list.clear (); - } - - std::vector<LoadedModuleInfo> m_list; - lldb::addr_t m_link_map; -}; - // TODO Randomly assigning a port is unsafe. We should get an unused // ephemeral port from the kernel and make sure we reserve it before passing // it to debugserver. @@ -2033,6 +1921,8 @@ ProcessGDBRemote::SetThreadStopInfo (lldb::tid_t tid, const std::vector<addr_t> &exc_data, addr_t thread_dispatch_qaddr, bool queue_vars_valid, // Set to true if queue_name, queue_kind and queue_serial are valid + LazyBool associated_with_dispatch_queue, + addr_t dispatch_queue_t, std::string &queue_name, QueueKind queue_kind, uint64_t queue_serial) @@ -2073,10 +1963,15 @@ ProcessGDBRemote::SetThreadStopInfo (lldb::tid_t tid, gdb_thread->SetThreadDispatchQAddr (thread_dispatch_qaddr); // Check if the GDB server was able to provide the queue name, kind and serial number if (queue_vars_valid) - gdb_thread->SetQueueInfo(std::move(queue_name), queue_kind, queue_serial); + gdb_thread->SetQueueInfo(std::move(queue_name), queue_kind, queue_serial, dispatch_queue_t, associated_with_dispatch_queue); else gdb_thread->ClearQueueInfo(); + gdb_thread->SetAssociatedWithLibdispatchQueue (associated_with_dispatch_queue); + + if (dispatch_queue_t != LLDB_INVALID_ADDRESS) + gdb_thread->SetQueueLibdispatchQueueAddress (dispatch_queue_t); + // Make sure we update our thread stop reason just once if (!thread_sp->StopInfoIsUpToDate()) { @@ -2247,9 +2142,11 @@ ProcessGDBRemote::SetThreadStopInfo (StructuredData::Dictionary *thread_dict) static ConstString g_key_metype("metype"); static ConstString g_key_medata("medata"); static ConstString g_key_qaddr("qaddr"); + static ConstString g_key_dispatch_queue_t("dispatch_queue_t"); + static ConstString g_key_associated_with_dispatch_queue("associated_with_dispatch_queue"); static ConstString g_key_queue_name("qname"); static ConstString g_key_queue_kind("qkind"); - static ConstString g_key_queue_serial("qserial"); + static ConstString g_key_queue_serial_number("qserialnum"); static ConstString g_key_registers("registers"); static ConstString g_key_memory("memory"); static ConstString g_key_address("address"); @@ -2269,9 +2166,11 @@ ProcessGDBRemote::SetThreadStopInfo (StructuredData::Dictionary *thread_dict) addr_t thread_dispatch_qaddr = LLDB_INVALID_ADDRESS; ExpeditedRegisterMap expedited_register_map; bool queue_vars_valid = false; + addr_t dispatch_queue_t = LLDB_INVALID_ADDRESS; + LazyBool associated_with_dispatch_queue = eLazyBoolCalculate; std::string queue_name; QueueKind queue_kind = eQueueKindUnknown; - uint64_t queue_serial = 0; + uint64_t queue_serial_number = 0; // Iterate through all of the thread dictionary key/value pairs from the structured data dictionary thread_dict->ForEach([this, @@ -2285,9 +2184,11 @@ ProcessGDBRemote::SetThreadStopInfo (StructuredData::Dictionary *thread_dict) &exc_data, &thread_dispatch_qaddr, &queue_vars_valid, + &associated_with_dispatch_queue, + &dispatch_queue_t, &queue_name, &queue_kind, - &queue_serial] + &queue_serial_number] (ConstString key, StructuredData::Object* object) -> bool { if (key == g_key_tid) @@ -2339,12 +2240,27 @@ ProcessGDBRemote::SetThreadStopInfo (StructuredData::Dictionary *thread_dict) queue_kind = eQueueKindConcurrent; } } - else if (key == g_key_queue_serial) + else if (key == g_key_queue_serial_number) { - queue_serial = object->GetIntegerValue(0); - if (queue_serial != 0) + queue_serial_number = object->GetIntegerValue(0); + if (queue_serial_number != 0) queue_vars_valid = true; } + else if (key == g_key_dispatch_queue_t) + { + dispatch_queue_t = object->GetIntegerValue(0); + if (dispatch_queue_t != 0 && dispatch_queue_t != LLDB_INVALID_ADDRESS) + queue_vars_valid = true; + } + else if (key == g_key_associated_with_dispatch_queue) + { + queue_vars_valid = true; + bool associated = object->GetBooleanValue (); + if (associated) + associated_with_dispatch_queue = eLazyBoolYes; + else + associated_with_dispatch_queue = eLazyBoolNo; + } else if (key == g_key_reason) { reason = object->GetStringValue(); @@ -2415,9 +2331,11 @@ ProcessGDBRemote::SetThreadStopInfo (StructuredData::Dictionary *thread_dict) exc_data, thread_dispatch_qaddr, queue_vars_valid, + associated_with_dispatch_queue, + dispatch_queue_t, queue_name, queue_kind, - queue_serial); + queue_serial_number); } StateType @@ -2460,9 +2378,11 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet) std::vector<addr_t> exc_data; addr_t thread_dispatch_qaddr = LLDB_INVALID_ADDRESS; bool queue_vars_valid = false; // says if locals below that start with "queue_" are valid + addr_t dispatch_queue_t = LLDB_INVALID_ADDRESS; + LazyBool associated_with_dispatch_queue = eLazyBoolCalculate; std::string queue_name; QueueKind queue_kind = eQueueKindUnknown; - uint64_t queue_serial = 0; + uint64_t queue_serial_number = 0; ExpeditedRegisterMap expedited_register_map; while (stop_packet.GetNameColonValue(key, value)) { @@ -2553,6 +2473,11 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet) { thread_dispatch_qaddr = StringConvert::ToUInt64 (value.c_str(), 0, 16); } + else if (key.compare("dispatch_queue_t") == 0) + { + queue_vars_valid = true; + dispatch_queue_t = StringConvert::ToUInt64 (value.c_str(), 0, 16); + } else if (key.compare("qname") == 0) { queue_vars_valid = true; @@ -2576,10 +2501,10 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet) queue_kind = eQueueKindConcurrent; } } - else if (key.compare("qserial") == 0) + else if (key.compare("qserialnum") == 0) { - queue_serial = StringConvert::ToUInt64 (value.c_str(), 0, 0); - if (queue_serial != 0) + queue_serial_number = StringConvert::ToUInt64 (value.c_str(), 0, 0); + if (queue_serial_number != 0) queue_vars_valid = true; } else if (key.compare("reason") == 0) @@ -2677,9 +2602,11 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet) exc_data, thread_dispatch_qaddr, queue_vars_valid, + associated_with_dispatch_queue, + dispatch_queue_t, queue_name, queue_kind, - queue_serial); + queue_serial_number); return eStateStopped; } @@ -3052,7 +2979,7 @@ ProcessGDBRemote::GetImageInfoAddress() // the loaded module list can also provides a link map address if (addr == LLDB_INVALID_ADDRESS) { - GDBLoadedModuleInfoList list; + LoadedModuleInfoList list; if (GetLoadedModuleList (list).Success()) addr = list.m_link_map; } @@ -4704,7 +4631,7 @@ ProcessGDBRemote::GetGDBServerRegisterInfo () } Error -ProcessGDBRemote::GetLoadedModuleList (GDBLoadedModuleInfoList & list) +ProcessGDBRemote::GetLoadedModuleList (LoadedModuleInfoList & list) { // Make sure LLDB has an XML parser it can use first if (!XMLDocument::XMLEnabled()) @@ -4748,7 +4675,7 @@ ProcessGDBRemote::GetLoadedModuleList (GDBLoadedModuleInfoList & list) root_element.ForEachChildElementWithName("library", [log, &list](const XMLNode &library) -> bool { - GDBLoadedModuleInfoList::LoadedModuleInfo module; + LoadedModuleInfoList::LoadedModuleInfo module; library.ForEachAttribute([log, &module](const llvm::StringRef &name, const llvm::StringRef &value) -> bool { @@ -4818,7 +4745,7 @@ ProcessGDBRemote::GetLoadedModuleList (GDBLoadedModuleInfoList & list) return Error(); root_element.ForEachChildElementWithName("library", [log, &list](const XMLNode &library) -> bool { - GDBLoadedModuleInfoList::LoadedModuleInfo module; + LoadedModuleInfoList::LoadedModuleInfo module; llvm::StringRef name = library.GetAttributeValue("name"); module.set_name(name.str()); @@ -4880,19 +4807,18 @@ ProcessGDBRemote::LoadModuleAtAddress (const FileSpec &file, lldb::addr_t base_a } size_t -ProcessGDBRemote::LoadModules () +ProcessGDBRemote::LoadModules (LoadedModuleInfoList &module_list) { using lldb_private::process_gdb_remote::ProcessGDBRemote; // request a list of loaded libraries from GDBServer - GDBLoadedModuleInfoList module_list; if (GetLoadedModuleList (module_list).Fail()) return 0; // get a list of all the modules ModuleList new_modules; - for (GDBLoadedModuleInfoList::LoadedModuleInfo & modInfo : module_list.m_list) + for (LoadedModuleInfoList::LoadedModuleInfo & modInfo : module_list.m_list) { std::string mod_name; lldb::addr_t mod_base; @@ -4943,6 +4869,14 @@ ProcessGDBRemote::LoadModules () } return new_modules.GetSize(); + +} + +size_t +ProcessGDBRemote::LoadModules () +{ + LoadedModuleInfoList module_list; + return LoadModules (module_list); } Error diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index 5474982..b48edd8 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -27,6 +27,7 @@ #include "lldb/Core/StringList.h" #include "lldb/Core/StructuredData.h" #include "lldb/Core/ThreadSafeValue.h" +#include "lldb/Core/LoadedModuleInfoList.h" #include "lldb/Host/HostThread.h" #include "lldb/lldb-private-forward.h" #include "lldb/Utility/StringExtractor.h" @@ -245,6 +246,9 @@ public: uint32_t &update) override; size_t + LoadModules(LoadedModuleInfoList &module_list) override; + + size_t LoadModules() override; Error @@ -261,8 +265,6 @@ protected: friend class GDBRemoteCommunicationClient; friend class GDBRemoteRegisterContext; - class GDBLoadedModuleInfoList; - //------------------------------------------------------------------ /// Broadcaster event bits definitions. //------------------------------------------------------------------ @@ -429,6 +431,8 @@ protected: const std::vector<lldb::addr_t> &exc_data, lldb::addr_t thread_dispatch_qaddr, bool queue_vars_valid, + lldb_private::LazyBool associated_with_libdispatch_queue, + lldb::addr_t dispatch_queue_t, std::string &queue_name, lldb::QueueKind queue_kind, uint64_t queue_serial); @@ -461,7 +465,7 @@ protected: // Query remote GDBServer for a detailed loaded library list Error - GetLoadedModuleList (GDBLoadedModuleInfoList &); + GetLoadedModuleList (LoadedModuleInfoList &); lldb::ModuleSP LoadModuleAtAddress (const FileSpec &file, lldb::addr_t base_addr, bool value_is_offset); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp index 9b410d8..a4af12c 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp @@ -41,8 +41,10 @@ ThreadGDBRemote::ThreadGDBRemote (Process &process, lldb::tid_t tid) : m_thread_name (), m_dispatch_queue_name (), m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS), - m_queue_kind(eQueueKindUnknown), - m_queue_serial(0) + m_dispatch_queue_t (LLDB_INVALID_ADDRESS), + m_queue_kind (eQueueKindUnknown), + m_queue_serial_number (LLDB_INVALID_QUEUE_ID), + m_associated_with_libdispatch_queue (eLazyBoolCalculate) { ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", this, @@ -73,15 +75,19 @@ ThreadGDBRemote::ClearQueueInfo () { m_dispatch_queue_name.clear(); m_queue_kind = eQueueKindUnknown; - m_queue_serial = 0; + m_queue_serial_number = 0; + m_dispatch_queue_t = LLDB_INVALID_ADDRESS; + m_associated_with_libdispatch_queue = eLazyBoolCalculate; } void -ThreadGDBRemote::SetQueueInfo (std::string &&queue_name, QueueKind queue_kind, uint64_t queue_serial) +ThreadGDBRemote::SetQueueInfo (std::string &&queue_name, QueueKind queue_kind, uint64_t queue_serial, addr_t dispatch_queue_t, LazyBool associated_with_libdispatch_queue) { m_dispatch_queue_name = queue_name; m_queue_kind = queue_kind; - m_queue_serial = queue_serial; + m_queue_serial_number = queue_serial; + m_dispatch_queue_t = dispatch_queue_t; + m_associated_with_libdispatch_queue = associated_with_libdispatch_queue; } @@ -100,7 +106,10 @@ ThreadGDBRemote::GetQueueName () } // Always re-fetch the dispatch queue name since it can change - if (m_thread_dispatch_qaddr != 0 || m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) + if (m_associated_with_libdispatch_queue == eLazyBoolNo) + return nullptr; + + if (m_thread_dispatch_qaddr != 0 && m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) { ProcessSP process_sp (GetProcess()); if (process_sp) @@ -118,6 +127,35 @@ ThreadGDBRemote::GetQueueName () return NULL; } +QueueKind +ThreadGDBRemote::GetQueueKind () +{ + // If our cached queue info is valid, then someone called ThreadGDBRemote::SetQueueInfo(...) + // with valid information that was gleaned from the stop reply packet. In this case we trust + // that the info is valid in m_dispatch_queue_name without refetching it + if (CachedQueueInfoIsValid()) + { + return m_queue_kind; + } + + if (m_associated_with_libdispatch_queue == eLazyBoolNo) + return eQueueKindUnknown; + + if (m_thread_dispatch_qaddr != 0 && m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) + { + ProcessSP process_sp (GetProcess()); + if (process_sp) + { + SystemRuntime *runtime = process_sp->GetSystemRuntime (); + if (runtime) + m_queue_kind = runtime->GetQueueKind (m_thread_dispatch_qaddr); + return m_queue_kind; + } + } + return eQueueKindUnknown; +} + + queue_id_t ThreadGDBRemote::GetQueueID () { @@ -125,9 +163,12 @@ ThreadGDBRemote::GetQueueID () // with valid information that was gleaned from the stop reply packet. In this case we trust // that the info is valid in m_dispatch_queue_name without refetching it if (CachedQueueInfoIsValid()) - return m_queue_serial; + return m_queue_serial_number; + + if (m_associated_with_libdispatch_queue == eLazyBoolNo) + return LLDB_INVALID_QUEUE_ID; - if (m_thread_dispatch_qaddr != 0 || m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) + if (m_thread_dispatch_qaddr != 0 && m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) { ProcessSP process_sp (GetProcess()); if (process_sp) @@ -161,20 +202,54 @@ ThreadGDBRemote::GetQueue () addr_t ThreadGDBRemote::GetQueueLibdispatchQueueAddress () { - addr_t dispatch_queue_t_addr = LLDB_INVALID_ADDRESS; - if (m_thread_dispatch_qaddr != 0 || m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) + if (m_dispatch_queue_t == LLDB_INVALID_ADDRESS) { - ProcessSP process_sp (GetProcess()); - if (process_sp) + if (m_thread_dispatch_qaddr != 0 && m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) { - SystemRuntime *runtime = process_sp->GetSystemRuntime (); - if (runtime) + ProcessSP process_sp (GetProcess()); + if (process_sp) { - dispatch_queue_t_addr = runtime->GetLibdispatchQueueAddressFromThreadQAddress (m_thread_dispatch_qaddr); + SystemRuntime *runtime = process_sp->GetSystemRuntime (); + if (runtime) + { + m_dispatch_queue_t = runtime->GetLibdispatchQueueAddressFromThreadQAddress (m_thread_dispatch_qaddr); + } } } } - return dispatch_queue_t_addr; + return m_dispatch_queue_t; +} + +void +ThreadGDBRemote::SetQueueLibdispatchQueueAddress (lldb::addr_t dispatch_queue_t) +{ + m_dispatch_queue_t = dispatch_queue_t; +} + +bool +ThreadGDBRemote::ThreadHasQueueInformation () const +{ + if (m_thread_dispatch_qaddr != 0 + && m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS + && m_dispatch_queue_t != LLDB_INVALID_ADDRESS + && m_queue_kind != eQueueKindUnknown + && m_queue_serial_number != 0) + { + return true; + } + return false; +} + +LazyBool +ThreadGDBRemote::GetAssociatedWithLibdispatchQueue () +{ + return m_associated_with_libdispatch_queue; +} + +void +ThreadGDBRemote::SetAssociatedWithLibdispatchQueue (LazyBool associated_with_libdispatch_queue) +{ + m_associated_with_libdispatch_queue = associated_with_libdispatch_queue; } StructuredData::ObjectSP diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h index 24693ba..d7619f4 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h @@ -46,6 +46,9 @@ public: const char * GetQueueName () override; + lldb::QueueKind + GetQueueKind () override; + lldb::queue_id_t GetQueueID () override; @@ -55,6 +58,12 @@ public: lldb::addr_t GetQueueLibdispatchQueueAddress () override; + void + SetQueueLibdispatchQueueAddress (lldb::addr_t dispatch_queue_t) override; + + bool + ThreadHasQueueInformation () const override; + lldb::RegisterContextSP GetRegisterContext () override; @@ -98,7 +107,13 @@ public: ClearQueueInfo (); void - SetQueueInfo (std::string &&queue_name, lldb::QueueKind queue_kind, uint64_t queue_serial); + SetQueueInfo (std::string &&queue_name, lldb::QueueKind queue_kind, uint64_t queue_serial, lldb::addr_t dispatch_queue_t, lldb_private::LazyBool associated_with_libdispatch_queue); + + lldb_private::LazyBool + GetAssociatedWithLibdispatchQueue () override; + + void + SetAssociatedWithLibdispatchQueue (lldb_private::LazyBool associated_with_libdispatch_queue) override; StructuredData::ObjectSP FetchThreadExtendedInfo () override; @@ -109,8 +124,10 @@ protected: std::string m_thread_name; std::string m_dispatch_queue_name; lldb::addr_t m_thread_dispatch_qaddr; + lldb::addr_t m_dispatch_queue_t; lldb::QueueKind m_queue_kind; // Queue info from stop reply/stop info for thread - uint64_t m_queue_serial; // Queue info from stop reply/stop info for thread + uint64_t m_queue_serial_number; // Queue info from stop reply/stop info for thread + lldb_private::LazyBool m_associated_with_libdispatch_queue; bool PrivateSetRegisterValue (uint32_t reg, |