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 const BreakpointOptions *
62 BreakpointLocation::GetOptionsSpecifyingKind(BreakpointOptions::OptionKind kind)
64 if (m_options_ap && m_options_ap->IsOptionSet(kind))
65 return m_options_ap.get();
67 return m_owner.GetOptions();
70 Address &BreakpointLocation::GetAddress() { return m_address; }
72 Breakpoint &BreakpointLocation::GetBreakpoint() { return m_owner; }
74 Target &BreakpointLocation::GetTarget() { return m_owner.GetTarget(); }
76 bool BreakpointLocation::IsEnabled() const {
77 if (!m_owner.IsEnabled())
79 else if (m_options_ap.get() != nullptr)
80 return m_options_ap->IsEnabled();
85 void BreakpointLocation::SetEnabled(bool enabled) {
86 GetLocationOptions()->SetEnabled(enabled);
88 ResolveBreakpointSite();
90 ClearBreakpointSite();
92 SendBreakpointLocationChangedEvent(enabled ? eBreakpointEventTypeEnabled
93 : eBreakpointEventTypeDisabled);
96 bool BreakpointLocation::IsAutoContinue() const {
98 && m_options_ap->IsOptionSet(BreakpointOptions::eAutoContinue))
99 return m_options_ap->IsAutoContinue();
101 return m_owner.IsAutoContinue();
104 void BreakpointLocation::SetAutoContinue(bool auto_continue) {
105 GetLocationOptions()->SetAutoContinue(auto_continue);
106 SendBreakpointLocationChangedEvent(eBreakpointEventTypeAutoContinueChanged);
109 void BreakpointLocation::SetThreadID(lldb::tid_t thread_id) {
110 if (thread_id != LLDB_INVALID_THREAD_ID)
111 GetLocationOptions()->SetThreadID(thread_id);
113 // If we're resetting this to an invalid thread id, then
114 // don't make an options pointer just to do that.
115 if (m_options_ap.get() != nullptr)
116 m_options_ap->SetThreadID(thread_id);
118 SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
121 lldb::tid_t BreakpointLocation::GetThreadID() {
122 const ThreadSpec *thread_spec =
123 GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
124 ->GetThreadSpecNoCreate();
126 return thread_spec->GetTID();
128 return LLDB_INVALID_THREAD_ID;
131 void BreakpointLocation::SetThreadIndex(uint32_t index) {
133 GetLocationOptions()->GetThreadSpec()->SetIndex(index);
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() != nullptr)
138 m_options_ap->GetThreadSpec()->SetIndex(index);
140 SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
143 uint32_t BreakpointLocation::GetThreadIndex() const {
144 const ThreadSpec *thread_spec =
145 GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
146 ->GetThreadSpecNoCreate();
148 return thread_spec->GetIndex();
153 void BreakpointLocation::SetThreadName(const char *thread_name) {
154 if (thread_name != nullptr)
155 GetLocationOptions()->GetThreadSpec()->SetName(thread_name);
157 // If we're resetting this to an invalid thread id, then
158 // don't make an options pointer just to do that.
159 if (m_options_ap.get() != nullptr)
160 m_options_ap->GetThreadSpec()->SetName(thread_name);
162 SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
165 const char *BreakpointLocation::GetThreadName() const {
166 const ThreadSpec *thread_spec =
167 GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
168 ->GetThreadSpecNoCreate();
170 return thread_spec->GetName();
175 void BreakpointLocation::SetQueueName(const char *queue_name) {
176 if (queue_name != nullptr)
177 GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name);
179 // If we're resetting this to an invalid thread id, then
180 // don't make an options pointer just to do that.
181 if (m_options_ap.get() != nullptr)
182 m_options_ap->GetThreadSpec()->SetQueueName(queue_name);
184 SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
187 const char *BreakpointLocation::GetQueueName() const {
188 const ThreadSpec *thread_spec =
189 GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
190 ->GetThreadSpecNoCreate();
192 return thread_spec->GetQueueName();
197 bool BreakpointLocation::InvokeCallback(StoppointCallbackContext *context) {
198 if (m_options_ap.get() != nullptr && m_options_ap->HasCallback())
199 return m_options_ap->InvokeCallback(context, m_owner.GetID(), GetID());
201 return m_owner.InvokeCallback(context, GetID());
204 void BreakpointLocation::SetCallback(BreakpointHitCallback callback,
205 void *baton, bool is_synchronous) {
206 // The default "Baton" class will keep a copy of "baton" and won't free
207 // or delete it when it goes goes out of scope.
208 GetLocationOptions()->SetCallback(
209 callback, std::make_shared<UntypedBaton>(baton), is_synchronous);
210 SendBreakpointLocationChangedEvent(eBreakpointEventTypeCommandChanged);
213 void BreakpointLocation::SetCallback(BreakpointHitCallback callback,
214 const BatonSP &baton_sp,
215 bool is_synchronous) {
216 GetLocationOptions()->SetCallback(callback, baton_sp, is_synchronous);
217 SendBreakpointLocationChangedEvent(eBreakpointEventTypeCommandChanged);
220 void BreakpointLocation::ClearCallback() {
221 GetLocationOptions()->ClearCallback();
224 void BreakpointLocation::SetCondition(const char *condition) {
225 GetLocationOptions()->SetCondition(condition);
226 SendBreakpointLocationChangedEvent(eBreakpointEventTypeConditionChanged);
229 const char *BreakpointLocation::GetConditionText(size_t *hash) const {
230 return GetOptionsSpecifyingKind(BreakpointOptions::eCondition)
231 ->GetConditionText(hash);
234 bool BreakpointLocation::ConditionSaysStop(ExecutionContext &exe_ctx,
236 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
238 std::lock_guard<std::mutex> guard(m_condition_mutex);
240 size_t condition_hash;
241 const char *condition_text = GetConditionText(&condition_hash);
243 if (!condition_text) {
244 m_user_expression_sp.reset();
250 DiagnosticManager diagnostics;
252 if (condition_hash != m_condition_hash || !m_user_expression_sp ||
253 !m_user_expression_sp->MatchesContext(exe_ctx)) {
254 LanguageType language = eLanguageTypeUnknown;
255 // See if we can figure out the language from the frame, otherwise use the
257 CompileUnit *comp_unit = m_address.CalculateSymbolContextCompileUnit();
259 language = comp_unit->GetLanguage();
261 m_user_expression_sp.reset(GetTarget().GetUserExpressionForLanguage(
262 condition_text, llvm::StringRef(), language, Expression::eResultTypeAny,
263 EvaluateExpressionOptions(), error));
266 log->Printf("Error getting condition expression: %s.",
268 m_user_expression_sp.reset();
272 if (!m_user_expression_sp->Parse(diagnostics, exe_ctx,
273 eExecutionPolicyOnlyWhenNeeded, true,
275 error.SetErrorStringWithFormat(
276 "Couldn't parse conditional expression:\n%s",
277 diagnostics.GetString().c_str());
278 m_user_expression_sp.reset();
282 m_condition_hash = condition_hash;
285 // We need to make sure the user sees any parse errors in their condition, so
287 // constructor errors up to the debugger's Async I/O.
289 ValueObjectSP result_value_sp;
291 EvaluateExpressionOptions options;
292 options.SetUnwindOnError(true);
293 options.SetIgnoreBreakpoints(true);
294 options.SetTryAllThreads(true);
295 options.SetResultIsInternal(
296 true); // Don't generate a user variable for condition expressions.
302 ExpressionVariableSP result_variable_sp;
304 ExpressionResults result_code = m_user_expression_sp->Execute(
305 diagnostics, exe_ctx, options, m_user_expression_sp, result_variable_sp);
309 if (result_code == eExpressionCompleted) {
310 if (!result_variable_sp) {
311 error.SetErrorString("Expression did not return a result");
315 result_value_sp = result_variable_sp->GetValueObject();
317 if (result_value_sp) {
318 ret = result_value_sp->IsLogicalTrue(error);
320 if (error.Success()) {
321 log->Printf("Condition successfully evaluated, result is %s.\n",
322 ret ? "true" : "false");
324 error.SetErrorString(
325 "Failed to get an integer result from the expression");
331 error.SetErrorString("Failed to get any result from the expression");
335 error.SetErrorStringWithFormat("Couldn't execute expression:\n%s",
336 diagnostics.GetString().c_str());
342 uint32_t BreakpointLocation::GetIgnoreCount() {
343 return GetOptionsSpecifyingKind(BreakpointOptions::eIgnoreCount)
347 void BreakpointLocation::SetIgnoreCount(uint32_t n) {
348 GetLocationOptions()->SetIgnoreCount(n);
349 SendBreakpointLocationChangedEvent(eBreakpointEventTypeIgnoreChanged);
352 void BreakpointLocation::DecrementIgnoreCount() {
353 if (m_options_ap.get() != nullptr) {
354 uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
356 m_options_ap->SetIgnoreCount(loc_ignore - 1);
360 bool BreakpointLocation::IgnoreCountShouldStop() {
361 if (m_options_ap.get() != nullptr) {
362 uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
363 if (loc_ignore != 0) {
364 m_owner.DecrementIgnoreCount();
365 DecrementIgnoreCount(); // Have to decrement our owners' ignore count,
366 // since it won't get a
374 BreakpointOptions *BreakpointLocation::GetLocationOptions() {
375 // If we make the copy we don't copy the callbacks because that is potentially
376 // expensive and we don't want to do that for the simple case where someone is
377 // just disabling the location.
378 if (m_options_ap.get() == nullptr)
380 new BreakpointOptions(false));
382 return m_options_ap.get();
385 bool BreakpointLocation::ValidForThisThread(Thread *thread) {
387 ->MatchesSpec(GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
388 ->GetThreadSpecNoCreate());
391 // RETURNS - true if we should stop at this breakpoint, false if we
392 // should continue. Note, we don't check the thread spec for the breakpoint
393 // here, since if the breakpoint is not for this thread, then the event won't
394 // even get reported, so the check is redundant.
396 bool BreakpointLocation::ShouldStop(StoppointCallbackContext *context) {
397 bool should_stop = true;
398 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
400 // Do this first, if a location is disabled, it shouldn't increment its hit
405 if (!IgnoreCountShouldStop())
408 if (!m_owner.IgnoreCountShouldStop())
411 // We only run synchronous callbacks in ShouldStop:
412 context->is_synchronous = true;
413 should_stop = InvokeCallback(context);
417 GetDescription(&s, lldb::eDescriptionLevelVerbose);
418 log->Printf("Hit breakpoint location: %s, %s.\n", s.GetData(),
419 should_stop ? "stopping" : "continuing");
425 void BreakpointLocation::BumpHitCount() {
427 // Step our hit count, and also step the hit count of the owner.
429 m_owner.IncrementHitCount();
433 void BreakpointLocation::UndoBumpHitCount() {
435 // Step our hit count, and also step the hit count of the owner.
437 m_owner.DecrementHitCount();
441 bool BreakpointLocation::IsResolved() const {
442 return m_bp_site_sp.get() != nullptr;
445 lldb::BreakpointSiteSP BreakpointLocation::GetBreakpointSite() const {
449 bool BreakpointLocation::ResolveBreakpointSite() {
453 Process *process = m_owner.GetTarget().GetProcessSP().get();
454 if (process == nullptr)
457 lldb::break_id_t new_id =
458 process->CreateBreakpointSite(shared_from_this(), m_owner.IsHardware());
460 if (new_id == LLDB_INVALID_BREAK_ID) {
461 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
463 log->Warning("Tried to add breakpoint site at 0x%" PRIx64
464 " but it was already present.\n",
465 m_address.GetOpcodeLoadAddress(&m_owner.GetTarget()));
472 bool BreakpointLocation::SetBreakpointSite(BreakpointSiteSP &bp_site_sp) {
473 m_bp_site_sp = bp_site_sp;
474 SendBreakpointLocationChangedEvent(eBreakpointEventTypeLocationsResolved);
478 bool BreakpointLocation::ClearBreakpointSite() {
479 if (m_bp_site_sp.get()) {
480 ProcessSP process_sp(m_owner.GetTarget().GetProcessSP());
481 // If the process exists, get it to remove the owner, it will remove the
482 // physical implementation
483 // of the breakpoint as well if there are no more owners. Otherwise just
484 // remove this owner.
486 process_sp->RemoveOwnerFromBreakpointSite(GetBreakpoint().GetID(),
487 GetID(), m_bp_site_sp);
489 m_bp_site_sp->RemoveOwner(GetBreakpoint().GetID(), GetID());
491 m_bp_site_sp.reset();
497 void BreakpointLocation::GetDescription(Stream *s,
498 lldb::DescriptionLevel level) {
501 // If the description level is "initial" then the breakpoint is printing out
502 // our initial state,
503 // and we should let it decide how it wants to print our label.
504 if (level != eDescriptionLevelInitial) {
506 BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID());
509 if (level == lldb::eDescriptionLevelBrief)
512 if (level != eDescriptionLevelInitial)
515 if (level == lldb::eDescriptionLevelVerbose)
518 if (m_address.IsSectionOffset()) {
519 m_address.CalculateSymbolContext(&sc);
521 if (level == lldb::eDescriptionLevelFull ||
522 level == eDescriptionLevelInitial) {
524 s->PutCString("re-exported target = ");
526 s->PutCString("where = ");
527 sc.DumpStopContext(s, m_owner.GetTarget().GetProcessSP().get(), m_address,
528 false, true, false, true, true);
532 s->Indent("module = ");
533 sc.module_sp->GetFileSpec().Dump(s);
536 if (sc.comp_unit != nullptr) {
538 s->Indent("compile unit = ");
539 static_cast<FileSpec *>(sc.comp_unit)->GetFilename().Dump(s);
541 if (sc.function != nullptr) {
543 s->Indent("function = ");
544 s->PutCString(sc.function->GetName().AsCString("<unknown>"));
547 if (sc.line_entry.line > 0) {
549 s->Indent("location = ");
550 sc.line_entry.DumpStopContext(s, true);
554 // If we don't have a comp unit, see if we have a symbol we can print.
558 s->Indent("re-exported target = ");
560 s->Indent("symbol = ");
561 s->PutCString(sc.symbol->GetName().AsCString("<unknown>"));
567 if (level == lldb::eDescriptionLevelVerbose) {
572 if (m_address.IsSectionOffset() &&
573 (level == eDescriptionLevelFull || level == eDescriptionLevelInitial))
575 s->Printf("address = ");
577 ExecutionContextScope *exe_scope = nullptr;
578 Target *target = &m_owner.GetTarget();
580 exe_scope = target->GetProcessSP().get();
581 if (exe_scope == nullptr)
584 if (level == eDescriptionLevelInitial)
585 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress,
586 Address::DumpStyleFileAddress);
588 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress,
589 Address::DumpStyleModuleWithFileAddress);
591 if (IsIndirect() && m_bp_site_sp) {
592 Address resolved_address;
593 resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target);
594 Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol();
595 if (resolved_symbol) {
596 if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)
598 else if (level == lldb::eDescriptionLevelVerbose) {
602 s->Printf("indirect target = %s",
603 resolved_symbol->GetName().GetCString());
607 if (level == lldb::eDescriptionLevelVerbose) {
610 s->Printf("resolved = %s\n", IsResolved() ? "true" : "false");
613 s->Printf("hit count = %-4u\n", GetHitCount());
615 if (m_options_ap.get()) {
617 m_options_ap->GetDescription(s, level);
621 } else if (level != eDescriptionLevelInitial) {
622 s->Printf(", %sresolved, hit count = %u ", (IsResolved() ? "" : "un"),
624 if (m_options_ap.get()) {
625 m_options_ap->GetDescription(s, level);
630 void BreakpointLocation::Dump(Stream *s) const {
634 lldb::tid_t tid = GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
635 ->GetThreadSpecNoCreate()->GetTID();
637 "BreakpointLocation %u: tid = %4.4" PRIx64 " load addr = 0x%8.8" PRIx64
638 " state = %s type = %s breakpoint "
639 "hw_index = %i hit_count = %-4u ignore_count = %-4u",
641 (uint64_t)m_address.GetOpcodeLoadAddress(&m_owner.GetTarget()),
642 (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled())
645 IsHardware() ? "hardware" : "software", GetHardwareIndex(), GetHitCount(),
646 GetOptionsSpecifyingKind(BreakpointOptions::eIgnoreCount)
650 void BreakpointLocation::SendBreakpointLocationChangedEvent(
651 lldb::BreakpointEventType eventKind) {
652 if (!m_being_created && !m_owner.IsInternal() &&
653 m_owner.GetTarget().EventTypeHasListeners(
654 Target::eBroadcastBitBreakpointChanged)) {
655 Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData(
656 eventKind, m_owner.shared_from_this());
657 data->GetBreakpointLocationCollection().Add(shared_from_this());
658 m_owner.GetTarget().BroadcastEvent(Target::eBroadcastBitBreakpointChanged,
663 void BreakpointLocation::SwapLocation(BreakpointLocationSP swap_from) {
664 m_address = swap_from->m_address;
665 m_should_resolve_indirect_functions =
666 swap_from->m_should_resolve_indirect_functions;
667 m_is_reexported = swap_from->m_is_reexported;
668 m_is_indirect = swap_from->m_is_indirect;
669 m_user_expression_sp.reset();