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