Path: blob/main/contrib/llvm-project/lldb/source/API/SBBreakpoint.cpp
39587 views
//===-- SBBreakpoint.cpp --------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "lldb/API/SBBreakpoint.h"9#include "lldb/API/SBBreakpointLocation.h"10#include "lldb/API/SBDebugger.h"11#include "lldb/API/SBEvent.h"12#include "lldb/API/SBProcess.h"13#include "lldb/API/SBStream.h"14#include "lldb/API/SBStringList.h"15#include "lldb/API/SBStructuredData.h"16#include "lldb/API/SBThread.h"17#include "lldb/Utility/Instrumentation.h"1819#include "lldb/Breakpoint/Breakpoint.h"20#include "lldb/Breakpoint/BreakpointIDList.h"21#include "lldb/Breakpoint/BreakpointLocation.h"22#include "lldb/Breakpoint/BreakpointResolver.h"23#include "lldb/Breakpoint/BreakpointResolverScripted.h"24#include "lldb/Breakpoint/StoppointCallbackContext.h"25#include "lldb/Core/Address.h"26#include "lldb/Core/Debugger.h"27#include "lldb/Core/StructuredDataImpl.h"28#include "lldb/Interpreter/CommandInterpreter.h"29#include "lldb/Interpreter/ScriptInterpreter.h"30#include "lldb/Target/Process.h"31#include "lldb/Target/SectionLoadList.h"32#include "lldb/Target/Target.h"33#include "lldb/Target/Thread.h"34#include "lldb/Target/ThreadSpec.h"35#include "lldb/Utility/Stream.h"3637#include "SBBreakpointOptionCommon.h"3839#include "lldb/lldb-enumerations.h"4041#include "llvm/ADT/STLExtras.h"4243using namespace lldb;44using namespace lldb_private;4546SBBreakpoint::SBBreakpoint() { LLDB_INSTRUMENT_VA(this); }4748SBBreakpoint::SBBreakpoint(const SBBreakpoint &rhs)49: m_opaque_wp(rhs.m_opaque_wp) {50LLDB_INSTRUMENT_VA(this, rhs);51}5253SBBreakpoint::SBBreakpoint(const lldb::BreakpointSP &bp_sp)54: m_opaque_wp(bp_sp) {55LLDB_INSTRUMENT_VA(this, bp_sp);56}5758SBBreakpoint::~SBBreakpoint() = default;5960const SBBreakpoint &SBBreakpoint::operator=(const SBBreakpoint &rhs) {61LLDB_INSTRUMENT_VA(this, rhs);6263m_opaque_wp = rhs.m_opaque_wp;64return *this;65}6667bool SBBreakpoint::operator==(const lldb::SBBreakpoint &rhs) {68LLDB_INSTRUMENT_VA(this, rhs);6970return m_opaque_wp.lock() == rhs.m_opaque_wp.lock();71}7273bool SBBreakpoint::operator!=(const lldb::SBBreakpoint &rhs) {74LLDB_INSTRUMENT_VA(this, rhs);7576return m_opaque_wp.lock() != rhs.m_opaque_wp.lock();77}7879SBTarget SBBreakpoint::GetTarget() const {80LLDB_INSTRUMENT_VA(this);8182BreakpointSP bkpt_sp = GetSP();83if (bkpt_sp)84return SBTarget(bkpt_sp->GetTargetSP());8586return SBTarget();87}8889break_id_t SBBreakpoint::GetID() const {90LLDB_INSTRUMENT_VA(this);9192break_id_t break_id = LLDB_INVALID_BREAK_ID;93BreakpointSP bkpt_sp = GetSP();94if (bkpt_sp)95break_id = bkpt_sp->GetID();9697return break_id;98}99100bool SBBreakpoint::IsValid() const {101LLDB_INSTRUMENT_VA(this);102return this->operator bool();103}104SBBreakpoint::operator bool() const {105LLDB_INSTRUMENT_VA(this);106107BreakpointSP bkpt_sp = GetSP();108if (!bkpt_sp)109return false;110else if (bkpt_sp->GetTarget().GetBreakpointByID(bkpt_sp->GetID()))111return true;112else113return false;114}115116void SBBreakpoint::ClearAllBreakpointSites() {117LLDB_INSTRUMENT_VA(this);118119BreakpointSP bkpt_sp = GetSP();120if (bkpt_sp) {121std::lock_guard<std::recursive_mutex> guard(122bkpt_sp->GetTarget().GetAPIMutex());123bkpt_sp->ClearAllBreakpointSites();124}125}126127SBBreakpointLocation SBBreakpoint::FindLocationByAddress(addr_t vm_addr) {128LLDB_INSTRUMENT_VA(this, vm_addr);129130SBBreakpointLocation sb_bp_location;131132BreakpointSP bkpt_sp = GetSP();133if (bkpt_sp) {134if (vm_addr != LLDB_INVALID_ADDRESS) {135std::lock_guard<std::recursive_mutex> guard(136bkpt_sp->GetTarget().GetAPIMutex());137Address address;138Target &target = bkpt_sp->GetTarget();139if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) {140address.SetRawAddress(vm_addr);141}142sb_bp_location.SetLocation(bkpt_sp->FindLocationByAddress(address));143}144}145return sb_bp_location;146}147148break_id_t SBBreakpoint::FindLocationIDByAddress(addr_t vm_addr) {149LLDB_INSTRUMENT_VA(this, vm_addr);150151break_id_t break_id = LLDB_INVALID_BREAK_ID;152BreakpointSP bkpt_sp = GetSP();153154if (bkpt_sp && vm_addr != LLDB_INVALID_ADDRESS) {155std::lock_guard<std::recursive_mutex> guard(156bkpt_sp->GetTarget().GetAPIMutex());157Address address;158Target &target = bkpt_sp->GetTarget();159if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) {160address.SetRawAddress(vm_addr);161}162break_id = bkpt_sp->FindLocationIDByAddress(address);163}164165return break_id;166}167168SBBreakpointLocation SBBreakpoint::FindLocationByID(break_id_t bp_loc_id) {169LLDB_INSTRUMENT_VA(this, bp_loc_id);170171SBBreakpointLocation sb_bp_location;172BreakpointSP bkpt_sp = GetSP();173174if (bkpt_sp) {175std::lock_guard<std::recursive_mutex> guard(176bkpt_sp->GetTarget().GetAPIMutex());177sb_bp_location.SetLocation(bkpt_sp->FindLocationByID(bp_loc_id));178}179180return sb_bp_location;181}182183SBBreakpointLocation SBBreakpoint::GetLocationAtIndex(uint32_t index) {184LLDB_INSTRUMENT_VA(this, index);185186SBBreakpointLocation sb_bp_location;187BreakpointSP bkpt_sp = GetSP();188189if (bkpt_sp) {190std::lock_guard<std::recursive_mutex> guard(191bkpt_sp->GetTarget().GetAPIMutex());192sb_bp_location.SetLocation(bkpt_sp->GetLocationAtIndex(index));193}194195return sb_bp_location;196}197198void SBBreakpoint::SetEnabled(bool enable) {199LLDB_INSTRUMENT_VA(this, enable);200201BreakpointSP bkpt_sp = GetSP();202203if (bkpt_sp) {204std::lock_guard<std::recursive_mutex> guard(205bkpt_sp->GetTarget().GetAPIMutex());206bkpt_sp->SetEnabled(enable);207}208}209210bool SBBreakpoint::IsEnabled() {211LLDB_INSTRUMENT_VA(this);212213BreakpointSP bkpt_sp = GetSP();214if (bkpt_sp) {215std::lock_guard<std::recursive_mutex> guard(216bkpt_sp->GetTarget().GetAPIMutex());217return bkpt_sp->IsEnabled();218} else219return false;220}221222void SBBreakpoint::SetOneShot(bool one_shot) {223LLDB_INSTRUMENT_VA(this, one_shot);224225BreakpointSP bkpt_sp = GetSP();226227if (bkpt_sp) {228std::lock_guard<std::recursive_mutex> guard(229bkpt_sp->GetTarget().GetAPIMutex());230bkpt_sp->SetOneShot(one_shot);231}232}233234bool SBBreakpoint::IsOneShot() const {235LLDB_INSTRUMENT_VA(this);236237BreakpointSP bkpt_sp = GetSP();238if (bkpt_sp) {239std::lock_guard<std::recursive_mutex> guard(240bkpt_sp->GetTarget().GetAPIMutex());241return bkpt_sp->IsOneShot();242} else243return false;244}245246bool SBBreakpoint::IsInternal() {247LLDB_INSTRUMENT_VA(this);248249BreakpointSP bkpt_sp = GetSP();250if (bkpt_sp) {251std::lock_guard<std::recursive_mutex> guard(252bkpt_sp->GetTarget().GetAPIMutex());253return bkpt_sp->IsInternal();254} else255return false;256}257258void SBBreakpoint::SetIgnoreCount(uint32_t count) {259LLDB_INSTRUMENT_VA(this, count);260261BreakpointSP bkpt_sp = GetSP();262263if (bkpt_sp) {264std::lock_guard<std::recursive_mutex> guard(265bkpt_sp->GetTarget().GetAPIMutex());266bkpt_sp->SetIgnoreCount(count);267}268}269270void SBBreakpoint::SetCondition(const char *condition) {271LLDB_INSTRUMENT_VA(this, condition);272273BreakpointSP bkpt_sp = GetSP();274if (bkpt_sp) {275std::lock_guard<std::recursive_mutex> guard(276bkpt_sp->GetTarget().GetAPIMutex());277bkpt_sp->SetCondition(condition);278}279}280281const char *SBBreakpoint::GetCondition() {282LLDB_INSTRUMENT_VA(this);283284BreakpointSP bkpt_sp = GetSP();285if (!bkpt_sp)286return nullptr;287288std::lock_guard<std::recursive_mutex> guard(289bkpt_sp->GetTarget().GetAPIMutex());290return ConstString(bkpt_sp->GetConditionText()).GetCString();291}292293void SBBreakpoint::SetAutoContinue(bool auto_continue) {294LLDB_INSTRUMENT_VA(this, auto_continue);295296BreakpointSP bkpt_sp = GetSP();297if (bkpt_sp) {298std::lock_guard<std::recursive_mutex> guard(299bkpt_sp->GetTarget().GetAPIMutex());300bkpt_sp->SetAutoContinue(auto_continue);301}302}303304bool SBBreakpoint::GetAutoContinue() {305LLDB_INSTRUMENT_VA(this);306307BreakpointSP bkpt_sp = GetSP();308if (bkpt_sp) {309std::lock_guard<std::recursive_mutex> guard(310bkpt_sp->GetTarget().GetAPIMutex());311return bkpt_sp->IsAutoContinue();312}313return false;314}315316uint32_t SBBreakpoint::GetHitCount() const {317LLDB_INSTRUMENT_VA(this);318319uint32_t count = 0;320BreakpointSP bkpt_sp = GetSP();321if (bkpt_sp) {322std::lock_guard<std::recursive_mutex> guard(323bkpt_sp->GetTarget().GetAPIMutex());324count = bkpt_sp->GetHitCount();325}326327return count;328}329330uint32_t SBBreakpoint::GetIgnoreCount() const {331LLDB_INSTRUMENT_VA(this);332333uint32_t count = 0;334BreakpointSP bkpt_sp = GetSP();335if (bkpt_sp) {336std::lock_guard<std::recursive_mutex> guard(337bkpt_sp->GetTarget().GetAPIMutex());338count = bkpt_sp->GetIgnoreCount();339}340341return count;342}343344void SBBreakpoint::SetThreadID(tid_t tid) {345LLDB_INSTRUMENT_VA(this, tid);346347BreakpointSP bkpt_sp = GetSP();348if (bkpt_sp) {349std::lock_guard<std::recursive_mutex> guard(350bkpt_sp->GetTarget().GetAPIMutex());351bkpt_sp->SetThreadID(tid);352}353}354355tid_t SBBreakpoint::GetThreadID() {356LLDB_INSTRUMENT_VA(this);357358tid_t tid = LLDB_INVALID_THREAD_ID;359BreakpointSP bkpt_sp = GetSP();360if (bkpt_sp) {361std::lock_guard<std::recursive_mutex> guard(362bkpt_sp->GetTarget().GetAPIMutex());363tid = bkpt_sp->GetThreadID();364}365366return tid;367}368369void SBBreakpoint::SetThreadIndex(uint32_t index) {370LLDB_INSTRUMENT_VA(this, index);371372BreakpointSP bkpt_sp = GetSP();373if (bkpt_sp) {374std::lock_guard<std::recursive_mutex> guard(375bkpt_sp->GetTarget().GetAPIMutex());376bkpt_sp->GetOptions().GetThreadSpec()->SetIndex(index);377}378}379380uint32_t SBBreakpoint::GetThreadIndex() const {381LLDB_INSTRUMENT_VA(this);382383uint32_t thread_idx = UINT32_MAX;384BreakpointSP bkpt_sp = GetSP();385if (bkpt_sp) {386std::lock_guard<std::recursive_mutex> guard(387bkpt_sp->GetTarget().GetAPIMutex());388const ThreadSpec *thread_spec =389bkpt_sp->GetOptions().GetThreadSpecNoCreate();390if (thread_spec != nullptr)391thread_idx = thread_spec->GetIndex();392}393394return thread_idx;395}396397void SBBreakpoint::SetThreadName(const char *thread_name) {398LLDB_INSTRUMENT_VA(this, thread_name);399400BreakpointSP bkpt_sp = GetSP();401402if (bkpt_sp) {403std::lock_guard<std::recursive_mutex> guard(404bkpt_sp->GetTarget().GetAPIMutex());405bkpt_sp->GetOptions().GetThreadSpec()->SetName(thread_name);406}407}408409const char *SBBreakpoint::GetThreadName() const {410LLDB_INSTRUMENT_VA(this);411412BreakpointSP bkpt_sp = GetSP();413if (!bkpt_sp)414return nullptr;415416std::lock_guard<std::recursive_mutex> guard(417bkpt_sp->GetTarget().GetAPIMutex());418if (const ThreadSpec *thread_spec =419bkpt_sp->GetOptions().GetThreadSpecNoCreate())420return ConstString(thread_spec->GetName()).GetCString();421422return nullptr;423}424425void SBBreakpoint::SetQueueName(const char *queue_name) {426LLDB_INSTRUMENT_VA(this, queue_name);427428BreakpointSP bkpt_sp = GetSP();429if (bkpt_sp) {430std::lock_guard<std::recursive_mutex> guard(431bkpt_sp->GetTarget().GetAPIMutex());432bkpt_sp->GetOptions().GetThreadSpec()->SetQueueName(queue_name);433}434}435436const char *SBBreakpoint::GetQueueName() const {437LLDB_INSTRUMENT_VA(this);438439BreakpointSP bkpt_sp = GetSP();440if (!bkpt_sp)441return nullptr;442443std::lock_guard<std::recursive_mutex> guard(444bkpt_sp->GetTarget().GetAPIMutex());445if (const ThreadSpec *thread_spec =446bkpt_sp->GetOptions().GetThreadSpecNoCreate())447return ConstString(thread_spec->GetQueueName()).GetCString();448449return nullptr;450}451452size_t SBBreakpoint::GetNumResolvedLocations() const {453LLDB_INSTRUMENT_VA(this);454455size_t num_resolved = 0;456BreakpointSP bkpt_sp = GetSP();457if (bkpt_sp) {458std::lock_guard<std::recursive_mutex> guard(459bkpt_sp->GetTarget().GetAPIMutex());460num_resolved = bkpt_sp->GetNumResolvedLocations();461}462return num_resolved;463}464465size_t SBBreakpoint::GetNumLocations() const {466LLDB_INSTRUMENT_VA(this);467468BreakpointSP bkpt_sp = GetSP();469size_t num_locs = 0;470if (bkpt_sp) {471std::lock_guard<std::recursive_mutex> guard(472bkpt_sp->GetTarget().GetAPIMutex());473num_locs = bkpt_sp->GetNumLocations();474}475return num_locs;476}477478void SBBreakpoint::SetCommandLineCommands(SBStringList &commands) {479LLDB_INSTRUMENT_VA(this, commands);480481BreakpointSP bkpt_sp = GetSP();482if (!bkpt_sp)483return;484if (commands.GetSize() == 0)485return;486487std::lock_guard<std::recursive_mutex> guard(488bkpt_sp->GetTarget().GetAPIMutex());489std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up(490new BreakpointOptions::CommandData(*commands, eScriptLanguageNone));491492bkpt_sp->GetOptions().SetCommandDataCallback(cmd_data_up);493}494495bool SBBreakpoint::GetCommandLineCommands(SBStringList &commands) {496LLDB_INSTRUMENT_VA(this, commands);497498BreakpointSP bkpt_sp = GetSP();499if (!bkpt_sp)500return false;501StringList command_list;502bool has_commands =503bkpt_sp->GetOptions().GetCommandLineCallbacks(command_list);504if (has_commands)505commands.AppendList(command_list);506return has_commands;507}508509bool SBBreakpoint::GetDescription(SBStream &s) {510LLDB_INSTRUMENT_VA(this, s);511512return GetDescription(s, true);513}514515bool SBBreakpoint::GetDescription(SBStream &s, bool include_locations) {516LLDB_INSTRUMENT_VA(this, s, include_locations);517518BreakpointSP bkpt_sp = GetSP();519if (bkpt_sp) {520std::lock_guard<std::recursive_mutex> guard(521bkpt_sp->GetTarget().GetAPIMutex());522s.Printf("SBBreakpoint: id = %i, ", bkpt_sp->GetID());523bkpt_sp->GetResolverDescription(s.get());524bkpt_sp->GetFilterDescription(s.get());525if (include_locations) {526const size_t num_locations = bkpt_sp->GetNumLocations();527s.Printf(", locations = %" PRIu64, (uint64_t)num_locations);528}529return true;530}531s.Printf("No value");532return false;533}534535SBError SBBreakpoint::AddLocation(SBAddress &address) {536LLDB_INSTRUMENT_VA(this, address);537538BreakpointSP bkpt_sp = GetSP();539SBError error;540541if (!address.IsValid()) {542error.SetErrorString("Can't add an invalid address.");543return error;544}545546if (!bkpt_sp) {547error.SetErrorString("No breakpoint to add a location to.");548return error;549}550551if (!llvm::isa<BreakpointResolverScripted>(bkpt_sp->GetResolver().get())) {552error.SetErrorString("Only a scripted resolver can add locations.");553return error;554}555556if (bkpt_sp->GetSearchFilter()->AddressPasses(address.ref()))557bkpt_sp->AddLocation(address.ref());558else {559StreamString s;560address.get()->Dump(&s, &bkpt_sp->GetTarget(),561Address::DumpStyleModuleWithFileAddress);562error.SetErrorStringWithFormat("Address: %s didn't pass the filter.",563s.GetData());564}565return error;566}567568SBStructuredData SBBreakpoint::SerializeToStructuredData() {569LLDB_INSTRUMENT_VA(this);570571SBStructuredData data;572BreakpointSP bkpt_sp = GetSP();573574if (!bkpt_sp)575return data;576577StructuredData::ObjectSP bkpt_dict = bkpt_sp->SerializeToStructuredData();578data.m_impl_up->SetObjectSP(bkpt_dict);579return data;580}581582void SBBreakpoint::SetCallback(SBBreakpointHitCallback callback, void *baton) {583LLDB_INSTRUMENT_VA(this, callback, baton);584585BreakpointSP bkpt_sp = GetSP();586587if (bkpt_sp) {588std::lock_guard<std::recursive_mutex> guard(589bkpt_sp->GetTarget().GetAPIMutex());590BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton));591bkpt_sp->SetCallback(SBBreakpointCallbackBaton592::PrivateBreakpointHitCallback, baton_sp,593false);594}595}596597void SBBreakpoint::SetScriptCallbackFunction(598const char *callback_function_name) {599LLDB_INSTRUMENT_VA(this, callback_function_name);600SBStructuredData empty_args;601SetScriptCallbackFunction(callback_function_name, empty_args);602}603604SBError SBBreakpoint::SetScriptCallbackFunction(605const char *callback_function_name,606SBStructuredData &extra_args) {607LLDB_INSTRUMENT_VA(this, callback_function_name, extra_args);608SBError sb_error;609BreakpointSP bkpt_sp = GetSP();610611if (bkpt_sp) {612Status error;613std::lock_guard<std::recursive_mutex> guard(614bkpt_sp->GetTarget().GetAPIMutex());615BreakpointOptions &bp_options = bkpt_sp->GetOptions();616error = bkpt_sp->GetTarget()617.GetDebugger()618.GetScriptInterpreter()619->SetBreakpointCommandCallbackFunction(bp_options,620callback_function_name,621extra_args.m_impl_up622->GetObjectSP());623sb_error.SetError(error);624} else625sb_error.SetErrorString("invalid breakpoint");626627return sb_error;628}629630SBError SBBreakpoint::SetScriptCallbackBody(const char *callback_body_text) {631LLDB_INSTRUMENT_VA(this, callback_body_text);632633BreakpointSP bkpt_sp = GetSP();634635SBError sb_error;636if (bkpt_sp) {637std::lock_guard<std::recursive_mutex> guard(638bkpt_sp->GetTarget().GetAPIMutex());639BreakpointOptions &bp_options = bkpt_sp->GetOptions();640Status error =641bkpt_sp->GetTarget()642.GetDebugger()643.GetScriptInterpreter()644->SetBreakpointCommandCallback(bp_options, callback_body_text,645/*is_callback=*/false);646sb_error.SetError(error);647} else648sb_error.SetErrorString("invalid breakpoint");649650return sb_error;651}652653bool SBBreakpoint::AddName(const char *new_name) {654LLDB_INSTRUMENT_VA(this, new_name);655656SBError status = AddNameWithErrorHandling(new_name);657return status.Success();658}659660SBError SBBreakpoint::AddNameWithErrorHandling(const char *new_name) {661LLDB_INSTRUMENT_VA(this, new_name);662663BreakpointSP bkpt_sp = GetSP();664665SBError status;666if (bkpt_sp) {667std::lock_guard<std::recursive_mutex> guard(668bkpt_sp->GetTarget().GetAPIMutex());669Status error;670bkpt_sp->GetTarget().AddNameToBreakpoint(bkpt_sp, new_name, error);671status.SetError(error);672} else {673status.SetErrorString("invalid breakpoint");674}675676return status;677}678679void SBBreakpoint::RemoveName(const char *name_to_remove) {680LLDB_INSTRUMENT_VA(this, name_to_remove);681682BreakpointSP bkpt_sp = GetSP();683684if (bkpt_sp) {685std::lock_guard<std::recursive_mutex> guard(686bkpt_sp->GetTarget().GetAPIMutex());687bkpt_sp->GetTarget().RemoveNameFromBreakpoint(bkpt_sp,688ConstString(name_to_remove));689}690}691692bool SBBreakpoint::MatchesName(const char *name) {693LLDB_INSTRUMENT_VA(this, name);694695BreakpointSP bkpt_sp = GetSP();696697if (bkpt_sp) {698std::lock_guard<std::recursive_mutex> guard(699bkpt_sp->GetTarget().GetAPIMutex());700return bkpt_sp->MatchesName(name);701}702703return false;704}705706void SBBreakpoint::GetNames(SBStringList &names) {707LLDB_INSTRUMENT_VA(this, names);708709BreakpointSP bkpt_sp = GetSP();710711if (bkpt_sp) {712std::lock_guard<std::recursive_mutex> guard(713bkpt_sp->GetTarget().GetAPIMutex());714std::vector<std::string> names_vec;715bkpt_sp->GetNames(names_vec);716for (const std::string &name : names_vec) {717names.AppendString(name.c_str());718}719}720}721722bool SBBreakpoint::EventIsBreakpointEvent(const lldb::SBEvent &event) {723LLDB_INSTRUMENT_VA(event);724725return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event.get()) !=726nullptr;727}728729BreakpointEventType730SBBreakpoint::GetBreakpointEventTypeFromEvent(const SBEvent &event) {731LLDB_INSTRUMENT_VA(event);732733if (event.IsValid())734return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent(735event.GetSP());736return eBreakpointEventTypeInvalidType;737}738739SBBreakpoint SBBreakpoint::GetBreakpointFromEvent(const lldb::SBEvent &event) {740LLDB_INSTRUMENT_VA(event);741742if (event.IsValid())743return SBBreakpoint(744Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event.GetSP()));745return SBBreakpoint();746}747748SBBreakpointLocation749SBBreakpoint::GetBreakpointLocationAtIndexFromEvent(const lldb::SBEvent &event,750uint32_t loc_idx) {751LLDB_INSTRUMENT_VA(event, loc_idx);752753SBBreakpointLocation sb_breakpoint_loc;754if (event.IsValid())755sb_breakpoint_loc.SetLocation(756Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent(757event.GetSP(), loc_idx));758return sb_breakpoint_loc;759}760761uint32_t762SBBreakpoint::GetNumBreakpointLocationsFromEvent(const lldb::SBEvent &event) {763LLDB_INSTRUMENT_VA(event);764765uint32_t num_locations = 0;766if (event.IsValid())767num_locations =768(Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(769event.GetSP()));770return num_locations;771}772773bool SBBreakpoint::IsHardware() const {774LLDB_INSTRUMENT_VA(this);775776BreakpointSP bkpt_sp = GetSP();777if (bkpt_sp)778return bkpt_sp->IsHardware();779return false;780}781782BreakpointSP SBBreakpoint::GetSP() const { return m_opaque_wp.lock(); }783784// This is simple collection of breakpoint id's and their target.785class SBBreakpointListImpl {786public:787SBBreakpointListImpl(lldb::TargetSP target_sp) {788if (target_sp && target_sp->IsValid())789m_target_wp = target_sp;790}791792~SBBreakpointListImpl() = default;793794size_t GetSize() { return m_break_ids.size(); }795796BreakpointSP GetBreakpointAtIndex(size_t idx) {797if (idx >= m_break_ids.size())798return BreakpointSP();799TargetSP target_sp = m_target_wp.lock();800if (!target_sp)801return BreakpointSP();802lldb::break_id_t bp_id = m_break_ids[idx];803return target_sp->GetBreakpointList().FindBreakpointByID(bp_id);804}805806BreakpointSP FindBreakpointByID(lldb::break_id_t desired_id) {807TargetSP target_sp = m_target_wp.lock();808if (!target_sp)809return BreakpointSP();810811for (lldb::break_id_t &break_id : m_break_ids) {812if (break_id == desired_id)813return target_sp->GetBreakpointList().FindBreakpointByID(break_id);814}815return BreakpointSP();816}817818bool Append(BreakpointSP bkpt) {819TargetSP target_sp = m_target_wp.lock();820if (!target_sp || !bkpt)821return false;822if (bkpt->GetTargetSP() != target_sp)823return false;824m_break_ids.push_back(bkpt->GetID());825return true;826}827828bool AppendIfUnique(BreakpointSP bkpt) {829TargetSP target_sp = m_target_wp.lock();830if (!target_sp || !bkpt)831return false;832if (bkpt->GetTargetSP() != target_sp)833return false;834lldb::break_id_t bp_id = bkpt->GetID();835if (!llvm::is_contained(m_break_ids, bp_id))836return false;837838m_break_ids.push_back(bkpt->GetID());839return true;840}841842bool AppendByID(lldb::break_id_t id) {843TargetSP target_sp = m_target_wp.lock();844if (!target_sp)845return false;846if (id == LLDB_INVALID_BREAK_ID)847return false;848m_break_ids.push_back(id);849return true;850}851852void Clear() { m_break_ids.clear(); }853854void CopyToBreakpointIDList(lldb_private::BreakpointIDList &bp_list) {855for (lldb::break_id_t id : m_break_ids) {856bp_list.AddBreakpointID(BreakpointID(id));857}858}859860TargetSP GetTarget() { return m_target_wp.lock(); }861862private:863std::vector<lldb::break_id_t> m_break_ids;864TargetWP m_target_wp;865};866867SBBreakpointList::SBBreakpointList(SBTarget &target)868: m_opaque_sp(new SBBreakpointListImpl(target.GetSP())) {869LLDB_INSTRUMENT_VA(this, target);870}871872SBBreakpointList::~SBBreakpointList() = default;873874size_t SBBreakpointList::GetSize() const {875LLDB_INSTRUMENT_VA(this);876877if (!m_opaque_sp)878return 0;879else880return m_opaque_sp->GetSize();881}882883SBBreakpoint SBBreakpointList::GetBreakpointAtIndex(size_t idx) {884LLDB_INSTRUMENT_VA(this, idx);885886if (!m_opaque_sp)887return SBBreakpoint();888889BreakpointSP bkpt_sp = m_opaque_sp->GetBreakpointAtIndex(idx);890return SBBreakpoint(bkpt_sp);891}892893SBBreakpoint SBBreakpointList::FindBreakpointByID(lldb::break_id_t id) {894LLDB_INSTRUMENT_VA(this, id);895896if (!m_opaque_sp)897return SBBreakpoint();898BreakpointSP bkpt_sp = m_opaque_sp->FindBreakpointByID(id);899return SBBreakpoint(bkpt_sp);900}901902void SBBreakpointList::Append(const SBBreakpoint &sb_bkpt) {903LLDB_INSTRUMENT_VA(this, sb_bkpt);904905if (!sb_bkpt.IsValid())906return;907if (!m_opaque_sp)908return;909m_opaque_sp->Append(sb_bkpt.m_opaque_wp.lock());910}911912void SBBreakpointList::AppendByID(lldb::break_id_t id) {913LLDB_INSTRUMENT_VA(this, id);914915if (!m_opaque_sp)916return;917m_opaque_sp->AppendByID(id);918}919920bool SBBreakpointList::AppendIfUnique(const SBBreakpoint &sb_bkpt) {921LLDB_INSTRUMENT_VA(this, sb_bkpt);922923if (!sb_bkpt.IsValid())924return false;925if (!m_opaque_sp)926return false;927return m_opaque_sp->AppendIfUnique(sb_bkpt.GetSP());928}929930void SBBreakpointList::Clear() {931LLDB_INSTRUMENT_VA(this);932933if (m_opaque_sp)934m_opaque_sp->Clear();935}936937void SBBreakpointList::CopyToBreakpointIDList(938lldb_private::BreakpointIDList &bp_id_list) {939if (m_opaque_sp)940m_opaque_sp->CopyToBreakpointIDList(bp_id_list);941}942943944