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