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 //===----------------------------------------------------------------------===//
10 #include "lldb/Breakpoint/BreakpointLocation.h"
11 #include "lldb/Breakpoint/BreakpointID.h"
12 #include "lldb/Breakpoint/StoppointCallbackContext.h"
13 #include "lldb/Core/Debugger.h"
14 #include "lldb/Core/Module.h"
15 #include "lldb/Core/ValueObject.h"
16 #include "lldb/Expression/DiagnosticManager.h"
17 #include "lldb/Expression/ExpressionVariable.h"
18 #include "lldb/Expression/UserExpression.h"
19 #include "lldb/Symbol/CompileUnit.h"
20 #include "lldb/Symbol/Symbol.h"
21 #include "lldb/Symbol/TypeSystem.h"
22 #include "lldb/Target/Process.h"
23 #include "lldb/Target/Target.h"
24 #include "lldb/Target/Thread.h"
25 #include "lldb/Target/ThreadSpec.h"
26 #include "lldb/Utility/Log.h"
27 #include "lldb/Utility/StreamString.h"
30 using namespace lldb_private;
32 BreakpointLocation::BreakpointLocation(break_id_t loc_id, Breakpoint &owner,
33 const Address &addr, lldb::tid_t tid,
34 bool hardware, bool check_for_resolver)
35 : StoppointLocation(loc_id, addr.GetOpcodeLoadAddress(&owner.GetTarget()),
37 m_being_created(true), m_should_resolve_indirect_functions(false),
38 m_is_reexported(false), m_is_indirect(false), m_address(addr),
39 m_owner(owner), m_options_ap(), m_bp_site_sp(), m_condition_mutex() {
40 if (check_for_resolver) {
41 Symbol *symbol = m_address.CalculateSymbolContextSymbol();
42 if (symbol && symbol->IsIndirect()) {
43 SetShouldResolveIndirectFunctions(true);
48 m_being_created = false;
51 BreakpointLocation::~BreakpointLocation() { ClearBreakpointSite(); }
53 lldb::addr_t BreakpointLocation::GetLoadAddress() const {
54 return m_address.GetOpcodeLoadAddress(&m_owner.GetTarget());
57 const BreakpointOptions *
58 BreakpointLocation::GetOptionsSpecifyingKind(BreakpointOptions::OptionKind kind)
60 if (m_options_ap && m_options_ap->IsOptionSet(kind))
61 return m_options_ap.get();
63 return m_owner.GetOptions();
66 Address &BreakpointLocation::GetAddress() { return m_address; }
68 Breakpoint &BreakpointLocation::GetBreakpoint() { return m_owner; }
70 Target &BreakpointLocation::GetTarget() { return m_owner.GetTarget(); }
72 bool BreakpointLocation::IsEnabled() const {
73 if (!m_owner.IsEnabled())
75 else if (m_options_ap.get() != nullptr)
76 return m_options_ap->IsEnabled();
81 void BreakpointLocation::SetEnabled(bool enabled) {
82 GetLocationOptions()->SetEnabled(enabled);
84 ResolveBreakpointSite();
86 ClearBreakpointSite();
88 SendBreakpointLocationChangedEvent(enabled ? eBreakpointEventTypeEnabled
89 : eBreakpointEventTypeDisabled);
92 bool BreakpointLocation::IsAutoContinue() const {
94 && m_options_ap->IsOptionSet(BreakpointOptions::eAutoContinue))
95 return m_options_ap->IsAutoContinue();
97 return m_owner.IsAutoContinue();
100 void BreakpointLocation::SetAutoContinue(bool auto_continue) {
101 GetLocationOptions()->SetAutoContinue(auto_continue);
102 SendBreakpointLocationChangedEvent(eBreakpointEventTypeAutoContinueChanged);
105 void BreakpointLocation::SetThreadID(lldb::tid_t thread_id) {
106 if (thread_id != LLDB_INVALID_THREAD_ID)
107 GetLocationOptions()->SetThreadID(thread_id);
109 // If we're resetting this to an invalid thread id, then don't make an
110 // options pointer just to do that.
111 if (m_options_ap.get() != nullptr)
112 m_options_ap->SetThreadID(thread_id);
114 SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
117 lldb::tid_t BreakpointLocation::GetThreadID() {
118 const ThreadSpec *thread_spec =
119 GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
120 ->GetThreadSpecNoCreate();
122 return thread_spec->GetTID();
124 return LLDB_INVALID_THREAD_ID;
127 void BreakpointLocation::SetThreadIndex(uint32_t index) {
129 GetLocationOptions()->GetThreadSpec()->SetIndex(index);
131 // If we're resetting this to an invalid thread id, then don't make an
132 // options pointer just to do that.
133 if (m_options_ap.get() != nullptr)
134 m_options_ap->GetThreadSpec()->SetIndex(index);
136 SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
139 uint32_t BreakpointLocation::GetThreadIndex() const {
140 const ThreadSpec *thread_spec =
141 GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
142 ->GetThreadSpecNoCreate();
144 return thread_spec->GetIndex();
149 void BreakpointLocation::SetThreadName(const char *thread_name) {
150 if (thread_name != nullptr)
151 GetLocationOptions()->GetThreadSpec()->SetName(thread_name);
153 // If we're resetting this to an invalid thread id, then don't make an
154 // options pointer just to do that.
155 if (m_options_ap.get() != nullptr)
156 m_options_ap->GetThreadSpec()->SetName(thread_name);
158 SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
161 const char *BreakpointLocation::GetThreadName() const {
162 const ThreadSpec *thread_spec =
163 GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
164 ->GetThreadSpecNoCreate();
166 return thread_spec->GetName();
171 void BreakpointLocation::SetQueueName(const char *queue_name) {
172 if (queue_name != nullptr)
173 GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name);
175 // If we're resetting this to an invalid thread id, then don't make an
176 // options pointer just to do that.
177 if (m_options_ap.get() != nullptr)
178 m_options_ap->GetThreadSpec()->SetQueueName(queue_name);
180 SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
183 const char *BreakpointLocation::GetQueueName() const {
184 const ThreadSpec *thread_spec =
185 GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
186 ->GetThreadSpecNoCreate();
188 return thread_spec->GetQueueName();
193 bool BreakpointLocation::InvokeCallback(StoppointCallbackContext *context) {
194 if (m_options_ap.get() != nullptr && m_options_ap->HasCallback())
195 return m_options_ap->InvokeCallback(context, m_owner.GetID(), GetID());
197 return m_owner.InvokeCallback(context, GetID());
200 void BreakpointLocation::SetCallback(BreakpointHitCallback callback,
201 void *baton, bool is_synchronous) {
202 // The default "Baton" class will keep a copy of "baton" and won't free or
203 // delete it when it goes goes out of scope.
204 GetLocationOptions()->SetCallback(
205 callback, std::make_shared<UntypedBaton>(baton), is_synchronous);
206 SendBreakpointLocationChangedEvent(eBreakpointEventTypeCommandChanged);
209 void BreakpointLocation::SetCallback(BreakpointHitCallback callback,
210 const BatonSP &baton_sp,
211 bool is_synchronous) {
212 GetLocationOptions()->SetCallback(callback, baton_sp, is_synchronous);
213 SendBreakpointLocationChangedEvent(eBreakpointEventTypeCommandChanged);
216 void BreakpointLocation::ClearCallback() {
217 GetLocationOptions()->ClearCallback();
220 void BreakpointLocation::SetCondition(const char *condition) {
221 GetLocationOptions()->SetCondition(condition);
222 SendBreakpointLocationChangedEvent(eBreakpointEventTypeConditionChanged);
225 const char *BreakpointLocation::GetConditionText(size_t *hash) const {
226 return GetOptionsSpecifyingKind(BreakpointOptions::eCondition)
227 ->GetConditionText(hash);
230 bool BreakpointLocation::ConditionSaysStop(ExecutionContext &exe_ctx,
232 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
234 std::lock_guard<std::mutex> guard(m_condition_mutex);
236 size_t condition_hash;
237 const char *condition_text = GetConditionText(&condition_hash);
239 if (!condition_text) {
240 m_user_expression_sp.reset();
246 DiagnosticManager diagnostics;
248 if (condition_hash != m_condition_hash || !m_user_expression_sp ||
249 !m_user_expression_sp->MatchesContext(exe_ctx)) {
250 LanguageType language = eLanguageTypeUnknown;
251 // See if we can figure out the language from the frame, otherwise use the
253 CompileUnit *comp_unit = m_address.CalculateSymbolContextCompileUnit();
255 language = comp_unit->GetLanguage();
257 m_user_expression_sp.reset(GetTarget().GetUserExpressionForLanguage(
258 condition_text, llvm::StringRef(), language, Expression::eResultTypeAny,
259 EvaluateExpressionOptions(), error));
262 log->Printf("Error getting condition expression: %s.",
264 m_user_expression_sp.reset();
268 if (!m_user_expression_sp->Parse(diagnostics, exe_ctx,
269 eExecutionPolicyOnlyWhenNeeded, true,
271 error.SetErrorStringWithFormat(
272 "Couldn't parse conditional expression:\n%s",
273 diagnostics.GetString().c_str());
274 m_user_expression_sp.reset();
278 m_condition_hash = condition_hash;
281 // We need to make sure the user sees any parse errors in their condition, so
282 // we'll hook the constructor errors up to the debugger's Async I/O.
284 ValueObjectSP result_value_sp;
286 EvaluateExpressionOptions options;
287 options.SetUnwindOnError(true);
288 options.SetIgnoreBreakpoints(true);
289 options.SetTryAllThreads(true);
290 options.SetResultIsInternal(
291 true); // Don't generate a user variable for condition expressions.
297 ExpressionVariableSP result_variable_sp;
299 ExpressionResults result_code = m_user_expression_sp->Execute(
300 diagnostics, exe_ctx, options, m_user_expression_sp, result_variable_sp);
304 if (result_code == eExpressionCompleted) {
305 if (!result_variable_sp) {
306 error.SetErrorString("Expression did not return a result");
310 result_value_sp = result_variable_sp->GetValueObject();
312 if (result_value_sp) {
313 ret = result_value_sp->IsLogicalTrue(error);
315 if (error.Success()) {
316 log->Printf("Condition successfully evaluated, result is %s.\n",
317 ret ? "true" : "false");
319 error.SetErrorString(
320 "Failed to get an integer result from the expression");
326 error.SetErrorString("Failed to get any result from the expression");
330 error.SetErrorStringWithFormat("Couldn't execute expression:\n%s",
331 diagnostics.GetString().c_str());
337 uint32_t BreakpointLocation::GetIgnoreCount() {
338 return GetOptionsSpecifyingKind(BreakpointOptions::eIgnoreCount)
342 void BreakpointLocation::SetIgnoreCount(uint32_t n) {
343 GetLocationOptions()->SetIgnoreCount(n);
344 SendBreakpointLocationChangedEvent(eBreakpointEventTypeIgnoreChanged);
347 void BreakpointLocation::DecrementIgnoreCount() {
348 if (m_options_ap.get() != nullptr) {
349 uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
351 m_options_ap->SetIgnoreCount(loc_ignore - 1);
355 bool BreakpointLocation::IgnoreCountShouldStop() {
356 if (m_options_ap.get() != nullptr) {
357 uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
358 if (loc_ignore != 0) {
359 m_owner.DecrementIgnoreCount();
360 DecrementIgnoreCount(); // Have to decrement our owners' ignore count,
361 // since it won't get a
369 BreakpointOptions *BreakpointLocation::GetLocationOptions() {
370 // If we make the copy we don't copy the callbacks because that is
371 // potentially expensive and we don't want to do that for the simple case
372 // where someone is just disabling the location.
373 if (m_options_ap.get() == nullptr)
375 new BreakpointOptions(false));
377 return m_options_ap.get();
380 bool BreakpointLocation::ValidForThisThread(Thread *thread) {
382 ->MatchesSpec(GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
383 ->GetThreadSpecNoCreate());
386 // RETURNS - true if we should stop at this breakpoint, false if we
387 // should continue. Note, we don't check the thread spec for the breakpoint
388 // here, since if the breakpoint is not for this thread, then the event won't
389 // even get reported, so the check is redundant.
391 bool BreakpointLocation::ShouldStop(StoppointCallbackContext *context) {
392 bool should_stop = true;
393 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
395 // Do this first, if a location is disabled, it shouldn't increment its hit
400 if (!IgnoreCountShouldStop())
403 if (!m_owner.IgnoreCountShouldStop())
406 // We only run synchronous callbacks in ShouldStop:
407 context->is_synchronous = true;
408 should_stop = InvokeCallback(context);
412 GetDescription(&s, lldb::eDescriptionLevelVerbose);
413 log->Printf("Hit breakpoint location: %s, %s.\n", s.GetData(),
414 should_stop ? "stopping" : "continuing");
420 void BreakpointLocation::BumpHitCount() {
422 // Step our hit count, and also step the hit count of the owner.
424 m_owner.IncrementHitCount();
428 void BreakpointLocation::UndoBumpHitCount() {
430 // Step our hit count, and also step the hit count of the owner.
432 m_owner.DecrementHitCount();
436 bool BreakpointLocation::IsResolved() const {
437 return m_bp_site_sp.get() != nullptr;
440 lldb::BreakpointSiteSP BreakpointLocation::GetBreakpointSite() const {
444 bool BreakpointLocation::ResolveBreakpointSite() {
448 Process *process = m_owner.GetTarget().GetProcessSP().get();
449 if (process == nullptr)
452 lldb::break_id_t new_id =
453 process->CreateBreakpointSite(shared_from_this(), m_owner.IsHardware());
455 if (new_id == LLDB_INVALID_BREAK_ID) {
456 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
458 log->Warning("Tried to add breakpoint site at 0x%" PRIx64
459 " but it was already present.\n",
460 m_address.GetOpcodeLoadAddress(&m_owner.GetTarget()));
467 bool BreakpointLocation::SetBreakpointSite(BreakpointSiteSP &bp_site_sp) {
468 m_bp_site_sp = bp_site_sp;
469 SendBreakpointLocationChangedEvent(eBreakpointEventTypeLocationsResolved);
473 bool BreakpointLocation::ClearBreakpointSite() {
474 if (m_bp_site_sp.get()) {
475 ProcessSP process_sp(m_owner.GetTarget().GetProcessSP());
476 // If the process exists, get it to remove the owner, it will remove the
477 // physical implementation of the breakpoint as well if there are no more
478 // owners. Otherwise just remove this owner.
480 process_sp->RemoveOwnerFromBreakpointSite(GetBreakpoint().GetID(),
481 GetID(), m_bp_site_sp);
483 m_bp_site_sp->RemoveOwner(GetBreakpoint().GetID(), GetID());
485 m_bp_site_sp.reset();
491 void BreakpointLocation::GetDescription(Stream *s,
492 lldb::DescriptionLevel level) {
495 // If the description level is "initial" then the breakpoint is printing out
496 // our initial state, and we should let it decide how it wants to print our
498 if (level != eDescriptionLevelInitial) {
500 BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID());
503 if (level == lldb::eDescriptionLevelBrief)
506 if (level != eDescriptionLevelInitial)
509 if (level == lldb::eDescriptionLevelVerbose)
512 if (m_address.IsSectionOffset()) {
513 m_address.CalculateSymbolContext(&sc);
515 if (level == lldb::eDescriptionLevelFull ||
516 level == eDescriptionLevelInitial) {
518 s->PutCString("re-exported target = ");
520 s->PutCString("where = ");
521 sc.DumpStopContext(s, m_owner.GetTarget().GetProcessSP().get(), m_address,
522 false, true, false, true, true);
526 s->Indent("module = ");
527 sc.module_sp->GetFileSpec().Dump(s);
530 if (sc.comp_unit != nullptr) {
532 s->Indent("compile unit = ");
533 static_cast<FileSpec *>(sc.comp_unit)->GetFilename().Dump(s);
535 if (sc.function != nullptr) {
537 s->Indent("function = ");
538 s->PutCString(sc.function->GetName().AsCString("<unknown>"));
541 if (sc.line_entry.line > 0) {
543 s->Indent("location = ");
544 sc.line_entry.DumpStopContext(s, true);
548 // If we don't have a comp unit, see if we have a symbol we can print.
552 s->Indent("re-exported target = ");
554 s->Indent("symbol = ");
555 s->PutCString(sc.symbol->GetName().AsCString("<unknown>"));
561 if (level == lldb::eDescriptionLevelVerbose) {
566 if (m_address.IsSectionOffset() &&
567 (level == eDescriptionLevelFull || level == eDescriptionLevelInitial))
569 s->Printf("address = ");
571 ExecutionContextScope *exe_scope = nullptr;
572 Target *target = &m_owner.GetTarget();
574 exe_scope = target->GetProcessSP().get();
575 if (exe_scope == nullptr)
578 if (level == eDescriptionLevelInitial)
579 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress,
580 Address::DumpStyleFileAddress);
582 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress,
583 Address::DumpStyleModuleWithFileAddress);
585 if (IsIndirect() && m_bp_site_sp) {
586 Address resolved_address;
587 resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target);
588 Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol();
589 if (resolved_symbol) {
590 if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)
592 else if (level == lldb::eDescriptionLevelVerbose) {
596 s->Printf("indirect target = %s",
597 resolved_symbol->GetName().GetCString());
601 if (level == lldb::eDescriptionLevelVerbose) {
604 s->Printf("resolved = %s\n", IsResolved() ? "true" : "false");
607 s->Printf("hit count = %-4u\n", GetHitCount());
609 if (m_options_ap.get()) {
611 m_options_ap->GetDescription(s, level);
615 } else if (level != eDescriptionLevelInitial) {
616 s->Printf(", %sresolved, hit count = %u ", (IsResolved() ? "" : "un"),
618 if (m_options_ap.get()) {
619 m_options_ap->GetDescription(s, level);
624 void BreakpointLocation::Dump(Stream *s) const {
628 lldb::tid_t tid = GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
629 ->GetThreadSpecNoCreate()->GetTID();
631 "BreakpointLocation %u: tid = %4.4" PRIx64 " load addr = 0x%8.8" PRIx64
632 " state = %s type = %s breakpoint "
633 "hw_index = %i hit_count = %-4u ignore_count = %-4u",
635 (uint64_t)m_address.GetOpcodeLoadAddress(&m_owner.GetTarget()),
636 (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled())
639 IsHardware() ? "hardware" : "software", GetHardwareIndex(), GetHitCount(),
640 GetOptionsSpecifyingKind(BreakpointOptions::eIgnoreCount)
644 void BreakpointLocation::SendBreakpointLocationChangedEvent(
645 lldb::BreakpointEventType eventKind) {
646 if (!m_being_created && !m_owner.IsInternal() &&
647 m_owner.GetTarget().EventTypeHasListeners(
648 Target::eBroadcastBitBreakpointChanged)) {
649 Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData(
650 eventKind, m_owner.shared_from_this());
651 data->GetBreakpointLocationCollection().Add(shared_from_this());
652 m_owner.GetTarget().BroadcastEvent(Target::eBroadcastBitBreakpointChanged,
657 void BreakpointLocation::SwapLocation(BreakpointLocationSP swap_from) {
658 m_address = swap_from->m_address;
659 m_should_resolve_indirect_functions =
660 swap_from->m_should_resolve_indirect_functions;
661 m_is_reexported = swap_from->m_is_reexported;
662 m_is_indirect = swap_from->m_is_indirect;
663 m_user_expression_sp.reset();