1//===-- 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 LLDB_HOST_DEBUG_H
10#define LLDB_HOST_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() = default;
36
37 ResumeActionList(lldb::StateType default_action, int signal) {
38 SetDefaultThreadActionIfNeeded(action: default_action, signal);
39 }
40
41 ResumeActionList(const ResumeAction *actions, size_t num_actions) {
42 if (actions && num_actions) {
43 m_actions.assign(first: actions, last: actions + num_actions);
44 m_signal_handled.assign(n: num_actions, x: false);
45 }
46 }
47
48 ~ResumeActionList() = default;
49
50 bool IsEmpty() const { return m_actions.empty(); }
51
52 void Append(const ResumeAction &action) {
53 m_actions.push_back(x: action);
54 m_signal_handled.push_back(x: false);
55 }
56
57 void AppendAction(lldb::tid_t tid, lldb::StateType state, int signal = 0) {
58 ResumeAction action = {.tid: tid, .state: state, .signal: signal};
59 Append(action);
60 }
61
62 void AppendResumeAll() {
63 AppendAction(LLDB_INVALID_THREAD_ID, state: lldb::eStateRunning);
64 }
65
66 void AppendSuspendAll() {
67 AppendAction(LLDB_INVALID_THREAD_ID, state: lldb::eStateStopped);
68 }
69
70 void AppendStepAll() {
71 AppendAction(LLDB_INVALID_THREAD_ID, state: lldb::eStateStepping);
72 }
73
74 const ResumeAction *GetActionForThread(lldb::tid_t tid,
75 bool default_ok) const {
76 const size_t num_actions = m_actions.size();
77 for (size_t i = 0; i < num_actions; ++i) {
78 if (m_actions[i].tid == tid)
79 return &m_actions[i];
80 }
81 if (default_ok && tid != LLDB_INVALID_THREAD_ID)
82 return GetActionForThread(LLDB_INVALID_THREAD_ID, default_ok: false);
83 return nullptr;
84 }
85
86 size_t NumActionsWithState(lldb::StateType state) const {
87 size_t count = 0;
88 const size_t num_actions = m_actions.size();
89 for (size_t i = 0; i < num_actions; ++i) {
90 if (m_actions[i].state == state)
91 ++count;
92 }
93 return count;
94 }
95
96 bool SetDefaultThreadActionIfNeeded(lldb::StateType action, int signal) {
97 if (GetActionForThread(LLDB_INVALID_THREAD_ID, default_ok: true) == nullptr) {
98 // There isn't a default action so we do need to set it.
99 ResumeAction default_action = {LLDB_INVALID_THREAD_ID, .state: action, .signal: signal};
100 m_actions.push_back(x: default_action);
101 m_signal_handled.push_back(x: false);
102 return true; // Return true as we did add the default action
103 }
104 return false;
105 }
106
107 void SetSignalHandledForThread(lldb::tid_t tid) const {
108 if (tid != LLDB_INVALID_THREAD_ID) {
109 const size_t num_actions = m_actions.size();
110 for (size_t i = 0; i < num_actions; ++i) {
111 if (m_actions[i].tid == tid)
112 m_signal_handled[i] = true;
113 }
114 }
115 }
116
117 const ResumeAction *GetFirst() const { return m_actions.data(); }
118
119 size_t GetSize() const { return m_actions.size(); }
120
121 void Clear() {
122 m_actions.clear();
123 m_signal_handled.clear();
124 }
125
126protected:
127 std::vector<ResumeAction> m_actions;
128 mutable std::vector<bool> m_signal_handled;
129};
130
131struct ThreadStopInfo {
132 lldb::StopReason reason;
133 uint32_t signo;
134 union {
135 // eStopReasonException
136 struct {
137 uint64_t type;
138 uint32_t data_count;
139 lldb::addr_t data[8];
140 } exception;
141
142 // eStopReasonFork / eStopReasonVFork
143 struct {
144 lldb::pid_t child_pid;
145 lldb::tid_t child_tid;
146 } fork;
147 } details;
148};
149}
150
151#endif // LLDB_HOST_DEBUG_H
152

source code of lldb/include/lldb/Host/Debug.h