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