diff options
Diffstat (limited to 'lldb/source/Breakpoint/BreakpointLocation.cpp')
-rw-r--r-- | lldb/source/Breakpoint/BreakpointLocation.cpp | 1115 |
1 files changed, 498 insertions, 617 deletions
diff --git a/lldb/source/Breakpoint/BreakpointLocation.cpp b/lldb/source/Breakpoint/BreakpointLocation.cpp index e1b1af0fe78..c68bf6a05df 100644 --- a/lldb/source/Breakpoint/BreakpointLocation.cpp +++ b/lldb/source/Breakpoint/BreakpointLocation.cpp @@ -25,421 +25,336 @@ #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/TypeSystem.h" -#include "lldb/Target/Target.h" #include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadSpec.h" using namespace lldb; using namespace lldb_private; -BreakpointLocation::BreakpointLocation(break_id_t loc_id, Breakpoint &owner, const Address &addr, lldb::tid_t tid, +BreakpointLocation::BreakpointLocation(break_id_t loc_id, Breakpoint &owner, + const Address &addr, lldb::tid_t tid, bool hardware, bool check_for_resolver) - : StoppointLocation(loc_id, addr.GetOpcodeLoadAddress(&owner.GetTarget()), hardware), - m_being_created(true), - m_should_resolve_indirect_functions(false), - m_is_reexported(false), - m_is_indirect(false), - m_address(addr), - m_owner(owner), - m_options_ap(), - m_bp_site_sp(), - m_condition_mutex() -{ - if (check_for_resolver) - { - Symbol *symbol = m_address.CalculateSymbolContextSymbol(); - if (symbol && symbol->IsIndirect()) - { - SetShouldResolveIndirectFunctions(true); - } + : StoppointLocation(loc_id, addr.GetOpcodeLoadAddress(&owner.GetTarget()), + hardware), + m_being_created(true), m_should_resolve_indirect_functions(false), + m_is_reexported(false), m_is_indirect(false), m_address(addr), + m_owner(owner), m_options_ap(), m_bp_site_sp(), m_condition_mutex() { + if (check_for_resolver) { + Symbol *symbol = m_address.CalculateSymbolContextSymbol(); + if (symbol && symbol->IsIndirect()) { + SetShouldResolveIndirectFunctions(true); } + } - SetThreadID(tid); - m_being_created = false; + SetThreadID(tid); + m_being_created = false; } -BreakpointLocation::~BreakpointLocation() -{ - ClearBreakpointSite(); -} +BreakpointLocation::~BreakpointLocation() { ClearBreakpointSite(); } -lldb::addr_t -BreakpointLocation::GetLoadAddress () const -{ - return m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()); +lldb::addr_t BreakpointLocation::GetLoadAddress() const { + return m_address.GetOpcodeLoadAddress(&m_owner.GetTarget()); } -Address & -BreakpointLocation::GetAddress () -{ - return m_address; -} +Address &BreakpointLocation::GetAddress() { return m_address; } -Breakpoint & -BreakpointLocation::GetBreakpoint () -{ - return m_owner; -} +Breakpoint &BreakpointLocation::GetBreakpoint() { return m_owner; } -Target & -BreakpointLocation::GetTarget() -{ - return m_owner.GetTarget(); -} +Target &BreakpointLocation::GetTarget() { return m_owner.GetTarget(); } -bool -BreakpointLocation::IsEnabled () const -{ - if (!m_owner.IsEnabled()) - return false; - else if (m_options_ap.get() != nullptr) - return m_options_ap->IsEnabled(); - else - return true; +bool BreakpointLocation::IsEnabled() const { + if (!m_owner.IsEnabled()) + return false; + else if (m_options_ap.get() != nullptr) + return m_options_ap->IsEnabled(); + else + return true; } -void -BreakpointLocation::SetEnabled (bool enabled) -{ - GetLocationOptions()->SetEnabled(enabled); - if (enabled) - { - ResolveBreakpointSite(); - } - else - { - ClearBreakpointSite(); - } - SendBreakpointLocationChangedEvent (enabled ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled); +void BreakpointLocation::SetEnabled(bool enabled) { + GetLocationOptions()->SetEnabled(enabled); + if (enabled) { + ResolveBreakpointSite(); + } else { + ClearBreakpointSite(); + } + SendBreakpointLocationChangedEvent(enabled ? eBreakpointEventTypeEnabled + : eBreakpointEventTypeDisabled); } -void -BreakpointLocation::SetThreadID (lldb::tid_t thread_id) -{ - if (thread_id != LLDB_INVALID_THREAD_ID) - GetLocationOptions()->SetThreadID(thread_id); - else - { - // If we're resetting this to an invalid thread id, then - // don't make an options pointer just to do that. - if (m_options_ap.get() != nullptr) - m_options_ap->SetThreadID (thread_id); - } - SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged); +void BreakpointLocation::SetThreadID(lldb::tid_t thread_id) { + if (thread_id != LLDB_INVALID_THREAD_ID) + GetLocationOptions()->SetThreadID(thread_id); + else { + // If we're resetting this to an invalid thread id, then + // don't make an options pointer just to do that. + if (m_options_ap.get() != nullptr) + m_options_ap->SetThreadID(thread_id); + } + SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged); } -lldb::tid_t -BreakpointLocation::GetThreadID () -{ - if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) - return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(); - else - return LLDB_INVALID_THREAD_ID; +lldb::tid_t BreakpointLocation::GetThreadID() { + if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) + return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(); + else + return LLDB_INVALID_THREAD_ID; } -void -BreakpointLocation::SetThreadIndex (uint32_t index) -{ - if (index != 0) - GetLocationOptions()->GetThreadSpec()->SetIndex(index); - else - { - // If we're resetting this to an invalid thread id, then - // don't make an options pointer just to do that. - if (m_options_ap.get() != nullptr) - m_options_ap->GetThreadSpec()->SetIndex(index); - } - SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged); +void BreakpointLocation::SetThreadIndex(uint32_t index) { + if (index != 0) + GetLocationOptions()->GetThreadSpec()->SetIndex(index); + else { + // If we're resetting this to an invalid thread id, then + // don't make an options pointer just to do that. + if (m_options_ap.get() != nullptr) + m_options_ap->GetThreadSpec()->SetIndex(index); + } + SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged); } -uint32_t -BreakpointLocation::GetThreadIndex() const -{ - if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) - return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetIndex(); - else - return 0; +uint32_t BreakpointLocation::GetThreadIndex() const { + if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) + return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetIndex(); + else + return 0; } -void -BreakpointLocation::SetThreadName (const char *thread_name) -{ - if (thread_name != nullptr) - GetLocationOptions()->GetThreadSpec()->SetName(thread_name); - else - { - // If we're resetting this to an invalid thread id, then - // don't make an options pointer just to do that. - if (m_options_ap.get() != nullptr) - m_options_ap->GetThreadSpec()->SetName(thread_name); - } - SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged); +void BreakpointLocation::SetThreadName(const char *thread_name) { + if (thread_name != nullptr) + GetLocationOptions()->GetThreadSpec()->SetName(thread_name); + else { + // If we're resetting this to an invalid thread id, then + // don't make an options pointer just to do that. + if (m_options_ap.get() != nullptr) + m_options_ap->GetThreadSpec()->SetName(thread_name); + } + SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged); } -const char * -BreakpointLocation::GetThreadName () const -{ - if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) - return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetName(); - else - return nullptr; +const char *BreakpointLocation::GetThreadName() const { + if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) + return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetName(); + else + return nullptr; } -void -BreakpointLocation::SetQueueName (const char *queue_name) -{ - if (queue_name != nullptr) - GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name); - else - { - // If we're resetting this to an invalid thread id, then - // don't make an options pointer just to do that. - if (m_options_ap.get() != nullptr) - m_options_ap->GetThreadSpec()->SetQueueName(queue_name); - } - SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged); +void BreakpointLocation::SetQueueName(const char *queue_name) { + if (queue_name != nullptr) + GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name); + else { + // If we're resetting this to an invalid thread id, then + // don't make an options pointer just to do that. + if (m_options_ap.get() != nullptr) + m_options_ap->GetThreadSpec()->SetQueueName(queue_name); + } + SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged); } -const char * -BreakpointLocation::GetQueueName () const -{ - if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) - return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetQueueName(); - else - return nullptr; +const char *BreakpointLocation::GetQueueName() const { + if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) + return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetQueueName(); + else + return nullptr; } -bool -BreakpointLocation::InvokeCallback (StoppointCallbackContext *context) -{ - if (m_options_ap.get() != nullptr && m_options_ap->HasCallback()) - return m_options_ap->InvokeCallback (context, m_owner.GetID(), GetID()); - else - return m_owner.InvokeCallback (context, GetID()); +bool BreakpointLocation::InvokeCallback(StoppointCallbackContext *context) { + if (m_options_ap.get() != nullptr && m_options_ap->HasCallback()) + return m_options_ap->InvokeCallback(context, m_owner.GetID(), GetID()); + else + return m_owner.InvokeCallback(context, GetID()); } -void -BreakpointLocation::SetCallback (BreakpointHitCallback callback, void *baton, - bool is_synchronous) -{ - // The default "Baton" class will keep a copy of "baton" and won't free - // or delete it when it goes goes out of scope. - GetLocationOptions()->SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous); - SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged); +void BreakpointLocation::SetCallback(BreakpointHitCallback callback, + void *baton, bool is_synchronous) { + // The default "Baton" class will keep a copy of "baton" and won't free + // or delete it when it goes goes out of scope. + GetLocationOptions()->SetCallback(callback, BatonSP(new Baton(baton)), + is_synchronous); + SendBreakpointLocationChangedEvent(eBreakpointEventTypeCommandChanged); } -void -BreakpointLocation::SetCallback (BreakpointHitCallback callback, const BatonSP &baton_sp, - bool is_synchronous) -{ - GetLocationOptions()->SetCallback (callback, baton_sp, is_synchronous); - SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged); +void BreakpointLocation::SetCallback(BreakpointHitCallback callback, + const BatonSP &baton_sp, + bool is_synchronous) { + GetLocationOptions()->SetCallback(callback, baton_sp, is_synchronous); + SendBreakpointLocationChangedEvent(eBreakpointEventTypeCommandChanged); } -void -BreakpointLocation::ClearCallback () -{ - GetLocationOptions()->ClearCallback(); +void BreakpointLocation::ClearCallback() { + GetLocationOptions()->ClearCallback(); } -void -BreakpointLocation::SetCondition (const char *condition) -{ - GetLocationOptions()->SetCondition (condition); - SendBreakpointLocationChangedEvent (eBreakpointEventTypeConditionChanged); +void BreakpointLocation::SetCondition(const char *condition) { + GetLocationOptions()->SetCondition(condition); + SendBreakpointLocationChangedEvent(eBreakpointEventTypeConditionChanged); } -const char * -BreakpointLocation::GetConditionText (size_t *hash) const -{ - return GetOptionsNoCreate()->GetConditionText(hash); +const char *BreakpointLocation::GetConditionText(size_t *hash) const { + return GetOptionsNoCreate()->GetConditionText(hash); } -bool -BreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error) -{ - Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); +bool BreakpointLocation::ConditionSaysStop(ExecutionContext &exe_ctx, + Error &error) { + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS); + + std::lock_guard<std::mutex> guard(m_condition_mutex); - std::lock_guard<std::mutex> guard(m_condition_mutex); + size_t condition_hash; + const char *condition_text = GetConditionText(&condition_hash); - size_t condition_hash; - const char *condition_text = GetConditionText(&condition_hash); - - if (!condition_text) - { - m_user_expression_sp.reset(); - return false; + if (!condition_text) { + m_user_expression_sp.reset(); + return false; + } + + error.Clear(); + + DiagnosticManager diagnostics; + + if (condition_hash != m_condition_hash || !m_user_expression_sp || + !m_user_expression_sp->MatchesContext(exe_ctx)) { + LanguageType language = eLanguageTypeUnknown; + // See if we can figure out the language from the frame, otherwise use the + // default language: + CompileUnit *comp_unit = m_address.CalculateSymbolContextCompileUnit(); + if (comp_unit) + language = comp_unit->GetLanguage(); + + m_user_expression_sp.reset(GetTarget().GetUserExpressionForLanguage( + condition_text, nullptr, language, Expression::eResultTypeAny, + EvaluateExpressionOptions(), error)); + if (error.Fail()) { + if (log) + log->Printf("Error getting condition expression: %s.", + error.AsCString()); + m_user_expression_sp.reset(); + return true; } - error.Clear(); - - DiagnosticManager diagnostics; - - if (condition_hash != m_condition_hash || !m_user_expression_sp || !m_user_expression_sp->MatchesContext(exe_ctx)) - { - LanguageType language = eLanguageTypeUnknown; - // See if we can figure out the language from the frame, otherwise use the default language: - CompileUnit *comp_unit = m_address.CalculateSymbolContextCompileUnit(); - if (comp_unit) - language = comp_unit->GetLanguage(); - - m_user_expression_sp.reset(GetTarget().GetUserExpressionForLanguage(condition_text, - nullptr, - language, - Expression::eResultTypeAny, - EvaluateExpressionOptions(), - error)); - if (error.Fail()) - { - if (log) - log->Printf("Error getting condition expression: %s.", error.AsCString()); - m_user_expression_sp.reset(); - return true; - } + if (!m_user_expression_sp->Parse(diagnostics, exe_ctx, + eExecutionPolicyOnlyWhenNeeded, true, + false)) { + error.SetErrorStringWithFormat( + "Couldn't parse conditional expression:\n%s", + diagnostics.GetString().c_str()); + m_user_expression_sp.reset(); + return true; + } - if (!m_user_expression_sp->Parse(diagnostics, exe_ctx, eExecutionPolicyOnlyWhenNeeded, true, false)) - { - error.SetErrorStringWithFormat("Couldn't parse conditional expression:\n%s", - diagnostics.GetString().c_str()); - m_user_expression_sp.reset(); - return true; - } + m_condition_hash = condition_hash; + } + + // We need to make sure the user sees any parse errors in their condition, so + // we'll hook the + // constructor errors up to the debugger's Async I/O. + + ValueObjectSP result_value_sp; + + EvaluateExpressionOptions options; + options.SetUnwindOnError(true); + options.SetIgnoreBreakpoints(true); + options.SetTryAllThreads(true); + options.SetResultIsInternal( + true); // Don't generate a user variable for condition expressions. + + Error expr_error; + + diagnostics.Clear(); - m_condition_hash = condition_hash; + ExpressionVariableSP result_variable_sp; + + ExpressionResults result_code = m_user_expression_sp->Execute( + diagnostics, exe_ctx, options, m_user_expression_sp, result_variable_sp); + + bool ret; + + if (result_code == eExpressionCompleted) { + if (!result_variable_sp) { + error.SetErrorString("Expression did not return a result"); + return false; } - // We need to make sure the user sees any parse errors in their condition, so we'll hook the - // constructor errors up to the debugger's Async I/O. - - ValueObjectSP result_value_sp; - - EvaluateExpressionOptions options; - options.SetUnwindOnError(true); - options.SetIgnoreBreakpoints(true); - options.SetTryAllThreads(true); - options.SetResultIsInternal(true); // Don't generate a user variable for condition expressions. - - Error expr_error; - - diagnostics.Clear(); - - ExpressionVariableSP result_variable_sp; - - ExpressionResults result_code = - m_user_expression_sp->Execute(diagnostics, exe_ctx, options, m_user_expression_sp, result_variable_sp); - - bool ret; - - if (result_code == eExpressionCompleted) - { - if (!result_variable_sp) - { - error.SetErrorString("Expression did not return a result"); - return false; - } - - result_value_sp = result_variable_sp->GetValueObject(); - - if (result_value_sp) - { - ret = result_value_sp->IsLogicalTrue(error); - if (log) - { - if (error.Success()) - { - log->Printf("Condition successfully evaluated, result is %s.\n", - ret ? "true" : "false"); - } - else - { - error.SetErrorString("Failed to get an integer result from the expression"); - ret = false; - } - - } + result_value_sp = result_variable_sp->GetValueObject(); + + if (result_value_sp) { + ret = result_value_sp->IsLogicalTrue(error); + if (log) { + if (error.Success()) { + log->Printf("Condition successfully evaluated, result is %s.\n", + ret ? "true" : "false"); + } else { + error.SetErrorString( + "Failed to get an integer result from the expression"); + ret = false; } - else - { - ret = false; - error.SetErrorString("Failed to get any result from the expression"); - } - } - else - { - ret = false; - error.SetErrorStringWithFormat("Couldn't execute expression:\n%s", diagnostics.GetString().c_str()); + } + } else { + ret = false; + error.SetErrorString("Failed to get any result from the expression"); } + } else { + ret = false; + error.SetErrorStringWithFormat("Couldn't execute expression:\n%s", + diagnostics.GetString().c_str()); + } - return ret; + return ret; } -uint32_t -BreakpointLocation::GetIgnoreCount () -{ - return GetOptionsNoCreate()->GetIgnoreCount(); +uint32_t BreakpointLocation::GetIgnoreCount() { + return GetOptionsNoCreate()->GetIgnoreCount(); } -void -BreakpointLocation::SetIgnoreCount (uint32_t n) -{ - GetLocationOptions()->SetIgnoreCount(n); - SendBreakpointLocationChangedEvent (eBreakpointEventTypeIgnoreChanged); +void BreakpointLocation::SetIgnoreCount(uint32_t n) { + GetLocationOptions()->SetIgnoreCount(n); + SendBreakpointLocationChangedEvent(eBreakpointEventTypeIgnoreChanged); } -void -BreakpointLocation::DecrementIgnoreCount() -{ - if (m_options_ap.get() != nullptr) - { - uint32_t loc_ignore = m_options_ap->GetIgnoreCount(); - if (loc_ignore != 0) - m_options_ap->SetIgnoreCount(loc_ignore - 1); - } +void BreakpointLocation::DecrementIgnoreCount() { + if (m_options_ap.get() != nullptr) { + uint32_t loc_ignore = m_options_ap->GetIgnoreCount(); + if (loc_ignore != 0) + m_options_ap->SetIgnoreCount(loc_ignore - 1); + } } -bool -BreakpointLocation::IgnoreCountShouldStop() -{ - if (m_options_ap.get() != nullptr) - { - uint32_t loc_ignore = m_options_ap->GetIgnoreCount(); - if (loc_ignore != 0) - { - m_owner.DecrementIgnoreCount(); - DecrementIgnoreCount(); // Have to decrement our owners' ignore count, since it won't get a - // chance to. - return false; - } +bool BreakpointLocation::IgnoreCountShouldStop() { + if (m_options_ap.get() != nullptr) { + uint32_t loc_ignore = m_options_ap->GetIgnoreCount(); + if (loc_ignore != 0) { + m_owner.DecrementIgnoreCount(); + DecrementIgnoreCount(); // Have to decrement our owners' ignore count, + // since it won't get a + // chance to. + return false; } - return true; + } + return true; } -const BreakpointOptions * -BreakpointLocation::GetOptionsNoCreate () const -{ - if (m_options_ap.get() != nullptr) - return m_options_ap.get(); - else - return m_owner.GetOptions (); -} - -BreakpointOptions * -BreakpointLocation::GetLocationOptions () -{ - // If we make the copy we don't copy the callbacks because that is potentially - // expensive and we don't want to do that for the simple case where someone is - // just disabling the location. - if (m_options_ap.get() == nullptr) - m_options_ap.reset(BreakpointOptions::CopyOptionsNoCallback(*m_owner.GetOptions ())); - +const BreakpointOptions *BreakpointLocation::GetOptionsNoCreate() const { + if (m_options_ap.get() != nullptr) return m_options_ap.get(); + else + return m_owner.GetOptions(); +} + +BreakpointOptions *BreakpointLocation::GetLocationOptions() { + // If we make the copy we don't copy the callbacks because that is potentially + // expensive and we don't want to do that for the simple case where someone is + // just disabling the location. + if (m_options_ap.get() == nullptr) + m_options_ap.reset( + BreakpointOptions::CopyOptionsNoCallback(*m_owner.GetOptions())); + + return m_options_ap.get(); } -bool -BreakpointLocation::ValidForThisThread (Thread *thread) -{ - return thread->MatchesSpec(GetOptionsNoCreate()->GetThreadSpecNoCreate()); +bool BreakpointLocation::ValidForThisThread(Thread *thread) { + return thread->MatchesSpec(GetOptionsNoCreate()->GetThreadSpecNoCreate()); } // RETURNS - true if we should stop at this breakpoint, false if we @@ -447,309 +362,275 @@ BreakpointLocation::ValidForThisThread (Thread *thread) // here, since if the breakpoint is not for this thread, then the event won't // even get reported, so the check is redundant. -bool -BreakpointLocation::ShouldStop (StoppointCallbackContext *context) -{ - bool should_stop = true; - Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); - - // Do this first, if a location is disabled, it shouldn't increment its hit count. - if (!IsEnabled()) - return false; - - if (!IgnoreCountShouldStop()) - return false; - - if (!m_owner.IgnoreCountShouldStop()) - return false; - - // We only run synchronous callbacks in ShouldStop: - context->is_synchronous = true; - should_stop = InvokeCallback (context); - - if (log) - { - StreamString s; - GetDescription (&s, lldb::eDescriptionLevelVerbose); - log->Printf ("Hit breakpoint location: %s, %s.\n", s.GetData(), should_stop ? "stopping" : "continuing"); - } - - return should_stop; -} - -void -BreakpointLocation::BumpHitCount() -{ - if (IsEnabled()) - { - // Step our hit count, and also step the hit count of the owner. - IncrementHitCount(); - m_owner.IncrementHitCount(); - } +bool BreakpointLocation::ShouldStop(StoppointCallbackContext *context) { + bool should_stop = true; + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS); + + // Do this first, if a location is disabled, it shouldn't increment its hit + // count. + if (!IsEnabled()) + return false; + + if (!IgnoreCountShouldStop()) + return false; + + if (!m_owner.IgnoreCountShouldStop()) + return false; + + // We only run synchronous callbacks in ShouldStop: + context->is_synchronous = true; + should_stop = InvokeCallback(context); + + if (log) { + StreamString s; + GetDescription(&s, lldb::eDescriptionLevelVerbose); + log->Printf("Hit breakpoint location: %s, %s.\n", s.GetData(), + should_stop ? "stopping" : "continuing"); + } + + return should_stop; } -void -BreakpointLocation::UndoBumpHitCount() -{ - if (IsEnabled()) - { - // Step our hit count, and also step the hit count of the owner. - DecrementHitCount(); - m_owner.DecrementHitCount(); - } +void BreakpointLocation::BumpHitCount() { + if (IsEnabled()) { + // Step our hit count, and also step the hit count of the owner. + IncrementHitCount(); + m_owner.IncrementHitCount(); + } } -bool -BreakpointLocation::IsResolved () const -{ - return m_bp_site_sp.get() != nullptr; +void BreakpointLocation::UndoBumpHitCount() { + if (IsEnabled()) { + // Step our hit count, and also step the hit count of the owner. + DecrementHitCount(); + m_owner.DecrementHitCount(); + } } -lldb::BreakpointSiteSP -BreakpointLocation::GetBreakpointSite() const -{ - return m_bp_site_sp; +bool BreakpointLocation::IsResolved() const { + return m_bp_site_sp.get() != nullptr; } -bool -BreakpointLocation::ResolveBreakpointSite () -{ - if (m_bp_site_sp) - return true; +lldb::BreakpointSiteSP BreakpointLocation::GetBreakpointSite() const { + return m_bp_site_sp; +} - Process *process = m_owner.GetTarget().GetProcessSP().get(); - if (process == nullptr) - return false; +bool BreakpointLocation::ResolveBreakpointSite() { + if (m_bp_site_sp) + return true; - lldb::break_id_t new_id = process->CreateBreakpointSite (shared_from_this(), m_owner.IsHardware()); + Process *process = m_owner.GetTarget().GetProcessSP().get(); + if (process == nullptr) + return false; - if (new_id == LLDB_INVALID_BREAK_ID) - { - Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); - if (log) - log->Warning ("Tried to add breakpoint site at 0x%" PRIx64 " but it was already present.\n", - m_address.GetOpcodeLoadAddress (&m_owner.GetTarget())); - return false; - } + lldb::break_id_t new_id = + process->CreateBreakpointSite(shared_from_this(), m_owner.IsHardware()); - return true; -} + if (new_id == LLDB_INVALID_BREAK_ID) { + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS); + if (log) + log->Warning("Tried to add breakpoint site at 0x%" PRIx64 + " but it was already present.\n", + m_address.GetOpcodeLoadAddress(&m_owner.GetTarget())); + return false; + } -bool -BreakpointLocation::SetBreakpointSite (BreakpointSiteSP& bp_site_sp) -{ - m_bp_site_sp = bp_site_sp; - SendBreakpointLocationChangedEvent (eBreakpointEventTypeLocationsResolved); - return true; + return true; } -bool -BreakpointLocation::ClearBreakpointSite () -{ - if (m_bp_site_sp.get()) - { - ProcessSP process_sp(m_owner.GetTarget().GetProcessSP()); - // If the process exists, get it to remove the owner, it will remove the physical implementation - // of the breakpoint as well if there are no more owners. Otherwise just remove this owner. - if (process_sp) - process_sp->RemoveOwnerFromBreakpointSite (GetBreakpoint().GetID(), - GetID(), m_bp_site_sp); - else - m_bp_site_sp->RemoveOwner(GetBreakpoint().GetID(), GetID()); - - m_bp_site_sp.reset(); - return true; - } - return false; +bool BreakpointLocation::SetBreakpointSite(BreakpointSiteSP &bp_site_sp) { + m_bp_site_sp = bp_site_sp; + SendBreakpointLocationChangedEvent(eBreakpointEventTypeLocationsResolved); + return true; } -void -BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level) -{ - SymbolContext sc; - - // If the description level is "initial" then the breakpoint is printing out our initial state, - // and we should let it decide how it wants to print our label. - if (level != eDescriptionLevelInitial) - { - s->Indent(); - BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID()); - } - - if (level == lldb::eDescriptionLevelBrief) - return; - - if (level != eDescriptionLevelInitial) - s->PutCString(": "); - - if (level == lldb::eDescriptionLevelVerbose) - s->IndentMore(); - - if (m_address.IsSectionOffset()) - { - m_address.CalculateSymbolContext(&sc); - - if (level == lldb::eDescriptionLevelFull || level == eDescriptionLevelInitial) - { - if (IsReExported()) - s->PutCString ("re-exported target = "); - else - s->PutCString("where = "); - sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false, true, true); - } - else - { - if (sc.module_sp) - { - s->EOL(); - s->Indent("module = "); - sc.module_sp->GetFileSpec().Dump (s); - } - - if (sc.comp_unit != nullptr) - { - s->EOL(); - s->Indent("compile unit = "); - static_cast<FileSpec*>(sc.comp_unit)->GetFilename().Dump (s); - - if (sc.function != nullptr) - { - s->EOL(); - s->Indent("function = "); - s->PutCString (sc.function->GetName().AsCString("<unknown>")); - } - - if (sc.line_entry.line > 0) - { - s->EOL(); - s->Indent("location = "); - sc.line_entry.DumpStopContext (s, true); - } - - } - else - { - // If we don't have a comp unit, see if we have a symbol we can print. - if (sc.symbol) - { - s->EOL(); - if (IsReExported()) - s->Indent ("re-exported target = "); - else - s->Indent("symbol = "); - s->PutCString(sc.symbol->GetName().AsCString("<unknown>")); - } - } - } - } +bool BreakpointLocation::ClearBreakpointSite() { + if (m_bp_site_sp.get()) { + ProcessSP process_sp(m_owner.GetTarget().GetProcessSP()); + // If the process exists, get it to remove the owner, it will remove the + // physical implementation + // of the breakpoint as well if there are no more owners. Otherwise just + // remove this owner. + if (process_sp) + process_sp->RemoveOwnerFromBreakpointSite(GetBreakpoint().GetID(), + GetID(), m_bp_site_sp); + else + m_bp_site_sp->RemoveOwner(GetBreakpoint().GetID(), GetID()); - if (level == lldb::eDescriptionLevelVerbose) - { + m_bp_site_sp.reset(); + return true; + } + return false; +} + +void BreakpointLocation::GetDescription(Stream *s, + lldb::DescriptionLevel level) { + SymbolContext sc; + + // If the description level is "initial" then the breakpoint is printing out + // our initial state, + // and we should let it decide how it wants to print our label. + if (level != eDescriptionLevelInitial) { + s->Indent(); + BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID()); + } + + if (level == lldb::eDescriptionLevelBrief) + return; + + if (level != eDescriptionLevelInitial) + s->PutCString(": "); + + if (level == lldb::eDescriptionLevelVerbose) + s->IndentMore(); + + if (m_address.IsSectionOffset()) { + m_address.CalculateSymbolContext(&sc); + + if (level == lldb::eDescriptionLevelFull || + level == eDescriptionLevelInitial) { + if (IsReExported()) + s->PutCString("re-exported target = "); + else + s->PutCString("where = "); + sc.DumpStopContext(s, m_owner.GetTarget().GetProcessSP().get(), m_address, + false, true, false, true, true); + } else { + if (sc.module_sp) { s->EOL(); - s->Indent(); - } - - if (m_address.IsSectionOffset() && (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)) - s->Printf (", "); - s->Printf ("address = "); - - ExecutionContextScope *exe_scope = nullptr; - Target *target = &m_owner.GetTarget(); - if (target) - exe_scope = target->GetProcessSP().get(); - if (exe_scope == nullptr) - exe_scope = target; - - if (level == eDescriptionLevelInitial) - m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress); - else - m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress); - - if (IsIndirect() && m_bp_site_sp) - { - Address resolved_address; - resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target); - Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol(); - if (resolved_symbol) - { - if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial) - s->Printf (", "); - else if (level == lldb::eDescriptionLevelVerbose) - { - s->EOL(); - s->Indent(); - } - s->Printf ("indirect target = %s", resolved_symbol->GetName().GetCString()); - } - } + s->Indent("module = "); + sc.module_sp->GetFileSpec().Dump(s); + } - if (level == lldb::eDescriptionLevelVerbose) - { + if (sc.comp_unit != nullptr) { s->EOL(); - s->Indent(); - s->Printf("resolved = %s\n", IsResolved() ? "true" : "false"); + s->Indent("compile unit = "); + static_cast<FileSpec *>(sc.comp_unit)->GetFilename().Dump(s); - s->Indent(); - s->Printf ("hit count = %-4u\n", GetHitCount()); + if (sc.function != nullptr) { + s->EOL(); + s->Indent("function = "); + s->PutCString(sc.function->GetName().AsCString("<unknown>")); + } - if (m_options_ap.get()) - { - s->Indent(); - m_options_ap->GetDescription (s, level); - s->EOL(); + if (sc.line_entry.line > 0) { + s->EOL(); + s->Indent("location = "); + sc.line_entry.DumpStopContext(s, true); } - s->IndentLess(); - } - else if (level != eDescriptionLevelInitial) - { - s->Printf(", %sresolved, hit count = %u ", - (IsResolved() ? "" : "un"), - GetHitCount()); - if (m_options_ap.get()) - { - m_options_ap->GetDescription (s, level); + + } else { + // If we don't have a comp unit, see if we have a symbol we can print. + if (sc.symbol) { + s->EOL(); + if (IsReExported()) + s->Indent("re-exported target = "); + else + s->Indent("symbol = "); + s->PutCString(sc.symbol->GetName().AsCString("<unknown>")); } + } } -} - -void -BreakpointLocation::Dump(Stream *s) const -{ - if (s == nullptr) - return; - - s->Printf("BreakpointLocation %u: tid = %4.4" PRIx64 " load addr = 0x%8.8" PRIx64 " state = %s type = %s breakpoint " - "hw_index = %i hit_count = %-4u ignore_count = %-4u", - GetID(), - GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(), - (uint64_t) m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()), - (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled()) ? "enabled " : "disabled", - IsHardware() ? "hardware" : "software", - GetHardwareIndex(), - GetHitCount(), - GetOptionsNoCreate()->GetIgnoreCount()); -} - -void -BreakpointLocation::SendBreakpointLocationChangedEvent (lldb::BreakpointEventType eventKind) -{ - if (!m_being_created - && !m_owner.IsInternal() - && m_owner.GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged)) - { - Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind, - m_owner.shared_from_this()); - data->GetBreakpointLocationCollection().Add (shared_from_this()); - m_owner.GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data); + } + + if (level == lldb::eDescriptionLevelVerbose) { + s->EOL(); + s->Indent(); + } + + if (m_address.IsSectionOffset() && + (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)) + s->Printf(", "); + s->Printf("address = "); + + ExecutionContextScope *exe_scope = nullptr; + Target *target = &m_owner.GetTarget(); + if (target) + exe_scope = target->GetProcessSP().get(); + if (exe_scope == nullptr) + exe_scope = target; + + if (level == eDescriptionLevelInitial) + m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, + Address::DumpStyleFileAddress); + else + m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, + Address::DumpStyleModuleWithFileAddress); + + if (IsIndirect() && m_bp_site_sp) { + Address resolved_address; + resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target); + Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol(); + if (resolved_symbol) { + if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial) + s->Printf(", "); + else if (level == lldb::eDescriptionLevelVerbose) { + s->EOL(); + s->Indent(); + } + s->Printf("indirect target = %s", + resolved_symbol->GetName().GetCString()); } -} + } -void -BreakpointLocation::SwapLocation (BreakpointLocationSP swap_from) -{ - m_address = swap_from->m_address; - m_should_resolve_indirect_functions = swap_from->m_should_resolve_indirect_functions; - m_is_reexported = swap_from->m_is_reexported; - m_is_indirect = swap_from->m_is_indirect; - m_user_expression_sp.reset(); + if (level == lldb::eDescriptionLevelVerbose) { + s->EOL(); + s->Indent(); + s->Printf("resolved = %s\n", IsResolved() ? "true" : "false"); + + s->Indent(); + s->Printf("hit count = %-4u\n", GetHitCount()); + + if (m_options_ap.get()) { + s->Indent(); + m_options_ap->GetDescription(s, level); + s->EOL(); + } + s->IndentLess(); + } else if (level != eDescriptionLevelInitial) { + s->Printf(", %sresolved, hit count = %u ", (IsResolved() ? "" : "un"), + GetHitCount()); + if (m_options_ap.get()) { + m_options_ap->GetDescription(s, level); + } + } +} + +void BreakpointLocation::Dump(Stream *s) const { + if (s == nullptr) + return; + + s->Printf( + "BreakpointLocation %u: tid = %4.4" PRIx64 " load addr = 0x%8.8" PRIx64 + " state = %s type = %s breakpoint " + "hw_index = %i hit_count = %-4u ignore_count = %-4u", + GetID(), GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(), + (uint64_t)m_address.GetOpcodeLoadAddress(&m_owner.GetTarget()), + (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled()) + ? "enabled " + : "disabled", + IsHardware() ? "hardware" : "software", GetHardwareIndex(), GetHitCount(), + GetOptionsNoCreate()->GetIgnoreCount()); +} + +void BreakpointLocation::SendBreakpointLocationChangedEvent( + lldb::BreakpointEventType eventKind) { + if (!m_being_created && !m_owner.IsInternal() && + m_owner.GetTarget().EventTypeHasListeners( + Target::eBroadcastBitBreakpointChanged)) { + Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData( + eventKind, m_owner.shared_from_this()); + data->GetBreakpointLocationCollection().Add(shared_from_this()); + m_owner.GetTarget().BroadcastEvent(Target::eBroadcastBitBreakpointChanged, + data); + } +} + +void BreakpointLocation::SwapLocation(BreakpointLocationSP swap_from) { + m_address = swap_from->m_address; + m_should_resolve_indirect_functions = + swap_from->m_should_resolve_indirect_functions; + m_is_reexported = swap_from->m_is_reexported; + m_is_indirect = swap_from->m_is_indirect; + m_user_expression_sp.reset(); } |