1 //===-- BreakpointLocation.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 // C Includes
13 // C++ Includes
14 #include <string>
15 
16 // Other libraries and framework includes
17 // Project includes
18 #include "lldb/lldb-private-log.h"
19 #include "lldb/Breakpoint/BreakpointLocation.h"
20 #include "lldb/Breakpoint/BreakpointID.h"
21 #include "lldb/Breakpoint/StoppointCallbackContext.h"
22 #include "lldb/Core/Debugger.h"
23 #include "lldb/Core/Log.h"
24 #include "lldb/Core/Module.h"
25 #include "lldb/Core/StreamString.h"
26 #include "lldb/Symbol/CompileUnit.h"
27 #include "lldb/Symbol/Symbol.h"
28 #include "lldb/Target/Target.h"
29 #include "lldb/Target/Process.h"
30 #include "lldb/Target/Thread.h"
31 #include "lldb/Target/ThreadSpec.h"
32 
33 using namespace lldb;
34 using namespace lldb_private;
35 
36 BreakpointLocation::BreakpointLocation
37 (
38     break_id_t loc_id,
39     Breakpoint &owner,
40     const Address &addr,
41     lldb::tid_t tid,
42     bool hardware
43 ) :
44     StoppointLocation (loc_id, addr.GetOpcodeLoadAddress(&owner.GetTarget()), hardware),
45     m_being_created(true),
46     m_address (addr),
47     m_owner (owner),
48     m_options_ap (),
49     m_bp_site_sp ()
50 {
51     SetThreadID (tid);
52     m_being_created = false;
53 }
54 
55 BreakpointLocation::~BreakpointLocation()
56 {
57     ClearBreakpointSite();
58 }
59 
60 lldb::addr_t
61 BreakpointLocation::GetLoadAddress () const
62 {
63     return m_address.GetOpcodeLoadAddress (&m_owner.GetTarget());
64 }
65 
66 Address &
67 BreakpointLocation::GetAddress ()
68 {
69     return m_address;
70 }
71 
72 Breakpoint &
73 BreakpointLocation::GetBreakpoint ()
74 {
75     return m_owner;
76 }
77 
78 bool
79 BreakpointLocation::IsEnabled () const
80 {
81     if (!m_owner.IsEnabled())
82         return false;
83     else if (m_options_ap.get() != NULL)
84         return m_options_ap->IsEnabled();
85     else
86         return true;
87 }
88 
89 void
90 BreakpointLocation::SetEnabled (bool enabled)
91 {
92     GetLocationOptions()->SetEnabled(enabled);
93     if (enabled)
94     {
95         ResolveBreakpointSite();
96     }
97     else
98     {
99         ClearBreakpointSite();
100     }
101     SendBreakpointLocationChangedEvent (enabled ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled);
102 }
103 
104 void
105 BreakpointLocation::SetThreadID (lldb::tid_t thread_id)
106 {
107     if (thread_id != LLDB_INVALID_THREAD_ID)
108         GetLocationOptions()->SetThreadID(thread_id);
109     else
110     {
111         // If we're resetting this to an invalid thread id, then
112         // don't make an options pointer just to do that.
113         if (m_options_ap.get() != NULL)
114             m_options_ap->SetThreadID (thread_id);
115     }
116     SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
117 }
118 
119 lldb::tid_t
120 BreakpointLocation::GetThreadID ()
121 {
122     if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
123         return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID();
124     else
125         return LLDB_INVALID_THREAD_ID;
126 }
127 
128 void
129 BreakpointLocation::SetThreadIndex (uint32_t index)
130 {
131     if (index != 0)
132         GetLocationOptions()->GetThreadSpec()->SetIndex(index);
133     else
134     {
135         // If we're resetting this to an invalid thread id, then
136         // don't make an options pointer just to do that.
137         if (m_options_ap.get() != NULL)
138             m_options_ap->GetThreadSpec()->SetIndex(index);
139     }
140     SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
141 
142 }
143 
144 uint32_t
145 BreakpointLocation::GetThreadIndex() const
146 {
147     if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
148         return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetIndex();
149     else
150         return 0;
151 }
152 
153 void
154 BreakpointLocation::SetThreadName (const char *thread_name)
155 {
156     if (thread_name != NULL)
157         GetLocationOptions()->GetThreadSpec()->SetName(thread_name);
158     else
159     {
160         // If we're resetting this to an invalid thread id, then
161         // don't make an options pointer just to do that.
162         if (m_options_ap.get() != NULL)
163             m_options_ap->GetThreadSpec()->SetName(thread_name);
164     }
165     SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
166 }
167 
168 const char *
169 BreakpointLocation::GetThreadName () const
170 {
171     if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
172         return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetName();
173     else
174         return NULL;
175 }
176 
177 void
178 BreakpointLocation::SetQueueName (const char *queue_name)
179 {
180     if (queue_name != NULL)
181         GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name);
182     else
183     {
184         // If we're resetting this to an invalid thread id, then
185         // don't make an options pointer just to do that.
186         if (m_options_ap.get() != NULL)
187             m_options_ap->GetThreadSpec()->SetQueueName(queue_name);
188     }
189     SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
190 }
191 
192 const char *
193 BreakpointLocation::GetQueueName () const
194 {
195     if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
196         return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetQueueName();
197     else
198         return NULL;
199 }
200 
201 bool
202 BreakpointLocation::InvokeCallback (StoppointCallbackContext *context)
203 {
204     if (m_options_ap.get() != NULL && m_options_ap->HasCallback())
205         return m_options_ap->InvokeCallback (context, m_owner.GetID(), GetID());
206     else
207         return m_owner.InvokeCallback (context, GetID());
208 }
209 
210 void
211 BreakpointLocation::SetCallback (BreakpointHitCallback callback, void *baton,
212                  bool is_synchronous)
213 {
214     // The default "Baton" class will keep a copy of "baton" and won't free
215     // or delete it when it goes goes out of scope.
216     GetLocationOptions()->SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous);
217     SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged);
218 }
219 
220 void
221 BreakpointLocation::SetCallback (BreakpointHitCallback callback, const BatonSP &baton_sp,
222                  bool is_synchronous)
223 {
224     GetLocationOptions()->SetCallback (callback, baton_sp, is_synchronous);
225     SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged);
226 }
227 
228 
229 void
230 BreakpointLocation::ClearCallback ()
231 {
232     GetLocationOptions()->ClearCallback();
233 }
234 
235 void
236 BreakpointLocation::SetCondition (const char *condition)
237 {
238     GetLocationOptions()->SetCondition (condition);
239     SendBreakpointLocationChangedEvent (eBreakpointEventTypeConditionChanged);
240 }
241 
242 const char *
243 BreakpointLocation::GetConditionText (size_t *hash) const
244 {
245     return GetOptionsNoCreate()->GetConditionText(hash);
246 }
247 
248 bool
249 BreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error)
250 {
251     Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
252 
253     size_t condition_hash;
254     const char *condition_text = GetConditionText(&condition_hash);
255 
256     if (!condition_text)
257         return false;
258 
259     if (condition_hash != m_condition_hash ||
260         !m_user_expression_sp ||
261         !m_user_expression_sp->MatchesContext(exe_ctx))
262     {
263         m_user_expression_sp.reset(new ClangUserExpression(condition_text,
264                                                            NULL,
265                                                            lldb::eLanguageTypeUnknown,
266                                                            ClangUserExpression::eResultTypeAny));
267 
268         StreamString errors;
269 
270         if (!m_user_expression_sp->Parse(errors,
271                                          exe_ctx,
272                                          eExecutionPolicyOnlyWhenNeeded,
273                                          true))
274         {
275             error.SetErrorStringWithFormat("Couldn't parse conditional expression:\n%s",
276                                            errors.GetData());
277             m_user_expression_sp.reset();
278             return false;
279         }
280 
281         m_condition_hash = condition_hash;
282     }
283 
284     // We need to make sure the user sees any parse errors in their condition, so we'll hook the
285     // constructor errors up to the debugger's Async I/O.
286 
287     ValueObjectSP result_value_sp;
288     const bool unwind_on_error = true;
289     const bool ignore_breakpoints = true;
290     const bool try_all_threads = true;
291 
292     Error expr_error;
293 
294     StreamString execution_errors;
295 
296     ClangExpressionVariableSP result_variable_sp;
297 
298     ExecutionResults result_code =
299     m_user_expression_sp->Execute(execution_errors,
300                                   exe_ctx,
301                                   unwind_on_error,
302                                   ignore_breakpoints,
303                                   m_user_expression_sp,
304                                   result_variable_sp,
305                                   try_all_threads,
306                                   ClangUserExpression::kDefaultTimeout);
307 
308     bool ret;
309 
310     if (result_code == eExecutionCompleted)
311     {
312         result_value_sp = result_variable_sp->GetValueObject();
313 
314         if (result_value_sp)
315         {
316             Scalar scalar_value;
317             if (result_value_sp->ResolveValue (scalar_value))
318             {
319                 if (scalar_value.ULongLong(1) == 0)
320                     ret = false;
321                 else
322                     ret = true;
323                 if (log)
324                     log->Printf("Condition successfully evaluated, result is %s.\n",
325                                 ret ? "true" : "false");
326             }
327             else
328             {
329                 ret = false;
330                 error.SetErrorString("Failed to get an integer result from the expression");
331             }
332         }
333         else
334         {
335             ret = false;
336             error.SetErrorString("Failed to get any result from the expression");
337         }
338     }
339     else
340     {
341         ret = false;
342         error.SetErrorStringWithFormat("Couldn't execute expression:\n%s", execution_errors.GetData());
343     }
344 
345     return ret;
346 }
347 
348 uint32_t
349 BreakpointLocation::GetIgnoreCount ()
350 {
351     return GetOptionsNoCreate()->GetIgnoreCount();
352 }
353 
354 void
355 BreakpointLocation::SetIgnoreCount (uint32_t n)
356 {
357     GetLocationOptions()->SetIgnoreCount(n);
358     SendBreakpointLocationChangedEvent (eBreakpointEventTypeIgnoreChanged);
359 }
360 
361 void
362 BreakpointLocation::DecrementIgnoreCount()
363 {
364     if (m_options_ap.get() != NULL)
365     {
366         uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
367         if (loc_ignore != 0)
368             m_options_ap->SetIgnoreCount(loc_ignore - 1);
369     }
370 }
371 
372 bool
373 BreakpointLocation::IgnoreCountShouldStop()
374 {
375     if (m_options_ap.get() != NULL)
376     {
377         uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
378         if (loc_ignore != 0)
379         {
380             m_owner.DecrementIgnoreCount();
381             DecrementIgnoreCount();          // Have to decrement our owners' ignore count, since it won't get a
382                                              // chance to.
383             return false;
384         }
385     }
386     return true;
387 }
388 
389 const BreakpointOptions *
390 BreakpointLocation::GetOptionsNoCreate () const
391 {
392     if (m_options_ap.get() != NULL)
393         return m_options_ap.get();
394     else
395         return m_owner.GetOptions ();
396 }
397 
398 BreakpointOptions *
399 BreakpointLocation::GetLocationOptions ()
400 {
401     // If we make the copy we don't copy the callbacks because that is potentially
402     // expensive and we don't want to do that for the simple case where someone is
403     // just disabling the location.
404     if (m_options_ap.get() == NULL)
405         m_options_ap.reset(BreakpointOptions::CopyOptionsNoCallback(*m_owner.GetOptions ()));
406 
407     return m_options_ap.get();
408 }
409 
410 bool
411 BreakpointLocation::ValidForThisThread (Thread *thread)
412 {
413     return thread->MatchesSpec(GetOptionsNoCreate()->GetThreadSpecNoCreate());
414 }
415 
416 // RETURNS - true if we should stop at this breakpoint, false if we
417 // should continue.  Note, we don't check the thread spec for the breakpoint
418 // here, since if the breakpoint is not for this thread, then the event won't
419 // even get reported, so the check is redundant.
420 
421 bool
422 BreakpointLocation::ShouldStop (StoppointCallbackContext *context)
423 {
424     bool should_stop = true;
425     Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
426 
427     IncrementHitCount();
428 
429     if (!IsEnabled())
430         return false;
431 
432     if (!IgnoreCountShouldStop())
433         return false;
434 
435     if (!m_owner.IgnoreCountShouldStop())
436         return false;
437 
438     // We only run synchronous callbacks in ShouldStop:
439     context->is_synchronous = true;
440     should_stop = InvokeCallback (context);
441 
442     if (log)
443     {
444         StreamString s;
445         GetDescription (&s, lldb::eDescriptionLevelVerbose);
446         log->Printf ("Hit breakpoint location: %s, %s.\n", s.GetData(), should_stop ? "stopping" : "continuing");
447     }
448 
449     return should_stop;
450 }
451 
452 bool
453 BreakpointLocation::IsResolved () const
454 {
455     return m_bp_site_sp.get() != NULL;
456 }
457 
458 lldb::BreakpointSiteSP
459 BreakpointLocation::GetBreakpointSite() const
460 {
461     return m_bp_site_sp;
462 }
463 
464 bool
465 BreakpointLocation::ResolveBreakpointSite ()
466 {
467     if (m_bp_site_sp)
468         return true;
469 
470     Process *process = m_owner.GetTarget().GetProcessSP().get();
471     if (process == NULL)
472         return false;
473 
474     if (m_owner.GetTarget().GetSectionLoadList().IsEmpty())
475         return false;
476 
477     lldb::break_id_t new_id = process->CreateBreakpointSite (shared_from_this(), false);
478 
479     if (new_id == LLDB_INVALID_BREAK_ID)
480     {
481         Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
482         if (log)
483             log->Warning ("Tried to add breakpoint site at 0x%" PRIx64 " but it was already present.\n",
484                           m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()));
485         return false;
486     }
487 
488     return true;
489 }
490 
491 bool
492 BreakpointLocation::SetBreakpointSite (BreakpointSiteSP& bp_site_sp)
493 {
494     m_bp_site_sp = bp_site_sp;
495     return true;
496 }
497 
498 bool
499 BreakpointLocation::ClearBreakpointSite ()
500 {
501     if (m_bp_site_sp.get())
502     {
503         m_owner.GetTarget().GetProcessSP()->RemoveOwnerFromBreakpointSite (GetBreakpoint().GetID(),
504                                                                            GetID(), m_bp_site_sp);
505         m_bp_site_sp.reset();
506         return true;
507     }
508     return false;
509 }
510 
511 void
512 BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level)
513 {
514     SymbolContext sc;
515 
516     // If the description level is "initial" then the breakpoint is printing out our initial state,
517     // and we should let it decide how it wants to print our label.
518     if (level != eDescriptionLevelInitial)
519     {
520         s->Indent();
521         BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID());
522     }
523 
524     if (level == lldb::eDescriptionLevelBrief)
525         return;
526 
527     if (level != eDescriptionLevelInitial)
528         s->PutCString(": ");
529 
530     if (level == lldb::eDescriptionLevelVerbose)
531         s->IndentMore();
532 
533     if (m_address.IsSectionOffset())
534     {
535         m_address.CalculateSymbolContext(&sc);
536 
537         if (level == lldb::eDescriptionLevelFull || level == eDescriptionLevelInitial)
538         {
539             s->PutCString("where = ");
540             sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false);
541         }
542         else
543         {
544             if (sc.module_sp)
545             {
546                 s->EOL();
547                 s->Indent("module = ");
548                 sc.module_sp->GetFileSpec().Dump (s);
549             }
550 
551             if (sc.comp_unit != NULL)
552             {
553                 s->EOL();
554                 s->Indent("compile unit = ");
555                 static_cast<FileSpec*>(sc.comp_unit)->GetFilename().Dump (s);
556 
557                 if (sc.function != NULL)
558                 {
559                     s->EOL();
560                     s->Indent("function = ");
561                     s->PutCString (sc.function->GetMangled().GetName().AsCString("<unknown>"));
562                 }
563 
564                 if (sc.line_entry.line > 0)
565                 {
566                     s->EOL();
567                     s->Indent("location = ");
568                     sc.line_entry.DumpStopContext (s, true);
569                 }
570 
571             }
572             else
573             {
574                 // If we don't have a comp unit, see if we have a symbol we can print.
575                 if (sc.symbol)
576                 {
577                     s->EOL();
578                     s->Indent("symbol = ");
579                     s->PutCString(sc.symbol->GetMangled().GetName().AsCString("<unknown>"));
580                 }
581             }
582         }
583     }
584 
585     if (level == lldb::eDescriptionLevelVerbose)
586     {
587         s->EOL();
588         s->Indent();
589     }
590 
591     if (m_address.IsSectionOffset() && (level == eDescriptionLevelFull || level == eDescriptionLevelInitial))
592         s->Printf (", ");
593     s->Printf ("address = ");
594 
595     ExecutionContextScope *exe_scope = NULL;
596     Target *target = &m_owner.GetTarget();
597     if (target)
598         exe_scope = target->GetProcessSP().get();
599     if (exe_scope == NULL)
600         exe_scope = target;
601 
602     if (eDescriptionLevelInitial)
603         m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
604     else
605         m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
606 
607     if (level == lldb::eDescriptionLevelVerbose)
608     {
609         s->EOL();
610         s->Indent();
611         s->Printf("resolved = %s\n", IsResolved() ? "true" : "false");
612 
613         s->Indent();
614         s->Printf ("hit count = %-4u\n", GetHitCount());
615 
616         if (m_options_ap.get())
617         {
618             s->Indent();
619             m_options_ap->GetDescription (s, level);
620             s->EOL();
621         }
622         s->IndentLess();
623     }
624     else if (level != eDescriptionLevelInitial)
625     {
626         s->Printf(", %sresolved, hit count = %u ",
627                   (IsResolved() ? "" : "un"),
628                   GetHitCount());
629         if (m_options_ap.get())
630         {
631             m_options_ap->GetDescription (s, level);
632         }
633     }
634 }
635 
636 void
637 BreakpointLocation::Dump(Stream *s) const
638 {
639     if (s == NULL)
640         return;
641 
642     s->Printf("BreakpointLocation %u: tid = %4.4" PRIx64 "  load addr = 0x%8.8" PRIx64 "  state = %s  type = %s breakpoint  "
643               "hw_index = %i  hit_count = %-4u  ignore_count = %-4u",
644               GetID(),
645               GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(),
646               (uint64_t) m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()),
647               (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled()) ? "enabled " : "disabled",
648               IsHardware() ? "hardware" : "software",
649               GetHardwareIndex(),
650               GetHitCount(),
651               GetOptionsNoCreate()->GetIgnoreCount());
652 }
653 
654 void
655 BreakpointLocation::SendBreakpointLocationChangedEvent (lldb::BreakpointEventType eventKind)
656 {
657     if (!m_being_created
658         && !m_owner.IsInternal()
659         && m_owner.GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
660     {
661         Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind,
662                                                                                      m_owner.shared_from_this());
663         data->GetBreakpointLocationCollection().Add (shared_from_this());
664         m_owner.GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
665     }
666 }
667 
668