blob: 05d7f3bad4f7df8b03defe257a58e8748038a238 [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"
Greg Clayton640dc6b2010-11-18 18:52:36 +000019#include "lldb/Breakpoint/Breakpoint.h"
Greg Clayton643ee732010-08-04 01:40:35 +000020#include "lldb/Breakpoint/BreakpointLocation.h"
21#include "lldb/Breakpoint/StoppointCallbackContext.h"
22#include "lldb/Core/StreamString.h"
23#include "lldb/Target/Thread.h"
24#include "lldb/Target/ThreadPlan.h"
25#include "lldb/Target/Process.h"
26#include "lldb/Target/UnixSignals.h"
27
28using namespace lldb;
29using namespace lldb_private;
30
31StopInfo::StopInfo (Thread &thread, uint64_t value) :
32 m_thread (thread),
33 m_stop_id (thread.GetProcess().GetStopID()),
34 m_value (value)
35{
36}
37
38bool
39StopInfo::IsValid () const
40{
41 return m_thread.GetProcess().GetStopID() == m_stop_id;
42}
43
Jim Ingham15dcb7c2011-01-20 02:03:18 +000044void
45StopInfo::MakeStopInfoValid ()
46{
47 m_stop_id = m_thread.GetProcess().GetStopID();
48}
49
Greg Clayton643ee732010-08-04 01:40:35 +000050//----------------------------------------------------------------------
51// StopInfoBreakpoint
52//----------------------------------------------------------------------
53
54class StopInfoBreakpoint : public StopInfo
55{
56public:
57
58 StopInfoBreakpoint (Thread &thread, break_id_t break_id) :
59 StopInfo (thread, break_id),
60 m_description(),
61 m_should_stop (false),
62 m_should_stop_is_valid (false)
63 {
64 }
65
Jim Inghamd1686902010-10-14 23:45:03 +000066 StopInfoBreakpoint (Thread &thread, break_id_t break_id, bool should_stop) :
67 StopInfo (thread, break_id),
68 m_description(),
69 m_should_stop (should_stop),
70 m_should_stop_is_valid (true)
71 {
72 }
73
Greg Clayton643ee732010-08-04 01:40:35 +000074 virtual ~StopInfoBreakpoint ()
75 {
76 }
77
78 virtual StopReason
79 GetStopReason () const
80 {
81 return eStopReasonBreakpoint;
82 }
83
84 virtual bool
85 ShouldStop (Event *event_ptr)
86 {
87 if (!m_should_stop_is_valid)
88 {
89 // Only check once if we should stop at a breakpoint
90 BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (m_value));
91 if (bp_site_sp)
92 {
93 StoppointCallbackContext context (event_ptr,
94 &m_thread.GetProcess(),
95 &m_thread,
96 m_thread.GetStackFrameAtIndex(0).get(),
Jim Ingham7508e732010-08-09 23:31:02 +000097 true);
Greg Clayton643ee732010-08-04 01:40:35 +000098
99 m_should_stop = bp_site_sp->ShouldStop (&context);
100 }
101 else
102 {
Greg Claytone005f2c2010-11-06 01:53:30 +0000103 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
Greg Clayton643ee732010-08-04 01:40:35 +0000104
105 if (log)
106 log->Printf ("Process::%s could not find breakpoint site id: %lld...", __FUNCTION__, m_value);
107
108 m_should_stop = true;
109 }
110 m_should_stop_is_valid = true;
111 }
112 return m_should_stop;
113 }
Jim Ingham6fb8baa2010-08-10 00:59:59 +0000114
115 virtual void
116 PerformAction (Event *event_ptr)
117 {
118 BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (m_value));
119 if (bp_site_sp)
120 {
121 size_t num_owners = bp_site_sp->GetNumberOfOwners();
122 for (size_t j = 0; j < num_owners; j++)
123 {
124 // The breakpoint action is an asynchronous breakpoint callback. If we ever need to have both
125 // callbacks and actions on the same breakpoint, we'll have to split this into two.
126 lldb::BreakpointLocationSP bp_loc_sp = bp_site_sp->GetOwnerAtIndex(j);
127 StoppointCallbackContext context (event_ptr,
128 &m_thread.GetProcess(),
129 &m_thread,
130 m_thread.GetStackFrameAtIndex(0).get(),
131 false);
132 bp_loc_sp->InvokeCallback (&context);
133 }
134 }
135 else
136 {
Greg Claytone005f2c2010-11-06 01:53:30 +0000137 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
Jim Ingham6fb8baa2010-08-10 00:59:59 +0000138
139 if (log)
140 log->Printf ("Process::%s could not find breakpoint site id: %lld...", __FUNCTION__, m_value);
141 }
142 }
Greg Clayton643ee732010-08-04 01:40:35 +0000143
144 virtual bool
145 ShouldNotify (Event *event_ptr)
146 {
147 BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (m_value));
148 if (bp_site_sp)
149 {
150 bool all_internal = true;
151
152 for (uint32_t i = 0; i < bp_site_sp->GetNumberOfOwners(); i++)
153 {
154 if (!bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().IsInternal())
155 {
156 all_internal = false;
157 break;
158 }
159 }
160 return all_internal == false;
161 }
162 return true;
163 }
164
165 virtual const char *
166 GetDescription ()
167 {
168 if (m_description.empty())
169 {
Jim Ingham6fb8baa2010-08-10 00:59:59 +0000170 BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (m_value));
171 if (bp_site_sp)
172 {
173 StreamString strm;
174 strm.Printf("breakpoint ");
175 bp_site_sp->GetDescription(&strm, eDescriptionLevelBrief);
176 m_description.swap (strm.GetString());
177 }
178 else
179 {
180 StreamString strm;
181 strm.Printf("breakpoint site %lli", m_value);
182 m_description.swap (strm.GetString());
183 }
Greg Clayton643ee732010-08-04 01:40:35 +0000184 }
185 return m_description.c_str();
186 }
187
188private:
189 std::string m_description;
190 bool m_should_stop;
191 bool m_should_stop_is_valid;
192};
193
194
195//----------------------------------------------------------------------
196// StopInfoWatchpoint
197//----------------------------------------------------------------------
198
199class StopInfoWatchpoint : public StopInfo
200{
201public:
202
203 StopInfoWatchpoint (Thread &thread, break_id_t watch_id) :
204 StopInfo (thread, watch_id),
205 m_description()
206 {
207 }
208
209 virtual ~StopInfoWatchpoint ()
210 {
211 }
212
213 virtual StopReason
214 GetStopReason () const
215 {
216 return eStopReasonWatchpoint;
217 }
218
219 virtual const char *
220 GetDescription ()
221 {
222 if (m_description.empty())
223 {
224 StreamString strm;
225 strm.Printf("watchpoint %lli", m_value);
226 m_description.swap (strm.GetString());
227 }
228 return m_description.c_str();
229 }
230
231
232
233private:
234 std::string m_description;
235};
236
237
238
239//----------------------------------------------------------------------
240// StopInfoUnixSignal
241//----------------------------------------------------------------------
242
243class StopInfoUnixSignal : public StopInfo
244{
245public:
246
247 StopInfoUnixSignal (Thread &thread, int signo) :
248 StopInfo (thread, signo),
249 m_description()
250 {
251 }
252
253 virtual ~StopInfoUnixSignal ()
254 {
255 }
256
257
258 virtual StopReason
259 GetStopReason () const
260 {
261 return eStopReasonSignal;
262 }
263
264 virtual bool
265 ShouldStop (Event *event_ptr)
266 {
267 return m_thread.GetProcess().GetUnixSignals().GetShouldStop (m_value);
268 }
269
270
271 // If should stop returns false, check if we should notify of this event
272 virtual bool
273 ShouldNotify (Event *event_ptr)
274 {
275 return m_thread.GetProcess().GetUnixSignals().GetShouldNotify (m_value);
276 }
277
278
279 virtual void
280 WillResume (lldb::StateType resume_state)
281 {
282 if (m_thread.GetProcess().GetUnixSignals().GetShouldSuppress(m_value) == false)
283 m_thread.SetResumeSignal(m_value);
284 }
285
286 virtual const char *
287 GetDescription ()
288 {
289 if (m_description.empty())
290 {
291 StreamString strm;
292 const char *signal_name = m_thread.GetProcess().GetUnixSignals().GetSignalAsCString (m_value);
293 if (signal_name)
Greg Claytona830adb2010-10-04 01:05:56 +0000294 strm.Printf("signal %s", signal_name);
Greg Clayton643ee732010-08-04 01:40:35 +0000295 else
Greg Claytona830adb2010-10-04 01:05:56 +0000296 strm.Printf("signal %lli", m_value);
Greg Clayton643ee732010-08-04 01:40:35 +0000297 m_description.swap (strm.GetString());
298 }
299 return m_description.c_str();
300 }
301
302private:
303 std::string m_description;
304};
305
306//----------------------------------------------------------------------
307// StopInfoTrace
308//----------------------------------------------------------------------
309
310class StopInfoTrace : public StopInfo
311{
312public:
313
314 StopInfoTrace (Thread &thread) :
315 StopInfo (thread, LLDB_INVALID_UID)
316 {
317 }
318
319 virtual ~StopInfoTrace ()
320 {
321 }
322
323 virtual StopReason
324 GetStopReason () const
325 {
326 return eStopReasonTrace;
327 }
328
329 virtual const char *
330 GetDescription ()
331 {
332 return "trace";
333 }
334};
335
336
337//----------------------------------------------------------------------
338// StopInfoThreadPlan
339//----------------------------------------------------------------------
340
341class StopInfoThreadPlan : public StopInfo
342{
343public:
344
345 StopInfoThreadPlan (ThreadPlanSP &plan_sp) :
346 StopInfo (plan_sp->GetThread(), LLDB_INVALID_UID),
347 m_plan_sp (plan_sp)
348 {
349 }
350
351 virtual ~StopInfoThreadPlan ()
352 {
353 }
354
355 virtual StopReason
356 GetStopReason () const
357 {
358 return eStopReasonPlanComplete;
359 }
360
361 virtual const char *
362 GetDescription ()
363 {
364 if (m_description.empty())
365 {
366 StreamString strm;
367 m_plan_sp->GetDescription (&strm, eDescriptionLevelBrief);
368 m_description.swap (strm.GetString());
369 }
370 return m_description.c_str();
371 }
372
373private:
374 ThreadPlanSP m_plan_sp;
375 std::string m_description;
376};
377
378StopInfoSP
379StopInfo::CreateStopReasonWithBreakpointSiteID (Thread &thread, break_id_t break_id)
380{
381 return StopInfoSP (new StopInfoBreakpoint (thread, break_id));
382}
383
384StopInfoSP
Jim Inghamd1686902010-10-14 23:45:03 +0000385StopInfo::CreateStopReasonWithBreakpointSiteID (Thread &thread, break_id_t break_id, bool should_stop)
386{
387 return StopInfoSP (new StopInfoBreakpoint (thread, break_id, should_stop));
388}
389
390StopInfoSP
Greg Clayton643ee732010-08-04 01:40:35 +0000391StopInfo::CreateStopReasonWithWatchpointID (Thread &thread, break_id_t watch_id)
392{
393 return StopInfoSP (new StopInfoWatchpoint (thread, watch_id));
394}
395
396StopInfoSP
397StopInfo::CreateStopReasonWithSignal (Thread &thread, int signo)
398{
399 return StopInfoSP (new StopInfoUnixSignal (thread, signo));
400}
401
402StopInfoSP
403StopInfo::CreateStopReasonToTrace (Thread &thread)
404{
405 return StopInfoSP (new StopInfoTrace (thread));
406}
407
408StopInfoSP
409StopInfo::CreateStopReasonWithPlan (ThreadPlanSP &plan_sp)
410{
411 return StopInfoSP (new StopInfoThreadPlan (plan_sp));
412}