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