blob: 036ce1ebccd59049dee64d2216201ee8077f2a58 [file] [log] [blame]
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001//===-- Debug.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 liblldb_Debug_h_
10#define liblldb_Debug_h_
11
12#include <vector>
13
14#include "lldb/lldb-private.h"
15
16namespace lldb_private {
17
18// Tells a thread what it needs to do when the process is resumed.
19struct ResumeAction {
20 lldb::tid_t tid; // The thread ID that this action applies to,
21 // LLDB_INVALID_THREAD_ID for the default thread
22 // action
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
26 // value is > 0
27};
28
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.
33class ResumeActionList {
34public:
35 ResumeActionList() : m_actions(), m_signal_handled() {}
36
37 ResumeActionList(lldb::StateType default_action, int signal)
38 : m_actions(), m_signal_handled() {
39 SetDefaultThreadActionIfNeeded(default_action, signal);
40 }
41
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);
47 }
48 }
49
50 ~ResumeActionList() = default;
51
52 bool IsEmpty() const { return m_actions.empty(); }
53
54 void Append(const ResumeAction &action) {
55 m_actions.push_back(action);
56 m_signal_handled.push_back(false);
57 }
58
59 void AppendAction(lldb::tid_t tid, lldb::StateType state, int signal = 0) {
60 ResumeAction action = {tid, state, signal};
61 Append(action);
62 }
63
64 void AppendResumeAll() {
65 AppendAction(LLDB_INVALID_THREAD_ID, lldb::eStateRunning);
66 }
67
68 void AppendSuspendAll() {
69 AppendAction(LLDB_INVALID_THREAD_ID, lldb::eStateStopped);
70 }
71
72 void AppendStepAll() {
73 AppendAction(LLDB_INVALID_THREAD_ID, lldb::eStateStepping);
74 }
75
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)
81 return &m_actions[i];
82 }
83 if (default_ok && tid != LLDB_INVALID_THREAD_ID)
84 return GetActionForThread(LLDB_INVALID_THREAD_ID, false);
85 return nullptr;
86 }
87
88 size_t NumActionsWithState(lldb::StateType state) const {
89 size_t count = 0;
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)
93 ++count;
94 }
95 return count;
96 }
97
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
105 }
106 return false;
107 }
108
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;
115 }
116 }
117 }
118
119 const ResumeAction *GetFirst() const { return m_actions.data(); }
120
121 size_t GetSize() const { return m_actions.size(); }
122
123 void Clear() {
124 m_actions.clear();
125 m_signal_handled.clear();
126 }
127
128protected:
129 std::vector<ResumeAction> m_actions;
130 mutable std::vector<bool> m_signal_handled;
131};
132
133struct ThreadStopInfo {
134 lldb::StopReason reason;
135 union {
136 // eStopReasonSignal
137 struct {
138 uint32_t signo;
139 } signal;
140
141 // eStopReasonException
142 struct {
143 uint64_t type;
144 uint32_t data_count;
145 lldb::addr_t data[8];
146 } exception;
147 } details;
148};
149}
150
151#endif // liblldb_Debug_h_