StopInfo.h revision 321369
1//===-- StopInfo.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_StopInfo_h_
11#define liblldb_StopInfo_h_
12
13// C Includes
14// C++ Includes
15#include <string>
16
17// Other libraries and framework includes
18// Project includes
19#include "lldb/Target/Process.h"
20#include "lldb/Utility/StructuredData.h"
21#include "lldb/lldb-public.h"
22
23namespace lldb_private {
24
25class StopInfo {
26  friend class Process::ProcessEventData;
27  friend class ThreadPlanBase;
28
29public:
30  //------------------------------------------------------------------
31  // Constructors and Destructors
32  //------------------------------------------------------------------
33  StopInfo(Thread &thread, uint64_t value);
34
35  virtual ~StopInfo() {}
36
37  bool IsValid() const;
38
39  void SetThread(const lldb::ThreadSP &thread_sp) { m_thread_wp = thread_sp; }
40
41  lldb::ThreadSP GetThread() const { return m_thread_wp.lock(); }
42
43  // The value of the StopInfo depends on the StopReason.
44  // StopReason                  Meaning
45  // ----------------------------------------------
46  // eStopReasonBreakpoint       BreakpointSiteID
47  // eStopReasonSignal           Signal number
48  // eStopReasonWatchpoint       WatchpointLocationID
49  // eStopReasonPlanComplete     No significance
50
51  uint64_t GetValue() const { return m_value; }
52
53  virtual lldb::StopReason GetStopReason() const = 0;
54
55  // ShouldStopSynchronous will get called before any thread plans are
56  // consulted, and if it says we should
57  // resume the target, then we will just immediately resume.  This should not
58  // run any code in or resume the
59  // target.
60
61  virtual bool ShouldStopSynchronous(Event *event_ptr) { return true; }
62
63  void OverrideShouldNotify(bool override_value) {
64    m_override_should_notify = override_value ? eLazyBoolYes : eLazyBoolNo;
65  }
66
67  // If should stop returns false, check if we should notify of this event
68  virtual bool ShouldNotify(Event *event_ptr) {
69    if (m_override_should_notify == eLazyBoolCalculate)
70      return DoShouldNotify(event_ptr);
71    else
72      return m_override_should_notify == eLazyBoolYes;
73  }
74
75  virtual void WillResume(lldb::StateType resume_state) {
76    // By default, don't do anything
77  }
78
79  virtual const char *GetDescription() { return m_description.c_str(); }
80
81  virtual void SetDescription(const char *desc_cstr) {
82    if (desc_cstr && desc_cstr[0])
83      m_description.assign(desc_cstr);
84    else
85      m_description.clear();
86  }
87
88  virtual bool IsValidForOperatingSystemThread(Thread &thread) { return true; }
89
90  // Sometimes the thread plan logic will know that it wants a given stop to
91  // stop or not,
92  // regardless of what the ordinary logic for that StopInfo would dictate.  The
93  // main example
94  // of this is the ThreadPlanCallFunction, which for instance knows - based on
95  // how that particular
96  // expression was executed - whether it wants all breakpoints to auto-continue
97  // or not.
98  // Use OverrideShouldStop on the StopInfo to implement this.
99
100  void OverrideShouldStop(bool override_value) {
101    m_override_should_stop = override_value ? eLazyBoolYes : eLazyBoolNo;
102  }
103
104  bool GetOverrideShouldStop() {
105    return m_override_should_stop != eLazyBoolCalculate;
106  }
107
108  bool GetOverriddenShouldStopValue() {
109    return m_override_should_stop == eLazyBoolYes;
110  }
111
112  StructuredData::ObjectSP GetExtendedInfo() { return m_extended_info; }
113
114  static lldb::StopInfoSP
115  CreateStopReasonWithBreakpointSiteID(Thread &thread,
116                                       lldb::break_id_t break_id);
117
118  // This creates a StopInfo for the thread where the should_stop is already
119  // set, and won't be recalculated.
120  static lldb::StopInfoSP CreateStopReasonWithBreakpointSiteID(
121      Thread &thread, lldb::break_id_t break_id, bool should_stop);
122
123  static lldb::StopInfoSP CreateStopReasonWithWatchpointID(
124      Thread &thread, lldb::break_id_t watch_id,
125      lldb::addr_t watch_hit_addr = LLDB_INVALID_ADDRESS);
126
127  static lldb::StopInfoSP
128  CreateStopReasonWithSignal(Thread &thread, int signo,
129                             const char *description = nullptr);
130
131  static lldb::StopInfoSP CreateStopReasonToTrace(Thread &thread);
132
133  static lldb::StopInfoSP
134  CreateStopReasonWithPlan(lldb::ThreadPlanSP &plan,
135                           lldb::ValueObjectSP return_valobj_sp,
136                           lldb::ExpressionVariableSP expression_variable_sp);
137
138  static lldb::StopInfoSP
139  CreateStopReasonWithException(Thread &thread, const char *description);
140
141  static lldb::StopInfoSP CreateStopReasonWithExec(Thread &thread);
142
143  static lldb::ValueObjectSP
144  GetReturnValueObject(lldb::StopInfoSP &stop_info_sp);
145
146  static lldb::ExpressionVariableSP
147  GetExpressionVariable(lldb::StopInfoSP &stop_info_sp);
148
149  static lldb::ValueObjectSP
150  GetCrashingDereference(lldb::StopInfoSP &stop_info_sp,
151                         lldb::addr_t *crashing_address = nullptr);
152
153protected:
154  // Perform any action that is associated with this stop.  This is done as the
155  // Event is removed from the event queue.  ProcessEventData::DoOnRemoval does
156  // the job.
157
158  virtual void PerformAction(Event *event_ptr) {}
159
160  virtual bool DoShouldNotify(Event *event_ptr) { return false; }
161
162  // Stop the thread by default. Subclasses can override this to allow
163  // the thread to continue if desired.  The ShouldStop method should not do
164  // anything
165  // that might run code.  If you need to run code when deciding whether to stop
166  // at this StopInfo, that must be done in the PerformAction.
167  // The PerformAction will always get called before the ShouldStop.  This is
168  // done by the
169  // ProcessEventData::DoOnRemoval, though the ThreadPlanBase needs to consult
170  // this later on.
171  virtual bool ShouldStop(Event *event_ptr) { return true; }
172
173  //------------------------------------------------------------------
174  // Classes that inherit from StackID can see and modify these
175  //------------------------------------------------------------------
176  lldb::ThreadWP m_thread_wp; // The thread corresponding to the stop reason.
177  uint32_t m_stop_id;   // The process stop ID for which this stop info is valid
178  uint32_t m_resume_id; // This is the resume ID when we made this stop ID.
179  uint64_t m_value; // A generic value that can be used for things pertaining to
180                    // this stop info
181  std::string m_description; // A textual description describing this stop.
182  LazyBool m_override_should_notify;
183  LazyBool m_override_should_stop;
184
185  StructuredData::ObjectSP
186      m_extended_info; // The extended info for this stop info
187
188  // This determines whether the target has run since this stop info.
189  // N.B. running to evaluate a user expression does not count.
190  bool HasTargetRunSinceMe();
191
192  // MakeStopInfoValid is necessary to allow saved stop infos to resurrect
193  // themselves as valid.
194  // It should only be used by Thread::RestoreThreadStateFromCheckpoint and to
195  // make sure the one-step
196  // needed for before-the-fact watchpoints does not prevent us from stopping
197  void MakeStopInfoValid();
198
199private:
200  friend class Thread;
201
202  DISALLOW_COPY_AND_ASSIGN(StopInfo);
203};
204
205} // namespace lldb_private
206
207#endif // liblldb_StopInfo_h_
208