blob: cfd340afa4fa3fabe899e65927693577f69fb478 [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"
Johnny Chenecd4feb2011-10-14 00:42:25 +000022#include "lldb/Breakpoint/Watchpoint.h"
Jim Ingham21f37ad2011-08-09 02:12:22 +000023#include "lldb/Core/Debugger.h"
Greg Clayton643ee732010-08-04 01:40:35 +000024#include "lldb/Core/StreamString.h"
Jim Ingham21f37ad2011-08-09 02:12:22 +000025#include "lldb/Expression/ClangUserExpression.h"
26#include "lldb/Target/Target.h"
Greg Clayton643ee732010-08-04 01:40:35 +000027#include "lldb/Target/Thread.h"
28#include "lldb/Target/ThreadPlan.h"
29#include "lldb/Target/Process.h"
30#include "lldb/Target/UnixSignals.h"
31
32using namespace lldb;
33using namespace lldb_private;
34
35StopInfo::StopInfo (Thread &thread, uint64_t value) :
36 m_thread (thread),
37 m_stop_id (thread.GetProcess().GetStopID()),
38 m_value (value)
39{
40}
41
42bool
43StopInfo::IsValid () const
44{
45 return m_thread.GetProcess().GetStopID() == m_stop_id;
46}
47
Jim Ingham15dcb7c2011-01-20 02:03:18 +000048void
49StopInfo::MakeStopInfoValid ()
50{
51 m_stop_id = m_thread.GetProcess().GetStopID();
52}
53
Jim Ingham21f37ad2011-08-09 02:12:22 +000054lldb::StateType
55StopInfo::GetPrivateState ()
56{
57 return m_thread.GetProcess().GetPrivateState();
58}
59
Greg Clayton643ee732010-08-04 01:40:35 +000060//----------------------------------------------------------------------
61// StopInfoBreakpoint
62//----------------------------------------------------------------------
63
Jim Ingham21f37ad2011-08-09 02:12:22 +000064namespace lldb_private
65{
Greg Clayton643ee732010-08-04 01:40:35 +000066class StopInfoBreakpoint : public StopInfo
67{
68public:
69
70 StopInfoBreakpoint (Thread &thread, break_id_t break_id) :
71 StopInfo (thread, break_id),
72 m_description(),
73 m_should_stop (false),
Jim Inghamf9f40c22011-02-08 05:20:59 +000074 m_should_stop_is_valid (false),
Jim Ingham1c658532011-10-28 01:12:19 +000075 m_should_perform_action (true),
76 m_address (LLDB_INVALID_ADDRESS)
Greg Clayton643ee732010-08-04 01:40:35 +000077 {
Jim Ingham1c658532011-10-28 01:12:19 +000078 BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (m_value));
79 if (bp_site_sp)
80 {
81 m_address = bp_site_sp->GetLoadAddress();
82 }
Greg Clayton643ee732010-08-04 01:40:35 +000083 }
84
Jim Inghamd1686902010-10-14 23:45:03 +000085 StopInfoBreakpoint (Thread &thread, break_id_t break_id, bool should_stop) :
86 StopInfo (thread, break_id),
87 m_description(),
88 m_should_stop (should_stop),
Jim Inghamf9f40c22011-02-08 05:20:59 +000089 m_should_stop_is_valid (true),
Jim Ingham1c658532011-10-28 01:12:19 +000090 m_should_perform_action (true),
91 m_address (LLDB_INVALID_ADDRESS)
Jim Inghamd1686902010-10-14 23:45:03 +000092 {
Jim Ingham1c658532011-10-28 01:12:19 +000093 BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (m_value));
94 if (bp_site_sp)
95 {
96 m_address = bp_site_sp->GetLoadAddress();
97 }
Jim Inghamd1686902010-10-14 23:45:03 +000098 }
99
Greg Clayton643ee732010-08-04 01:40:35 +0000100 virtual ~StopInfoBreakpoint ()
101 {
102 }
103
104 virtual StopReason
105 GetStopReason () const
106 {
107 return eStopReasonBreakpoint;
108 }
109
110 virtual bool
111 ShouldStop (Event *event_ptr)
112 {
113 if (!m_should_stop_is_valid)
114 {
115 // Only check once if we should stop at a breakpoint
116 BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (m_value));
117 if (bp_site_sp)
118 {
119 StoppointCallbackContext context (event_ptr,
120 &m_thread.GetProcess(),
121 &m_thread,
122 m_thread.GetStackFrameAtIndex(0).get(),
Jim Ingham7508e732010-08-09 23:31:02 +0000123 true);
Greg Clayton643ee732010-08-04 01:40:35 +0000124
125 m_should_stop = bp_site_sp->ShouldStop (&context);
126 }
127 else
128 {
Greg Claytone005f2c2010-11-06 01:53:30 +0000129 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
Greg Clayton643ee732010-08-04 01:40:35 +0000130
131 if (log)
132 log->Printf ("Process::%s could not find breakpoint site id: %lld...", __FUNCTION__, m_value);
133
134 m_should_stop = true;
135 }
136 m_should_stop_is_valid = true;
137 }
138 return m_should_stop;
139 }
Jim Ingham6fb8baa2010-08-10 00:59:59 +0000140
141 virtual void
142 PerformAction (Event *event_ptr)
143 {
Jim Inghamf9f40c22011-02-08 05:20:59 +0000144 if (!m_should_perform_action)
145 return;
146 m_should_perform_action = false;
147
Jim Ingham21f37ad2011-08-09 02:12:22 +0000148 LogSP log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
149 // We're going to calculate whether we should stop or not in some way during the course of
150 // this code. So set the valid flag here. Also by default we're going to stop, so
151 // set that here too.
152 // m_should_stop_is_valid = true;
153 m_should_stop = true;
154
Jim Ingham6fb8baa2010-08-10 00:59:59 +0000155 BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (m_value));
156 if (bp_site_sp)
157 {
158 size_t num_owners = bp_site_sp->GetNumberOfOwners();
Jim Ingham21f37ad2011-08-09 02:12:22 +0000159
160 // We only continue from the callbacks if ALL the callbacks want us to continue.
161 // However we want to run all the callbacks, except of course if one of them actually
162 // resumes the target.
163 // So we use stop_requested to track what we're were asked to do.
164 bool stop_requested = true;
Jim Ingham6fb8baa2010-08-10 00:59:59 +0000165 for (size_t j = 0; j < num_owners; j++)
166 {
Jim Ingham6fb8baa2010-08-10 00:59:59 +0000167 lldb::BreakpointLocationSP bp_loc_sp = bp_site_sp->GetOwnerAtIndex(j);
168 StoppointCallbackContext context (event_ptr,
169 &m_thread.GetProcess(),
170 &m_thread,
171 m_thread.GetStackFrameAtIndex(0).get(),
172 false);
Jim Ingham21f37ad2011-08-09 02:12:22 +0000173 stop_requested = bp_loc_sp->InvokeCallback (&context);
174 // Also make sure that the callback hasn't continued the target.
175 // If it did, when we'll set m_should_start to false and get out of here.
176 if (GetPrivateState() == eStateRunning)
177 m_should_stop = false;
178 }
179
180 if (m_should_stop && !stop_requested)
181 {
182 m_should_stop_is_valid = true;
183 m_should_stop = false;
184 }
185
186 // Okay, so now if all the callbacks say we should stop, let's try the Conditions:
187 if (m_should_stop)
188 {
189 size_t num_owners = bp_site_sp->GetNumberOfOwners();
190 for (size_t j = 0; j < num_owners; j++)
191 {
192 lldb::BreakpointLocationSP bp_loc_sp = bp_site_sp->GetOwnerAtIndex(j);
193 if (bp_loc_sp->GetConditionText() != NULL)
194 {
195 // We need to make sure the user sees any parse errors in their condition, so we'll hook the
196 // constructor errors up to the debugger's Async I/O.
197
198 StoppointCallbackContext context (event_ptr,
199 &m_thread.GetProcess(),
200 &m_thread,
201 m_thread.GetStackFrameAtIndex(0).get(),
202 false);
203 ValueObjectSP result_valobj_sp;
204
205 ExecutionResults result_code;
206 ValueObjectSP result_value_sp;
207 const bool discard_on_error = true;
208 Error error;
209 result_code = ClangUserExpression::EvaluateWithError (context.exe_ctx,
Sean Callanan47dc4572011-09-15 02:13:07 +0000210 eExecutionPolicyAlways,
211 discard_on_error,
212 bp_loc_sp->GetConditionText(),
213 NULL,
214 result_value_sp,
215 error);
Jim Ingham21f37ad2011-08-09 02:12:22 +0000216 if (result_code == eExecutionCompleted)
217 {
218 if (result_value_sp)
219 {
220 Scalar scalar_value;
221 if (result_value_sp->ResolveValue (scalar_value))
222 {
223 if (scalar_value.ULongLong(1) == 0)
224 m_should_stop = false;
225 else
226 m_should_stop = true;
227 if (log)
228 log->Printf("Condition successfully evaluated, result is %s.\n",
229 m_should_stop ? "true" : "false");
230 }
231 else
232 {
233 m_should_stop = true;
234 if (log)
235 log->Printf("Failed to get an integer result from the expression.");
236 }
237 }
238 }
239 else
240 {
Greg Clayton567e7f32011-09-22 04:58:26 +0000241 Debugger &debugger = context.exe_ctx.GetTargetRef().GetDebugger();
Jim Ingham21f37ad2011-08-09 02:12:22 +0000242 StreamSP error_sp = debugger.GetAsyncErrorStream ();
243 error_sp->Printf ("Stopped due to an error evaluating condition of breakpoint ");
244 bp_loc_sp->GetDescription (error_sp.get(), eDescriptionLevelBrief);
245 error_sp->Printf (": \"%s\"",
246 bp_loc_sp->GetConditionText());
247 error_sp->EOL();
248 const char *err_str = error.AsCString("<Unknown Error>");
249 if (log)
250 log->Printf("Error evaluating condition: \"%s\"\n", err_str);
251
252 error_sp->PutCString (err_str);
253 error_sp->EOL();
254 error_sp->Flush();
255 // If the condition fails to be parsed or run, we should stop.
256 m_should_stop = true;
257 }
258 }
259
260 // If any condition says we should stop, then we're going to stop, so we don't need
261 // to evaluate the others.
262 if (m_should_stop)
263 break;
264 }
Jim Ingham6fb8baa2010-08-10 00:59:59 +0000265 }
266 }
267 else
268 {
Greg Claytone005f2c2010-11-06 01:53:30 +0000269 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
Jim Ingham6fb8baa2010-08-10 00:59:59 +0000270
271 if (log)
272 log->Printf ("Process::%s could not find breakpoint site id: %lld...", __FUNCTION__, m_value);
273 }
Jim Ingham21f37ad2011-08-09 02:12:22 +0000274 if (log)
275 log->Printf ("Process::%s returning from action with m_should_stop: %d.", __FUNCTION__, m_should_stop);
Jim Ingham6fb8baa2010-08-10 00:59:59 +0000276 }
Greg Clayton643ee732010-08-04 01:40:35 +0000277
278 virtual bool
279 ShouldNotify (Event *event_ptr)
280 {
281 BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (m_value));
282 if (bp_site_sp)
283 {
284 bool all_internal = true;
285
286 for (uint32_t i = 0; i < bp_site_sp->GetNumberOfOwners(); i++)
287 {
288 if (!bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().IsInternal())
289 {
290 all_internal = false;
291 break;
292 }
293 }
294 return all_internal == false;
295 }
296 return true;
297 }
298
299 virtual const char *
300 GetDescription ()
301 {
302 if (m_description.empty())
303 {
Jim Ingham6fb8baa2010-08-10 00:59:59 +0000304 BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (m_value));
305 if (bp_site_sp)
306 {
307 StreamString strm;
308 strm.Printf("breakpoint ");
309 bp_site_sp->GetDescription(&strm, eDescriptionLevelBrief);
310 m_description.swap (strm.GetString());
311 }
312 else
313 {
314 StreamString strm;
Jim Ingham1c658532011-10-28 01:12:19 +0000315 if (m_address == LLDB_INVALID_ADDRESS)
316 strm.Printf("breakpoint site %lli which has been deleted - unknown address", m_value);
317 else
318 strm.Printf("breakpoint site %lli which has been deleted - was at 0x%llx", m_value, m_address);
Jim Ingham6fb8baa2010-08-10 00:59:59 +0000319 m_description.swap (strm.GetString());
320 }
Greg Clayton643ee732010-08-04 01:40:35 +0000321 }
322 return m_description.c_str();
323 }
324
325private:
326 std::string m_description;
327 bool m_should_stop;
328 bool m_should_stop_is_valid;
Jim Inghamf9f40c22011-02-08 05:20:59 +0000329 bool m_should_perform_action; // Since we are trying to preserve the "state" of the system even if we run functions
330 // etc. behind the users backs, we need to make sure we only REALLY perform the action once.
Jim Ingham1c658532011-10-28 01:12:19 +0000331 lldb::addr_t m_address; // We use this to capture the breakpoint site address when we create the StopInfo,
332 // in case somebody deletes it between the time the StopInfo is made and the
333 // description is asked for.
Greg Clayton643ee732010-08-04 01:40:35 +0000334};
335
336
337//----------------------------------------------------------------------
338// StopInfoWatchpoint
339//----------------------------------------------------------------------
340
341class StopInfoWatchpoint : public StopInfo
342{
343public:
344
345 StopInfoWatchpoint (Thread &thread, break_id_t watch_id) :
Johnny Chen043f8c22011-09-21 22:47:15 +0000346 StopInfo(thread, watch_id),
347 m_description(),
348 m_should_stop(false),
349 m_should_stop_is_valid(false)
Greg Clayton643ee732010-08-04 01:40:35 +0000350 {
351 }
352
353 virtual ~StopInfoWatchpoint ()
354 {
355 }
356
357 virtual StopReason
358 GetStopReason () const
359 {
360 return eStopReasonWatchpoint;
361 }
362
Johnny Chen043f8c22011-09-21 22:47:15 +0000363 virtual bool
364 ShouldStop (Event *event_ptr)
365 {
366 // ShouldStop() method is idempotent and should not affect hit count.
Johnny Chen712a6282011-10-17 18:58:00 +0000367 // See Process::RunPrivateStateThread()->Process()->HandlePrivateEvent()
368 // -->Process()::ShouldBroadcastEvent()->ThreadList::ShouldStop()->
369 // Thread::ShouldStop()->ThreadPlanBase::ShouldStop()->
370 // StopInfoWatchpoint::ShouldStop() and
371 // Event::DoOnRemoval()->Process::ProcessEventData::DoOnRemoval()->
372 // StopInfoWatchpoint::PerformAction().
Johnny Chen043f8c22011-09-21 22:47:15 +0000373 if (m_should_stop_is_valid)
374 return m_should_stop;
375
Johnny Chenecd4feb2011-10-14 00:42:25 +0000376 WatchpointSP wp_sp =
377 m_thread.GetProcess().GetTarget().GetWatchpointList().FindByID(GetValue());
378 if (wp_sp)
Johnny Chen043f8c22011-09-21 22:47:15 +0000379 {
380 // Check if we should stop at a watchpoint.
381 StoppointCallbackContext context (event_ptr,
382 &m_thread.GetProcess(),
383 &m_thread,
384 m_thread.GetStackFrameAtIndex(0).get(),
385 true);
386
Johnny Chenecd4feb2011-10-14 00:42:25 +0000387 m_should_stop = wp_sp->ShouldStop (&context);
Johnny Chen043f8c22011-09-21 22:47:15 +0000388 }
389 else
390 {
391 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
392
393 if (log)
394 log->Printf ("Process::%s could not find watchpoint location id: %lld...",
395 __FUNCTION__, GetValue());
396
397 m_should_stop = true;
398 }
399 m_should_stop_is_valid = true;
400 return m_should_stop;
401 }
402
Johnny Chen712a6282011-10-17 18:58:00 +0000403 // Perform any action that is associated with this stop. This is done as the
404 // Event is removed from the event queue.
405 virtual void
406 PerformAction (Event *event_ptr)
407 {
408 LogSP log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
409 // We're going to calculate if we should stop or not in some way during the course of
410 // this code. Also by default we're going to stop, so set that here.
411 m_should_stop = true;
412
413 WatchpointSP wp_sp =
414 m_thread.GetProcess().GetTarget().GetWatchpointList().FindByID(GetValue());
415 if (wp_sp)
416 {
417 StoppointCallbackContext context (event_ptr,
418 &m_thread.GetProcess(),
419 &m_thread,
420 m_thread.GetStackFrameAtIndex(0).get(),
421 false);
422 bool stop_requested = wp_sp->InvokeCallback (&context);
423 // Also make sure that the callback hasn't continued the target.
424 // If it did, when we'll set m_should_start to false and get out of here.
425 if (GetPrivateState() == eStateRunning)
426 m_should_stop = false;
427
428 if (m_should_stop && !stop_requested)
429 {
430 // We have been vetoed.
431 m_should_stop = false;
432 }
433
434 if (m_should_stop && wp_sp->GetConditionText() != NULL)
435 {
436 // We need to make sure the user sees any parse errors in their condition, so we'll hook the
437 // constructor errors up to the debugger's Async I/O.
438 StoppointCallbackContext context (event_ptr,
439 &m_thread.GetProcess(),
440 &m_thread,
441 m_thread.GetStackFrameAtIndex(0).get(),
442 false);
443 ExecutionResults result_code;
444 ValueObjectSP result_value_sp;
445 const bool discard_on_error = true;
446 Error error;
447 result_code = ClangUserExpression::EvaluateWithError (context.exe_ctx,
448 eExecutionPolicyAlways,
449 discard_on_error,
450 wp_sp->GetConditionText(),
451 NULL,
452 result_value_sp,
453 error);
454 if (result_code == eExecutionCompleted)
455 {
456 if (result_value_sp)
457 {
458 Scalar scalar_value;
459 if (result_value_sp->ResolveValue (scalar_value))
460 {
461 if (scalar_value.ULongLong(1) == 0)
462 {
463 // We have been vetoed. This takes precedence over querying
464 // the watchpoint whether it should stop (aka ignore count and
465 // friends). See also StopInfoWatchpoint::ShouldStop() as well
466 // as Process::ProcessEventData::DoOnRemoval().
467 m_should_stop = false;
468 }
469 else
470 m_should_stop = true;
471 if (log)
472 log->Printf("Condition successfully evaluated, result is %s.\n",
473 m_should_stop ? "true" : "false");
474 }
475 else
476 {
477 m_should_stop = true;
478 if (log)
479 log->Printf("Failed to get an integer result from the expression.");
480 }
481 }
482 }
483 else
484 {
485 Debugger &debugger = context.exe_ctx.GetTargetRef().GetDebugger();
486 StreamSP error_sp = debugger.GetAsyncErrorStream ();
487 error_sp->Printf ("Stopped due to an error evaluating condition of breakpoint ");
488 wp_sp->GetDescription (error_sp.get(), eDescriptionLevelBrief);
489 error_sp->Printf (": \"%s\"",
490 wp_sp->GetConditionText());
491 error_sp->EOL();
492 const char *err_str = error.AsCString("<Unknown Error>");
493 if (log)
494 log->Printf("Error evaluating condition: \"%s\"\n", err_str);
495
496 error_sp->PutCString (err_str);
497 error_sp->EOL();
498 error_sp->Flush();
499 // If the condition fails to be parsed or run, we should stop.
500 m_should_stop = true;
501 }
502 }
503 }
504 else
505 {
506 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
507
508 if (log)
509 log->Printf ("Process::%s could not find watchpoint id: %lld...", __FUNCTION__, m_value);
510 }
511 if (log)
512 log->Printf ("Process::%s returning from action with m_should_stop: %d.", __FUNCTION__, m_should_stop);
513 }
514
Greg Clayton643ee732010-08-04 01:40:35 +0000515 virtual const char *
516 GetDescription ()
517 {
518 if (m_description.empty())
519 {
520 StreamString strm;
521 strm.Printf("watchpoint %lli", m_value);
522 m_description.swap (strm.GetString());
523 }
524 return m_description.c_str();
525 }
526
Greg Clayton643ee732010-08-04 01:40:35 +0000527private:
528 std::string m_description;
Johnny Chen043f8c22011-09-21 22:47:15 +0000529 bool m_should_stop;
530 bool m_should_stop_is_valid;
Greg Clayton643ee732010-08-04 01:40:35 +0000531};
532
533
534
535//----------------------------------------------------------------------
536// StopInfoUnixSignal
537//----------------------------------------------------------------------
538
539class StopInfoUnixSignal : public StopInfo
540{
541public:
542
543 StopInfoUnixSignal (Thread &thread, int signo) :
Greg Clayton65611552011-06-04 01:26:29 +0000544 StopInfo (thread, signo)
Greg Clayton643ee732010-08-04 01:40:35 +0000545 {
546 }
547
548 virtual ~StopInfoUnixSignal ()
549 {
550 }
551
552
553 virtual StopReason
554 GetStopReason () const
555 {
556 return eStopReasonSignal;
557 }
558
559 virtual bool
560 ShouldStop (Event *event_ptr)
561 {
562 return m_thread.GetProcess().GetUnixSignals().GetShouldStop (m_value);
563 }
564
565
566 // If should stop returns false, check if we should notify of this event
567 virtual bool
568 ShouldNotify (Event *event_ptr)
569 {
570 return m_thread.GetProcess().GetUnixSignals().GetShouldNotify (m_value);
571 }
572
573
574 virtual void
575 WillResume (lldb::StateType resume_state)
576 {
577 if (m_thread.GetProcess().GetUnixSignals().GetShouldSuppress(m_value) == false)
578 m_thread.SetResumeSignal(m_value);
579 }
580
581 virtual const char *
582 GetDescription ()
583 {
584 if (m_description.empty())
585 {
586 StreamString strm;
587 const char *signal_name = m_thread.GetProcess().GetUnixSignals().GetSignalAsCString (m_value);
588 if (signal_name)
Greg Claytona830adb2010-10-04 01:05:56 +0000589 strm.Printf("signal %s", signal_name);
Greg Clayton643ee732010-08-04 01:40:35 +0000590 else
Greg Claytona830adb2010-10-04 01:05:56 +0000591 strm.Printf("signal %lli", m_value);
Greg Clayton643ee732010-08-04 01:40:35 +0000592 m_description.swap (strm.GetString());
593 }
594 return m_description.c_str();
595 }
Greg Clayton643ee732010-08-04 01:40:35 +0000596};
597
598//----------------------------------------------------------------------
599// StopInfoTrace
600//----------------------------------------------------------------------
601
602class StopInfoTrace : public StopInfo
603{
604public:
605
606 StopInfoTrace (Thread &thread) :
607 StopInfo (thread, LLDB_INVALID_UID)
608 {
609 }
610
611 virtual ~StopInfoTrace ()
612 {
613 }
614
615 virtual StopReason
616 GetStopReason () const
617 {
618 return eStopReasonTrace;
619 }
620
621 virtual const char *
622 GetDescription ()
623 {
Greg Clayton65611552011-06-04 01:26:29 +0000624 if (m_description.empty())
Greg Clayton643ee732010-08-04 01:40:35 +0000625 return "trace";
Greg Clayton65611552011-06-04 01:26:29 +0000626 else
627 return m_description.c_str();
628 }
629};
630
631
632//----------------------------------------------------------------------
633// StopInfoException
634//----------------------------------------------------------------------
635
636class StopInfoException : public StopInfo
637{
638public:
639
640 StopInfoException (Thread &thread, const char *description) :
641 StopInfo (thread, LLDB_INVALID_UID)
642 {
643 if (description)
644 SetDescription (description);
645 }
646
647 virtual
648 ~StopInfoException ()
649 {
650 }
651
652 virtual StopReason
653 GetStopReason () const
654 {
655 return eStopReasonException;
656 }
657
658 virtual const char *
659 GetDescription ()
660 {
661 if (m_description.empty())
662 return "exception";
663 else
664 return m_description.c_str();
Greg Clayton643ee732010-08-04 01:40:35 +0000665 }
666};
667
668
669//----------------------------------------------------------------------
670// StopInfoThreadPlan
671//----------------------------------------------------------------------
672
673class StopInfoThreadPlan : public StopInfo
674{
675public:
676
677 StopInfoThreadPlan (ThreadPlanSP &plan_sp) :
678 StopInfo (plan_sp->GetThread(), LLDB_INVALID_UID),
679 m_plan_sp (plan_sp)
680 {
681 }
682
683 virtual ~StopInfoThreadPlan ()
684 {
685 }
686
687 virtual StopReason
688 GetStopReason () const
689 {
690 return eStopReasonPlanComplete;
691 }
692
693 virtual const char *
694 GetDescription ()
695 {
696 if (m_description.empty())
697 {
698 StreamString strm;
699 m_plan_sp->GetDescription (&strm, eDescriptionLevelBrief);
700 m_description.swap (strm.GetString());
701 }
702 return m_description.c_str();
703 }
704
705private:
706 ThreadPlanSP m_plan_sp;
Greg Clayton643ee732010-08-04 01:40:35 +0000707};
Jim Ingham21f37ad2011-08-09 02:12:22 +0000708} // namespace lldb_private
Greg Clayton643ee732010-08-04 01:40:35 +0000709
710StopInfoSP
711StopInfo::CreateStopReasonWithBreakpointSiteID (Thread &thread, break_id_t break_id)
712{
713 return StopInfoSP (new StopInfoBreakpoint (thread, break_id));
714}
715
716StopInfoSP
Jim Inghamd1686902010-10-14 23:45:03 +0000717StopInfo::CreateStopReasonWithBreakpointSiteID (Thread &thread, break_id_t break_id, bool should_stop)
718{
719 return StopInfoSP (new StopInfoBreakpoint (thread, break_id, should_stop));
720}
721
722StopInfoSP
Greg Clayton643ee732010-08-04 01:40:35 +0000723StopInfo::CreateStopReasonWithWatchpointID (Thread &thread, break_id_t watch_id)
724{
725 return StopInfoSP (new StopInfoWatchpoint (thread, watch_id));
726}
727
728StopInfoSP
729StopInfo::CreateStopReasonWithSignal (Thread &thread, int signo)
730{
731 return StopInfoSP (new StopInfoUnixSignal (thread, signo));
732}
733
734StopInfoSP
735StopInfo::CreateStopReasonToTrace (Thread &thread)
736{
737 return StopInfoSP (new StopInfoTrace (thread));
738}
739
740StopInfoSP
741StopInfo::CreateStopReasonWithPlan (ThreadPlanSP &plan_sp)
742{
743 return StopInfoSP (new StopInfoThreadPlan (plan_sp));
744}
Greg Clayton65611552011-06-04 01:26:29 +0000745
746StopInfoSP
747StopInfo::CreateStopReasonWithException (Thread &thread, const char *description)
748{
749 return StopInfoSP (new StopInfoException (thread, description));
750}