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