blob: 9d48e8188d4a9b2310d263045d0a0363a8fbfe4b [file] [log] [blame]
Greg Clayton643ee732010-08-04 01:40:35 +00001//===-- StopInfo.cpp ---------------------------------------------*- 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#include "lldb/Target/StopInfo.h"
11
12// C Includes
13// C++ Includes
14#include <string>
15
16// Other libraries and framework includes
17// Project includes
18#include "lldb/Core/Log.h"
19#include "lldb/Breakpoint/BreakpointLocation.h"
20#include "lldb/Breakpoint/StoppointCallbackContext.h"
21#include "lldb/Core/StreamString.h"
22#include "lldb/Target/Thread.h"
23#include "lldb/Target/ThreadPlan.h"
24#include "lldb/Target/Process.h"
25#include "lldb/Target/UnixSignals.h"
26
27using namespace lldb;
28using namespace lldb_private;
29
30StopInfo::StopInfo (Thread &thread, uint64_t value) :
31 m_thread (thread),
32 m_stop_id (thread.GetProcess().GetStopID()),
33 m_value (value)
34{
35}
36
37bool
38StopInfo::IsValid () const
39{
40 return m_thread.GetProcess().GetStopID() == m_stop_id;
41}
42
43//----------------------------------------------------------------------
44// StopInfoBreakpoint
45//----------------------------------------------------------------------
46
47class StopInfoBreakpoint : public StopInfo
48{
49public:
50
51 StopInfoBreakpoint (Thread &thread, break_id_t break_id) :
52 StopInfo (thread, break_id),
53 m_description(),
54 m_should_stop (false),
55 m_should_stop_is_valid (false)
56 {
57 }
58
59 virtual ~StopInfoBreakpoint ()
60 {
61 }
62
63 virtual StopReason
64 GetStopReason () const
65 {
66 return eStopReasonBreakpoint;
67 }
68
69 virtual bool
70 ShouldStop (Event *event_ptr)
71 {
72 if (!m_should_stop_is_valid)
73 {
74 // Only check once if we should stop at a breakpoint
75 BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (m_value));
76 if (bp_site_sp)
77 {
78 StoppointCallbackContext context (event_ptr,
79 &m_thread.GetProcess(),
80 &m_thread,
81 m_thread.GetStackFrameAtIndex(0).get(),
82 false);
83
84 m_should_stop = bp_site_sp->ShouldStop (&context);
85 }
86 else
87 {
88 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
89
90 if (log)
91 log->Printf ("Process::%s could not find breakpoint site id: %lld...", __FUNCTION__, m_value);
92
93 m_should_stop = true;
94 }
95 m_should_stop_is_valid = true;
96 }
97 return m_should_stop;
98 }
99
100 virtual bool
101 ShouldNotify (Event *event_ptr)
102 {
103 BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (m_value));
104 if (bp_site_sp)
105 {
106 bool all_internal = true;
107
108 for (uint32_t i = 0; i < bp_site_sp->GetNumberOfOwners(); i++)
109 {
110 if (!bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().IsInternal())
111 {
112 all_internal = false;
113 break;
114 }
115 }
116 return all_internal == false;
117 }
118 return true;
119 }
120
121 virtual const char *
122 GetDescription ()
123 {
124 if (m_description.empty())
125 {
126 StreamString strm;
127 strm.Printf("breakpoint %lli", m_value);
128 m_description.swap (strm.GetString());
129 }
130 return m_description.c_str();
131 }
132
133private:
134 std::string m_description;
135 bool m_should_stop;
136 bool m_should_stop_is_valid;
137};
138
139
140//----------------------------------------------------------------------
141// StopInfoWatchpoint
142//----------------------------------------------------------------------
143
144class StopInfoWatchpoint : public StopInfo
145{
146public:
147
148 StopInfoWatchpoint (Thread &thread, break_id_t watch_id) :
149 StopInfo (thread, watch_id),
150 m_description()
151 {
152 }
153
154 virtual ~StopInfoWatchpoint ()
155 {
156 }
157
158 virtual StopReason
159 GetStopReason () const
160 {
161 return eStopReasonWatchpoint;
162 }
163
164 virtual const char *
165 GetDescription ()
166 {
167 if (m_description.empty())
168 {
169 StreamString strm;
170 strm.Printf("watchpoint %lli", m_value);
171 m_description.swap (strm.GetString());
172 }
173 return m_description.c_str();
174 }
175
176
177
178private:
179 std::string m_description;
180};
181
182
183
184//----------------------------------------------------------------------
185// StopInfoUnixSignal
186//----------------------------------------------------------------------
187
188class StopInfoUnixSignal : public StopInfo
189{
190public:
191
192 StopInfoUnixSignal (Thread &thread, int signo) :
193 StopInfo (thread, signo),
194 m_description()
195 {
196 }
197
198 virtual ~StopInfoUnixSignal ()
199 {
200 }
201
202
203 virtual StopReason
204 GetStopReason () const
205 {
206 return eStopReasonSignal;
207 }
208
209 virtual bool
210 ShouldStop (Event *event_ptr)
211 {
212 return m_thread.GetProcess().GetUnixSignals().GetShouldStop (m_value);
213 }
214
215
216 // If should stop returns false, check if we should notify of this event
217 virtual bool
218 ShouldNotify (Event *event_ptr)
219 {
220 return m_thread.GetProcess().GetUnixSignals().GetShouldNotify (m_value);
221 }
222
223
224 virtual void
225 WillResume (lldb::StateType resume_state)
226 {
227 if (m_thread.GetProcess().GetUnixSignals().GetShouldSuppress(m_value) == false)
228 m_thread.SetResumeSignal(m_value);
229 }
230
231 virtual const char *
232 GetDescription ()
233 {
234 if (m_description.empty())
235 {
236 StreamString strm;
237 const char *signal_name = m_thread.GetProcess().GetUnixSignals().GetSignalAsCString (m_value);
238 if (signal_name)
239 strm.Printf("signal = %s", signal_name);
240 else
241 strm.Printf("signal = %lli", m_value);
242 m_description.swap (strm.GetString());
243 }
244 return m_description.c_str();
245 }
246
247private:
248 std::string m_description;
249};
250
251//----------------------------------------------------------------------
252// StopInfoTrace
253//----------------------------------------------------------------------
254
255class StopInfoTrace : public StopInfo
256{
257public:
258
259 StopInfoTrace (Thread &thread) :
260 StopInfo (thread, LLDB_INVALID_UID)
261 {
262 }
263
264 virtual ~StopInfoTrace ()
265 {
266 }
267
268 virtual StopReason
269 GetStopReason () const
270 {
271 return eStopReasonTrace;
272 }
273
274 virtual const char *
275 GetDescription ()
276 {
277 return "trace";
278 }
279};
280
281
282//----------------------------------------------------------------------
283// StopInfoThreadPlan
284//----------------------------------------------------------------------
285
286class StopInfoThreadPlan : public StopInfo
287{
288public:
289
290 StopInfoThreadPlan (ThreadPlanSP &plan_sp) :
291 StopInfo (plan_sp->GetThread(), LLDB_INVALID_UID),
292 m_plan_sp (plan_sp)
293 {
294 }
295
296 virtual ~StopInfoThreadPlan ()
297 {
298 }
299
300 virtual StopReason
301 GetStopReason () const
302 {
303 return eStopReasonPlanComplete;
304 }
305
306 virtual const char *
307 GetDescription ()
308 {
309 if (m_description.empty())
310 {
311 StreamString strm;
312 m_plan_sp->GetDescription (&strm, eDescriptionLevelBrief);
313 m_description.swap (strm.GetString());
314 }
315 return m_description.c_str();
316 }
317
318private:
319 ThreadPlanSP m_plan_sp;
320 std::string m_description;
321};
322
323StopInfoSP
324StopInfo::CreateStopReasonWithBreakpointSiteID (Thread &thread, break_id_t break_id)
325{
326 return StopInfoSP (new StopInfoBreakpoint (thread, break_id));
327}
328
329StopInfoSP
330StopInfo::CreateStopReasonWithWatchpointID (Thread &thread, break_id_t watch_id)
331{
332 return StopInfoSP (new StopInfoWatchpoint (thread, watch_id));
333}
334
335StopInfoSP
336StopInfo::CreateStopReasonWithSignal (Thread &thread, int signo)
337{
338 return StopInfoSP (new StopInfoUnixSignal (thread, signo));
339}
340
341StopInfoSP
342StopInfo::CreateStopReasonToTrace (Thread &thread)
343{
344 return StopInfoSP (new StopInfoTrace (thread));
345}
346
347StopInfoSP
348StopInfo::CreateStopReasonWithPlan (ThreadPlanSP &plan_sp)
349{
350 return StopInfoSP (new StopInfoThreadPlan (plan_sp));
351}