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