1b60736ecSDimitry Andric //===-- CommandObjectThreadUtil.h -------------------------------*- C++ -*-===// 2b60736ecSDimitry Andric // 3b60736ecSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4b60736ecSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5b60736ecSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6b60736ecSDimitry Andric // 7b60736ecSDimitry Andric //===----------------------------------------------------------------------===// 8b60736ecSDimitry Andric 9b60736ecSDimitry Andric #ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTTHREADUTIL_H 10b60736ecSDimitry Andric #define LLDB_SOURCE_COMMANDS_COMMANDOBJECTTHREADUTIL_H 11b60736ecSDimitry Andric 12b60736ecSDimitry Andric #include "lldb/Interpreter/CommandObjectMultiword.h" 13ac9a064cSDimitry Andric #include <stack> 14b60736ecSDimitry Andric 15b60736ecSDimitry Andric namespace lldb_private { 16b60736ecSDimitry Andric 17b60736ecSDimitry Andric class CommandObjectIterateOverThreads : public CommandObjectParsed { 18b60736ecSDimitry Andric 19b60736ecSDimitry Andric class UniqueStack { 20b60736ecSDimitry Andric public: UniqueStack(std::stack<lldb::addr_t> stack_frames,uint32_t thread_index_id)21b60736ecSDimitry Andric UniqueStack(std::stack<lldb::addr_t> stack_frames, uint32_t thread_index_id) 22b60736ecSDimitry Andric : m_stack_frames(stack_frames) { 23b60736ecSDimitry Andric m_thread_index_ids.push_back(thread_index_id); 24b60736ecSDimitry Andric } 25b60736ecSDimitry Andric AddThread(uint32_t thread_index_id)26b60736ecSDimitry Andric void AddThread(uint32_t thread_index_id) const { 27b60736ecSDimitry Andric m_thread_index_ids.push_back(thread_index_id); 28b60736ecSDimitry Andric } 29b60736ecSDimitry Andric GetUniqueThreadIndexIDs()30b60736ecSDimitry Andric const std::vector<uint32_t> &GetUniqueThreadIndexIDs() const { 31b60736ecSDimitry Andric return m_thread_index_ids; 32b60736ecSDimitry Andric } 33b60736ecSDimitry Andric GetRepresentativeThread()34b60736ecSDimitry Andric lldb::tid_t GetRepresentativeThread() const { 35b60736ecSDimitry Andric return m_thread_index_ids.front(); 36b60736ecSDimitry Andric } 37b60736ecSDimitry Andric 38b60736ecSDimitry Andric friend bool inline operator<(const UniqueStack &lhs, 39b60736ecSDimitry Andric const UniqueStack &rhs) { 40b60736ecSDimitry Andric return lhs.m_stack_frames < rhs.m_stack_frames; 41b60736ecSDimitry Andric } 42b60736ecSDimitry Andric 43b60736ecSDimitry Andric protected: 44b60736ecSDimitry Andric // Mark the thread index as mutable, as we don't care about it from a const 45b60736ecSDimitry Andric // perspective, we only care about m_stack_frames so we keep our std::set 46b60736ecSDimitry Andric // sorted. 47b60736ecSDimitry Andric mutable std::vector<uint32_t> m_thread_index_ids; 48b60736ecSDimitry Andric std::stack<lldb::addr_t> m_stack_frames; 49b60736ecSDimitry Andric }; 50b60736ecSDimitry Andric 51b60736ecSDimitry Andric public: 52b60736ecSDimitry Andric CommandObjectIterateOverThreads(CommandInterpreter &interpreter, 53b60736ecSDimitry Andric const char *name, const char *help, 54b60736ecSDimitry Andric const char *syntax, uint32_t flags); 55b60736ecSDimitry Andric 56b60736ecSDimitry Andric ~CommandObjectIterateOverThreads() override = default; 57b60736ecSDimitry Andric 58b1c73532SDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override; 59b60736ecSDimitry Andric 60b60736ecSDimitry Andric protected: 61b60736ecSDimitry Andric // Override this to do whatever you need to do for one thread. 62b60736ecSDimitry Andric // 63b60736ecSDimitry Andric // If you return false, the iteration will stop, otherwise it will proceed. 64b60736ecSDimitry Andric // The result is set to m_success_return (defaults to 65b60736ecSDimitry Andric // eReturnStatusSuccessFinishResult) before the iteration, so you only need 66b60736ecSDimitry Andric // to set the return status in HandleOneThread if you want to indicate an 67b60736ecSDimitry Andric // error. If m_add_return is true, a blank line will be inserted between each 68b60736ecSDimitry Andric // of the listings (except the last one.) 69b60736ecSDimitry Andric 70b60736ecSDimitry Andric virtual bool HandleOneThread(lldb::tid_t, CommandReturnObject &result) = 0; 71b60736ecSDimitry Andric 72b60736ecSDimitry Andric bool BucketThread(lldb::tid_t tid, std::set<UniqueStack> &unique_stacks, 73b60736ecSDimitry Andric CommandReturnObject &result); 74b60736ecSDimitry Andric 75b60736ecSDimitry Andric lldb::ReturnStatus m_success_return = lldb::eReturnStatusSuccessFinishResult; 76b60736ecSDimitry Andric bool m_unique_stacks = false; 77b60736ecSDimitry Andric bool m_add_return = true; 78b60736ecSDimitry Andric }; 79b60736ecSDimitry Andric 80344a3780SDimitry Andric /// Class similar to \a CommandObjectIterateOverThreads, but which performs 81344a3780SDimitry Andric /// an action on multiple threads at once instead of iterating over each thread. 82344a3780SDimitry Andric class CommandObjectMultipleThreads : public CommandObjectParsed { 83344a3780SDimitry Andric public: 84145449b1SDimitry Andric CommandObjectMultipleThreads(CommandInterpreter &interpreter, 85145449b1SDimitry Andric const char *name, const char *help, 86145449b1SDimitry Andric const char *syntax, uint32_t flags); 87344a3780SDimitry Andric 88b1c73532SDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override; 89344a3780SDimitry Andric 90344a3780SDimitry Andric protected: 91344a3780SDimitry Andric /// Method that handles the command after the main arguments have been parsed. 92344a3780SDimitry Andric /// 93344a3780SDimitry Andric /// \param[in] tids 94344a3780SDimitry Andric /// The thread ids passed as arguments. 95344a3780SDimitry Andric /// 96344a3780SDimitry Andric /// \return 97344a3780SDimitry Andric /// A boolean result similar to the one expected from \a DoExecute. 98344a3780SDimitry Andric virtual bool DoExecuteOnThreads(Args &command, CommandReturnObject &result, 99344a3780SDimitry Andric llvm::ArrayRef<lldb::tid_t> tids) = 0; 100344a3780SDimitry Andric }; 101344a3780SDimitry Andric 102b60736ecSDimitry Andric } // namespace lldb_private 103b60736ecSDimitry Andric 104b60736ecSDimitry Andric #endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTTHREADUTIL_H 105