diff --git a/lldb/include/lldb/Host/common/NativeProcessProtocol.h b/lldb/include/lldb/Host/common/NativeProcessProtocol.h --- a/lldb/include/lldb/Host/common/NativeProcessProtocol.h +++ b/lldb/include/lldb/Host/common/NativeProcessProtocol.h @@ -15,6 +15,7 @@ #include "lldb/Host/Host.h" #include "lldb/Host/MainLoop.h" #include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/Iterable.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/TraceGDBRemotePackets.h" #include "lldb/Utility/UnimplementedError.h" @@ -48,6 +49,16 @@ public: virtual ~NativeProcessProtocol() = default; + typedef std::vector> thread_collection; + template + static NativeThreadProtocol &thread_list_adapter(I &iter) { + assert(*iter); + return **iter; + } + typedef LockingAdaptedIterable + ThreadIterable; + virtual Status Resume(const ResumeActionList &resume_actions) = 0; virtual Status Halt() = 0; @@ -210,6 +221,10 @@ return GetThreadByID(m_current_thread_id); } + ThreadIterable Threads() const { + return ThreadIterable(m_threads, m_threads_mutex); + } + // Access to inferior stdio virtual int GetTerminalFileDescriptor() { return m_terminal_fd; } diff --git a/lldb/source/Plugins/Process/Linux/IntelPTCollector.cpp b/lldb/source/Plugins/Process/Linux/IntelPTCollector.cpp --- a/lldb/source/Plugins/Process/Linux/IntelPTCollector.cpp +++ b/lldb/source/Plugins/Process/Linux/IntelPTCollector.cpp @@ -98,8 +98,8 @@ } } else { std::vector process_threads; - for (size_t i = 0; m_process.GetThreadAtIndex(i); i++) - process_threads.push_back(m_process.GetThreadAtIndex(i)->GetID()); + for (NativeThreadProtocol &thread : m_process.Threads()) + process_threads.push_back(thread.GetID()); // per-thread process tracing if (Expected trace = diff --git a/lldb/source/Plugins/Process/Linux/IntelPTMultiCoreTrace.cpp b/lldb/source/Plugins/Process/Linux/IntelPTMultiCoreTrace.cpp --- a/lldb/source/Plugins/Process/Linux/IntelPTMultiCoreTrace.cpp +++ b/lldb/source/Plugins/Process/Linux/IntelPTMultiCoreTrace.cpp @@ -107,9 +107,9 @@ TraceIntelPTGetStateResponse IntelPTMultiCoreTrace::GetState() { TraceIntelPTGetStateResponse state; - for (size_t i = 0; m_process.GetThreadAtIndex(i); i++) + for (NativeThreadProtocol &thread : m_process.Threads()) state.traced_threads.push_back( - TraceThreadState{m_process.GetThreadAtIndex(i)->GetID(), {}}); + TraceThreadState{thread.GetID(), {}}); state.cpus.emplace(); ForEachCore([&](lldb::cpu_id_t cpu_id, diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -724,17 +724,12 @@ json::Array threads_array; // Ensure we can get info on the given thread. - uint32_t thread_idx = 0; - for (NativeThreadProtocol *thread; - (thread = process.GetThreadAtIndex(thread_idx)) != nullptr; - ++thread_idx) { - - lldb::tid_t tid = thread->GetID(); - + for (NativeThreadProtocol &thread : process.Threads()) { + lldb::tid_t tid = thread.GetID(); // Grab the reason this thread stopped. struct ThreadStopInfo tid_stop_info; std::string description; - if (!thread->GetStopReason(tid_stop_info, description)) + if (!thread.GetStopReason(tid_stop_info, description)) return llvm::make_error( "failed to get stop reason", llvm::inconvertibleErrorCode()); @@ -751,7 +746,7 @@ json::Object thread_obj; if (!abridged) { - if (llvm::Optional registers = GetRegistersAsJSON(*thread)) + if (llvm::Optional registers = GetRegistersAsJSON(thread)) thread_obj.try_emplace("registers", std::move(*registers)); } @@ -760,7 +755,7 @@ if (signum != 0) thread_obj.try_emplace("signal", signum); - const std::string thread_name = thread->GetName(); + const std::string thread_name = thread.GetName(); if (!thread_name.empty()) thread_obj.try_emplace("name", thread_name); @@ -856,14 +851,12 @@ if (m_list_threads_in_stop_reply) { response.PutCString("threads:"); - uint32_t thread_index = 0; - NativeThreadProtocol *listed_thread; - for (listed_thread = process.GetThreadAtIndex(thread_index); listed_thread; - ++thread_index, - listed_thread = process.GetThreadAtIndex(thread_index)) { - if (thread_index > 0) + uint32_t thread_num = 0; + for (NativeThreadProtocol &listed_thread : process.Threads()) { + if (thread_num > 0) response.PutChar(','); - response.Printf("%" PRIx64, listed_thread->GetID()); + response.Printf("%" PRIx64, listed_thread.GetID()); + ++thread_num; } response.PutChar(';'); @@ -872,7 +865,7 @@ // is hex ascii JSON that contains the thread IDs thread stop info only for // threads that have stop reasons. Only send this if we have more than one // thread otherwise this packet has all the info it needs. - if (thread_index > 1) { + if (thread_num > 1) { const bool threads_with_valid_stop_info_only = true; llvm::Expected threads_info = GetJSONThreadsInfo( *m_current_process, threads_with_valid_stop_info_only); @@ -889,12 +882,10 @@ } } - uint32_t i = 0; response.PutCString("thread-pcs"); char delimiter = ':'; - for (NativeThreadProtocol *thread; - (thread = process.GetThreadAtIndex(i)) != nullptr; ++i) { - NativeRegisterContext ®_ctx = thread->GetRegisterContext(); + for (NativeThreadProtocol &thread : process.Threads()) { + NativeRegisterContext ®_ctx = thread.GetRegisterContext(); uint32_t reg_to_read = reg_ctx.ConvertRegisterKindToRegisterNumber( eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); @@ -1024,12 +1015,10 @@ if (!m_non_stop) return; - uint32_t thread_index = 0; - while (NativeThreadProtocol *listed_thread = - m_current_process->GetThreadAtIndex(thread_index++)) { - if (listed_thread->GetID() != thread_to_skip) + for (NativeThreadProtocol &listed_thread : m_current_process->Threads()) { + if (listed_thread.GetID() != thread_to_skip) m_stop_notification_queue.push_back( - PrepareStopReplyPacketForThread(*listed_thread).GetString().str()); + PrepareStopReplyPacketForThread(listed_thread).GetString().str()); } } @@ -1990,15 +1979,10 @@ return; LLDB_LOG(log, "iterating over threads of process {0}", process.GetID()); - NativeThreadProtocol *thread; - uint32_t thread_index; - for (thread_index = 0, thread = process.GetThreadAtIndex(thread_index); - thread; - ++thread_index, thread = process.GetThreadAtIndex(thread_index)) { - LLDB_LOG(log, "iterated thread {0} (tid={1})", thread_index, - thread->GetID()); + for (NativeThreadProtocol &thread : process.Threads()) { + LLDB_LOG(log, "iterated thread tid={0}", thread.GetID()); response.PutChar(had_any ? ',' : 'm'); - AppendThreadIDToResponse(response, pid, thread->GetID()); + AppendThreadIDToResponse(response, pid, thread.GetID()); had_any = true; } }