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                 const bool notify = false;
439                 watchpoint->TurnOnEphemeralMode();
440                 process->DisableWatchpoint(watchpoint, notify);
441             }
442         }
443         ~WatchpointSentry()
444         {
445             if (process && watchpoint)
446             {
447                 if (!watchpoint->IsDisabledDuringEphemeralMode())
448                 {
449                     const bool notify = false;
450                     process->EnableWatchpoint(watchpoint, notify);
451                 }
452                 watchpoint->TurnOffEphemeralMode();
453             }
454         }
455     private:
456         Process *process;
457         Watchpoint *watchpoint;
458     };
459 
460     StopInfoWatchpoint (Thread &thread, break_id_t watch_id) :
461         StopInfo(thread, watch_id),
462         m_description(),
463         m_should_stop(false),
464         m_should_stop_is_valid(false)
465     {
466     }
467 
468     virtual ~StopInfoWatchpoint ()
469     {
470     }
471 
472     virtual StopReason
473     GetStopReason () const
474     {
475         return eStopReasonWatchpoint;
476     }
477 
478     virtual const char *
479     GetDescription ()
480     {
481         if (m_description.empty())
482         {
483             StreamString strm;
484             strm.Printf("watchpoint %" PRIi64, m_value);
485             m_description.swap (strm.GetString());
486         }
487         return m_description.c_str();
488     }
489 
490 protected:
491     virtual bool
492     ShouldStop (Event *event_ptr)
493     {
494         // ShouldStop() method is idempotent and should not affect hit count.
495         // See Process::RunPrivateStateThread()->Process()->HandlePrivateEvent()
496         // -->Process()::ShouldBroadcastEvent()->ThreadList::ShouldStop()->
497         // Thread::ShouldStop()->ThreadPlanBase::ShouldStop()->
498         // StopInfoWatchpoint::ShouldStop() and
499         // Event::DoOnRemoval()->Process::ProcessEventData::DoOnRemoval()->
500         // StopInfoWatchpoint::PerformAction().
501         if (m_should_stop_is_valid)
502             return m_should_stop;
503 
504         WatchpointSP wp_sp =
505             m_thread.CalculateTarget()->GetWatchpointList().FindByID(GetValue());
506         if (wp_sp)
507         {
508             // Check if we should stop at a watchpoint.
509             ExecutionContext exe_ctx (m_thread.GetStackFrameAtIndex(0));
510             StoppointCallbackContext context (event_ptr, exe_ctx, true);
511             m_should_stop = wp_sp->ShouldStop (&context);
512         }
513         else
514         {
515             LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
516 
517             if (log)
518                 log->Printf ("Process::%s could not find watchpoint location id: %" PRId64 "...",
519                              __FUNCTION__, GetValue());
520 
521             m_should_stop = true;
522         }
523         m_should_stop_is_valid = true;
524         return m_should_stop;
525     }
526 
527     virtual void
528     PerformAction (Event *event_ptr)
529     {
530         LogSP log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS);
531         // We're going to calculate if we should stop or not in some way during the course of
532         // this code.  Also by default we're going to stop, so set that here.
533         m_should_stop = true;
534 
535         WatchpointSP wp_sp =
536             m_thread.CalculateTarget()->GetWatchpointList().FindByID(GetValue());
537         if (wp_sp)
538         {
539             ExecutionContext exe_ctx (m_thread.GetStackFrameAtIndex(0));
540             Process* process = exe_ctx.GetProcessPtr();
541 
542             // This sentry object makes sure the current watchpoint is disabled while performing watchpoint actions,
543             // and it is then enabled after we are finished.
544             WatchpointSentry sentry(process, wp_sp.get());
545 
546             {
547                 // check if this process is running on an architecture where watchpoints trigger
548 				// before the associated instruction runs. if so, disable the WP, single-step and then
549 				// re-enable the watchpoint
550                 if (process)
551                 {
552                     uint32_t num; bool wp_triggers_after;
553                     if (process->GetWatchpointSupportInfo(num, wp_triggers_after).Success())
554                     {
555                         if (!wp_triggers_after)
556                         {
557                             ThreadPlan *new_plan = m_thread.QueueThreadPlanForStepSingleInstruction(false, // step-over
558                                                                                                     false, // abort_other_plans
559                                                                                                     true); // stop_other_threads
560                             new_plan->SetIsMasterPlan (true);
561                             new_plan->SetOkayToDiscard (false);
562                             process->GetThreadList().SetSelectedThreadByID (m_thread.GetID());
563                             process->Resume ();
564                             process->WaitForProcessToStop (NULL);
565                             process->GetThreadList().SetSelectedThreadByID (m_thread.GetID());
566                             MakeStopInfoValid(); // make sure we do not fail to stop because of the single-step taken above
567                         }
568                     }
569                 }
570             }
571 
572             if (m_should_stop && wp_sp->GetConditionText() != NULL)
573             {
574                 // We need to make sure the user sees any parse errors in their condition, so we'll hook the
575                 // constructor errors up to the debugger's Async I/O.
576                 ExecutionResults result_code;
577                 ValueObjectSP result_value_sp;
578                 const bool discard_on_error = true;
579                 Error error;
580                 result_code = ClangUserExpression::EvaluateWithError (exe_ctx,
581                                                                       eExecutionPolicyOnlyWhenNeeded,
582                                                                       lldb::eLanguageTypeUnknown,
583                                                                       ClangUserExpression::eResultTypeAny,
584                                                                       discard_on_error,
585                                                                       wp_sp->GetConditionText(),
586                                                                       NULL,
587                                                                       result_value_sp,
588                                                                       error,
589                                                                       true,
590                                                                       ClangUserExpression::kDefaultTimeout);
591                 if (result_code == eExecutionCompleted)
592                 {
593                     if (result_value_sp)
594                     {
595                         Scalar scalar_value;
596                         if (result_value_sp->ResolveValue (scalar_value))
597                         {
598                             if (scalar_value.ULongLong(1) == 0)
599                             {
600                                 // We have been vetoed.  This takes precedence over querying
601                                 // the watchpoint whether it should stop (aka ignore count and
602                                 // friends).  See also StopInfoWatchpoint::ShouldStop() as well
603                                 // as Process::ProcessEventData::DoOnRemoval().
604                                 m_should_stop = false;
605                             }
606                             else
607                                 m_should_stop = true;
608                             if (log)
609                                 log->Printf("Condition successfully evaluated, result is %s.\n",
610                                             m_should_stop ? "true" : "false");
611                         }
612                         else
613                         {
614                             m_should_stop = true;
615                             if (log)
616                                 log->Printf("Failed to get an integer result from the expression.");
617                         }
618                     }
619                 }
620                 else
621                 {
622                     Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
623                     StreamSP error_sp = debugger.GetAsyncErrorStream ();
624                     error_sp->Printf ("Stopped due to an error evaluating condition of watchpoint ");
625                     wp_sp->GetDescription (error_sp.get(), eDescriptionLevelBrief);
626                     error_sp->Printf (": \"%s\"",
627                                       wp_sp->GetConditionText());
628                     error_sp->EOL();
629                     const char *err_str = error.AsCString("<Unknown Error>");
630                     if (log)
631                         log->Printf("Error evaluating condition: \"%s\"\n", err_str);
632 
633                     error_sp->PutCString (err_str);
634                     error_sp->EOL();
635                     error_sp->Flush();
636                     // If the condition fails to be parsed or run, we should stop.
637                     m_should_stop = true;
638                 }
639             }
640 
641             // If the condition says to stop, we run the callback to further decide whether to stop.
642             if (m_should_stop)
643             {
644                 StoppointCallbackContext context (event_ptr, exe_ctx, false);
645                 bool stop_requested = wp_sp->InvokeCallback (&context);
646                 // Also make sure that the callback hasn't continued the target.
647                 // If it did, when we'll set m_should_stop to false and get out of here.
648                 if (HasTargetRunSinceMe ())
649                     m_should_stop = false;
650 
651                 if (m_should_stop && !stop_requested)
652                 {
653                     // We have been vetoed by the callback mechanism.
654                     m_should_stop = false;
655                 }
656             }
657             // Finally, if we are going to stop, print out the new & old values:
658             if (m_should_stop)
659             {
660                 wp_sp->CaptureWatchedValue(exe_ctx);
661 
662                 Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
663                 StreamSP output_sp = debugger.GetAsyncOutputStream ();
664                 wp_sp->DumpSnapshots(output_sp.get());
665                 output_sp->EOL();
666                 output_sp->Flush();
667             }
668 
669         }
670         else
671         {
672             LogSP log_process(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
673 
674             if (log_process)
675                 log_process->Printf ("Process::%s could not find watchpoint id: %" PRId64 "...", __FUNCTION__, m_value);
676         }
677         if (log)
678             log->Printf ("Process::%s returning from action with m_should_stop: %d.", __FUNCTION__, m_should_stop);
679 
680     }
681 
682 private:
683     std::string m_description;
684     bool m_should_stop;
685     bool m_should_stop_is_valid;
686 };
687 
688 
689 
690 //----------------------------------------------------------------------
691 // StopInfoUnixSignal
692 //----------------------------------------------------------------------
693 
694 class StopInfoUnixSignal : public StopInfo
695 {
696 public:
697 
698     StopInfoUnixSignal (Thread &thread, int signo) :
699         StopInfo (thread, signo)
700     {
701     }
702 
703     virtual ~StopInfoUnixSignal ()
704     {
705     }
706 
707 
708     virtual StopReason
709     GetStopReason () const
710     {
711         return eStopReasonSignal;
712     }
713 
714     virtual bool
715     ShouldStop (Event *event_ptr)
716     {
717         return m_thread.GetProcess()->GetUnixSignals().GetShouldStop (m_value);
718     }
719 
720 
721     // If should stop returns false, check if we should notify of this event
722     virtual bool
723     ShouldNotify (Event *event_ptr)
724     {
725         return m_thread.GetProcess()->GetUnixSignals().GetShouldNotify (m_value);
726     }
727 
728 
729     virtual void
730     WillResume (lldb::StateType resume_state)
731     {
732         if (m_thread.GetProcess()->GetUnixSignals().GetShouldSuppress(m_value) == false)
733             m_thread.SetResumeSignal(m_value);
734     }
735 
736     virtual const char *
737     GetDescription ()
738     {
739         if (m_description.empty())
740         {
741             StreamString strm;
742             const char *signal_name = m_thread.GetProcess()->GetUnixSignals().GetSignalAsCString (m_value);
743             if (signal_name)
744                 strm.Printf("signal %s", signal_name);
745             else
746                 strm.Printf("signal %" PRIi64, m_value);
747             m_description.swap (strm.GetString());
748         }
749         return m_description.c_str();
750     }
751 };
752 
753 //----------------------------------------------------------------------
754 // StopInfoTrace
755 //----------------------------------------------------------------------
756 
757 class StopInfoTrace : public StopInfo
758 {
759 public:
760 
761     StopInfoTrace (Thread &thread) :
762         StopInfo (thread, LLDB_INVALID_UID)
763     {
764     }
765 
766     virtual ~StopInfoTrace ()
767     {
768     }
769 
770     virtual StopReason
771     GetStopReason () const
772     {
773         return eStopReasonTrace;
774     }
775 
776     virtual const char *
777     GetDescription ()
778     {
779         if (m_description.empty())
780         return "trace";
781         else
782             return m_description.c_str();
783     }
784 };
785 
786 
787 //----------------------------------------------------------------------
788 // StopInfoException
789 //----------------------------------------------------------------------
790 
791 class StopInfoException : public StopInfo
792 {
793 public:
794 
795     StopInfoException (Thread &thread, const char *description) :
796         StopInfo (thread, LLDB_INVALID_UID)
797     {
798         if (description)
799             SetDescription (description);
800     }
801 
802     virtual
803     ~StopInfoException ()
804     {
805     }
806 
807     virtual StopReason
808     GetStopReason () const
809     {
810         return eStopReasonException;
811     }
812 
813     virtual const char *
814     GetDescription ()
815     {
816         if (m_description.empty())
817             return "exception";
818         else
819             return m_description.c_str();
820     }
821 };
822 
823 
824 //----------------------------------------------------------------------
825 // StopInfoThreadPlan
826 //----------------------------------------------------------------------
827 
828 class StopInfoThreadPlan : public StopInfo
829 {
830 public:
831 
832     StopInfoThreadPlan (ThreadPlanSP &plan_sp, ValueObjectSP &return_valobj_sp) :
833         StopInfo (plan_sp->GetThread(), LLDB_INVALID_UID),
834         m_plan_sp (plan_sp),
835         m_return_valobj_sp (return_valobj_sp)
836     {
837     }
838 
839     virtual ~StopInfoThreadPlan ()
840     {
841     }
842 
843     virtual StopReason
844     GetStopReason () const
845     {
846         return eStopReasonPlanComplete;
847     }
848 
849     virtual const char *
850     GetDescription ()
851     {
852         if (m_description.empty())
853         {
854             StreamString strm;
855             m_plan_sp->GetDescription (&strm, eDescriptionLevelBrief);
856             m_description.swap (strm.GetString());
857         }
858         return m_description.c_str();
859     }
860 
861     ValueObjectSP
862     GetReturnValueObject()
863     {
864         return m_return_valobj_sp;
865     }
866 
867 private:
868     ThreadPlanSP m_plan_sp;
869     ValueObjectSP m_return_valobj_sp;
870 };
871 
872 class StopInfoExec : public StopInfo
873 {
874 public:
875 
876     StopInfoExec (Thread &thread) :
877         StopInfo (thread, LLDB_INVALID_UID),
878         m_performed_action (false)
879     {
880     }
881 
882     virtual
883     ~StopInfoExec ()
884     {
885     }
886 
887     virtual StopReason
888     GetStopReason () const
889     {
890         return eStopReasonExec;
891     }
892 
893     virtual const char *
894     GetDescription ()
895     {
896         return "exec";
897     }
898 protected:
899 protected:
900 
901     virtual void
902     PerformAction (Event *event_ptr)
903     {
904         // Only perform the action once
905         if (m_performed_action)
906             return;
907         m_performed_action = true;
908         m_thread.GetProcess()->DidExec();
909     }
910 
911     bool m_performed_action;
912 };
913 
914 } // namespace lldb_private
915 
916 StopInfoSP
917 StopInfo::CreateStopReasonWithBreakpointSiteID (Thread &thread, break_id_t break_id)
918 {
919     return StopInfoSP (new StopInfoBreakpoint (thread, break_id));
920 }
921 
922 StopInfoSP
923 StopInfo::CreateStopReasonWithBreakpointSiteID (Thread &thread, break_id_t break_id, bool should_stop)
924 {
925     return StopInfoSP (new StopInfoBreakpoint (thread, break_id, should_stop));
926 }
927 
928 StopInfoSP
929 StopInfo::CreateStopReasonWithWatchpointID (Thread &thread, break_id_t watch_id)
930 {
931     return StopInfoSP (new StopInfoWatchpoint (thread, watch_id));
932 }
933 
934 StopInfoSP
935 StopInfo::CreateStopReasonWithSignal (Thread &thread, int signo)
936 {
937     return StopInfoSP (new StopInfoUnixSignal (thread, signo));
938 }
939 
940 StopInfoSP
941 StopInfo::CreateStopReasonToTrace (Thread &thread)
942 {
943     return StopInfoSP (new StopInfoTrace (thread));
944 }
945 
946 StopInfoSP
947 StopInfo::CreateStopReasonWithPlan (ThreadPlanSP &plan_sp, ValueObjectSP return_valobj_sp)
948 {
949     return StopInfoSP (new StopInfoThreadPlan (plan_sp, return_valobj_sp));
950 }
951 
952 StopInfoSP
953 StopInfo::CreateStopReasonWithException (Thread &thread, const char *description)
954 {
955     return StopInfoSP (new StopInfoException (thread, description));
956 }
957 
958 StopInfoSP
959 StopInfo::CreateStopReasonWithExec (Thread &thread)
960 {
961     return StopInfoSP (new StopInfoExec (thread));
962 }
963 
964 ValueObjectSP
965 StopInfo::GetReturnValueObject(StopInfoSP &stop_info_sp)
966 {
967     if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonPlanComplete)
968     {
969         StopInfoThreadPlan *plan_stop_info = static_cast<StopInfoThreadPlan *>(stop_info_sp.get());
970         return plan_stop_info->GetReturnValueObject();
971     }
972     else
973         return ValueObjectSP();
974 }
975