blob: f70f2b08e113bdc01772c0b04664f44c8cb8e911 [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,
Sean Callanan5b658cc2011-11-07 23:35:40 +0000211 lldb::eLanguageTypeUnknown,
Sean Callanan47dc4572011-09-15 02:13:07 +0000212 discard_on_error,
213 bp_loc_sp->GetConditionText(),
214 NULL,
215 result_value_sp,
216 error);
Jim Ingham21f37ad2011-08-09 02:12:22 +0000217 if (result_code == eExecutionCompleted)
218 {
219 if (result_value_sp)
220 {
221 Scalar scalar_value;
222 if (result_value_sp->ResolveValue (scalar_value))
223 {
224 if (scalar_value.ULongLong(1) == 0)
225 m_should_stop = false;
226 else
227 m_should_stop = true;
228 if (log)
229 log->Printf("Condition successfully evaluated, result is %s.\n",
230 m_should_stop ? "true" : "false");
231 }
232 else
233 {
234 m_should_stop = true;
235 if (log)
236 log->Printf("Failed to get an integer result from the expression.");
237 }
238 }
239 }
240 else
241 {
Greg Clayton567e7f32011-09-22 04:58:26 +0000242 Debugger &debugger = context.exe_ctx.GetTargetRef().GetDebugger();
Jim Ingham21f37ad2011-08-09 02:12:22 +0000243 StreamSP error_sp = debugger.GetAsyncErrorStream ();
244 error_sp->Printf ("Stopped due to an error evaluating condition of breakpoint ");
245 bp_loc_sp->GetDescription (error_sp.get(), eDescriptionLevelBrief);
246 error_sp->Printf (": \"%s\"",
247 bp_loc_sp->GetConditionText());
248 error_sp->EOL();
249 const char *err_str = error.AsCString("<Unknown Error>");
250 if (log)
251 log->Printf("Error evaluating condition: \"%s\"\n", err_str);
252
253 error_sp->PutCString (err_str);
254 error_sp->EOL();
255 error_sp->Flush();
256 // If the condition fails to be parsed or run, we should stop.
257 m_should_stop = true;
258 }
259 }
260
261 // If any condition says we should stop, then we're going to stop, so we don't need
262 // to evaluate the others.
263 if (m_should_stop)
264 break;
265 }
Jim Ingham6fb8baa2010-08-10 00:59:59 +0000266 }
267 }
268 else
269 {
Greg Claytone005f2c2010-11-06 01:53:30 +0000270 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
Jim Ingham6fb8baa2010-08-10 00:59:59 +0000271
272 if (log)
273 log->Printf ("Process::%s could not find breakpoint site id: %lld...", __FUNCTION__, m_value);
274 }
Jim Ingham21f37ad2011-08-09 02:12:22 +0000275 if (log)
276 log->Printf ("Process::%s returning from action with m_should_stop: %d.", __FUNCTION__, m_should_stop);
Jim Ingham6fb8baa2010-08-10 00:59:59 +0000277 }
Greg Clayton643ee732010-08-04 01:40:35 +0000278
279 virtual bool
280 ShouldNotify (Event *event_ptr)
281 {
282 BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (m_value));
283 if (bp_site_sp)
284 {
285 bool all_internal = true;
286
287 for (uint32_t i = 0; i < bp_site_sp->GetNumberOfOwners(); i++)
288 {
289 if (!bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().IsInternal())
290 {
291 all_internal = false;
292 break;
293 }
294 }
295 return all_internal == false;
296 }
297 return true;
298 }
299
300 virtual const char *
301 GetDescription ()
302 {
303 if (m_description.empty())
304 {
Jim Ingham6fb8baa2010-08-10 00:59:59 +0000305 BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (m_value));
306 if (bp_site_sp)
307 {
308 StreamString strm;
309 strm.Printf("breakpoint ");
310 bp_site_sp->GetDescription(&strm, eDescriptionLevelBrief);
311 m_description.swap (strm.GetString());
312 }
313 else
314 {
315 StreamString strm;
Jim Ingham1c658532011-10-28 01:12:19 +0000316 if (m_address == LLDB_INVALID_ADDRESS)
317 strm.Printf("breakpoint site %lli which has been deleted - unknown address", m_value);
318 else
319 strm.Printf("breakpoint site %lli which has been deleted - was at 0x%llx", m_value, m_address);
Jim Ingham6fb8baa2010-08-10 00:59:59 +0000320 m_description.swap (strm.GetString());
321 }
Greg Clayton643ee732010-08-04 01:40:35 +0000322 }
323 return m_description.c_str();
324 }
325
326private:
327 std::string m_description;
328 bool m_should_stop;
329 bool m_should_stop_is_valid;
Jim Inghamf9f40c22011-02-08 05:20:59 +0000330 bool m_should_perform_action; // Since we are trying to preserve the "state" of the system even if we run functions
331 // etc. behind the users backs, we need to make sure we only REALLY perform the action once.
Jim Ingham1c658532011-10-28 01:12:19 +0000332 lldb::addr_t m_address; // We use this to capture the breakpoint site address when we create the StopInfo,
333 // in case somebody deletes it between the time the StopInfo is made and the
334 // description is asked for.
Greg Clayton643ee732010-08-04 01:40:35 +0000335};
336
337
338//----------------------------------------------------------------------
339// StopInfoWatchpoint
340//----------------------------------------------------------------------
341
342class StopInfoWatchpoint : public StopInfo
343{
344public:
345
346 StopInfoWatchpoint (Thread &thread, break_id_t watch_id) :
Johnny Chen043f8c22011-09-21 22:47:15 +0000347 StopInfo(thread, watch_id),
348 m_description(),
349 m_should_stop(false),
350 m_should_stop_is_valid(false)
Greg Clayton643ee732010-08-04 01:40:35 +0000351 {
352 }
353
354 virtual ~StopInfoWatchpoint ()
355 {
356 }
357
358 virtual StopReason
359 GetStopReason () const
360 {
361 return eStopReasonWatchpoint;
362 }
363
Johnny Chen043f8c22011-09-21 22:47:15 +0000364 virtual bool
365 ShouldStop (Event *event_ptr)
366 {
367 // ShouldStop() method is idempotent and should not affect hit count.
Johnny Chen712a6282011-10-17 18:58:00 +0000368 // See Process::RunPrivateStateThread()->Process()->HandlePrivateEvent()
369 // -->Process()::ShouldBroadcastEvent()->ThreadList::ShouldStop()->
370 // Thread::ShouldStop()->ThreadPlanBase::ShouldStop()->
371 // StopInfoWatchpoint::ShouldStop() and
372 // Event::DoOnRemoval()->Process::ProcessEventData::DoOnRemoval()->
373 // StopInfoWatchpoint::PerformAction().
Johnny Chen043f8c22011-09-21 22:47:15 +0000374 if (m_should_stop_is_valid)
375 return m_should_stop;
376
Johnny Chenecd4feb2011-10-14 00:42:25 +0000377 WatchpointSP wp_sp =
378 m_thread.GetProcess().GetTarget().GetWatchpointList().FindByID(GetValue());
379 if (wp_sp)
Johnny Chen043f8c22011-09-21 22:47:15 +0000380 {
381 // Check if we should stop at a watchpoint.
382 StoppointCallbackContext context (event_ptr,
383 &m_thread.GetProcess(),
384 &m_thread,
385 m_thread.GetStackFrameAtIndex(0).get(),
386 true);
387
Johnny Chenecd4feb2011-10-14 00:42:25 +0000388 m_should_stop = wp_sp->ShouldStop (&context);
Johnny Chen043f8c22011-09-21 22:47:15 +0000389 }
390 else
391 {
392 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
393
394 if (log)
395 log->Printf ("Process::%s could not find watchpoint location id: %lld...",
396 __FUNCTION__, GetValue());
397
398 m_should_stop = true;
399 }
400 m_should_stop_is_valid = true;
401 return m_should_stop;
402 }
403
Johnny Chen712a6282011-10-17 18:58:00 +0000404 // Perform any action that is associated with this stop. This is done as the
405 // Event is removed from the event queue.
406 virtual void
407 PerformAction (Event *event_ptr)
408 {
409 LogSP log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
410 // We're going to calculate if we should stop or not in some way during the course of
411 // this code. Also by default we're going to stop, so set that here.
412 m_should_stop = true;
413
414 WatchpointSP wp_sp =
415 m_thread.GetProcess().GetTarget().GetWatchpointList().FindByID(GetValue());
416 if (wp_sp)
417 {
418 StoppointCallbackContext context (event_ptr,
419 &m_thread.GetProcess(),
420 &m_thread,
421 m_thread.GetStackFrameAtIndex(0).get(),
422 false);
423 bool stop_requested = wp_sp->InvokeCallback (&context);
424 // Also make sure that the callback hasn't continued the target.
425 // If it did, when we'll set m_should_start to false and get out of here.
426 if (GetPrivateState() == eStateRunning)
427 m_should_stop = false;
428
429 if (m_should_stop && !stop_requested)
430 {
431 // We have been vetoed.
432 m_should_stop = false;
433 }
434
435 if (m_should_stop && wp_sp->GetConditionText() != NULL)
436 {
437 // We need to make sure the user sees any parse errors in their condition, so we'll hook the
438 // constructor errors up to the debugger's Async I/O.
439 StoppointCallbackContext context (event_ptr,
440 &m_thread.GetProcess(),
441 &m_thread,
442 m_thread.GetStackFrameAtIndex(0).get(),
443 false);
444 ExecutionResults result_code;
445 ValueObjectSP result_value_sp;
446 const bool discard_on_error = true;
447 Error error;
448 result_code = ClangUserExpression::EvaluateWithError (context.exe_ctx,
449 eExecutionPolicyAlways,
Sean Callanan5b658cc2011-11-07 23:35:40 +0000450 lldb::eLanguageTypeUnknown,
Johnny Chen712a6282011-10-17 18:58:00 +0000451 discard_on_error,
452 wp_sp->GetConditionText(),
453 NULL,
454 result_value_sp,
455 error);
456 if (result_code == eExecutionCompleted)
457 {
458 if (result_value_sp)
459 {
460 Scalar scalar_value;
461 if (result_value_sp->ResolveValue (scalar_value))
462 {
463 if (scalar_value.ULongLong(1) == 0)
464 {
465 // We have been vetoed. This takes precedence over querying
466 // the watchpoint whether it should stop (aka ignore count and
467 // friends). See also StopInfoWatchpoint::ShouldStop() as well
468 // as Process::ProcessEventData::DoOnRemoval().
469 m_should_stop = false;
470 }
471 else
472 m_should_stop = true;
473 if (log)
474 log->Printf("Condition successfully evaluated, result is %s.\n",
475 m_should_stop ? "true" : "false");
476 }
477 else
478 {
479 m_should_stop = true;
480 if (log)
481 log->Printf("Failed to get an integer result from the expression.");
482 }
483 }
484 }
485 else
486 {
487 Debugger &debugger = context.exe_ctx.GetTargetRef().GetDebugger();
488 StreamSP error_sp = debugger.GetAsyncErrorStream ();
489 error_sp->Printf ("Stopped due to an error evaluating condition of breakpoint ");
490 wp_sp->GetDescription (error_sp.get(), eDescriptionLevelBrief);
491 error_sp->Printf (": \"%s\"",
492 wp_sp->GetConditionText());
493 error_sp->EOL();
494 const char *err_str = error.AsCString("<Unknown Error>");
495 if (log)
496 log->Printf("Error evaluating condition: \"%s\"\n", err_str);
497
498 error_sp->PutCString (err_str);
499 error_sp->EOL();
500 error_sp->Flush();
501 // If the condition fails to be parsed or run, we should stop.
502 m_should_stop = true;
503 }
504 }
505 }
506 else
507 {
508 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
509
510 if (log)
511 log->Printf ("Process::%s could not find watchpoint id: %lld...", __FUNCTION__, m_value);
512 }
513 if (log)
514 log->Printf ("Process::%s returning from action with m_should_stop: %d.", __FUNCTION__, m_should_stop);
515 }
516
Greg Clayton643ee732010-08-04 01:40:35 +0000517 virtual const char *
518 GetDescription ()
519 {
520 if (m_description.empty())
521 {
522 StreamString strm;
523 strm.Printf("watchpoint %lli", m_value);
524 m_description.swap (strm.GetString());
525 }
526 return m_description.c_str();
527 }
528
Greg Clayton643ee732010-08-04 01:40:35 +0000529private:
530 std::string m_description;
Johnny Chen043f8c22011-09-21 22:47:15 +0000531 bool m_should_stop;
532 bool m_should_stop_is_valid;
Greg Clayton643ee732010-08-04 01:40:35 +0000533};
534
535
536
537//----------------------------------------------------------------------
538// StopInfoUnixSignal
539//----------------------------------------------------------------------
540
541class StopInfoUnixSignal : public StopInfo
542{
543public:
544
545 StopInfoUnixSignal (Thread &thread, int signo) :
Greg Clayton65611552011-06-04 01:26:29 +0000546 StopInfo (thread, signo)
Greg Clayton643ee732010-08-04 01:40:35 +0000547 {
548 }
549
550 virtual ~StopInfoUnixSignal ()
551 {
552 }
553
554
555 virtual StopReason
556 GetStopReason () const
557 {
558 return eStopReasonSignal;
559 }
560
561 virtual bool
562 ShouldStop (Event *event_ptr)
563 {
564 return m_thread.GetProcess().GetUnixSignals().GetShouldStop (m_value);
565 }
566
567
568 // If should stop returns false, check if we should notify of this event
569 virtual bool
570 ShouldNotify (Event *event_ptr)
571 {
572 return m_thread.GetProcess().GetUnixSignals().GetShouldNotify (m_value);
573 }
574
575
576 virtual void
577 WillResume (lldb::StateType resume_state)
578 {
579 if (m_thread.GetProcess().GetUnixSignals().GetShouldSuppress(m_value) == false)
580 m_thread.SetResumeSignal(m_value);
581 }
582
583 virtual const char *
584 GetDescription ()
585 {
586 if (m_description.empty())
587 {
588 StreamString strm;
589 const char *signal_name = m_thread.GetProcess().GetUnixSignals().GetSignalAsCString (m_value);
590 if (signal_name)
Greg Claytona830adb2010-10-04 01:05:56 +0000591 strm.Printf("signal %s", signal_name);
Greg Clayton643ee732010-08-04 01:40:35 +0000592 else
Greg Claytona830adb2010-10-04 01:05:56 +0000593 strm.Printf("signal %lli", m_value);
Greg Clayton643ee732010-08-04 01:40:35 +0000594 m_description.swap (strm.GetString());
595 }
596 return m_description.c_str();
597 }
Greg Clayton643ee732010-08-04 01:40:35 +0000598};
599
600//----------------------------------------------------------------------
601// StopInfoTrace
602//----------------------------------------------------------------------
603
604class StopInfoTrace : public StopInfo
605{
606public:
607
608 StopInfoTrace (Thread &thread) :
609 StopInfo (thread, LLDB_INVALID_UID)
610 {
611 }
612
613 virtual ~StopInfoTrace ()
614 {
615 }
616
617 virtual StopReason
618 GetStopReason () const
619 {
620 return eStopReasonTrace;
621 }
622
623 virtual const char *
624 GetDescription ()
625 {
Greg Clayton65611552011-06-04 01:26:29 +0000626 if (m_description.empty())
Greg Clayton643ee732010-08-04 01:40:35 +0000627 return "trace";
Greg Clayton65611552011-06-04 01:26:29 +0000628 else
629 return m_description.c_str();
630 }
631};
632
633
634//----------------------------------------------------------------------
635// StopInfoException
636//----------------------------------------------------------------------
637
638class StopInfoException : public StopInfo
639{
640public:
641
642 StopInfoException (Thread &thread, const char *description) :
643 StopInfo (thread, LLDB_INVALID_UID)
644 {
645 if (description)
646 SetDescription (description);
647 }
648
649 virtual
650 ~StopInfoException ()
651 {
652 }
653
654 virtual StopReason
655 GetStopReason () const
656 {
657 return eStopReasonException;
658 }
659
660 virtual const char *
661 GetDescription ()
662 {
663 if (m_description.empty())
664 return "exception";
665 else
666 return m_description.c_str();
Greg Clayton643ee732010-08-04 01:40:35 +0000667 }
668};
669
670
671//----------------------------------------------------------------------
672// StopInfoThreadPlan
673//----------------------------------------------------------------------
674
675class StopInfoThreadPlan : public StopInfo
676{
677public:
678
679 StopInfoThreadPlan (ThreadPlanSP &plan_sp) :
680 StopInfo (plan_sp->GetThread(), LLDB_INVALID_UID),
681 m_plan_sp (plan_sp)
682 {
683 }
684
685 virtual ~StopInfoThreadPlan ()
686 {
687 }
688
689 virtual StopReason
690 GetStopReason () const
691 {
692 return eStopReasonPlanComplete;
693 }
694
695 virtual const char *
696 GetDescription ()
697 {
698 if (m_description.empty())
699 {
700 StreamString strm;
701 m_plan_sp->GetDescription (&strm, eDescriptionLevelBrief);
702 m_description.swap (strm.GetString());
703 }
704 return m_description.c_str();
705 }
706
707private:
708 ThreadPlanSP m_plan_sp;
Greg Clayton643ee732010-08-04 01:40:35 +0000709};
Jim Ingham21f37ad2011-08-09 02:12:22 +0000710} // namespace lldb_private
Greg Clayton643ee732010-08-04 01:40:35 +0000711
712StopInfoSP
713StopInfo::CreateStopReasonWithBreakpointSiteID (Thread &thread, break_id_t break_id)
714{
715 return StopInfoSP (new StopInfoBreakpoint (thread, break_id));
716}
717
718StopInfoSP
Jim Inghamd1686902010-10-14 23:45:03 +0000719StopInfo::CreateStopReasonWithBreakpointSiteID (Thread &thread, break_id_t break_id, bool should_stop)
720{
721 return StopInfoSP (new StopInfoBreakpoint (thread, break_id, should_stop));
722}
723
724StopInfoSP
Greg Clayton643ee732010-08-04 01:40:35 +0000725StopInfo::CreateStopReasonWithWatchpointID (Thread &thread, break_id_t watch_id)
726{
727 return StopInfoSP (new StopInfoWatchpoint (thread, watch_id));
728}
729
730StopInfoSP
731StopInfo::CreateStopReasonWithSignal (Thread &thread, int signo)
732{
733 return StopInfoSP (new StopInfoUnixSignal (thread, signo));
734}
735
736StopInfoSP
737StopInfo::CreateStopReasonToTrace (Thread &thread)
738{
739 return StopInfoSP (new StopInfoTrace (thread));
740}
741
742StopInfoSP
743StopInfo::CreateStopReasonWithPlan (ThreadPlanSP &plan_sp)
744{
745 return StopInfoSP (new StopInfoThreadPlan (plan_sp));
746}
Greg Clayton65611552011-06-04 01:26:29 +0000747
748StopInfoSP
749StopInfo::CreateStopReasonWithException (Thread &thread, const char *description)
750{
751 return StopInfoSP (new StopInfoException (thread, description));
752}