//===-- SBBreakpoint.cpp ----------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "lldb/API/SBBreakpoint.h" #include "SBReproducerPrivate.h" #include "lldb/API/SBBreakpointLocation.h" #include "lldb/API/SBDebugger.h" #include "lldb/API/SBEvent.h" #include "lldb/API/SBProcess.h" #include "lldb/API/SBStream.h" #include "lldb/API/SBStringList.h" #include "lldb/API/SBThread.h" #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Breakpoint/BreakpointIDList.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Breakpoint/BreakpointResolver.h" #include "lldb/Breakpoint/BreakpointResolverScripted.h" #include "lldb/Breakpoint/StoppointCallbackContext.h" #include "lldb/Core/Address.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/StreamFile.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/ScriptInterpreter.h" #include "lldb/Target/Process.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadSpec.h" #include "lldb/Utility/Stream.h" #include "SBBreakpointOptionCommon.h" #include "lldb/lldb-enumerations.h" #include "llvm/ADT/STLExtras.h" using namespace lldb; using namespace lldb_private; SBBreakpoint::SBBreakpoint() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBBreakpoint); } SBBreakpoint::SBBreakpoint(const SBBreakpoint &rhs) : m_opaque_wp(rhs.m_opaque_wp) { LLDB_RECORD_CONSTRUCTOR(SBBreakpoint, (const lldb::SBBreakpoint &), rhs); } SBBreakpoint::SBBreakpoint(const lldb::BreakpointSP &bp_sp) : m_opaque_wp(bp_sp) { LLDB_RECORD_CONSTRUCTOR(SBBreakpoint, (const lldb::BreakpointSP &), bp_sp); } SBBreakpoint::~SBBreakpoint() = default; const SBBreakpoint &SBBreakpoint::operator=(const SBBreakpoint &rhs) { LLDB_RECORD_METHOD(const lldb::SBBreakpoint &, SBBreakpoint, operator=,(const lldb::SBBreakpoint &), rhs); m_opaque_wp = rhs.m_opaque_wp; return LLDB_RECORD_RESULT(*this); } bool SBBreakpoint::operator==(const lldb::SBBreakpoint &rhs) { LLDB_RECORD_METHOD( bool, SBBreakpoint, operator==,(const lldb::SBBreakpoint &), rhs); return m_opaque_wp.lock() == rhs.m_opaque_wp.lock(); } bool SBBreakpoint::operator!=(const lldb::SBBreakpoint &rhs) { LLDB_RECORD_METHOD( bool, SBBreakpoint, operator!=,(const lldb::SBBreakpoint &), rhs); return m_opaque_wp.lock() != rhs.m_opaque_wp.lock(); } break_id_t SBBreakpoint::GetID() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::break_id_t, SBBreakpoint, GetID); break_id_t break_id = LLDB_INVALID_BREAK_ID; BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) break_id = bkpt_sp->GetID(); return break_id; } bool SBBreakpoint::IsValid() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBreakpoint, IsValid); return this->operator bool(); } SBBreakpoint::operator bool() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBreakpoint, operator bool); BreakpointSP bkpt_sp = GetSP(); if (!bkpt_sp) return false; else if (bkpt_sp->GetTarget().GetBreakpointByID(bkpt_sp->GetID())) return true; else return false; } void SBBreakpoint::ClearAllBreakpointSites() { LLDB_RECORD_METHOD_NO_ARGS(void, SBBreakpoint, ClearAllBreakpointSites); BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); bkpt_sp->ClearAllBreakpointSites(); } } SBBreakpointLocation SBBreakpoint::FindLocationByAddress(addr_t vm_addr) { LLDB_RECORD_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, FindLocationByAddress, (lldb::addr_t), vm_addr); SBBreakpointLocation sb_bp_location; BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { if (vm_addr != LLDB_INVALID_ADDRESS) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); Address address; Target &target = bkpt_sp->GetTarget(); if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) { address.SetRawAddress(vm_addr); } sb_bp_location.SetLocation(bkpt_sp->FindLocationByAddress(address)); } } return LLDB_RECORD_RESULT(sb_bp_location); } break_id_t SBBreakpoint::FindLocationIDByAddress(addr_t vm_addr) { LLDB_RECORD_METHOD(lldb::break_id_t, SBBreakpoint, FindLocationIDByAddress, (lldb::addr_t), vm_addr); break_id_t break_id = LLDB_INVALID_BREAK_ID; BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp && vm_addr != LLDB_INVALID_ADDRESS) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); Address address; Target &target = bkpt_sp->GetTarget(); if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) { address.SetRawAddress(vm_addr); } break_id = bkpt_sp->FindLocationIDByAddress(address); } return break_id; } SBBreakpointLocation SBBreakpoint::FindLocationByID(break_id_t bp_loc_id) { LLDB_RECORD_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, FindLocationByID, (lldb::break_id_t), bp_loc_id); SBBreakpointLocation sb_bp_location; BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); sb_bp_location.SetLocation(bkpt_sp->FindLocationByID(bp_loc_id)); } return LLDB_RECORD_RESULT(sb_bp_location); } SBBreakpointLocation SBBreakpoint::GetLocationAtIndex(uint32_t index) { LLDB_RECORD_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, GetLocationAtIndex, (uint32_t), index); SBBreakpointLocation sb_bp_location; BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); sb_bp_location.SetLocation(bkpt_sp->GetLocationAtIndex(index)); } return LLDB_RECORD_RESULT(sb_bp_location); } void SBBreakpoint::SetEnabled(bool enable) { LLDB_RECORD_METHOD(void, SBBreakpoint, SetEnabled, (bool), enable); BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); bkpt_sp->SetEnabled(enable); } } bool SBBreakpoint::IsEnabled() { LLDB_RECORD_METHOD_NO_ARGS(bool, SBBreakpoint, IsEnabled); BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); return bkpt_sp->IsEnabled(); } else return false; } void SBBreakpoint::SetOneShot(bool one_shot) { LLDB_RECORD_METHOD(void, SBBreakpoint, SetOneShot, (bool), one_shot); BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); bkpt_sp->SetOneShot(one_shot); } } bool SBBreakpoint::IsOneShot() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBreakpoint, IsOneShot); BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); return bkpt_sp->IsOneShot(); } else return false; } bool SBBreakpoint::IsInternal() { LLDB_RECORD_METHOD_NO_ARGS(bool, SBBreakpoint, IsInternal); BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); return bkpt_sp->IsInternal(); } else return false; } void SBBreakpoint::SetIgnoreCount(uint32_t count) { LLDB_RECORD_METHOD(void, SBBreakpoint, SetIgnoreCount, (uint32_t), count); BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); bkpt_sp->SetIgnoreCount(count); } } void SBBreakpoint::SetCondition(const char *condition) { LLDB_RECORD_METHOD(void, SBBreakpoint, SetCondition, (const char *), condition); BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); bkpt_sp->SetCondition(condition); } } const char *SBBreakpoint::GetCondition() { LLDB_RECORD_METHOD_NO_ARGS(const char *, SBBreakpoint, GetCondition); BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); return bkpt_sp->GetConditionText(); } return nullptr; } void SBBreakpoint::SetAutoContinue(bool auto_continue) { LLDB_RECORD_METHOD(void, SBBreakpoint, SetAutoContinue, (bool), auto_continue); BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); bkpt_sp->SetAutoContinue(auto_continue); } } bool SBBreakpoint::GetAutoContinue() { LLDB_RECORD_METHOD_NO_ARGS(bool, SBBreakpoint, GetAutoContinue); BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); return bkpt_sp->IsAutoContinue(); } return false; } uint32_t SBBreakpoint::GetHitCount() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBBreakpoint, GetHitCount); uint32_t count = 0; BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); count = bkpt_sp->GetHitCount(); } return count; } uint32_t SBBreakpoint::GetIgnoreCount() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBBreakpoint, GetIgnoreCount); uint32_t count = 0; BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); count = bkpt_sp->GetIgnoreCount(); } return count; } void SBBreakpoint::SetThreadID(tid_t tid) { LLDB_RECORD_METHOD(void, SBBreakpoint, SetThreadID, (lldb::tid_t), tid); BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); bkpt_sp->SetThreadID(tid); } } tid_t SBBreakpoint::GetThreadID() { LLDB_RECORD_METHOD_NO_ARGS(lldb::tid_t, SBBreakpoint, GetThreadID); tid_t tid = LLDB_INVALID_THREAD_ID; BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); tid = bkpt_sp->GetThreadID(); } return tid; } void SBBreakpoint::SetThreadIndex(uint32_t index) { LLDB_RECORD_METHOD(void, SBBreakpoint, SetThreadIndex, (uint32_t), index); BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); bkpt_sp->GetOptions()->GetThreadSpec()->SetIndex(index); } } uint32_t SBBreakpoint::GetThreadIndex() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBBreakpoint, GetThreadIndex); uint32_t thread_idx = UINT32_MAX; BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); const ThreadSpec *thread_spec = bkpt_sp->GetOptions()->GetThreadSpecNoCreate(); if (thread_spec != nullptr) thread_idx = thread_spec->GetIndex(); } return thread_idx; } void SBBreakpoint::SetThreadName(const char *thread_name) { LLDB_RECORD_METHOD(void, SBBreakpoint, SetThreadName, (const char *), thread_name); BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); bkpt_sp->GetOptions()->GetThreadSpec()->SetName(thread_name); } } const char *SBBreakpoint::GetThreadName() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBBreakpoint, GetThreadName); const char *name = nullptr; BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); const ThreadSpec *thread_spec = bkpt_sp->GetOptions()->GetThreadSpecNoCreate(); if (thread_spec != nullptr) name = thread_spec->GetName(); } return name; } void SBBreakpoint::SetQueueName(const char *queue_name) { LLDB_RECORD_METHOD(void, SBBreakpoint, SetQueueName, (const char *), queue_name); BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); bkpt_sp->GetOptions()->GetThreadSpec()->SetQueueName(queue_name); } } const char *SBBreakpoint::GetQueueName() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBBreakpoint, GetQueueName); const char *name = nullptr; BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); const ThreadSpec *thread_spec = bkpt_sp->GetOptions()->GetThreadSpecNoCreate(); if (thread_spec) name = thread_spec->GetQueueName(); } return name; } size_t SBBreakpoint::GetNumResolvedLocations() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(size_t, SBBreakpoint, GetNumResolvedLocations); size_t num_resolved = 0; BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); num_resolved = bkpt_sp->GetNumResolvedLocations(); } return num_resolved; } size_t SBBreakpoint::GetNumLocations() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(size_t, SBBreakpoint, GetNumLocations); BreakpointSP bkpt_sp = GetSP(); size_t num_locs = 0; if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); num_locs = bkpt_sp->GetNumLocations(); } return num_locs; } void SBBreakpoint::SetCommandLineCommands(SBStringList &commands) { LLDB_RECORD_METHOD(void, SBBreakpoint, SetCommandLineCommands, (lldb::SBStringList &), commands); BreakpointSP bkpt_sp = GetSP(); if (!bkpt_sp) return; if (commands.GetSize() == 0) return; std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); std::unique_ptr cmd_data_up( new BreakpointOptions::CommandData(*commands, eScriptLanguageNone)); bkpt_sp->GetOptions()->SetCommandDataCallback(cmd_data_up); } bool SBBreakpoint::GetCommandLineCommands(SBStringList &commands) { LLDB_RECORD_METHOD(bool, SBBreakpoint, GetCommandLineCommands, (lldb::SBStringList &), commands); BreakpointSP bkpt_sp = GetSP(); if (!bkpt_sp) return false; StringList command_list; bool has_commands = bkpt_sp->GetOptions()->GetCommandLineCallbacks(command_list); if (has_commands) commands.AppendList(command_list); return has_commands; } bool SBBreakpoint::GetDescription(SBStream &s) { LLDB_RECORD_METHOD(bool, SBBreakpoint, GetDescription, (lldb::SBStream &), s); return GetDescription(s, true); } bool SBBreakpoint::GetDescription(SBStream &s, bool include_locations) { LLDB_RECORD_METHOD(bool, SBBreakpoint, GetDescription, (lldb::SBStream &, bool), s, include_locations); BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); s.Printf("SBBreakpoint: id = %i, ", bkpt_sp->GetID()); bkpt_sp->GetResolverDescription(s.get()); bkpt_sp->GetFilterDescription(s.get()); if (include_locations) { const size_t num_locations = bkpt_sp->GetNumLocations(); s.Printf(", locations = %" PRIu64, (uint64_t)num_locations); } return true; } s.Printf("No value"); return false; } SBError SBBreakpoint::AddLocation(SBAddress &address) { LLDB_RECORD_METHOD(lldb::SBError, SBBreakpoint, AddLocation, (lldb::SBAddress &), address); BreakpointSP bkpt_sp = GetSP(); SBError error; if (!address.IsValid()) { error.SetErrorString("Can't add an invalid address."); return LLDB_RECORD_RESULT(error); } if (!bkpt_sp) { error.SetErrorString("No breakpoint to add a location to."); return LLDB_RECORD_RESULT(error); } if (!llvm::isa(bkpt_sp->GetResolver().get())) { error.SetErrorString("Only a scripted resolver can add locations."); return LLDB_RECORD_RESULT(error); } if (bkpt_sp->GetSearchFilter()->AddressPasses(address.ref())) bkpt_sp->AddLocation(address.ref()); else { StreamString s; address.get()->Dump(&s, &bkpt_sp->GetTarget(), Address::DumpStyleModuleWithFileAddress); error.SetErrorStringWithFormat("Address: %s didn't pass the filter.", s.GetData()); } return LLDB_RECORD_RESULT(error); } void SBBreakpoint ::SetCallback(SBBreakpointHitCallback callback, void *baton) { LLDB_RECORD_DUMMY(void, SBBreakpoint, SetCallback, (lldb::SBBreakpointHitCallback, void *), callback, baton); BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton)); bkpt_sp->SetCallback(SBBreakpointCallbackBaton ::PrivateBreakpointHitCallback, baton_sp, false); } } void SBBreakpoint::SetScriptCallbackFunction( const char *callback_function_name) { LLDB_RECORD_METHOD(void, SBBreakpoint, SetScriptCallbackFunction, (const char *), callback_function_name); BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); BreakpointOptions *bp_options = bkpt_sp->GetOptions(); bkpt_sp->GetTarget() .GetDebugger() .GetScriptInterpreter() ->SetBreakpointCommandCallbackFunction(bp_options, callback_function_name); } } SBError SBBreakpoint::SetScriptCallbackBody(const char *callback_body_text) { LLDB_RECORD_METHOD(lldb::SBError, SBBreakpoint, SetScriptCallbackBody, (const char *), callback_body_text); BreakpointSP bkpt_sp = GetSP(); SBError sb_error; if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); BreakpointOptions *bp_options = bkpt_sp->GetOptions(); Status error = bkpt_sp->GetTarget() .GetDebugger() .GetScriptInterpreter() ->SetBreakpointCommandCallback(bp_options, callback_body_text); sb_error.SetError(error); } else sb_error.SetErrorString("invalid breakpoint"); return LLDB_RECORD_RESULT(sb_error); } bool SBBreakpoint::AddName(const char *new_name) { LLDB_RECORD_METHOD(bool, SBBreakpoint, AddName, (const char *), new_name); BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); Status error; // Think I'm just going to swallow the error here, it's // probably more annoying to have to provide it. bkpt_sp->GetTarget().AddNameToBreakpoint(bkpt_sp, new_name, error); if (error.Fail()) return false; } return true; } void SBBreakpoint::RemoveName(const char *name_to_remove) { LLDB_RECORD_METHOD(void, SBBreakpoint, RemoveName, (const char *), name_to_remove); BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); bkpt_sp->GetTarget().RemoveNameFromBreakpoint(bkpt_sp, ConstString(name_to_remove)); } } bool SBBreakpoint::MatchesName(const char *name) { LLDB_RECORD_METHOD(bool, SBBreakpoint, MatchesName, (const char *), name); BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); return bkpt_sp->MatchesName(name); } return false; } void SBBreakpoint::GetNames(SBStringList &names) { LLDB_RECORD_METHOD(void, SBBreakpoint, GetNames, (lldb::SBStringList &), names); BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); std::vector names_vec; bkpt_sp->GetNames(names_vec); for (std::string name : names_vec) { names.AppendString(name.c_str()); } } } bool SBBreakpoint::EventIsBreakpointEvent(const lldb::SBEvent &event) { LLDB_RECORD_STATIC_METHOD(bool, SBBreakpoint, EventIsBreakpointEvent, (const lldb::SBEvent &), event); return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event.get()) != nullptr; } BreakpointEventType SBBreakpoint::GetBreakpointEventTypeFromEvent(const SBEvent &event) { LLDB_RECORD_STATIC_METHOD(lldb::BreakpointEventType, SBBreakpoint, GetBreakpointEventTypeFromEvent, (const lldb::SBEvent &), event); if (event.IsValid()) return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent( event.GetSP()); return eBreakpointEventTypeInvalidType; } SBBreakpoint SBBreakpoint::GetBreakpointFromEvent(const lldb::SBEvent &event) { LLDB_RECORD_STATIC_METHOD(lldb::SBBreakpoint, SBBreakpoint, GetBreakpointFromEvent, (const lldb::SBEvent &), event); if (event.IsValid()) return LLDB_RECORD_RESULT( SBBreakpoint(Breakpoint::BreakpointEventData::GetBreakpointFromEvent( event.GetSP()))); return LLDB_RECORD_RESULT(SBBreakpoint()); } SBBreakpointLocation SBBreakpoint::GetBreakpointLocationAtIndexFromEvent(const lldb::SBEvent &event, uint32_t loc_idx) { LLDB_RECORD_STATIC_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, GetBreakpointLocationAtIndexFromEvent, (const lldb::SBEvent &, uint32_t), event, loc_idx); SBBreakpointLocation sb_breakpoint_loc; if (event.IsValid()) sb_breakpoint_loc.SetLocation( Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent( event.GetSP(), loc_idx)); return LLDB_RECORD_RESULT(sb_breakpoint_loc); } uint32_t SBBreakpoint::GetNumBreakpointLocationsFromEvent(const lldb::SBEvent &event) { LLDB_RECORD_STATIC_METHOD(uint32_t, SBBreakpoint, GetNumBreakpointLocationsFromEvent, (const lldb::SBEvent &), event); uint32_t num_locations = 0; if (event.IsValid()) num_locations = (Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent( event.GetSP())); return num_locations; } bool SBBreakpoint::IsHardware() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBreakpoint, IsHardware); BreakpointSP bkpt_sp = GetSP(); if (bkpt_sp) return bkpt_sp->IsHardware(); return false; } BreakpointSP SBBreakpoint::GetSP() const { return m_opaque_wp.lock(); } // This is simple collection of breakpoint id's and their target. class SBBreakpointListImpl { public: SBBreakpointListImpl(lldb::TargetSP target_sp) : m_target_wp() { if (target_sp && target_sp->IsValid()) m_target_wp = target_sp; } ~SBBreakpointListImpl() = default; size_t GetSize() { return m_break_ids.size(); } BreakpointSP GetBreakpointAtIndex(size_t idx) { if (idx >= m_break_ids.size()) return BreakpointSP(); TargetSP target_sp = m_target_wp.lock(); if (!target_sp) return BreakpointSP(); lldb::break_id_t bp_id = m_break_ids[idx]; return target_sp->GetBreakpointList().FindBreakpointByID(bp_id); } BreakpointSP FindBreakpointByID(lldb::break_id_t desired_id) { TargetSP target_sp = m_target_wp.lock(); if (!target_sp) return BreakpointSP(); for (lldb::break_id_t &break_id : m_break_ids) { if (break_id == desired_id) return target_sp->GetBreakpointList().FindBreakpointByID(break_id); } return BreakpointSP(); } bool Append(BreakpointSP bkpt) { TargetSP target_sp = m_target_wp.lock(); if (!target_sp || !bkpt) return false; if (bkpt->GetTargetSP() != target_sp) return false; m_break_ids.push_back(bkpt->GetID()); return true; } bool AppendIfUnique(BreakpointSP bkpt) { TargetSP target_sp = m_target_wp.lock(); if (!target_sp || !bkpt) return false; if (bkpt->GetTargetSP() != target_sp) return false; lldb::break_id_t bp_id = bkpt->GetID(); if (find(m_break_ids.begin(), m_break_ids.end(), bp_id) == m_break_ids.end()) return false; m_break_ids.push_back(bkpt->GetID()); return true; } bool AppendByID(lldb::break_id_t id) { TargetSP target_sp = m_target_wp.lock(); if (!target_sp) return false; if (id == LLDB_INVALID_BREAK_ID) return false; m_break_ids.push_back(id); return true; } void Clear() { m_break_ids.clear(); } void CopyToBreakpointIDList(lldb_private::BreakpointIDList &bp_list) { for (lldb::break_id_t id : m_break_ids) { bp_list.AddBreakpointID(BreakpointID(id)); } } TargetSP GetTarget() { return m_target_wp.lock(); } private: std::vector m_break_ids; TargetWP m_target_wp; }; SBBreakpointList::SBBreakpointList(SBTarget &target) : m_opaque_sp(new SBBreakpointListImpl(target.GetSP())) { LLDB_RECORD_CONSTRUCTOR(SBBreakpointList, (lldb::SBTarget &), target); } SBBreakpointList::~SBBreakpointList() {} size_t SBBreakpointList::GetSize() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(size_t, SBBreakpointList, GetSize); if (!m_opaque_sp) return 0; else return m_opaque_sp->GetSize(); } SBBreakpoint SBBreakpointList::GetBreakpointAtIndex(size_t idx) { LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBBreakpointList, GetBreakpointAtIndex, (size_t), idx); if (!m_opaque_sp) return LLDB_RECORD_RESULT(SBBreakpoint()); BreakpointSP bkpt_sp = m_opaque_sp->GetBreakpointAtIndex(idx); return LLDB_RECORD_RESULT(SBBreakpoint(bkpt_sp)); } SBBreakpoint SBBreakpointList::FindBreakpointByID(lldb::break_id_t id) { LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBBreakpointList, FindBreakpointByID, (lldb::break_id_t), id); if (!m_opaque_sp) return LLDB_RECORD_RESULT(SBBreakpoint()); BreakpointSP bkpt_sp = m_opaque_sp->FindBreakpointByID(id); return LLDB_RECORD_RESULT(SBBreakpoint(bkpt_sp)); } void SBBreakpointList::Append(const SBBreakpoint &sb_bkpt) { LLDB_RECORD_METHOD(void, SBBreakpointList, Append, (const lldb::SBBreakpoint &), sb_bkpt); if (!sb_bkpt.IsValid()) return; if (!m_opaque_sp) return; m_opaque_sp->Append(sb_bkpt.m_opaque_wp.lock()); } void SBBreakpointList::AppendByID(lldb::break_id_t id) { LLDB_RECORD_METHOD(void, SBBreakpointList, AppendByID, (lldb::break_id_t), id); if (!m_opaque_sp) return; m_opaque_sp->AppendByID(id); } bool SBBreakpointList::AppendIfUnique(const SBBreakpoint &sb_bkpt) { LLDB_RECORD_METHOD(bool, SBBreakpointList, AppendIfUnique, (const lldb::SBBreakpoint &), sb_bkpt); if (!sb_bkpt.IsValid()) return false; if (!m_opaque_sp) return false; return m_opaque_sp->AppendIfUnique(sb_bkpt.GetSP()); } void SBBreakpointList::Clear() { LLDB_RECORD_METHOD_NO_ARGS(void, SBBreakpointList, Clear); if (m_opaque_sp) m_opaque_sp->Clear(); } void SBBreakpointList::CopyToBreakpointIDList( lldb_private::BreakpointIDList &bp_id_list) { if (m_opaque_sp) m_opaque_sp->CopyToBreakpointIDList(bp_id_list); } namespace lldb_private { namespace repro { template <> void RegisterMethods(Registry &R) { LLDB_REGISTER_CONSTRUCTOR(SBBreakpoint, ()); LLDB_REGISTER_CONSTRUCTOR(SBBreakpoint, (const lldb::SBBreakpoint &)); LLDB_REGISTER_CONSTRUCTOR(SBBreakpoint, (const lldb::BreakpointSP &)); LLDB_REGISTER_METHOD(const lldb::SBBreakpoint &, SBBreakpoint, operator=,(const lldb::SBBreakpoint &)); LLDB_REGISTER_METHOD(bool, SBBreakpoint, operator==,(const lldb::SBBreakpoint &)); LLDB_REGISTER_METHOD(bool, SBBreakpoint, operator!=,(const lldb::SBBreakpoint &)); LLDB_REGISTER_METHOD_CONST(lldb::break_id_t, SBBreakpoint, GetID, ()); LLDB_REGISTER_METHOD_CONST(bool, SBBreakpoint, IsValid, ()); LLDB_REGISTER_METHOD_CONST(bool, SBBreakpoint, operator bool, ()); LLDB_REGISTER_METHOD(void, SBBreakpoint, ClearAllBreakpointSites, ()); LLDB_REGISTER_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, FindLocationByAddress, (lldb::addr_t)); LLDB_REGISTER_METHOD(lldb::break_id_t, SBBreakpoint, FindLocationIDByAddress, (lldb::addr_t)); LLDB_REGISTER_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, FindLocationByID, (lldb::break_id_t)); LLDB_REGISTER_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, GetLocationAtIndex, (uint32_t)); LLDB_REGISTER_METHOD(void, SBBreakpoint, SetEnabled, (bool)); LLDB_REGISTER_METHOD(bool, SBBreakpoint, IsEnabled, ()); LLDB_REGISTER_METHOD(void, SBBreakpoint, SetOneShot, (bool)); LLDB_REGISTER_METHOD_CONST(bool, SBBreakpoint, IsOneShot, ()); LLDB_REGISTER_METHOD(bool, SBBreakpoint, IsInternal, ()); LLDB_REGISTER_METHOD(void, SBBreakpoint, SetIgnoreCount, (uint32_t)); LLDB_REGISTER_METHOD(void, SBBreakpoint, SetCondition, (const char *)); LLDB_REGISTER_METHOD(const char *, SBBreakpoint, GetCondition, ()); LLDB_REGISTER_METHOD(void, SBBreakpoint, SetAutoContinue, (bool)); LLDB_REGISTER_METHOD(bool, SBBreakpoint, GetAutoContinue, ()); LLDB_REGISTER_METHOD_CONST(uint32_t, SBBreakpoint, GetHitCount, ()); LLDB_REGISTER_METHOD_CONST(uint32_t, SBBreakpoint, GetIgnoreCount, ()); LLDB_REGISTER_METHOD(void, SBBreakpoint, SetThreadID, (lldb::tid_t)); LLDB_REGISTER_METHOD(lldb::tid_t, SBBreakpoint, GetThreadID, ()); LLDB_REGISTER_METHOD(void, SBBreakpoint, SetThreadIndex, (uint32_t)); LLDB_REGISTER_METHOD_CONST(uint32_t, SBBreakpoint, GetThreadIndex, ()); LLDB_REGISTER_METHOD(void, SBBreakpoint, SetThreadName, (const char *)); LLDB_REGISTER_METHOD_CONST(const char *, SBBreakpoint, GetThreadName, ()); LLDB_REGISTER_METHOD(void, SBBreakpoint, SetQueueName, (const char *)); LLDB_REGISTER_METHOD_CONST(const char *, SBBreakpoint, GetQueueName, ()); LLDB_REGISTER_METHOD_CONST(size_t, SBBreakpoint, GetNumResolvedLocations, ()); LLDB_REGISTER_METHOD_CONST(size_t, SBBreakpoint, GetNumLocations, ()); LLDB_REGISTER_METHOD(void, SBBreakpoint, SetCommandLineCommands, (lldb::SBStringList &)); LLDB_REGISTER_METHOD(bool, SBBreakpoint, GetCommandLineCommands, (lldb::SBStringList &)); LLDB_REGISTER_METHOD(bool, SBBreakpoint, GetDescription, (lldb::SBStream &)); LLDB_REGISTER_METHOD(bool, SBBreakpoint, GetDescription, (lldb::SBStream &, bool)); LLDB_REGISTER_METHOD(lldb::SBError, SBBreakpoint, AddLocation, (lldb::SBAddress &)); LLDB_REGISTER_METHOD(void, SBBreakpoint, SetScriptCallbackFunction, (const char *)); LLDB_REGISTER_METHOD(lldb::SBError, SBBreakpoint, SetScriptCallbackBody, (const char *)); LLDB_REGISTER_METHOD(bool, SBBreakpoint, AddName, (const char *)); LLDB_REGISTER_METHOD(void, SBBreakpoint, RemoveName, (const char *)); LLDB_REGISTER_METHOD(bool, SBBreakpoint, MatchesName, (const char *)); LLDB_REGISTER_METHOD(void, SBBreakpoint, GetNames, (lldb::SBStringList &)); LLDB_REGISTER_STATIC_METHOD(bool, SBBreakpoint, EventIsBreakpointEvent, (const lldb::SBEvent &)); LLDB_REGISTER_STATIC_METHOD(lldb::BreakpointEventType, SBBreakpoint, GetBreakpointEventTypeFromEvent, (const lldb::SBEvent &)); LLDB_REGISTER_STATIC_METHOD(lldb::SBBreakpoint, SBBreakpoint, GetBreakpointFromEvent, (const lldb::SBEvent &)); LLDB_REGISTER_STATIC_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, GetBreakpointLocationAtIndexFromEvent, (const lldb::SBEvent &, uint32_t)); LLDB_REGISTER_STATIC_METHOD(uint32_t, SBBreakpoint, GetNumBreakpointLocationsFromEvent, (const lldb::SBEvent &)); LLDB_REGISTER_METHOD_CONST(bool, SBBreakpoint, IsHardware, ()); } template <> void RegisterMethods(Registry &R) { LLDB_REGISTER_CONSTRUCTOR(SBBreakpointList, (lldb::SBTarget &)); LLDB_REGISTER_METHOD_CONST(size_t, SBBreakpointList, GetSize, ()); LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBBreakpointList, GetBreakpointAtIndex, (size_t)); LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBBreakpointList, FindBreakpointByID, (lldb::break_id_t)); LLDB_REGISTER_METHOD(void, SBBreakpointList, Append, (const lldb::SBBreakpoint &)); LLDB_REGISTER_METHOD(void, SBBreakpointList, AppendByID, (lldb::break_id_t)); LLDB_REGISTER_METHOD(bool, SBBreakpointList, AppendIfUnique, (const lldb::SBBreakpoint &)); LLDB_REGISTER_METHOD(void, SBBreakpointList, Clear, ()); } } }