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