1 //===-- 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/Breakpoint.h"
20 #include "lldb/Breakpoint/BreakpointLocation.h"
21 #include "lldb/Breakpoint/StoppointCallbackContext.h"
22 #include "lldb/Breakpoint/Watchpoint.h"
23 #include "lldb/Core/Debugger.h"
24 #include "lldb/Core/StreamString.h"
25 #include "lldb/Expression/ClangUserExpression.h"
26 #include "lldb/Target/Target.h"
27 #include "lldb/Target/Thread.h"
28 #include "lldb/Target/ThreadPlan.h"
29 #include "lldb/Target/Process.h"
30 #include "lldb/Target/UnixSignals.h"
31 
32 using namespace lldb;
33 using namespace lldb_private;
34 
35 StopInfo::StopInfo (Thread &thread, uint64_t value) :
36     m_thread (thread),
37     m_stop_id (thread.GetProcess()->GetStopID()),
38     m_resume_id (thread.GetProcess()->GetResumeID()),
39     m_value (value)
40 {
41 }
42 
43 bool
44 StopInfo::IsValid () const
45 {
46     return m_thread.GetProcess()->GetStopID() == m_stop_id;
47 }
48 
49 void
50 StopInfo::MakeStopInfoValid ()
51 {
52     m_stop_id = m_thread.GetProcess()->GetStopID();
53     m_resume_id = m_thread.GetProcess()->GetResumeID();
54 }
55 
56 bool
57 StopInfo::HasTargetRunSinceMe ()
58 {
59     lldb::StateType ret_type = m_thread.GetProcess()->GetPrivateState();
60     if (ret_type == eStateRunning)
61     {
62         return true;
63     }
64     else if (ret_type == eStateStopped)
65     {
66         // This is a little tricky.  We want to count "run and stopped again before you could
67         // ask this question as a "TRUE" answer to HasTargetRunSinceMe.  But we don't want to
68         // include any running of the target done for expressions.  So we track both resumes,
69         // and resumes caused by expressions, and check if there are any resumes NOT caused
70         // by expressions.
71 
72         uint32_t curr_resume_id = m_thread.GetProcess()->GetResumeID();
73         uint32_t last_user_expression_id = m_thread.GetProcess()->GetLastUserExpressionResumeID ();
74         if (curr_resume_id == m_resume_id)
75         {
76             return false;
77         }
78         else if (curr_resume_id > last_user_expression_id)
79         {
80             return true;
81         }
82     }
83     return false;
84 }
85 
86 //----------------------------------------------------------------------
87 // StopInfoBreakpoint
88 //----------------------------------------------------------------------
89 
90 namespace lldb_private
91 {
92 class StopInfoBreakpoint : public StopInfo
93 {
94 public:
95 
96     StopInfoBreakpoint (Thread &thread, break_id_t break_id) :
97         StopInfo (thread, break_id),
98         m_description(),
99         m_should_stop (false),
100         m_should_stop_is_valid (false),
101         m_should_perform_action (true),
102         m_address (LLDB_INVALID_ADDRESS),
103         m_break_id(LLDB_INVALID_BREAK_ID),
104         m_was_one_shot (false)
105     {
106         StoreBPInfo();
107     }
108 
109     StopInfoBreakpoint (Thread &thread, break_id_t break_id, bool should_stop) :
110         StopInfo (thread, break_id),
111         m_description(),
112         m_should_stop (should_stop),
113         m_should_stop_is_valid (true),
114         m_should_perform_action (true),
115         m_address (LLDB_INVALID_ADDRESS),
116         m_break_id(LLDB_INVALID_BREAK_ID),
117         m_was_one_shot (false)
118     {
119         StoreBPInfo();
120     }
121 
122     void StoreBPInfo ()
123     {
124         BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value));
125         if (bp_site_sp)
126         {
127             if (bp_site_sp->GetNumberOfOwners() == 1)
128             {
129                 BreakpointLocationSP bp_loc_sp = bp_site_sp->GetOwnerAtIndex(0);
130                 if (bp_loc_sp)
131                 {
132                     m_break_id = bp_loc_sp->GetBreakpoint().GetID();
133                     m_was_one_shot = bp_loc_sp->GetBreakpoint().IsOneShot();
134                 }
135             }
136             m_address = bp_site_sp->GetLoadAddress();
137         }
138     }
139 
140     virtual ~StopInfoBreakpoint ()
141     {
142     }
143 
144     virtual StopReason
145     GetStopReason () const
146     {
147         return eStopReasonBreakpoint;
148     }
149 
150     virtual bool
151     ShouldStopSynchronous (Event *event_ptr)
152     {
153         if (!m_should_stop_is_valid)
154         {
155             // Only check once if we should stop at a breakpoint
156             BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value));
157             if (bp_site_sp)
158             {
159                 ExecutionContext exe_ctx (m_thread.GetStackFrameAtIndex(0));
160                 StoppointCallbackContext context (event_ptr, exe_ctx, true);
161                 m_should_stop = bp_site_sp->ShouldStop (&context);
162             }
163             else
164             {
165                 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
166 
167                 if (log)
168                     log->Printf ("Process::%s could not find breakpoint site id: %lld...", __FUNCTION__, m_value);
169 
170                 m_should_stop = true;
171             }
172             m_should_stop_is_valid = true;
173         }
174         return m_should_stop;
175     }
176 
177     virtual bool
178     ShouldNotify (Event *event_ptr)
179     {
180         BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value));
181         if (bp_site_sp)
182         {
183             bool all_internal = true;
184 
185             for (uint32_t i = 0; i < bp_site_sp->GetNumberOfOwners(); i++)
186             {
187                 if (!bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().IsInternal())
188                 {
189                     all_internal = false;
190                     break;
191                 }
192             }
193             return all_internal == false;
194         }
195         return true;
196     }
197 
198     virtual const char *
199     GetDescription ()
200     {
201         if (m_description.empty())
202         {
203             BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value));
204             if (bp_site_sp)
205             {
206                 StreamString strm;
207                 strm.Printf("breakpoint ");
208                 bp_site_sp->GetDescription(&strm, eDescriptionLevelBrief);
209                 m_description.swap (strm.GetString());
210             }
211             else
212             {
213                 StreamString strm;
214                 if (m_break_id != LLDB_INVALID_BREAK_ID)
215                 {
216                     if (m_was_one_shot)
217                         strm.Printf ("one-shot breakpoint %d", m_break_id);
218                     else
219                         strm.Printf ("breakpoint %d which has been deleted.", m_break_id);
220                 }
221                 else if (m_address == LLDB_INVALID_ADDRESS)
222                     strm.Printf("breakpoint site %lli which has been deleted - unknown address", m_value);
223                 else
224                     strm.Printf("breakpoint site %lli which has been deleted - was at 0x%llx", m_value, m_address);
225 
226                 m_description.swap (strm.GetString());
227             }
228         }
229         return m_description.c_str();
230     }
231 
232 protected:
233     bool
234     ShouldStop (Event *event_ptr)
235     {
236         // This just reports the work done by PerformAction or the synchronous stop.  It should
237         // only ever get called after they have had a chance to run.
238         assert (m_should_stop_is_valid);
239         return m_should_stop;
240     }
241 
242     virtual void
243     PerformAction (Event *event_ptr)
244     {
245         if (!m_should_perform_action)
246             return;
247         m_should_perform_action = false;
248 
249         LogSP log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
250 
251         BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value));
252 
253         if (bp_site_sp)
254         {
255             size_t num_owners = bp_site_sp->GetNumberOfOwners();
256 
257             if (num_owners == 0)
258             {
259                 m_should_stop = true;
260             }
261             else
262             {
263                 // We go through each location, and test first its condition.  If the condition says to stop,
264                 // then we run the callback for that location.  If that callback says to stop as well, then
265                 // we set m_should_stop to true; we are going to stop.
266                 // But we still want to give all the breakpoints whose conditions say we are going to stop a
267                 // chance to run their callbacks.
268                 // Of course if any callback restarts the target by putting "continue" in the callback, then
269                 // we're going to restart, without running the rest of the callbacks.  And in this case we will
270                 // end up not stopping even if another location said we should stop.  But that's better than not
271                 // running all the callbacks.
272 
273                 m_should_stop = false;
274 
275                 ExecutionContext exe_ctx (m_thread.GetStackFrameAtIndex(0));
276                 StoppointCallbackContext context (event_ptr, exe_ctx, false);
277 
278                 for (size_t j = 0; j < num_owners; j++)
279                 {
280                     lldb::BreakpointLocationSP bp_loc_sp = bp_site_sp->GetOwnerAtIndex(j);
281 
282                     // First run the condition for the breakpoint.  If that says we should stop, then we'll run
283                     // the callback for the breakpoint.  If the callback says we shouldn't stop that will win.
284 
285                     bool condition_says_stop = true;
286                     if (bp_loc_sp->GetConditionText() != NULL)
287                     {
288                         // We need to make sure the user sees any parse errors in their condition, so we'll hook the
289                         // constructor errors up to the debugger's Async I/O.
290 
291                         ValueObjectSP result_valobj_sp;
292 
293                         ExecutionResults result_code;
294                         ValueObjectSP result_value_sp;
295                         const bool discard_on_error = true;
296                         Error error;
297                         result_code = ClangUserExpression::EvaluateWithError (exe_ctx,
298                                                                               eExecutionPolicyOnlyWhenNeeded,
299                                                                               lldb::eLanguageTypeUnknown,
300                                                                               ClangUserExpression::eResultTypeAny,
301                                                                               discard_on_error,
302                                                                               bp_loc_sp->GetConditionText(),
303                                                                               NULL,
304                                                                               result_value_sp,
305                                                                               error,
306                                                                               true,
307                                                                               ClangUserExpression::kDefaultTimeout);
308                         if (result_code == eExecutionCompleted)
309                         {
310                             if (result_value_sp)
311                             {
312                                 Scalar scalar_value;
313                                 if (result_value_sp->ResolveValue (scalar_value))
314                                 {
315                                     if (scalar_value.ULongLong(1) == 0)
316                                         condition_says_stop = false;
317                                     else
318                                         condition_says_stop = true;
319                                     if (log)
320                                         log->Printf("Condition successfully evaluated, result is %s.\n",
321                                                     m_should_stop ? "true" : "false");
322                                 }
323                                 else
324                                 {
325                                     condition_says_stop = true;
326                                     if (log)
327                                         log->Printf("Failed to get an integer result from the expression.");
328                                 }
329                             }
330                         }
331                         else
332                         {
333                             Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
334                             StreamSP error_sp = debugger.GetAsyncErrorStream ();
335                             error_sp->Printf ("Stopped due to an error evaluating condition of breakpoint ");
336                             bp_loc_sp->GetDescription (error_sp.get(), eDescriptionLevelBrief);
337                             error_sp->Printf (": \"%s\"",
338                                               bp_loc_sp->GetConditionText());
339                             error_sp->EOL();
340                             const char *err_str = error.AsCString("<Unknown Error>");
341                             if (log)
342                                 log->Printf("Error evaluating condition: \"%s\"\n", err_str);
343 
344                             error_sp->PutCString (err_str);
345                             error_sp->EOL();
346                             error_sp->Flush();
347                             // If the condition fails to be parsed or run, we should stop.
348                             condition_says_stop = true;
349                         }
350                     }
351 
352                     // If this location's condition says we should aren't going to stop,
353                     // then don't run the callback for this location.
354                     if (!condition_says_stop)
355                         continue;
356 
357                     bool callback_says_stop;
358 
359                     // FIXME: For now the callbacks have to run in async mode - the first time we restart we need
360                     // to get out of there.  So set it here.
361                     // When we figure out how to nest breakpoint hits then this will change.
362 
363                     Debugger &debugger = m_thread.CalculateTarget()->GetDebugger();
364                     bool old_async = debugger.GetAsyncExecution();
365                     debugger.SetAsyncExecution (true);
366 
367                     callback_says_stop = bp_loc_sp->InvokeCallback (&context);
368 
369                     debugger.SetAsyncExecution (old_async);
370 
371                     if (callback_says_stop)
372                         m_should_stop = true;
373 
374                     // If we are going to stop for this breakpoint, then remove the breakpoint.
375                     if (callback_says_stop && bp_loc_sp && bp_loc_sp->GetBreakpoint().IsOneShot())
376                     {
377                         m_thread.GetProcess()->GetTarget().RemoveBreakpointByID (bp_loc_sp->GetBreakpoint().GetID());
378                     }
379 
380                     // Also make sure that the callback hasn't continued the target.
381                     // If it did, when we'll set m_should_start to false and get out of here.
382                     if (HasTargetRunSinceMe ())
383                     {
384                         m_should_stop = false;
385                         break;
386                     }
387                 }
388             }
389             // We've figured out what this stop wants to do, so mark it as valid so we don't compute it again.
390             m_should_stop_is_valid = true;
391 
392         }
393         else
394         {
395             m_should_stop = true;
396             m_should_stop_is_valid = true;
397             LogSP log_process(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
398 
399             if (log_process)
400                 log_process->Printf ("Process::%s could not find breakpoint site id: %lld...", __FUNCTION__, m_value);
401         }
402         if (log)
403             log->Printf ("Process::%s returning from action with m_should_stop: %d.", __FUNCTION__, m_should_stop);
404     }
405 
406 private:
407     std::string m_description;
408     bool m_should_stop;
409     bool m_should_stop_is_valid;
410     bool m_should_perform_action; // Since we are trying to preserve the "state" of the system even if we run functions
411                                   // etc. behind the users backs, we need to make sure we only REALLY perform the action once.
412     lldb::addr_t m_address;       // We use this to capture the breakpoint site address when we create the StopInfo,
413                                   // in case somebody deletes it between the time the StopInfo is made and the
414                                   // description is asked for.
415     lldb::break_id_t m_break_id;
416     bool m_was_one_shot;
417 };
418 
419 
420 //----------------------------------------------------------------------
421 // StopInfoWatchpoint
422 //----------------------------------------------------------------------
423 
424 class StopInfoWatchpoint : public StopInfo
425 {
426 public:
427     // Make sure watchpoint is properly disabled and subsequently enabled while performing watchpoint actions.
428     class WatchpointSentry {
429     public:
430         WatchpointSentry(Process *p, Watchpoint *w):
431             process(p),
432             watchpoint(w)
433         {
434             if (process && watchpoint)
435             {
436                 watchpoint->TurnOnEphemeralMode();
437                 process->DisableWatchpoint(watchpoint);
438             }
439         }
440         ~WatchpointSentry()
441         {
442             if (process && watchpoint)
443             {
444                 if (!watchpoint->IsDisabledDuringEphemeralMode())
445                     process->EnableWatchpoint(watchpoint);
446                 watchpoint->TurnOffEphemeralMode();
447             }
448         }
449     private:
450         Process *process;
451         Watchpoint *watchpoint;
452     };
453 
454     StopInfoWatchpoint (Thread &thread, break_id_t watch_id) :
455         StopInfo(thread, watch_id),
456         m_description(),
457         m_should_stop(false),
458         m_should_stop_is_valid(false)
459     {
460     }
461 
462     virtual ~StopInfoWatchpoint ()
463     {
464     }
465 
466     virtual StopReason
467     GetStopReason () const
468     {
469         return eStopReasonWatchpoint;
470     }
471 
472     virtual const char *
473     GetDescription ()
474     {
475         if (m_description.empty())
476         {
477             StreamString strm;
478             strm.Printf("watchpoint %lli", m_value);
479             m_description.swap (strm.GetString());
480         }
481         return m_description.c_str();
482     }
483 
484 protected:
485     virtual bool
486     ShouldStop (Event *event_ptr)
487     {
488         // ShouldStop() method is idempotent and should not affect hit count.
489         // See Process::RunPrivateStateThread()->Process()->HandlePrivateEvent()
490         // -->Process()::ShouldBroadcastEvent()->ThreadList::ShouldStop()->
491         // Thread::ShouldStop()->ThreadPlanBase::ShouldStop()->
492         // StopInfoWatchpoint::ShouldStop() and
493         // Event::DoOnRemoval()->Process::ProcessEventData::DoOnRemoval()->
494         // StopInfoWatchpoint::PerformAction().
495         if (m_should_stop_is_valid)
496             return m_should_stop;
497 
498         WatchpointSP wp_sp =
499             m_thread.CalculateTarget()->GetWatchpointList().FindByID(GetValue());
500         if (wp_sp)
501         {
502             // Check if we should stop at a watchpoint.
503             ExecutionContext exe_ctx (m_thread.GetStackFrameAtIndex(0));
504             StoppointCallbackContext context (event_ptr, exe_ctx, true);
505             m_should_stop = wp_sp->ShouldStop (&context);
506         }
507         else
508         {
509             LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
510 
511             if (log)
512                 log->Printf ("Process::%s could not find watchpoint location id: %lld...",
513                              __FUNCTION__, GetValue());
514 
515             m_should_stop = true;
516         }
517         m_should_stop_is_valid = true;
518         return m_should_stop;
519     }
520 
521     virtual void
522     PerformAction (Event *event_ptr)
523     {
524         LogSP log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS);
525         // We're going to calculate if we should stop or not in some way during the course of
526         // this code.  Also by default we're going to stop, so set that here.
527         m_should_stop = true;
528 
529         WatchpointSP wp_sp =
530             m_thread.CalculateTarget()->GetWatchpointList().FindByID(GetValue());
531         if (wp_sp)
532         {
533             ExecutionContext exe_ctx (m_thread.GetStackFrameAtIndex(0));
534             Process* process = exe_ctx.GetProcessPtr();
535 
536             // This sentry object makes sure the current watchpoint is disabled while performing watchpoint actions,
537             // and it is then enabled after we are finished.
538             WatchpointSentry sentry(process, wp_sp.get());
539 
540             {
541                 // check if this process is running on an architecture where watchpoints trigger
542 				// before the associated instruction runs. if so, disable the WP, single-step and then
543 				// re-enable the watchpoint
544                 if (process)
545                 {
546                     uint32_t num; bool wp_triggers_after;
547                     if (process->GetWatchpointSupportInfo(num, wp_triggers_after).Success())
548                     {
549                         if (!wp_triggers_after)
550                         {
551                             ThreadPlan *new_plan = m_thread.QueueThreadPlanForStepSingleInstruction(false, // step-over
552                                                                                                     false, // abort_other_plans
553                                                                                                     true); // stop_other_threads
554                             new_plan->SetIsMasterPlan (true);
555                             new_plan->SetOkayToDiscard (false);
556                             process->GetThreadList().SetSelectedThreadByID (m_thread.GetID());
557                             process->Resume ();
558                             process->WaitForProcessToStop (NULL);
559                             process->GetThreadList().SetSelectedThreadByID (m_thread.GetID());
560                             MakeStopInfoValid(); // make sure we do not fail to stop because of the single-step taken above
561                         }
562                     }
563                 }
564             }
565 
566             if (m_should_stop && wp_sp->GetConditionText() != NULL)
567             {
568                 // We need to make sure the user sees any parse errors in their condition, so we'll hook the
569                 // constructor errors up to the debugger's Async I/O.
570                 ExecutionResults result_code;
571                 ValueObjectSP result_value_sp;
572                 const bool discard_on_error = true;
573                 Error error;
574                 result_code = ClangUserExpression::EvaluateWithError (exe_ctx,
575                                                                       eExecutionPolicyOnlyWhenNeeded,
576                                                                       lldb::eLanguageTypeUnknown,
577                                                                       ClangUserExpression::eResultTypeAny,
578                                                                       discard_on_error,
579                                                                       wp_sp->GetConditionText(),
580                                                                       NULL,
581                                                                       result_value_sp,
582                                                                       error,
583                                                                       true,
584                                                                       ClangUserExpression::kDefaultTimeout);
585                 if (result_code == eExecutionCompleted)
586                 {
587                     if (result_value_sp)
588                     {
589                         Scalar scalar_value;
590                         if (result_value_sp->ResolveValue (scalar_value))
591                         {
592                             if (scalar_value.ULongLong(1) == 0)
593                             {
594                                 // We have been vetoed.  This takes precedence over querying
595                                 // the watchpoint whether it should stop (aka ignore count and
596                                 // friends).  See also StopInfoWatchpoint::ShouldStop() as well
597                                 // as Process::ProcessEventData::DoOnRemoval().
598                                 m_should_stop = false;
599                             }
600                             else
601                                 m_should_stop = true;
602                             if (log)
603                                 log->Printf("Condition successfully evaluated, result is %s.\n",
604                                             m_should_stop ? "true" : "false");
605                         }
606                         else
607                         {
608                             m_should_stop = true;
609                             if (log)
610                                 log->Printf("Failed to get an integer result from the expression.");
611                         }
612                     }
613                 }
614                 else
615                 {
616                     Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
617                     StreamSP error_sp = debugger.GetAsyncErrorStream ();
618                     error_sp->Printf ("Stopped due to an error evaluating condition of watchpoint ");
619                     wp_sp->GetDescription (error_sp.get(), eDescriptionLevelBrief);
620                     error_sp->Printf (": \"%s\"",
621                                       wp_sp->GetConditionText());
622                     error_sp->EOL();
623                     const char *err_str = error.AsCString("<Unknown Error>");
624                     if (log)
625                         log->Printf("Error evaluating condition: \"%s\"\n", err_str);
626 
627                     error_sp->PutCString (err_str);
628                     error_sp->EOL();
629                     error_sp->Flush();
630                     // If the condition fails to be parsed or run, we should stop.
631                     m_should_stop = true;
632                 }
633             }
634 
635             // If the condition says to stop, we run the callback to further decide whether to stop.
636             if (m_should_stop)
637             {
638                 StoppointCallbackContext context (event_ptr, exe_ctx, false);
639                 bool stop_requested = wp_sp->InvokeCallback (&context);
640                 // Also make sure that the callback hasn't continued the target.
641                 // If it did, when we'll set m_should_stop to false and get out of here.
642                 if (HasTargetRunSinceMe ())
643                     m_should_stop = false;
644 
645                 if (m_should_stop && !stop_requested)
646                 {
647                     // We have been vetoed by the callback mechanism.
648                     m_should_stop = false;
649                 }
650             }
651             // Finally, if we are going to stop, print out the new & old values:
652             if (m_should_stop)
653             {
654                 wp_sp->CaptureWatchedValue(exe_ctx);
655 
656                 Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
657                 StreamSP output_sp = debugger.GetAsyncOutputStream ();
658                 wp_sp->DumpSnapshots(output_sp.get());
659                 output_sp->EOL();
660                 output_sp->Flush();
661             }
662 
663         }
664         else
665         {
666             LogSP log_process(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
667 
668             if (log_process)
669                 log_process->Printf ("Process::%s could not find watchpoint id: %lld...", __FUNCTION__, m_value);
670         }
671         if (log)
672             log->Printf ("Process::%s returning from action with m_should_stop: %d.", __FUNCTION__, m_should_stop);
673 
674     }
675 
676 private:
677     std::string m_description;
678     bool m_should_stop;
679     bool m_should_stop_is_valid;
680 };
681 
682 
683 
684 //----------------------------------------------------------------------
685 // StopInfoUnixSignal
686 //----------------------------------------------------------------------
687 
688 class StopInfoUnixSignal : public StopInfo
689 {
690 public:
691 
692     StopInfoUnixSignal (Thread &thread, int signo) :
693         StopInfo (thread, signo)
694     {
695     }
696 
697     virtual ~StopInfoUnixSignal ()
698     {
699     }
700 
701 
702     virtual StopReason
703     GetStopReason () const
704     {
705         return eStopReasonSignal;
706     }
707 
708     virtual bool
709     ShouldStop (Event *event_ptr)
710     {
711         return m_thread.GetProcess()->GetUnixSignals().GetShouldStop (m_value);
712     }
713 
714 
715     // If should stop returns false, check if we should notify of this event
716     virtual bool
717     ShouldNotify (Event *event_ptr)
718     {
719         return m_thread.GetProcess()->GetUnixSignals().GetShouldNotify (m_value);
720     }
721 
722 
723     virtual void
724     WillResume (lldb::StateType resume_state)
725     {
726         if (m_thread.GetProcess()->GetUnixSignals().GetShouldSuppress(m_value) == false)
727             m_thread.SetResumeSignal(m_value);
728     }
729 
730     virtual const char *
731     GetDescription ()
732     {
733         if (m_description.empty())
734         {
735             StreamString strm;
736             const char *signal_name = m_thread.GetProcess()->GetUnixSignals().GetSignalAsCString (m_value);
737             if (signal_name)
738                 strm.Printf("signal %s", signal_name);
739             else
740                 strm.Printf("signal %lli", m_value);
741             m_description.swap (strm.GetString());
742         }
743         return m_description.c_str();
744     }
745 };
746 
747 //----------------------------------------------------------------------
748 // StopInfoTrace
749 //----------------------------------------------------------------------
750 
751 class StopInfoTrace : public StopInfo
752 {
753 public:
754 
755     StopInfoTrace (Thread &thread) :
756         StopInfo (thread, LLDB_INVALID_UID)
757     {
758     }
759 
760     virtual ~StopInfoTrace ()
761     {
762     }
763 
764     virtual StopReason
765     GetStopReason () const
766     {
767         return eStopReasonTrace;
768     }
769 
770     virtual const char *
771     GetDescription ()
772     {
773         if (m_description.empty())
774         return "trace";
775         else
776             return m_description.c_str();
777     }
778 };
779 
780 
781 //----------------------------------------------------------------------
782 // StopInfoException
783 //----------------------------------------------------------------------
784 
785 class StopInfoException : public StopInfo
786 {
787 public:
788 
789     StopInfoException (Thread &thread, const char *description) :
790         StopInfo (thread, LLDB_INVALID_UID)
791     {
792         if (description)
793             SetDescription (description);
794     }
795 
796     virtual
797     ~StopInfoException ()
798     {
799     }
800 
801     virtual StopReason
802     GetStopReason () const
803     {
804         return eStopReasonException;
805     }
806 
807     virtual const char *
808     GetDescription ()
809     {
810         if (m_description.empty())
811             return "exception";
812         else
813             return m_description.c_str();
814     }
815 };
816 
817 
818 //----------------------------------------------------------------------
819 // StopInfoThreadPlan
820 //----------------------------------------------------------------------
821 
822 class StopInfoThreadPlan : public StopInfo
823 {
824 public:
825 
826     StopInfoThreadPlan (ThreadPlanSP &plan_sp, ValueObjectSP &return_valobj_sp) :
827         StopInfo (plan_sp->GetThread(), LLDB_INVALID_UID),
828         m_plan_sp (plan_sp),
829         m_return_valobj_sp (return_valobj_sp)
830     {
831     }
832 
833     virtual ~StopInfoThreadPlan ()
834     {
835     }
836 
837     virtual StopReason
838     GetStopReason () const
839     {
840         return eStopReasonPlanComplete;
841     }
842 
843     virtual const char *
844     GetDescription ()
845     {
846         if (m_description.empty())
847         {
848             StreamString strm;
849             m_plan_sp->GetDescription (&strm, eDescriptionLevelBrief);
850             m_description.swap (strm.GetString());
851         }
852         return m_description.c_str();
853     }
854 
855     ValueObjectSP
856     GetReturnValueObject()
857     {
858         return m_return_valobj_sp;
859     }
860 
861 private:
862     ThreadPlanSP m_plan_sp;
863     ValueObjectSP m_return_valobj_sp;
864 };
865 } // namespace lldb_private
866 
867 StopInfoSP
868 StopInfo::CreateStopReasonWithBreakpointSiteID (Thread &thread, break_id_t break_id)
869 {
870     return StopInfoSP (new StopInfoBreakpoint (thread, break_id));
871 }
872 
873 StopInfoSP
874 StopInfo::CreateStopReasonWithBreakpointSiteID (Thread &thread, break_id_t break_id, bool should_stop)
875 {
876     return StopInfoSP (new StopInfoBreakpoint (thread, break_id, should_stop));
877 }
878 
879 StopInfoSP
880 StopInfo::CreateStopReasonWithWatchpointID (Thread &thread, break_id_t watch_id)
881 {
882     return StopInfoSP (new StopInfoWatchpoint (thread, watch_id));
883 }
884 
885 StopInfoSP
886 StopInfo::CreateStopReasonWithSignal (Thread &thread, int signo)
887 {
888     return StopInfoSP (new StopInfoUnixSignal (thread, signo));
889 }
890 
891 StopInfoSP
892 StopInfo::CreateStopReasonToTrace (Thread &thread)
893 {
894     return StopInfoSP (new StopInfoTrace (thread));
895 }
896 
897 StopInfoSP
898 StopInfo::CreateStopReasonWithPlan (ThreadPlanSP &plan_sp, ValueObjectSP return_valobj_sp)
899 {
900     return StopInfoSP (new StopInfoThreadPlan (plan_sp, return_valobj_sp));
901 }
902 
903 StopInfoSP
904 StopInfo::CreateStopReasonWithException (Thread &thread, const char *description)
905 {
906     return StopInfoSP (new StopInfoException (thread, description));
907 }
908 
909 ValueObjectSP
910 StopInfo::GetReturnValueObject(StopInfoSP &stop_info_sp)
911 {
912     if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonPlanComplete)
913     {
914         StopInfoThreadPlan *plan_stop_info = static_cast<StopInfoThreadPlan *>(stop_info_sp.get());
915         return plan_stop_info->GetReturnValueObject();
916     }
917     else
918         return ValueObjectSP();
919 }
920