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