Debug.h revision 314564
1//===-- Debug.h -------------------------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef liblldb_Debug_h_ 11#define liblldb_Debug_h_ 12 13// C Includes 14// C++ Includes 15#include <vector> 16 17// Other libraries and framework includes 18// Project includes 19#include "lldb/lldb-private.h" 20 21namespace lldb_private { 22 23//------------------------------------------------------------------ 24// Tells a thread what it needs to do when the process is resumed. 25//------------------------------------------------------------------ 26struct ResumeAction { 27 lldb::tid_t tid; // The thread ID that this action applies to, 28 // LLDB_INVALID_THREAD_ID for the default thread action 29 lldb::StateType state; // Valid values are eStateStopped/eStateSuspended, 30 // eStateRunning, and eStateStepping. 31 int signal; // When resuming this thread, resume it with this signal if this 32 // value is > 0 33}; 34 35//------------------------------------------------------------------ 36// A class that contains instructions for all threads for 37// NativeProcessProtocol::Resume(). Each thread can either run, stay 38// suspended, or step when the process is resumed. We optionally 39// have the ability to also send a signal to the thread when the 40// action is run or step. 41//------------------------------------------------------------------ 42class ResumeActionList { 43public: 44 ResumeActionList() : m_actions(), m_signal_handled() {} 45 46 ResumeActionList(lldb::StateType default_action, int signal) 47 : m_actions(), m_signal_handled() { 48 SetDefaultThreadActionIfNeeded(default_action, signal); 49 } 50 51 ResumeActionList(const ResumeAction *actions, size_t num_actions) 52 : m_actions(), m_signal_handled() { 53 if (actions && num_actions) { 54 m_actions.assign(actions, actions + num_actions); 55 m_signal_handled.assign(num_actions, false); 56 } 57 } 58 59 ~ResumeActionList() = default; 60 61 bool IsEmpty() const { return m_actions.empty(); } 62 63 void Append(const ResumeAction &action) { 64 m_actions.push_back(action); 65 m_signal_handled.push_back(false); 66 } 67 68 void AppendAction(lldb::tid_t tid, lldb::StateType state, int signal = 0) { 69 ResumeAction action = {tid, state, signal}; 70 Append(action); 71 } 72 73 void AppendResumeAll() { 74 AppendAction(LLDB_INVALID_THREAD_ID, lldb::eStateRunning); 75 } 76 77 void AppendSuspendAll() { 78 AppendAction(LLDB_INVALID_THREAD_ID, lldb::eStateStopped); 79 } 80 81 void AppendStepAll() { 82 AppendAction(LLDB_INVALID_THREAD_ID, lldb::eStateStepping); 83 } 84 85 const ResumeAction *GetActionForThread(lldb::tid_t tid, 86 bool default_ok) const { 87 const size_t num_actions = m_actions.size(); 88 for (size_t i = 0; i < num_actions; ++i) { 89 if (m_actions[i].tid == tid) 90 return &m_actions[i]; 91 } 92 if (default_ok && tid != LLDB_INVALID_THREAD_ID) 93 return GetActionForThread(LLDB_INVALID_THREAD_ID, false); 94 return nullptr; 95 } 96 97 size_t NumActionsWithState(lldb::StateType state) const { 98 size_t count = 0; 99 const size_t num_actions = m_actions.size(); 100 for (size_t i = 0; i < num_actions; ++i) { 101 if (m_actions[i].state == state) 102 ++count; 103 } 104 return count; 105 } 106 107 bool SetDefaultThreadActionIfNeeded(lldb::StateType action, int signal) { 108 if (GetActionForThread(LLDB_INVALID_THREAD_ID, true) == nullptr) { 109 // There isn't a default action so we do need to set it. 110 ResumeAction default_action = {LLDB_INVALID_THREAD_ID, action, signal}; 111 m_actions.push_back(default_action); 112 m_signal_handled.push_back(false); 113 return true; // Return true as we did add the default action 114 } 115 return false; 116 } 117 118 void SetSignalHandledForThread(lldb::tid_t tid) const { 119 if (tid != LLDB_INVALID_THREAD_ID) { 120 const size_t num_actions = m_actions.size(); 121 for (size_t i = 0; i < num_actions; ++i) { 122 if (m_actions[i].tid == tid) 123 m_signal_handled[i] = true; 124 } 125 } 126 } 127 128 const ResumeAction *GetFirst() const { return m_actions.data(); } 129 130 size_t GetSize() const { return m_actions.size(); } 131 132 void Clear() { 133 m_actions.clear(); 134 m_signal_handled.clear(); 135 } 136 137protected: 138 std::vector<ResumeAction> m_actions; 139 mutable std::vector<bool> m_signal_handled; 140}; 141 142struct ThreadStopInfo { 143 lldb::StopReason reason; 144 union { 145 // eStopReasonSignal 146 struct { 147 uint32_t signo; 148 } signal; 149 150 // eStopReasonException 151 struct { 152 uint64_t type; 153 uint32_t data_count; 154 lldb::addr_t data[8]; 155 } exception; 156 } details; 157}; 158} 159 160#endif // liblldb_Debug_h_ 161