1 //===-- Debug.h -------------------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef liblldb_Debug_h_
10 #define liblldb_Debug_h_
14 #include "lldb/lldb-private.h"
16 namespace lldb_private {
18 // Tells a thread what it needs to do when the process is resumed.
20 lldb::tid_t tid; // The thread ID that this action applies to,
21 // LLDB_INVALID_THREAD_ID for the default thread
23 lldb::StateType state; // Valid values are eStateStopped/eStateSuspended,
24 // eStateRunning, and eStateStepping.
25 int signal; // When resuming this thread, resume it with this signal if this
29 // A class that contains instructions for all threads for
30 // NativeProcessProtocol::Resume(). Each thread can either run, stay suspended,
31 // or step when the process is resumed. We optionally have the ability to also
32 // send a signal to the thread when the action is run or step.
33 class ResumeActionList {
35 ResumeActionList() : m_actions(), m_signal_handled() {}
37 ResumeActionList(lldb::StateType default_action, int signal)
38 : m_actions(), m_signal_handled() {
39 SetDefaultThreadActionIfNeeded(default_action, signal);
42 ResumeActionList(const ResumeAction *actions, size_t num_actions)
43 : m_actions(), m_signal_handled() {
44 if (actions && num_actions) {
45 m_actions.assign(actions, actions + num_actions);
46 m_signal_handled.assign(num_actions, false);
50 ~ResumeActionList() = default;
52 bool IsEmpty() const { return m_actions.empty(); }
54 void Append(const ResumeAction &action) {
55 m_actions.push_back(action);
56 m_signal_handled.push_back(false);
59 void AppendAction(lldb::tid_t tid, lldb::StateType state, int signal = 0) {
60 ResumeAction action = {tid, state, signal};
64 void AppendResumeAll() {
65 AppendAction(LLDB_INVALID_THREAD_ID, lldb::eStateRunning);
68 void AppendSuspendAll() {
69 AppendAction(LLDB_INVALID_THREAD_ID, lldb::eStateStopped);
72 void AppendStepAll() {
73 AppendAction(LLDB_INVALID_THREAD_ID, lldb::eStateStepping);
76 const ResumeAction *GetActionForThread(lldb::tid_t tid,
77 bool default_ok) const {
78 const size_t num_actions = m_actions.size();
79 for (size_t i = 0; i < num_actions; ++i) {
80 if (m_actions[i].tid == tid)
83 if (default_ok && tid != LLDB_INVALID_THREAD_ID)
84 return GetActionForThread(LLDB_INVALID_THREAD_ID, false);
88 size_t NumActionsWithState(lldb::StateType state) const {
90 const size_t num_actions = m_actions.size();
91 for (size_t i = 0; i < num_actions; ++i) {
92 if (m_actions[i].state == state)
98 bool SetDefaultThreadActionIfNeeded(lldb::StateType action, int signal) {
99 if (GetActionForThread(LLDB_INVALID_THREAD_ID, true) == nullptr) {
100 // There isn't a default action so we do need to set it.
101 ResumeAction default_action = {LLDB_INVALID_THREAD_ID, action, signal};
102 m_actions.push_back(default_action);
103 m_signal_handled.push_back(false);
104 return true; // Return true as we did add the default action
109 void SetSignalHandledForThread(lldb::tid_t tid) const {
110 if (tid != LLDB_INVALID_THREAD_ID) {
111 const size_t num_actions = m_actions.size();
112 for (size_t i = 0; i < num_actions; ++i) {
113 if (m_actions[i].tid == tid)
114 m_signal_handled[i] = true;
119 const ResumeAction *GetFirst() const { return m_actions.data(); }
121 size_t GetSize() const { return m_actions.size(); }
125 m_signal_handled.clear();
129 std::vector<ResumeAction> m_actions;
130 mutable std::vector<bool> m_signal_handled;
133 struct ThreadStopInfo {
134 lldb::StopReason reason;
141 // eStopReasonException
145 lldb::addr_t data[8];
151 #endif // liblldb_Debug_h_