brintos

brintos / llvm-project-archived public Read only

0
0
Text · 25.4 KiB · 04af7a3 Raw
972 lines · cpp
1//===-- SBBreakpoint.cpp --------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "lldb/API/SBBreakpoint.h"10#include "lldb/API/SBBreakpointLocation.h"11#include "lldb/API/SBDebugger.h"12#include "lldb/API/SBEvent.h"13#include "lldb/API/SBProcess.h"14#include "lldb/API/SBStream.h"15#include "lldb/API/SBStringList.h"16#include "lldb/API/SBStructuredData.h"17#include "lldb/API/SBThread.h"18#include "lldb/Utility/Instrumentation.h"19 20#include "lldb/Breakpoint/Breakpoint.h"21#include "lldb/Breakpoint/BreakpointIDList.h"22#include "lldb/Breakpoint/BreakpointLocation.h"23#include "lldb/Breakpoint/BreakpointResolver.h"24#include "lldb/Breakpoint/BreakpointResolverScripted.h"25#include "lldb/Breakpoint/StoppointCallbackContext.h"26#include "lldb/Core/Address.h"27#include "lldb/Core/Debugger.h"28#include "lldb/Core/StructuredDataImpl.h"29#include "lldb/Interpreter/CommandInterpreter.h"30#include "lldb/Interpreter/ScriptInterpreter.h"31#include "lldb/Target/Process.h"32#include "lldb/Target/SectionLoadList.h"33#include "lldb/Target/Target.h"34#include "lldb/Target/Thread.h"35#include "lldb/Target/ThreadSpec.h"36#include "lldb/Utility/Stream.h"37 38#include "SBBreakpointOptionCommon.h"39 40#include "lldb/lldb-enumerations.h"41 42#include "llvm/ADT/STLExtras.h"43 44using namespace lldb;45using namespace lldb_private;46 47SBBreakpoint::SBBreakpoint() { LLDB_INSTRUMENT_VA(this); }48 49SBBreakpoint::SBBreakpoint(const SBBreakpoint &rhs)50    : m_opaque_wp(rhs.m_opaque_wp) {51  LLDB_INSTRUMENT_VA(this, rhs);52}53 54SBBreakpoint::SBBreakpoint(const lldb::BreakpointSP &bp_sp)55    : m_opaque_wp(bp_sp) {56  LLDB_INSTRUMENT_VA(this, bp_sp);57}58 59SBBreakpoint::~SBBreakpoint() = default;60 61const SBBreakpoint &SBBreakpoint::operator=(const SBBreakpoint &rhs) {62  LLDB_INSTRUMENT_VA(this, rhs);63 64  m_opaque_wp = rhs.m_opaque_wp;65  return *this;66}67 68bool SBBreakpoint::operator==(const lldb::SBBreakpoint &rhs) {69  LLDB_INSTRUMENT_VA(this, rhs);70 71  return m_opaque_wp.lock() == rhs.m_opaque_wp.lock();72}73 74bool SBBreakpoint::operator!=(const lldb::SBBreakpoint &rhs) {75  LLDB_INSTRUMENT_VA(this, rhs);76 77  return m_opaque_wp.lock() != rhs.m_opaque_wp.lock();78}79 80SBTarget SBBreakpoint::GetTarget() const {81  LLDB_INSTRUMENT_VA(this);82 83  BreakpointSP bkpt_sp = GetSP();84  if (bkpt_sp)85    return SBTarget(bkpt_sp->GetTargetSP());86 87  return SBTarget();88}89 90break_id_t SBBreakpoint::GetID() const {91  LLDB_INSTRUMENT_VA(this);92 93  break_id_t break_id = LLDB_INVALID_BREAK_ID;94  BreakpointSP bkpt_sp = GetSP();95  if (bkpt_sp)96    break_id = bkpt_sp->GetID();97 98  return break_id;99}100 101bool SBBreakpoint::IsValid() const {102  LLDB_INSTRUMENT_VA(this);103  return this->operator bool();104}105SBBreakpoint::operator bool() const {106  LLDB_INSTRUMENT_VA(this);107 108  BreakpointSP bkpt_sp = GetSP();109  if (!bkpt_sp)110    return false;111  else if (bkpt_sp->GetTarget().GetBreakpointByID(bkpt_sp->GetID()))112    return true;113  else114    return false;115}116 117void SBBreakpoint::ClearAllBreakpointSites() {118  LLDB_INSTRUMENT_VA(this);119 120  BreakpointSP bkpt_sp = GetSP();121  if (bkpt_sp) {122    std::lock_guard<std::recursive_mutex> guard(123        bkpt_sp->GetTarget().GetAPIMutex());124    bkpt_sp->ClearAllBreakpointSites();125  }126}127 128SBBreakpointLocation SBBreakpoint::FindLocationByAddress(addr_t vm_addr) {129  LLDB_INSTRUMENT_VA(this, vm_addr);130 131  SBBreakpointLocation sb_bp_location;132 133  BreakpointSP bkpt_sp = GetSP();134  if (bkpt_sp) {135    if (vm_addr != LLDB_INVALID_ADDRESS) {136      std::lock_guard<std::recursive_mutex> guard(137          bkpt_sp->GetTarget().GetAPIMutex());138      Address address;139      Target &target = bkpt_sp->GetTarget();140      if (!target.ResolveLoadAddress(vm_addr, address)) {141        address.SetRawAddress(vm_addr);142      }143      sb_bp_location.SetLocation(bkpt_sp->FindLocationByAddress(address));144    }145  }146  return sb_bp_location;147}148 149break_id_t SBBreakpoint::FindLocationIDByAddress(addr_t vm_addr) {150  LLDB_INSTRUMENT_VA(this, vm_addr);151 152  break_id_t break_id = LLDB_INVALID_BREAK_ID;153  BreakpointSP bkpt_sp = GetSP();154 155  if (bkpt_sp && vm_addr != LLDB_INVALID_ADDRESS) {156    std::lock_guard<std::recursive_mutex> guard(157        bkpt_sp->GetTarget().GetAPIMutex());158    Address address;159    Target &target = bkpt_sp->GetTarget();160    if (!target.ResolveLoadAddress(vm_addr, address)) {161      address.SetRawAddress(vm_addr);162    }163    break_id = bkpt_sp->FindLocationIDByAddress(address);164  }165 166  return break_id;167}168 169SBBreakpointLocation SBBreakpoint::FindLocationByID(break_id_t bp_loc_id) {170  LLDB_INSTRUMENT_VA(this, bp_loc_id);171 172  SBBreakpointLocation sb_bp_location;173  BreakpointSP bkpt_sp = GetSP();174 175  if (bkpt_sp) {176    std::lock_guard<std::recursive_mutex> guard(177        bkpt_sp->GetTarget().GetAPIMutex());178    sb_bp_location.SetLocation(bkpt_sp->FindLocationByID(bp_loc_id));179  }180 181  return sb_bp_location;182}183 184SBBreakpointLocation SBBreakpoint::GetLocationAtIndex(uint32_t index) {185  LLDB_INSTRUMENT_VA(this, index);186 187  SBBreakpointLocation sb_bp_location;188  BreakpointSP bkpt_sp = GetSP();189 190  if (bkpt_sp) {191    std::lock_guard<std::recursive_mutex> guard(192        bkpt_sp->GetTarget().GetAPIMutex());193    sb_bp_location.SetLocation(bkpt_sp->GetLocationAtIndex(index));194  }195 196  return sb_bp_location;197}198 199void SBBreakpoint::SetEnabled(bool enable) {200  LLDB_INSTRUMENT_VA(this, enable);201 202  BreakpointSP bkpt_sp = GetSP();203 204  if (bkpt_sp) {205    std::lock_guard<std::recursive_mutex> guard(206        bkpt_sp->GetTarget().GetAPIMutex());207    bkpt_sp->SetEnabled(enable);208  }209}210 211bool SBBreakpoint::IsEnabled() {212  LLDB_INSTRUMENT_VA(this);213 214  BreakpointSP bkpt_sp = GetSP();215  if (bkpt_sp) {216    std::lock_guard<std::recursive_mutex> guard(217        bkpt_sp->GetTarget().GetAPIMutex());218    return bkpt_sp->IsEnabled();219  } else220    return false;221}222 223void SBBreakpoint::SetOneShot(bool one_shot) {224  LLDB_INSTRUMENT_VA(this, one_shot);225 226  BreakpointSP bkpt_sp = GetSP();227 228  if (bkpt_sp) {229    std::lock_guard<std::recursive_mutex> guard(230        bkpt_sp->GetTarget().GetAPIMutex());231    bkpt_sp->SetOneShot(one_shot);232  }233}234 235bool SBBreakpoint::IsOneShot() const {236  LLDB_INSTRUMENT_VA(this);237 238  BreakpointSP bkpt_sp = GetSP();239  if (bkpt_sp) {240    std::lock_guard<std::recursive_mutex> guard(241        bkpt_sp->GetTarget().GetAPIMutex());242    return bkpt_sp->IsOneShot();243  } else244    return false;245}246 247bool SBBreakpoint::IsInternal() {248  LLDB_INSTRUMENT_VA(this);249 250  BreakpointSP bkpt_sp = GetSP();251  if (bkpt_sp) {252    std::lock_guard<std::recursive_mutex> guard(253        bkpt_sp->GetTarget().GetAPIMutex());254    return bkpt_sp->IsInternal();255  } else256    return false;257}258 259void SBBreakpoint::SetIgnoreCount(uint32_t count) {260  LLDB_INSTRUMENT_VA(this, count);261 262  BreakpointSP bkpt_sp = GetSP();263 264  if (bkpt_sp) {265    std::lock_guard<std::recursive_mutex> guard(266        bkpt_sp->GetTarget().GetAPIMutex());267    bkpt_sp->SetIgnoreCount(count);268  }269}270 271void SBBreakpoint::SetCondition(const char *condition) {272  LLDB_INSTRUMENT_VA(this, condition);273 274  BreakpointSP bkpt_sp = GetSP();275  if (bkpt_sp) {276    std::lock_guard<std::recursive_mutex> guard(277        bkpt_sp->GetTarget().GetAPIMutex());278    // Treat a null pointer as resetting the condition.279    if (!condition)280      bkpt_sp->SetCondition(StopCondition());281    else282      bkpt_sp->SetCondition(StopCondition(condition));283  }284}285 286const char *SBBreakpoint::GetCondition() {287  LLDB_INSTRUMENT_VA(this);288 289  BreakpointSP bkpt_sp = GetSP();290  if (!bkpt_sp)291    return nullptr;292 293  std::lock_guard<std::recursive_mutex> guard(294      bkpt_sp->GetTarget().GetAPIMutex());295  StopCondition cond = bkpt_sp->GetCondition();296  if (!cond)297    return nullptr;298  return ConstString(cond.GetText()).GetCString();299}300 301void SBBreakpoint::SetAutoContinue(bool auto_continue) {302  LLDB_INSTRUMENT_VA(this, auto_continue);303 304  BreakpointSP bkpt_sp = GetSP();305  if (bkpt_sp) {306    std::lock_guard<std::recursive_mutex> guard(307        bkpt_sp->GetTarget().GetAPIMutex());308    bkpt_sp->SetAutoContinue(auto_continue);309  }310}311 312bool SBBreakpoint::GetAutoContinue() {313  LLDB_INSTRUMENT_VA(this);314 315  BreakpointSP bkpt_sp = GetSP();316  if (bkpt_sp) {317    std::lock_guard<std::recursive_mutex> guard(318        bkpt_sp->GetTarget().GetAPIMutex());319    return bkpt_sp->IsAutoContinue();320  }321  return false;322}323 324uint32_t SBBreakpoint::GetHitCount() const {325  LLDB_INSTRUMENT_VA(this);326 327  uint32_t count = 0;328  BreakpointSP bkpt_sp = GetSP();329  if (bkpt_sp) {330    std::lock_guard<std::recursive_mutex> guard(331        bkpt_sp->GetTarget().GetAPIMutex());332    count = bkpt_sp->GetHitCount();333  }334 335  return count;336}337 338uint32_t SBBreakpoint::GetIgnoreCount() const {339  LLDB_INSTRUMENT_VA(this);340 341  uint32_t count = 0;342  BreakpointSP bkpt_sp = GetSP();343  if (bkpt_sp) {344    std::lock_guard<std::recursive_mutex> guard(345        bkpt_sp->GetTarget().GetAPIMutex());346    count = bkpt_sp->GetIgnoreCount();347  }348 349  return count;350}351 352void SBBreakpoint::SetThreadID(lldb::tid_t tid) {353  LLDB_INSTRUMENT_VA(this, tid);354 355  BreakpointSP bkpt_sp = GetSP();356  if (bkpt_sp) {357    std::lock_guard<std::recursive_mutex> guard(358        bkpt_sp->GetTarget().GetAPIMutex());359    bkpt_sp->SetThreadID(tid);360  }361}362 363lldb::tid_t SBBreakpoint::GetThreadID() {364  LLDB_INSTRUMENT_VA(this);365 366  lldb::tid_t tid = LLDB_INVALID_THREAD_ID;367  BreakpointSP bkpt_sp = GetSP();368  if (bkpt_sp) {369    std::lock_guard<std::recursive_mutex> guard(370        bkpt_sp->GetTarget().GetAPIMutex());371    tid = bkpt_sp->GetThreadID();372  }373 374  return tid;375}376 377void SBBreakpoint::SetThreadIndex(uint32_t index) {378  LLDB_INSTRUMENT_VA(this, index);379 380  BreakpointSP bkpt_sp = GetSP();381  if (bkpt_sp) {382    std::lock_guard<std::recursive_mutex> guard(383        bkpt_sp->GetTarget().GetAPIMutex());384    bkpt_sp->GetOptions().GetThreadSpec()->SetIndex(index);385  }386}387 388uint32_t SBBreakpoint::GetThreadIndex() const {389  LLDB_INSTRUMENT_VA(this);390 391  uint32_t thread_idx = UINT32_MAX;392  BreakpointSP bkpt_sp = GetSP();393  if (bkpt_sp) {394    std::lock_guard<std::recursive_mutex> guard(395        bkpt_sp->GetTarget().GetAPIMutex());396    const ThreadSpec *thread_spec =397        bkpt_sp->GetOptions().GetThreadSpecNoCreate();398    if (thread_spec != nullptr)399      thread_idx = thread_spec->GetIndex();400  }401 402  return thread_idx;403}404 405void SBBreakpoint::SetThreadName(const char *thread_name) {406  LLDB_INSTRUMENT_VA(this, thread_name);407 408  BreakpointSP bkpt_sp = GetSP();409 410  if (bkpt_sp) {411    std::lock_guard<std::recursive_mutex> guard(412        bkpt_sp->GetTarget().GetAPIMutex());413    bkpt_sp->GetOptions().GetThreadSpec()->SetName(thread_name);414  }415}416 417const char *SBBreakpoint::GetThreadName() const {418  LLDB_INSTRUMENT_VA(this);419 420  BreakpointSP bkpt_sp = GetSP();421  if (!bkpt_sp)422    return nullptr;423 424  std::lock_guard<std::recursive_mutex> guard(425      bkpt_sp->GetTarget().GetAPIMutex());426  if (const ThreadSpec *thread_spec =427          bkpt_sp->GetOptions().GetThreadSpecNoCreate())428    return ConstString(thread_spec->GetName()).GetCString();429 430  return nullptr;431}432 433void SBBreakpoint::SetQueueName(const char *queue_name) {434  LLDB_INSTRUMENT_VA(this, queue_name);435 436  BreakpointSP bkpt_sp = GetSP();437  if (bkpt_sp) {438    std::lock_guard<std::recursive_mutex> guard(439        bkpt_sp->GetTarget().GetAPIMutex());440    bkpt_sp->GetOptions().GetThreadSpec()->SetQueueName(queue_name);441  }442}443 444const char *SBBreakpoint::GetQueueName() const {445  LLDB_INSTRUMENT_VA(this);446 447  BreakpointSP bkpt_sp = GetSP();448  if (!bkpt_sp)449    return nullptr;450 451  std::lock_guard<std::recursive_mutex> guard(452      bkpt_sp->GetTarget().GetAPIMutex());453  if (const ThreadSpec *thread_spec =454          bkpt_sp->GetOptions().GetThreadSpecNoCreate())455    return ConstString(thread_spec->GetQueueName()).GetCString();456 457  return nullptr;458}459 460size_t SBBreakpoint::GetNumResolvedLocations() const {461  LLDB_INSTRUMENT_VA(this);462 463  size_t num_resolved = 0;464  BreakpointSP bkpt_sp = GetSP();465  if (bkpt_sp) {466    std::lock_guard<std::recursive_mutex> guard(467        bkpt_sp->GetTarget().GetAPIMutex());468    num_resolved = bkpt_sp->GetNumResolvedLocations();469  }470  return num_resolved;471}472 473size_t SBBreakpoint::GetNumLocations() const {474  LLDB_INSTRUMENT_VA(this);475 476  BreakpointSP bkpt_sp = GetSP();477  size_t num_locs = 0;478  if (bkpt_sp) {479    std::lock_guard<std::recursive_mutex> guard(480        bkpt_sp->GetTarget().GetAPIMutex());481    num_locs = bkpt_sp->GetNumLocations();482  }483  return num_locs;484}485 486void SBBreakpoint::SetCommandLineCommands(SBStringList &commands) {487  LLDB_INSTRUMENT_VA(this, commands);488 489  BreakpointSP bkpt_sp = GetSP();490  if (!bkpt_sp)491    return;492  if (commands.GetSize() == 0)493    return;494 495  std::lock_guard<std::recursive_mutex> guard(496      bkpt_sp->GetTarget().GetAPIMutex());497  std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up(498      new BreakpointOptions::CommandData(*commands, eScriptLanguageNone));499 500  bkpt_sp->GetOptions().SetCommandDataCallback(cmd_data_up);501}502 503bool SBBreakpoint::GetCommandLineCommands(SBStringList &commands) {504  LLDB_INSTRUMENT_VA(this, commands);505 506  BreakpointSP bkpt_sp = GetSP();507  if (!bkpt_sp)508    return false;509  StringList command_list;510  bool has_commands =511      bkpt_sp->GetOptions().GetCommandLineCallbacks(command_list);512  if (has_commands)513    commands.AppendList(command_list);514  return has_commands;515}516 517bool SBBreakpoint::GetDescription(SBStream &s) {518  LLDB_INSTRUMENT_VA(this, s);519 520  return GetDescription(s, true);521}522 523bool SBBreakpoint::GetDescription(SBStream &s, bool include_locations) {524  LLDB_INSTRUMENT_VA(this, s, include_locations);525 526  BreakpointSP bkpt_sp = GetSP();527  if (bkpt_sp) {528    std::lock_guard<std::recursive_mutex> guard(529        bkpt_sp->GetTarget().GetAPIMutex());530    s.Printf("SBBreakpoint: id = %i, ", bkpt_sp->GetID());531    bkpt_sp->GetResolverDescription(s.get());532    bkpt_sp->GetFilterDescription(s.get());533    if (include_locations) {534      const size_t num_locations = bkpt_sp->GetNumLocations();535      s.Printf(", locations = %" PRIu64, (uint64_t)num_locations);536    }537    return true;538  }539  s.Printf("No value");540  return false;541}542 543SBError SBBreakpoint::AddLocation(SBAddress &address) {544  LLDB_INSTRUMENT_VA(this, address);545 546  BreakpointSP bkpt_sp = GetSP();547  SBError error;548 549  if (!address.IsValid()) {550    error = Status::FromErrorString("Can't add an invalid address.");551    return error;552  }553 554  if (!bkpt_sp) {555    error = Status::FromErrorString("No breakpoint to add a location to.");556    return error;557  }558 559  if (!llvm::isa<BreakpointResolverScripted>(bkpt_sp->GetResolver().get())) {560    error =561        Status::FromErrorString("Only a scripted resolver can add locations.");562    return error;563  }564 565  if (bkpt_sp->GetSearchFilter()->AddressPasses(address.ref()))566    bkpt_sp->AddLocation(address.ref());567  else {568    StreamString s;569    address.get()->Dump(&s, &bkpt_sp->GetTarget(),570                        Address::DumpStyleModuleWithFileAddress);571    error = Status::FromErrorStringWithFormat(572        "Address: %s didn't pass the filter.", s.GetData());573  }574  return error;575}576 577SBBreakpointLocation SBBreakpoint::AddFacadeLocation() {578  BreakpointSP bkpt_sp = GetSP();579  if (!bkpt_sp)580    return {};581 582  BreakpointLocationSP loc_sp = bkpt_sp->AddFacadeLocation();583  return SBBreakpointLocation(loc_sp);584}585 586SBStructuredData SBBreakpoint::SerializeToStructuredData() {587  LLDB_INSTRUMENT_VA(this);588 589  SBStructuredData data;590  BreakpointSP bkpt_sp = GetSP();591 592  if (!bkpt_sp)593    return data;594 595  StructuredData::ObjectSP bkpt_dict = bkpt_sp->SerializeToStructuredData();596  data.m_impl_up->SetObjectSP(bkpt_dict);597  return data;598}599 600void SBBreakpoint::SetCallback(SBBreakpointHitCallback callback, void *baton) {601  LLDB_INSTRUMENT_VA(this, callback, baton);602 603  BreakpointSP bkpt_sp = GetSP();604 605  if (bkpt_sp) {606    std::lock_guard<std::recursive_mutex> guard(607        bkpt_sp->GetTarget().GetAPIMutex());608    BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton));609    bkpt_sp->SetCallback(SBBreakpointCallbackBaton610      ::PrivateBreakpointHitCallback, baton_sp,611                         false);612  }613}614 615void SBBreakpoint::SetScriptCallbackFunction(616  const char *callback_function_name) {617  LLDB_INSTRUMENT_VA(this, callback_function_name);618  SBStructuredData empty_args;619  SetScriptCallbackFunction(callback_function_name, empty_args);620}621 622SBError SBBreakpoint::SetScriptCallbackFunction(623    const char *callback_function_name,624    SBStructuredData &extra_args) {625  LLDB_INSTRUMENT_VA(this, callback_function_name, extra_args);626  SBError sb_error;627  BreakpointSP bkpt_sp = GetSP();628 629  if (bkpt_sp) {630    Status error;631    std::lock_guard<std::recursive_mutex> guard(632        bkpt_sp->GetTarget().GetAPIMutex());633    BreakpointOptions &bp_options = bkpt_sp->GetOptions();634    error = bkpt_sp->GetTarget()635        .GetDebugger()636        .GetScriptInterpreter()637        ->SetBreakpointCommandCallbackFunction(bp_options,638                                               callback_function_name,639                                               extra_args.m_impl_up640                                                   ->GetObjectSP());641    sb_error.SetError(std::move(error));642  } else643    sb_error = Status::FromErrorString("invalid breakpoint");644 645  return sb_error;646}647 648SBError SBBreakpoint::SetScriptCallbackBody(const char *callback_body_text) {649  LLDB_INSTRUMENT_VA(this, callback_body_text);650 651  BreakpointSP bkpt_sp = GetSP();652 653  SBError sb_error;654  if (bkpt_sp) {655    std::lock_guard<std::recursive_mutex> guard(656        bkpt_sp->GetTarget().GetAPIMutex());657    BreakpointOptions &bp_options = bkpt_sp->GetOptions();658    Status error =659        bkpt_sp->GetTarget()660            .GetDebugger()661            .GetScriptInterpreter()662            ->SetBreakpointCommandCallback(bp_options, callback_body_text,663                                           /*is_callback=*/false);664    sb_error.SetError(std::move(error));665  } else666    sb_error = Status::FromErrorString("invalid breakpoint");667 668  return sb_error;669}670 671bool SBBreakpoint::AddName(const char *new_name) {672  LLDB_INSTRUMENT_VA(this, new_name);673 674  SBError status = AddNameWithErrorHandling(new_name);675  return status.Success();676}677 678SBError SBBreakpoint::AddNameWithErrorHandling(const char *new_name) {679  LLDB_INSTRUMENT_VA(this, new_name);680 681  BreakpointSP bkpt_sp = GetSP();682 683  SBError status;684  if (bkpt_sp) {685    std::lock_guard<std::recursive_mutex> guard(686        bkpt_sp->GetTarget().GetAPIMutex());687    Status error;688    bkpt_sp->GetTarget().AddNameToBreakpoint(bkpt_sp, new_name, error);689    status.SetError(std::move(error));690  } else {691    status = Status::FromErrorString("invalid breakpoint");692  }693 694  return status;695}696 697void SBBreakpoint::RemoveName(const char *name_to_remove) {698  LLDB_INSTRUMENT_VA(this, name_to_remove);699 700  BreakpointSP bkpt_sp = GetSP();701 702  if (bkpt_sp) {703    std::lock_guard<std::recursive_mutex> guard(704        bkpt_sp->GetTarget().GetAPIMutex());705    bkpt_sp->GetTarget().RemoveNameFromBreakpoint(bkpt_sp,706                                                  ConstString(name_to_remove));707  }708}709 710bool SBBreakpoint::MatchesName(const char *name) {711  LLDB_INSTRUMENT_VA(this, name);712 713  BreakpointSP bkpt_sp = GetSP();714 715  if (bkpt_sp) {716    std::lock_guard<std::recursive_mutex> guard(717        bkpt_sp->GetTarget().GetAPIMutex());718    return bkpt_sp->MatchesName(name);719  }720 721  return false;722}723 724void SBBreakpoint::GetNames(SBStringList &names) {725  LLDB_INSTRUMENT_VA(this, names);726 727  BreakpointSP bkpt_sp = GetSP();728 729  if (bkpt_sp) {730    std::lock_guard<std::recursive_mutex> guard(731        bkpt_sp->GetTarget().GetAPIMutex());732    std::vector<std::string> names_vec;733    bkpt_sp->GetNames(names_vec);734    for (const std::string &name : names_vec) {735      names.AppendString(name.c_str());736    }737  }738}739 740bool SBBreakpoint::EventIsBreakpointEvent(const lldb::SBEvent &event) {741  LLDB_INSTRUMENT_VA(event);742 743  return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event.get()) !=744         nullptr;745}746 747BreakpointEventType748SBBreakpoint::GetBreakpointEventTypeFromEvent(const SBEvent &event) {749  LLDB_INSTRUMENT_VA(event);750 751  if (event.IsValid())752    return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent(753        event.GetSP());754  return eBreakpointEventTypeInvalidType;755}756 757SBBreakpoint SBBreakpoint::GetBreakpointFromEvent(const lldb::SBEvent &event) {758  LLDB_INSTRUMENT_VA(event);759 760  if (event.IsValid())761    return SBBreakpoint(762        Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event.GetSP()));763  return SBBreakpoint();764}765 766SBBreakpointLocation767SBBreakpoint::GetBreakpointLocationAtIndexFromEvent(const lldb::SBEvent &event,768                                                    uint32_t loc_idx) {769  LLDB_INSTRUMENT_VA(event, loc_idx);770 771  SBBreakpointLocation sb_breakpoint_loc;772  if (event.IsValid())773    sb_breakpoint_loc.SetLocation(774        Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent(775            event.GetSP(), loc_idx));776  return sb_breakpoint_loc;777}778 779uint32_t780SBBreakpoint::GetNumBreakpointLocationsFromEvent(const lldb::SBEvent &event) {781  LLDB_INSTRUMENT_VA(event);782 783  uint32_t num_locations = 0;784  if (event.IsValid())785    num_locations =786        (Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(787            event.GetSP()));788  return num_locations;789}790 791bool SBBreakpoint::IsHardware() const {792  LLDB_INSTRUMENT_VA(this);793 794  BreakpointSP bkpt_sp = GetSP();795  if (bkpt_sp)796    return bkpt_sp->IsHardware();797  return false;798}799 800lldb::SBError SBBreakpoint::SetIsHardware(bool is_hardware) {801  LLDB_INSTRUMENT_VA(this, is_hardware);802 803  BreakpointSP bkpt_sp = GetSP();804  if (bkpt_sp) {805    std::lock_guard<std::recursive_mutex> guard(806        bkpt_sp->GetTarget().GetAPIMutex());807    return SBError(Status::FromError(bkpt_sp->SetIsHardware(is_hardware)));808  }809  return SBError();810}811 812BreakpointSP SBBreakpoint::GetSP() const { return m_opaque_wp.lock(); }813 814// This is simple collection of breakpoint id's and their target.815class SBBreakpointListImpl {816public:817  SBBreakpointListImpl(lldb::TargetSP target_sp) {818    if (target_sp && target_sp->IsValid())819      m_target_wp = target_sp;820  }821 822  ~SBBreakpointListImpl() = default;823 824  size_t GetSize() { return m_break_ids.size(); }825 826  BreakpointSP GetBreakpointAtIndex(size_t idx) {827    if (idx >= m_break_ids.size())828      return BreakpointSP();829    TargetSP target_sp = m_target_wp.lock();830    if (!target_sp)831      return BreakpointSP();832    lldb::break_id_t bp_id = m_break_ids[idx];833    return target_sp->GetBreakpointList().FindBreakpointByID(bp_id);834  }835 836  BreakpointSP FindBreakpointByID(lldb::break_id_t desired_id) {837    TargetSP target_sp = m_target_wp.lock();838    if (!target_sp)839      return BreakpointSP();840 841    for (lldb::break_id_t &break_id : m_break_ids) {842      if (break_id == desired_id)843        return target_sp->GetBreakpointList().FindBreakpointByID(break_id);844    }845    return BreakpointSP();846  }847 848  bool Append(BreakpointSP bkpt) {849    TargetSP target_sp = m_target_wp.lock();850    if (!target_sp || !bkpt)851      return false;852    if (bkpt->GetTargetSP() != target_sp)853      return false;854    m_break_ids.push_back(bkpt->GetID());855    return true;856  }857 858  bool AppendIfUnique(BreakpointSP bkpt) {859    TargetSP target_sp = m_target_wp.lock();860    if (!target_sp || !bkpt)861      return false;862    if (bkpt->GetTargetSP() != target_sp)863      return false;864    lldb::break_id_t bp_id = bkpt->GetID();865    if (!llvm::is_contained(m_break_ids, bp_id))866      return false;867 868    m_break_ids.push_back(bkpt->GetID());869    return true;870  }871 872  bool AppendByID(lldb::break_id_t id) {873    TargetSP target_sp = m_target_wp.lock();874    if (!target_sp)875      return false;876    if (id == LLDB_INVALID_BREAK_ID)877      return false;878    m_break_ids.push_back(id);879    return true;880  }881 882  void Clear() { m_break_ids.clear(); }883 884  void CopyToBreakpointIDList(lldb_private::BreakpointIDList &bp_list) {885    for (lldb::break_id_t id : m_break_ids) {886      bp_list.AddBreakpointID(BreakpointID(id));887    }888  }889 890  TargetSP GetTarget() { return m_target_wp.lock(); }891 892private:893  std::vector<lldb::break_id_t> m_break_ids;894  TargetWP m_target_wp;895};896 897SBBreakpointList::SBBreakpointList(SBTarget &target)898    : m_opaque_sp(new SBBreakpointListImpl(target.GetSP())) {899  LLDB_INSTRUMENT_VA(this, target);900}901 902SBBreakpointList::~SBBreakpointList() = default;903 904size_t SBBreakpointList::GetSize() const {905  LLDB_INSTRUMENT_VA(this);906 907  if (!m_opaque_sp)908    return 0;909  else910    return m_opaque_sp->GetSize();911}912 913SBBreakpoint SBBreakpointList::GetBreakpointAtIndex(size_t idx) {914  LLDB_INSTRUMENT_VA(this, idx);915 916  if (!m_opaque_sp)917    return SBBreakpoint();918 919  BreakpointSP bkpt_sp = m_opaque_sp->GetBreakpointAtIndex(idx);920  return SBBreakpoint(bkpt_sp);921}922 923SBBreakpoint SBBreakpointList::FindBreakpointByID(lldb::break_id_t id) {924  LLDB_INSTRUMENT_VA(this, id);925 926  if (!m_opaque_sp)927    return SBBreakpoint();928  BreakpointSP bkpt_sp = m_opaque_sp->FindBreakpointByID(id);929  return SBBreakpoint(bkpt_sp);930}931 932void SBBreakpointList::Append(const SBBreakpoint &sb_bkpt) {933  LLDB_INSTRUMENT_VA(this, sb_bkpt);934 935  if (!sb_bkpt.IsValid())936    return;937  if (!m_opaque_sp)938    return;939  m_opaque_sp->Append(sb_bkpt.m_opaque_wp.lock());940}941 942void SBBreakpointList::AppendByID(lldb::break_id_t id) {943  LLDB_INSTRUMENT_VA(this, id);944 945  if (!m_opaque_sp)946    return;947  m_opaque_sp->AppendByID(id);948}949 950bool SBBreakpointList::AppendIfUnique(const SBBreakpoint &sb_bkpt) {951  LLDB_INSTRUMENT_VA(this, sb_bkpt);952 953  if (!sb_bkpt.IsValid())954    return false;955  if (!m_opaque_sp)956    return false;957  return m_opaque_sp->AppendIfUnique(sb_bkpt.GetSP());958}959 960void SBBreakpointList::Clear() {961  LLDB_INSTRUMENT_VA(this);962 963  if (m_opaque_sp)964    m_opaque_sp->Clear();965}966 967void SBBreakpointList::CopyToBreakpointIDList(968    lldb_private::BreakpointIDList &bp_id_list) {969  if (m_opaque_sp)970    m_opaque_sp->CopyToBreakpointIDList(bp_id_list);971}972