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