1 //===-- BreakpointLocation.cpp ----------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
12 // Other libraries and framework 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"
34 using namespace lldb_private;
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()),
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);
52 m_being_created = false;
55 BreakpointLocation::~BreakpointLocation() { ClearBreakpointSite(); }
57 lldb::addr_t BreakpointLocation::GetLoadAddress() const {
58 return m_address.GetOpcodeLoadAddress(&m_owner.GetTarget());
61 Address &BreakpointLocation::GetAddress() { return m_address; }
63 Breakpoint &BreakpointLocation::GetBreakpoint() { return m_owner; }
65 Target &BreakpointLocation::GetTarget() { return m_owner.GetTarget(); }
67 bool BreakpointLocation::IsEnabled() const {
68 if (!m_owner.IsEnabled())
70 else if (m_options_ap.get() != nullptr)
71 return m_options_ap->IsEnabled();
76 void BreakpointLocation::SetEnabled(bool enabled) {
77 GetLocationOptions()->SetEnabled(enabled);
79 ResolveBreakpointSite();
81 ClearBreakpointSite();
83 SendBreakpointLocationChangedEvent(enabled ? eBreakpointEventTypeEnabled
84 : eBreakpointEventTypeDisabled);
87 void BreakpointLocation::SetThreadID(lldb::tid_t thread_id) {
88 if (thread_id != LLDB_INVALID_THREAD_ID)
89 GetLocationOptions()->SetThreadID(thread_id);
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);
96 SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
99 lldb::tid_t BreakpointLocation::GetThreadID() {
100 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
101 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID();
103 return LLDB_INVALID_THREAD_ID;
106 void BreakpointLocation::SetThreadIndex(uint32_t index) {
108 GetLocationOptions()->GetThreadSpec()->SetIndex(index);
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);
115 SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
118 uint32_t BreakpointLocation::GetThreadIndex() const {
119 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
120 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetIndex();
125 void BreakpointLocation::SetThreadName(const char *thread_name) {
126 if (thread_name != nullptr)
127 GetLocationOptions()->GetThreadSpec()->SetName(thread_name);
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);
134 SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
137 const char *BreakpointLocation::GetThreadName() const {
138 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
139 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetName();
144 void BreakpointLocation::SetQueueName(const char *queue_name) {
145 if (queue_name != nullptr)
146 GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name);
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);
153 SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
156 const char *BreakpointLocation::GetQueueName() const {
157 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
158 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetQueueName();
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());
167 return m_owner.InvokeCallback(context, GetID());
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);
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);
186 void BreakpointLocation::ClearCallback() {
187 GetLocationOptions()->ClearCallback();
190 void BreakpointLocation::SetCondition(const char *condition) {
191 GetLocationOptions()->SetCondition(condition);
192 SendBreakpointLocationChangedEvent(eBreakpointEventTypeConditionChanged);
195 const char *BreakpointLocation::GetConditionText(size_t *hash) const {
196 return GetOptionsNoCreate()->GetConditionText(hash);
199 bool BreakpointLocation::ConditionSaysStop(ExecutionContext &exe_ctx,
201 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
203 std::lock_guard<std::mutex> guard(m_condition_mutex);
205 size_t condition_hash;
206 const char *condition_text = GetConditionText(&condition_hash);
208 if (!condition_text) {
209 m_user_expression_sp.reset();
215 DiagnosticManager diagnostics;
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
222 CompileUnit *comp_unit = m_address.CalculateSymbolContextCompileUnit();
224 language = comp_unit->GetLanguage();
226 m_user_expression_sp.reset(GetTarget().GetUserExpressionForLanguage(
227 condition_text, llvm::StringRef(), language, Expression::eResultTypeAny,
228 EvaluateExpressionOptions(), error));
231 log->Printf("Error getting condition expression: %s.",
233 m_user_expression_sp.reset();
237 if (!m_user_expression_sp->Parse(diagnostics, exe_ctx,
238 eExecutionPolicyOnlyWhenNeeded, true,
240 error.SetErrorStringWithFormat(
241 "Couldn't parse conditional expression:\n%s",
242 diagnostics.GetString().c_str());
243 m_user_expression_sp.reset();
247 m_condition_hash = condition_hash;
250 // We need to make sure the user sees any parse errors in their condition, so
252 // constructor errors up to the debugger's Async I/O.
254 ValueObjectSP result_value_sp;
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.
267 ExpressionVariableSP result_variable_sp;
269 ExpressionResults result_code = m_user_expression_sp->Execute(
270 diagnostics, exe_ctx, options, m_user_expression_sp, result_variable_sp);
274 if (result_code == eExpressionCompleted) {
275 if (!result_variable_sp) {
276 error.SetErrorString("Expression did not return a result");
280 result_value_sp = result_variable_sp->GetValueObject();
282 if (result_value_sp) {
283 ret = result_value_sp->IsLogicalTrue(error);
285 if (error.Success()) {
286 log->Printf("Condition successfully evaluated, result is %s.\n",
287 ret ? "true" : "false");
289 error.SetErrorString(
290 "Failed to get an integer result from the expression");
296 error.SetErrorString("Failed to get any result from the expression");
300 error.SetErrorStringWithFormat("Couldn't execute expression:\n%s",
301 diagnostics.GetString().c_str());
307 uint32_t BreakpointLocation::GetIgnoreCount() {
308 return GetOptionsNoCreate()->GetIgnoreCount();
311 void BreakpointLocation::SetIgnoreCount(uint32_t n) {
312 GetLocationOptions()->SetIgnoreCount(n);
313 SendBreakpointLocationChangedEvent(eBreakpointEventTypeIgnoreChanged);
316 void BreakpointLocation::DecrementIgnoreCount() {
317 if (m_options_ap.get() != nullptr) {
318 uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
320 m_options_ap->SetIgnoreCount(loc_ignore - 1);
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
338 const BreakpointOptions *BreakpointLocation::GetOptionsNoCreate() const {
339 if (m_options_ap.get() != nullptr)
340 return m_options_ap.get();
342 return m_owner.GetOptions();
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)
351 BreakpointOptions::CopyOptionsNoCallback(*m_owner.GetOptions()));
353 return m_options_ap.get();
356 bool BreakpointLocation::ValidForThisThread(Thread *thread) {
357 return thread->MatchesSpec(GetOptionsNoCreate()->GetThreadSpecNoCreate());
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.
365 bool BreakpointLocation::ShouldStop(StoppointCallbackContext *context) {
366 bool should_stop = true;
367 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
369 // Do this first, if a location is disabled, it shouldn't increment its hit
374 if (!IgnoreCountShouldStop())
377 if (!m_owner.IgnoreCountShouldStop())
380 // We only run synchronous callbacks in ShouldStop:
381 context->is_synchronous = true;
382 should_stop = InvokeCallback(context);
386 GetDescription(&s, lldb::eDescriptionLevelVerbose);
387 log->Printf("Hit breakpoint location: %s, %s.\n", s.GetData(),
388 should_stop ? "stopping" : "continuing");
394 void BreakpointLocation::BumpHitCount() {
396 // Step our hit count, and also step the hit count of the owner.
398 m_owner.IncrementHitCount();
402 void BreakpointLocation::UndoBumpHitCount() {
404 // Step our hit count, and also step the hit count of the owner.
406 m_owner.DecrementHitCount();
410 bool BreakpointLocation::IsResolved() const {
411 return m_bp_site_sp.get() != nullptr;
414 lldb::BreakpointSiteSP BreakpointLocation::GetBreakpointSite() const {
418 bool BreakpointLocation::ResolveBreakpointSite() {
422 Process *process = m_owner.GetTarget().GetProcessSP().get();
423 if (process == nullptr)
426 lldb::break_id_t new_id =
427 process->CreateBreakpointSite(shared_from_this(), m_owner.IsHardware());
429 if (new_id == LLDB_INVALID_BREAK_ID) {
430 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
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()));
441 bool BreakpointLocation::SetBreakpointSite(BreakpointSiteSP &bp_site_sp) {
442 m_bp_site_sp = bp_site_sp;
443 SendBreakpointLocationChangedEvent(eBreakpointEventTypeLocationsResolved);
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.
455 process_sp->RemoveOwnerFromBreakpointSite(GetBreakpoint().GetID(),
456 GetID(), m_bp_site_sp);
458 m_bp_site_sp->RemoveOwner(GetBreakpoint().GetID(), GetID());
460 m_bp_site_sp.reset();
466 void BreakpointLocation::GetDescription(Stream *s,
467 lldb::DescriptionLevel level) {
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) {
475 BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID());
478 if (level == lldb::eDescriptionLevelBrief)
481 if (level != eDescriptionLevelInitial)
484 if (level == lldb::eDescriptionLevelVerbose)
487 if (m_address.IsSectionOffset()) {
488 m_address.CalculateSymbolContext(&sc);
490 if (level == lldb::eDescriptionLevelFull ||
491 level == eDescriptionLevelInitial) {
493 s->PutCString("re-exported target = ");
495 s->PutCString("where = ");
496 sc.DumpStopContext(s, m_owner.GetTarget().GetProcessSP().get(), m_address,
497 false, true, false, true, true);
501 s->Indent("module = ");
502 sc.module_sp->GetFileSpec().Dump(s);
505 if (sc.comp_unit != nullptr) {
507 s->Indent("compile unit = ");
508 static_cast<FileSpec *>(sc.comp_unit)->GetFilename().Dump(s);
510 if (sc.function != nullptr) {
512 s->Indent("function = ");
513 s->PutCString(sc.function->GetName().AsCString("<unknown>"));
516 if (sc.line_entry.line > 0) {
518 s->Indent("location = ");
519 sc.line_entry.DumpStopContext(s, true);
523 // If we don't have a comp unit, see if we have a symbol we can print.
527 s->Indent("re-exported target = ");
529 s->Indent("symbol = ");
530 s->PutCString(sc.symbol->GetName().AsCString("<unknown>"));
536 if (level == lldb::eDescriptionLevelVerbose) {
541 if (m_address.IsSectionOffset() &&
542 (level == eDescriptionLevelFull || level == eDescriptionLevelInitial))
544 s->Printf("address = ");
546 ExecutionContextScope *exe_scope = nullptr;
547 Target *target = &m_owner.GetTarget();
549 exe_scope = target->GetProcessSP().get();
550 if (exe_scope == nullptr)
553 if (level == eDescriptionLevelInitial)
554 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress,
555 Address::DumpStyleFileAddress);
557 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress,
558 Address::DumpStyleModuleWithFileAddress);
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)
567 else if (level == lldb::eDescriptionLevelVerbose) {
571 s->Printf("indirect target = %s",
572 resolved_symbol->GetName().GetCString());
576 if (level == lldb::eDescriptionLevelVerbose) {
579 s->Printf("resolved = %s\n", IsResolved() ? "true" : "false");
582 s->Printf("hit count = %-4u\n", GetHitCount());
584 if (m_options_ap.get()) {
586 m_options_ap->GetDescription(s, level);
590 } else if (level != eDescriptionLevelInitial) {
591 s->Printf(", %sresolved, hit count = %u ", (IsResolved() ? "" : "un"),
593 if (m_options_ap.get()) {
594 m_options_ap->GetDescription(s, level);
599 void BreakpointLocation::Dump(Stream *s) const {
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())
612 IsHardware() ? "hardware" : "software", GetHardwareIndex(), GetHitCount(),
613 GetOptionsNoCreate()->GetIgnoreCount());
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,
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();