15ffd83dbSDimitry Andric //===-- SBBreakpoint.cpp --------------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric #include "lldb/API/SBBreakpoint.h"
100b57cec5SDimitry Andric #include "lldb/API/SBBreakpointLocation.h"
110b57cec5SDimitry Andric #include "lldb/API/SBDebugger.h"
120b57cec5SDimitry Andric #include "lldb/API/SBEvent.h"
130b57cec5SDimitry Andric #include "lldb/API/SBProcess.h"
140b57cec5SDimitry Andric #include "lldb/API/SBStream.h"
150b57cec5SDimitry Andric #include "lldb/API/SBStringList.h"
16480093f4SDimitry Andric #include "lldb/API/SBStructuredData.h"
170b57cec5SDimitry Andric #include "lldb/API/SBThread.h"
1804eeddc0SDimitry Andric #include "lldb/Utility/Instrumentation.h"
190b57cec5SDimitry Andric
200b57cec5SDimitry Andric #include "lldb/Breakpoint/Breakpoint.h"
210b57cec5SDimitry Andric #include "lldb/Breakpoint/BreakpointIDList.h"
220b57cec5SDimitry Andric #include "lldb/Breakpoint/BreakpointLocation.h"
230b57cec5SDimitry Andric #include "lldb/Breakpoint/BreakpointResolver.h"
240b57cec5SDimitry Andric #include "lldb/Breakpoint/BreakpointResolverScripted.h"
250b57cec5SDimitry Andric #include "lldb/Breakpoint/StoppointCallbackContext.h"
260b57cec5SDimitry Andric #include "lldb/Core/Address.h"
270b57cec5SDimitry Andric #include "lldb/Core/Debugger.h"
28480093f4SDimitry Andric #include "lldb/Core/StructuredDataImpl.h"
290b57cec5SDimitry Andric #include "lldb/Interpreter/CommandInterpreter.h"
300b57cec5SDimitry Andric #include "lldb/Interpreter/ScriptInterpreter.h"
310b57cec5SDimitry Andric #include "lldb/Target/Process.h"
320b57cec5SDimitry Andric #include "lldb/Target/SectionLoadList.h"
330b57cec5SDimitry Andric #include "lldb/Target/Target.h"
340b57cec5SDimitry Andric #include "lldb/Target/Thread.h"
350b57cec5SDimitry Andric #include "lldb/Target/ThreadSpec.h"
360b57cec5SDimitry Andric #include "lldb/Utility/Stream.h"
370b57cec5SDimitry Andric
380b57cec5SDimitry Andric #include "SBBreakpointOptionCommon.h"
390b57cec5SDimitry Andric
400b57cec5SDimitry Andric #include "lldb/lldb-enumerations.h"
410b57cec5SDimitry Andric
420b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
430b57cec5SDimitry Andric
440b57cec5SDimitry Andric using namespace lldb;
450b57cec5SDimitry Andric using namespace lldb_private;
460b57cec5SDimitry Andric
SBBreakpoint()4704eeddc0SDimitry Andric SBBreakpoint::SBBreakpoint() { LLDB_INSTRUMENT_VA(this); }
480b57cec5SDimitry Andric
SBBreakpoint(const SBBreakpoint & rhs)490b57cec5SDimitry Andric SBBreakpoint::SBBreakpoint(const SBBreakpoint &rhs)
500b57cec5SDimitry Andric : m_opaque_wp(rhs.m_opaque_wp) {
5104eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, rhs);
520b57cec5SDimitry Andric }
530b57cec5SDimitry Andric
SBBreakpoint(const lldb::BreakpointSP & bp_sp)540b57cec5SDimitry Andric SBBreakpoint::SBBreakpoint(const lldb::BreakpointSP &bp_sp)
550b57cec5SDimitry Andric : m_opaque_wp(bp_sp) {
5604eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, bp_sp);
570b57cec5SDimitry Andric }
580b57cec5SDimitry Andric
590b57cec5SDimitry Andric SBBreakpoint::~SBBreakpoint() = default;
600b57cec5SDimitry Andric
operator =(const SBBreakpoint & rhs)610b57cec5SDimitry Andric const SBBreakpoint &SBBreakpoint::operator=(const SBBreakpoint &rhs) {
6204eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, rhs);
630b57cec5SDimitry Andric
640b57cec5SDimitry Andric m_opaque_wp = rhs.m_opaque_wp;
6504eeddc0SDimitry Andric return *this;
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric
operator ==(const lldb::SBBreakpoint & rhs)680b57cec5SDimitry Andric bool SBBreakpoint::operator==(const lldb::SBBreakpoint &rhs) {
6904eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, rhs);
700b57cec5SDimitry Andric
710b57cec5SDimitry Andric return m_opaque_wp.lock() == rhs.m_opaque_wp.lock();
720b57cec5SDimitry Andric }
730b57cec5SDimitry Andric
operator !=(const lldb::SBBreakpoint & rhs)740b57cec5SDimitry Andric bool SBBreakpoint::operator!=(const lldb::SBBreakpoint &rhs) {
7504eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, rhs);
760b57cec5SDimitry Andric
770b57cec5SDimitry Andric return m_opaque_wp.lock() != rhs.m_opaque_wp.lock();
780b57cec5SDimitry Andric }
790b57cec5SDimitry Andric
GetTarget() const80e8d8bef9SDimitry Andric SBTarget SBBreakpoint::GetTarget() const {
8104eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this);
82e8d8bef9SDimitry Andric
83e8d8bef9SDimitry Andric BreakpointSP bkpt_sp = GetSP();
84e8d8bef9SDimitry Andric if (bkpt_sp)
8504eeddc0SDimitry Andric return SBTarget(bkpt_sp->GetTargetSP());
86e8d8bef9SDimitry Andric
8704eeddc0SDimitry Andric return SBTarget();
88e8d8bef9SDimitry Andric }
89e8d8bef9SDimitry Andric
GetID() const900b57cec5SDimitry Andric break_id_t SBBreakpoint::GetID() const {
9104eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this);
920b57cec5SDimitry Andric
930b57cec5SDimitry Andric break_id_t break_id = LLDB_INVALID_BREAK_ID;
940b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
950b57cec5SDimitry Andric if (bkpt_sp)
960b57cec5SDimitry Andric break_id = bkpt_sp->GetID();
970b57cec5SDimitry Andric
980b57cec5SDimitry Andric return break_id;
990b57cec5SDimitry Andric }
1000b57cec5SDimitry Andric
IsValid() const1010b57cec5SDimitry Andric bool SBBreakpoint::IsValid() const {
10204eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this);
1030b57cec5SDimitry Andric return this->operator bool();
1040b57cec5SDimitry Andric }
operator bool() const1050b57cec5SDimitry Andric SBBreakpoint::operator bool() const {
10604eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this);
1070b57cec5SDimitry Andric
1080b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
1090b57cec5SDimitry Andric if (!bkpt_sp)
1100b57cec5SDimitry Andric return false;
1110b57cec5SDimitry Andric else if (bkpt_sp->GetTarget().GetBreakpointByID(bkpt_sp->GetID()))
1120b57cec5SDimitry Andric return true;
1130b57cec5SDimitry Andric else
1140b57cec5SDimitry Andric return false;
1150b57cec5SDimitry Andric }
1160b57cec5SDimitry Andric
ClearAllBreakpointSites()1170b57cec5SDimitry Andric void SBBreakpoint::ClearAllBreakpointSites() {
11804eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this);
1190b57cec5SDimitry Andric
1200b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
1210b57cec5SDimitry Andric if (bkpt_sp) {
1220b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
1230b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
1240b57cec5SDimitry Andric bkpt_sp->ClearAllBreakpointSites();
1250b57cec5SDimitry Andric }
1260b57cec5SDimitry Andric }
1270b57cec5SDimitry Andric
FindLocationByAddress(addr_t vm_addr)1280b57cec5SDimitry Andric SBBreakpointLocation SBBreakpoint::FindLocationByAddress(addr_t vm_addr) {
12904eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, vm_addr);
1300b57cec5SDimitry Andric
1310b57cec5SDimitry Andric SBBreakpointLocation sb_bp_location;
1320b57cec5SDimitry Andric
1330b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
1340b57cec5SDimitry Andric if (bkpt_sp) {
1350b57cec5SDimitry Andric if (vm_addr != LLDB_INVALID_ADDRESS) {
1360b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
1370b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
1380b57cec5SDimitry Andric Address address;
1390b57cec5SDimitry Andric Target &target = bkpt_sp->GetTarget();
1400b57cec5SDimitry Andric if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) {
1410b57cec5SDimitry Andric address.SetRawAddress(vm_addr);
1420b57cec5SDimitry Andric }
1430b57cec5SDimitry Andric sb_bp_location.SetLocation(bkpt_sp->FindLocationByAddress(address));
1440b57cec5SDimitry Andric }
1450b57cec5SDimitry Andric }
14604eeddc0SDimitry Andric return sb_bp_location;
1470b57cec5SDimitry Andric }
1480b57cec5SDimitry Andric
FindLocationIDByAddress(addr_t vm_addr)1490b57cec5SDimitry Andric break_id_t SBBreakpoint::FindLocationIDByAddress(addr_t vm_addr) {
15004eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, vm_addr);
1510b57cec5SDimitry Andric
1520b57cec5SDimitry Andric break_id_t break_id = LLDB_INVALID_BREAK_ID;
1530b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
1540b57cec5SDimitry Andric
1550b57cec5SDimitry Andric if (bkpt_sp && vm_addr != LLDB_INVALID_ADDRESS) {
1560b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
1570b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
1580b57cec5SDimitry Andric Address address;
1590b57cec5SDimitry Andric Target &target = bkpt_sp->GetTarget();
1600b57cec5SDimitry Andric if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) {
1610b57cec5SDimitry Andric address.SetRawAddress(vm_addr);
1620b57cec5SDimitry Andric }
1630b57cec5SDimitry Andric break_id = bkpt_sp->FindLocationIDByAddress(address);
1640b57cec5SDimitry Andric }
1650b57cec5SDimitry Andric
1660b57cec5SDimitry Andric return break_id;
1670b57cec5SDimitry Andric }
1680b57cec5SDimitry Andric
FindLocationByID(break_id_t bp_loc_id)1690b57cec5SDimitry Andric SBBreakpointLocation SBBreakpoint::FindLocationByID(break_id_t bp_loc_id) {
17004eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, bp_loc_id);
1710b57cec5SDimitry Andric
1720b57cec5SDimitry Andric SBBreakpointLocation sb_bp_location;
1730b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
1740b57cec5SDimitry Andric
1750b57cec5SDimitry Andric if (bkpt_sp) {
1760b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
1770b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
1780b57cec5SDimitry Andric sb_bp_location.SetLocation(bkpt_sp->FindLocationByID(bp_loc_id));
1790b57cec5SDimitry Andric }
1800b57cec5SDimitry Andric
18104eeddc0SDimitry Andric return sb_bp_location;
1820b57cec5SDimitry Andric }
1830b57cec5SDimitry Andric
GetLocationAtIndex(uint32_t index)1840b57cec5SDimitry Andric SBBreakpointLocation SBBreakpoint::GetLocationAtIndex(uint32_t index) {
18504eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, index);
1860b57cec5SDimitry Andric
1870b57cec5SDimitry Andric SBBreakpointLocation sb_bp_location;
1880b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
1890b57cec5SDimitry Andric
1900b57cec5SDimitry Andric if (bkpt_sp) {
1910b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
1920b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
1930b57cec5SDimitry Andric sb_bp_location.SetLocation(bkpt_sp->GetLocationAtIndex(index));
1940b57cec5SDimitry Andric }
1950b57cec5SDimitry Andric
19604eeddc0SDimitry Andric return sb_bp_location;
1970b57cec5SDimitry Andric }
1980b57cec5SDimitry Andric
SetEnabled(bool enable)1990b57cec5SDimitry Andric void SBBreakpoint::SetEnabled(bool enable) {
20004eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, enable);
2010b57cec5SDimitry Andric
2020b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
2030b57cec5SDimitry Andric
2040b57cec5SDimitry Andric if (bkpt_sp) {
2050b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
2060b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
2070b57cec5SDimitry Andric bkpt_sp->SetEnabled(enable);
2080b57cec5SDimitry Andric }
2090b57cec5SDimitry Andric }
2100b57cec5SDimitry Andric
IsEnabled()2110b57cec5SDimitry Andric bool SBBreakpoint::IsEnabled() {
21204eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this);
2130b57cec5SDimitry Andric
2140b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
2150b57cec5SDimitry Andric if (bkpt_sp) {
2160b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
2170b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
2180b57cec5SDimitry Andric return bkpt_sp->IsEnabled();
2190b57cec5SDimitry Andric } else
2200b57cec5SDimitry Andric return false;
2210b57cec5SDimitry Andric }
2220b57cec5SDimitry Andric
SetOneShot(bool one_shot)2230b57cec5SDimitry Andric void SBBreakpoint::SetOneShot(bool one_shot) {
22404eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, one_shot);
2250b57cec5SDimitry Andric
2260b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
2270b57cec5SDimitry Andric
2280b57cec5SDimitry Andric if (bkpt_sp) {
2290b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
2300b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
2310b57cec5SDimitry Andric bkpt_sp->SetOneShot(one_shot);
2320b57cec5SDimitry Andric }
2330b57cec5SDimitry Andric }
2340b57cec5SDimitry Andric
IsOneShot() const2350b57cec5SDimitry Andric bool SBBreakpoint::IsOneShot() const {
23604eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this);
2370b57cec5SDimitry Andric
2380b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
2390b57cec5SDimitry Andric if (bkpt_sp) {
2400b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
2410b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
2420b57cec5SDimitry Andric return bkpt_sp->IsOneShot();
2430b57cec5SDimitry Andric } else
2440b57cec5SDimitry Andric return false;
2450b57cec5SDimitry Andric }
2460b57cec5SDimitry Andric
IsInternal()2470b57cec5SDimitry Andric bool SBBreakpoint::IsInternal() {
24804eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this);
2490b57cec5SDimitry Andric
2500b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
2510b57cec5SDimitry Andric if (bkpt_sp) {
2520b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
2530b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
2540b57cec5SDimitry Andric return bkpt_sp->IsInternal();
2550b57cec5SDimitry Andric } else
2560b57cec5SDimitry Andric return false;
2570b57cec5SDimitry Andric }
2580b57cec5SDimitry Andric
SetIgnoreCount(uint32_t count)2590b57cec5SDimitry Andric void SBBreakpoint::SetIgnoreCount(uint32_t count) {
26004eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, count);
2610b57cec5SDimitry Andric
2620b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
2630b57cec5SDimitry Andric
2640b57cec5SDimitry Andric if (bkpt_sp) {
2650b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
2660b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
2670b57cec5SDimitry Andric bkpt_sp->SetIgnoreCount(count);
2680b57cec5SDimitry Andric }
2690b57cec5SDimitry Andric }
2700b57cec5SDimitry Andric
SetCondition(const char * condition)2710b57cec5SDimitry Andric void SBBreakpoint::SetCondition(const char *condition) {
27204eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, condition);
2730b57cec5SDimitry Andric
2740b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
2750b57cec5SDimitry Andric if (bkpt_sp) {
2760b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
2770b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
2780b57cec5SDimitry Andric bkpt_sp->SetCondition(condition);
2790b57cec5SDimitry Andric }
2800b57cec5SDimitry Andric }
2810b57cec5SDimitry Andric
GetCondition()2820b57cec5SDimitry Andric const char *SBBreakpoint::GetCondition() {
28304eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this);
2840b57cec5SDimitry Andric
2850b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
28606c3fb27SDimitry Andric if (!bkpt_sp)
28706c3fb27SDimitry Andric return nullptr;
28806c3fb27SDimitry Andric
2890b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
2900b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
29106c3fb27SDimitry Andric return ConstString(bkpt_sp->GetConditionText()).GetCString();
2920b57cec5SDimitry Andric }
2930b57cec5SDimitry Andric
SetAutoContinue(bool auto_continue)2940b57cec5SDimitry Andric void SBBreakpoint::SetAutoContinue(bool auto_continue) {
29504eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, auto_continue);
2960b57cec5SDimitry Andric
2970b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
2980b57cec5SDimitry Andric if (bkpt_sp) {
2990b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
3000b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
3010b57cec5SDimitry Andric bkpt_sp->SetAutoContinue(auto_continue);
3020b57cec5SDimitry Andric }
3030b57cec5SDimitry Andric }
3040b57cec5SDimitry Andric
GetAutoContinue()3050b57cec5SDimitry Andric bool SBBreakpoint::GetAutoContinue() {
30604eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this);
3070b57cec5SDimitry Andric
3080b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
3090b57cec5SDimitry Andric if (bkpt_sp) {
3100b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
3110b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
3120b57cec5SDimitry Andric return bkpt_sp->IsAutoContinue();
3130b57cec5SDimitry Andric }
3140b57cec5SDimitry Andric return false;
3150b57cec5SDimitry Andric }
3160b57cec5SDimitry Andric
GetHitCount() const3170b57cec5SDimitry Andric uint32_t SBBreakpoint::GetHitCount() const {
31804eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this);
3190b57cec5SDimitry Andric
3200b57cec5SDimitry Andric uint32_t count = 0;
3210b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
3220b57cec5SDimitry Andric if (bkpt_sp) {
3230b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
3240b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
3250b57cec5SDimitry Andric count = bkpt_sp->GetHitCount();
3260b57cec5SDimitry Andric }
3270b57cec5SDimitry Andric
3280b57cec5SDimitry Andric return count;
3290b57cec5SDimitry Andric }
3300b57cec5SDimitry Andric
GetIgnoreCount() const3310b57cec5SDimitry Andric uint32_t SBBreakpoint::GetIgnoreCount() const {
33204eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this);
3330b57cec5SDimitry Andric
3340b57cec5SDimitry Andric uint32_t count = 0;
3350b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
3360b57cec5SDimitry Andric if (bkpt_sp) {
3370b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
3380b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
3390b57cec5SDimitry Andric count = bkpt_sp->GetIgnoreCount();
3400b57cec5SDimitry Andric }
3410b57cec5SDimitry Andric
3420b57cec5SDimitry Andric return count;
3430b57cec5SDimitry Andric }
3440b57cec5SDimitry Andric
SetThreadID(tid_t tid)3450b57cec5SDimitry Andric void SBBreakpoint::SetThreadID(tid_t tid) {
34604eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, tid);
3470b57cec5SDimitry Andric
3480b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
3490b57cec5SDimitry Andric if (bkpt_sp) {
3500b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
3510b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
3520b57cec5SDimitry Andric bkpt_sp->SetThreadID(tid);
3530b57cec5SDimitry Andric }
3540b57cec5SDimitry Andric }
3550b57cec5SDimitry Andric
GetThreadID()3560b57cec5SDimitry Andric tid_t SBBreakpoint::GetThreadID() {
35704eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this);
3580b57cec5SDimitry Andric
3590b57cec5SDimitry Andric tid_t tid = LLDB_INVALID_THREAD_ID;
3600b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
3610b57cec5SDimitry Andric if (bkpt_sp) {
3620b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
3630b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
3640b57cec5SDimitry Andric tid = bkpt_sp->GetThreadID();
3650b57cec5SDimitry Andric }
3660b57cec5SDimitry Andric
3670b57cec5SDimitry Andric return tid;
3680b57cec5SDimitry Andric }
3690b57cec5SDimitry Andric
SetThreadIndex(uint32_t index)3700b57cec5SDimitry Andric void SBBreakpoint::SetThreadIndex(uint32_t index) {
37104eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, index);
3720b57cec5SDimitry Andric
3730b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
3740b57cec5SDimitry Andric if (bkpt_sp) {
3750b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
3760b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
377fe6060f1SDimitry Andric bkpt_sp->GetOptions().GetThreadSpec()->SetIndex(index);
3780b57cec5SDimitry Andric }
3790b57cec5SDimitry Andric }
3800b57cec5SDimitry Andric
GetThreadIndex() const3810b57cec5SDimitry Andric uint32_t SBBreakpoint::GetThreadIndex() const {
38204eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this);
3830b57cec5SDimitry Andric
3840b57cec5SDimitry Andric uint32_t thread_idx = UINT32_MAX;
3850b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
3860b57cec5SDimitry Andric if (bkpt_sp) {
3870b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
3880b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
3890b57cec5SDimitry Andric const ThreadSpec *thread_spec =
390fe6060f1SDimitry Andric bkpt_sp->GetOptions().GetThreadSpecNoCreate();
3910b57cec5SDimitry Andric if (thread_spec != nullptr)
3920b57cec5SDimitry Andric thread_idx = thread_spec->GetIndex();
3930b57cec5SDimitry Andric }
3940b57cec5SDimitry Andric
3950b57cec5SDimitry Andric return thread_idx;
3960b57cec5SDimitry Andric }
3970b57cec5SDimitry Andric
SetThreadName(const char * thread_name)3980b57cec5SDimitry Andric void SBBreakpoint::SetThreadName(const char *thread_name) {
39904eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, thread_name);
4000b57cec5SDimitry Andric
4010b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
4020b57cec5SDimitry Andric
4030b57cec5SDimitry Andric if (bkpt_sp) {
4040b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
4050b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
406fe6060f1SDimitry Andric bkpt_sp->GetOptions().GetThreadSpec()->SetName(thread_name);
4070b57cec5SDimitry Andric }
4080b57cec5SDimitry Andric }
4090b57cec5SDimitry Andric
GetThreadName() const4100b57cec5SDimitry Andric const char *SBBreakpoint::GetThreadName() const {
41104eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this);
4120b57cec5SDimitry Andric
4130b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
41406c3fb27SDimitry Andric if (!bkpt_sp)
41506c3fb27SDimitry Andric return nullptr;
41606c3fb27SDimitry Andric
4170b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
4180b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
41906c3fb27SDimitry Andric if (const ThreadSpec *thread_spec =
42006c3fb27SDimitry Andric bkpt_sp->GetOptions().GetThreadSpecNoCreate())
42106c3fb27SDimitry Andric return ConstString(thread_spec->GetName()).GetCString();
4220b57cec5SDimitry Andric
42306c3fb27SDimitry Andric return nullptr;
4240b57cec5SDimitry Andric }
4250b57cec5SDimitry Andric
SetQueueName(const char * queue_name)4260b57cec5SDimitry Andric void SBBreakpoint::SetQueueName(const char *queue_name) {
42704eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, queue_name);
4280b57cec5SDimitry Andric
4290b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
4300b57cec5SDimitry Andric if (bkpt_sp) {
4310b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
4320b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
433fe6060f1SDimitry Andric bkpt_sp->GetOptions().GetThreadSpec()->SetQueueName(queue_name);
4340b57cec5SDimitry Andric }
4350b57cec5SDimitry Andric }
4360b57cec5SDimitry Andric
GetQueueName() const4370b57cec5SDimitry Andric const char *SBBreakpoint::GetQueueName() const {
43804eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this);
4390b57cec5SDimitry Andric
4400b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
44106c3fb27SDimitry Andric if (!bkpt_sp)
44206c3fb27SDimitry Andric return nullptr;
44306c3fb27SDimitry Andric
4440b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
4450b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
44606c3fb27SDimitry Andric if (const ThreadSpec *thread_spec =
44706c3fb27SDimitry Andric bkpt_sp->GetOptions().GetThreadSpecNoCreate())
44806c3fb27SDimitry Andric return ConstString(thread_spec->GetQueueName()).GetCString();
4490b57cec5SDimitry Andric
45006c3fb27SDimitry Andric return nullptr;
4510b57cec5SDimitry Andric }
4520b57cec5SDimitry Andric
GetNumResolvedLocations() const4530b57cec5SDimitry Andric size_t SBBreakpoint::GetNumResolvedLocations() const {
45404eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this);
4550b57cec5SDimitry Andric
4560b57cec5SDimitry Andric size_t num_resolved = 0;
4570b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
4580b57cec5SDimitry Andric if (bkpt_sp) {
4590b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
4600b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
4610b57cec5SDimitry Andric num_resolved = bkpt_sp->GetNumResolvedLocations();
4620b57cec5SDimitry Andric }
4630b57cec5SDimitry Andric return num_resolved;
4640b57cec5SDimitry Andric }
4650b57cec5SDimitry Andric
GetNumLocations() const4660b57cec5SDimitry Andric size_t SBBreakpoint::GetNumLocations() const {
46704eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this);
4680b57cec5SDimitry Andric
4690b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
4700b57cec5SDimitry Andric size_t num_locs = 0;
4710b57cec5SDimitry Andric if (bkpt_sp) {
4720b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
4730b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
4740b57cec5SDimitry Andric num_locs = bkpt_sp->GetNumLocations();
4750b57cec5SDimitry Andric }
4760b57cec5SDimitry Andric return num_locs;
4770b57cec5SDimitry Andric }
4780b57cec5SDimitry Andric
SetCommandLineCommands(SBStringList & commands)4790b57cec5SDimitry Andric void SBBreakpoint::SetCommandLineCommands(SBStringList &commands) {
48004eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, commands);
4810b57cec5SDimitry Andric
4820b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
4830b57cec5SDimitry Andric if (!bkpt_sp)
4840b57cec5SDimitry Andric return;
4850b57cec5SDimitry Andric if (commands.GetSize() == 0)
4860b57cec5SDimitry Andric return;
4870b57cec5SDimitry Andric
4880b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
4890b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
4900b57cec5SDimitry Andric std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up(
4910b57cec5SDimitry Andric new BreakpointOptions::CommandData(*commands, eScriptLanguageNone));
4920b57cec5SDimitry Andric
493fe6060f1SDimitry Andric bkpt_sp->GetOptions().SetCommandDataCallback(cmd_data_up);
4940b57cec5SDimitry Andric }
4950b57cec5SDimitry Andric
GetCommandLineCommands(SBStringList & commands)4960b57cec5SDimitry Andric bool SBBreakpoint::GetCommandLineCommands(SBStringList &commands) {
49704eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, commands);
4980b57cec5SDimitry Andric
4990b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
5000b57cec5SDimitry Andric if (!bkpt_sp)
5010b57cec5SDimitry Andric return false;
5020b57cec5SDimitry Andric StringList command_list;
5030b57cec5SDimitry Andric bool has_commands =
504fe6060f1SDimitry Andric bkpt_sp->GetOptions().GetCommandLineCallbacks(command_list);
5050b57cec5SDimitry Andric if (has_commands)
5060b57cec5SDimitry Andric commands.AppendList(command_list);
5070b57cec5SDimitry Andric return has_commands;
5080b57cec5SDimitry Andric }
5090b57cec5SDimitry Andric
GetDescription(SBStream & s)5100b57cec5SDimitry Andric bool SBBreakpoint::GetDescription(SBStream &s) {
51104eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, s);
5120b57cec5SDimitry Andric
5130b57cec5SDimitry Andric return GetDescription(s, true);
5140b57cec5SDimitry Andric }
5150b57cec5SDimitry Andric
GetDescription(SBStream & s,bool include_locations)5160b57cec5SDimitry Andric bool SBBreakpoint::GetDescription(SBStream &s, bool include_locations) {
51704eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, s, include_locations);
5180b57cec5SDimitry Andric
5190b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
5200b57cec5SDimitry Andric if (bkpt_sp) {
5210b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
5220b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
5230b57cec5SDimitry Andric s.Printf("SBBreakpoint: id = %i, ", bkpt_sp->GetID());
5240b57cec5SDimitry Andric bkpt_sp->GetResolverDescription(s.get());
5250b57cec5SDimitry Andric bkpt_sp->GetFilterDescription(s.get());
5260b57cec5SDimitry Andric if (include_locations) {
5270b57cec5SDimitry Andric const size_t num_locations = bkpt_sp->GetNumLocations();
5280b57cec5SDimitry Andric s.Printf(", locations = %" PRIu64, (uint64_t)num_locations);
5290b57cec5SDimitry Andric }
5300b57cec5SDimitry Andric return true;
5310b57cec5SDimitry Andric }
5320b57cec5SDimitry Andric s.Printf("No value");
5330b57cec5SDimitry Andric return false;
5340b57cec5SDimitry Andric }
5350b57cec5SDimitry Andric
AddLocation(SBAddress & address)5360b57cec5SDimitry Andric SBError SBBreakpoint::AddLocation(SBAddress &address) {
53704eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, address);
5380b57cec5SDimitry Andric
5390b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
5400b57cec5SDimitry Andric SBError error;
5410b57cec5SDimitry Andric
5420b57cec5SDimitry Andric if (!address.IsValid()) {
5430b57cec5SDimitry Andric error.SetErrorString("Can't add an invalid address.");
54404eeddc0SDimitry Andric return error;
5450b57cec5SDimitry Andric }
5460b57cec5SDimitry Andric
5470b57cec5SDimitry Andric if (!bkpt_sp) {
5480b57cec5SDimitry Andric error.SetErrorString("No breakpoint to add a location to.");
54904eeddc0SDimitry Andric return error;
5500b57cec5SDimitry Andric }
5510b57cec5SDimitry Andric
5520b57cec5SDimitry Andric if (!llvm::isa<BreakpointResolverScripted>(bkpt_sp->GetResolver().get())) {
5530b57cec5SDimitry Andric error.SetErrorString("Only a scripted resolver can add locations.");
55404eeddc0SDimitry Andric return error;
5550b57cec5SDimitry Andric }
5560b57cec5SDimitry Andric
5570b57cec5SDimitry Andric if (bkpt_sp->GetSearchFilter()->AddressPasses(address.ref()))
5580b57cec5SDimitry Andric bkpt_sp->AddLocation(address.ref());
5590b57cec5SDimitry Andric else {
5600b57cec5SDimitry Andric StreamString s;
5610b57cec5SDimitry Andric address.get()->Dump(&s, &bkpt_sp->GetTarget(),
5620b57cec5SDimitry Andric Address::DumpStyleModuleWithFileAddress);
5630b57cec5SDimitry Andric error.SetErrorStringWithFormat("Address: %s didn't pass the filter.",
5640b57cec5SDimitry Andric s.GetData());
5650b57cec5SDimitry Andric }
56604eeddc0SDimitry Andric return error;
5670b57cec5SDimitry Andric }
5680b57cec5SDimitry Andric
SerializeToStructuredData()569e8d8bef9SDimitry Andric SBStructuredData SBBreakpoint::SerializeToStructuredData() {
57004eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this);
571e8d8bef9SDimitry Andric
572e8d8bef9SDimitry Andric SBStructuredData data;
573e8d8bef9SDimitry Andric BreakpointSP bkpt_sp = GetSP();
574e8d8bef9SDimitry Andric
575e8d8bef9SDimitry Andric if (!bkpt_sp)
57604eeddc0SDimitry Andric return data;
577e8d8bef9SDimitry Andric
578e8d8bef9SDimitry Andric StructuredData::ObjectSP bkpt_dict = bkpt_sp->SerializeToStructuredData();
579e8d8bef9SDimitry Andric data.m_impl_up->SetObjectSP(bkpt_dict);
58004eeddc0SDimitry Andric return data;
581e8d8bef9SDimitry Andric }
582e8d8bef9SDimitry Andric
SetCallback(SBBreakpointHitCallback callback,void * baton)5830b57cec5SDimitry Andric void SBBreakpoint::SetCallback(SBBreakpointHitCallback callback, void *baton) {
58404eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, callback, baton);
5850b57cec5SDimitry Andric
5860b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
5870b57cec5SDimitry Andric
5880b57cec5SDimitry Andric if (bkpt_sp) {
5890b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
5900b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
5910b57cec5SDimitry Andric BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton));
5920b57cec5SDimitry Andric bkpt_sp->SetCallback(SBBreakpointCallbackBaton
5930b57cec5SDimitry Andric ::PrivateBreakpointHitCallback, baton_sp,
5940b57cec5SDimitry Andric false);
5950b57cec5SDimitry Andric }
5960b57cec5SDimitry Andric }
5970b57cec5SDimitry Andric
SetScriptCallbackFunction(const char * callback_function_name)5980b57cec5SDimitry Andric void SBBreakpoint::SetScriptCallbackFunction(
5990b57cec5SDimitry Andric const char *callback_function_name) {
60004eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, callback_function_name);
601480093f4SDimitry Andric SBStructuredData empty_args;
602480093f4SDimitry Andric SetScriptCallbackFunction(callback_function_name, empty_args);
603480093f4SDimitry Andric }
6040b57cec5SDimitry Andric
SetScriptCallbackFunction(const char * callback_function_name,SBStructuredData & extra_args)605480093f4SDimitry Andric SBError SBBreakpoint::SetScriptCallbackFunction(
606480093f4SDimitry Andric const char *callback_function_name,
607480093f4SDimitry Andric SBStructuredData &extra_args) {
60804eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, callback_function_name, extra_args);
609480093f4SDimitry Andric SBError sb_error;
6100b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
6110b57cec5SDimitry Andric
6120b57cec5SDimitry Andric if (bkpt_sp) {
613480093f4SDimitry Andric Status error;
6140b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
6150b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
616fe6060f1SDimitry Andric BreakpointOptions &bp_options = bkpt_sp->GetOptions();
617480093f4SDimitry Andric error = bkpt_sp->GetTarget()
6180b57cec5SDimitry Andric .GetDebugger()
6190b57cec5SDimitry Andric .GetScriptInterpreter()
6200b57cec5SDimitry Andric ->SetBreakpointCommandCallbackFunction(bp_options,
621480093f4SDimitry Andric callback_function_name,
622480093f4SDimitry Andric extra_args.m_impl_up
623480093f4SDimitry Andric ->GetObjectSP());
624480093f4SDimitry Andric sb_error.SetError(error);
625480093f4SDimitry Andric } else
626480093f4SDimitry Andric sb_error.SetErrorString("invalid breakpoint");
627480093f4SDimitry Andric
62804eeddc0SDimitry Andric return sb_error;
6290b57cec5SDimitry Andric }
6300b57cec5SDimitry Andric
SetScriptCallbackBody(const char * callback_body_text)6310b57cec5SDimitry Andric SBError SBBreakpoint::SetScriptCallbackBody(const char *callback_body_text) {
63204eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, callback_body_text);
6330b57cec5SDimitry Andric
6340b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
6350b57cec5SDimitry Andric
6360b57cec5SDimitry Andric SBError sb_error;
6370b57cec5SDimitry Andric if (bkpt_sp) {
6380b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
6390b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
640fe6060f1SDimitry Andric BreakpointOptions &bp_options = bkpt_sp->GetOptions();
6410b57cec5SDimitry Andric Status error =
6420b57cec5SDimitry Andric bkpt_sp->GetTarget()
6430b57cec5SDimitry Andric .GetDebugger()
6440b57cec5SDimitry Andric .GetScriptInterpreter()
64506c3fb27SDimitry Andric ->SetBreakpointCommandCallback(bp_options, callback_body_text,
64606c3fb27SDimitry Andric /*is_callback=*/false);
6470b57cec5SDimitry Andric sb_error.SetError(error);
6480b57cec5SDimitry Andric } else
6490b57cec5SDimitry Andric sb_error.SetErrorString("invalid breakpoint");
6500b57cec5SDimitry Andric
65104eeddc0SDimitry Andric return sb_error;
6520b57cec5SDimitry Andric }
6530b57cec5SDimitry Andric
AddName(const char * new_name)6540b57cec5SDimitry Andric bool SBBreakpoint::AddName(const char *new_name) {
65504eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, new_name);
6560b57cec5SDimitry Andric
6575ffd83dbSDimitry Andric SBError status = AddNameWithErrorHandling(new_name);
6585ffd83dbSDimitry Andric return status.Success();
6595ffd83dbSDimitry Andric }
6605ffd83dbSDimitry Andric
AddNameWithErrorHandling(const char * new_name)6615ffd83dbSDimitry Andric SBError SBBreakpoint::AddNameWithErrorHandling(const char *new_name) {
66204eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, new_name);
6635ffd83dbSDimitry Andric
6640b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
6650b57cec5SDimitry Andric
6665ffd83dbSDimitry Andric SBError status;
6670b57cec5SDimitry Andric if (bkpt_sp) {
6680b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
6690b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
6705ffd83dbSDimitry Andric Status error;
6710b57cec5SDimitry Andric bkpt_sp->GetTarget().AddNameToBreakpoint(bkpt_sp, new_name, error);
6725ffd83dbSDimitry Andric status.SetError(error);
6735ffd83dbSDimitry Andric } else {
6745ffd83dbSDimitry Andric status.SetErrorString("invalid breakpoint");
6750b57cec5SDimitry Andric }
6760b57cec5SDimitry Andric
67704eeddc0SDimitry Andric return status;
6780b57cec5SDimitry Andric }
6790b57cec5SDimitry Andric
RemoveName(const char * name_to_remove)6800b57cec5SDimitry Andric void SBBreakpoint::RemoveName(const char *name_to_remove) {
68104eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, name_to_remove);
6820b57cec5SDimitry Andric
6830b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
6840b57cec5SDimitry Andric
6850b57cec5SDimitry Andric if (bkpt_sp) {
6860b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
6870b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
6880b57cec5SDimitry Andric bkpt_sp->GetTarget().RemoveNameFromBreakpoint(bkpt_sp,
6890b57cec5SDimitry Andric ConstString(name_to_remove));
6900b57cec5SDimitry Andric }
6910b57cec5SDimitry Andric }
6920b57cec5SDimitry Andric
MatchesName(const char * name)6930b57cec5SDimitry Andric bool SBBreakpoint::MatchesName(const char *name) {
69404eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, name);
6950b57cec5SDimitry Andric
6960b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
6970b57cec5SDimitry Andric
6980b57cec5SDimitry Andric if (bkpt_sp) {
6990b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
7000b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
7010b57cec5SDimitry Andric return bkpt_sp->MatchesName(name);
7020b57cec5SDimitry Andric }
7030b57cec5SDimitry Andric
7040b57cec5SDimitry Andric return false;
7050b57cec5SDimitry Andric }
7060b57cec5SDimitry Andric
GetNames(SBStringList & names)7070b57cec5SDimitry Andric void SBBreakpoint::GetNames(SBStringList &names) {
70804eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, names);
7090b57cec5SDimitry Andric
7100b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
7110b57cec5SDimitry Andric
7120b57cec5SDimitry Andric if (bkpt_sp) {
7130b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
7140b57cec5SDimitry Andric bkpt_sp->GetTarget().GetAPIMutex());
7150b57cec5SDimitry Andric std::vector<std::string> names_vec;
7160b57cec5SDimitry Andric bkpt_sp->GetNames(names_vec);
717*0fca6ea1SDimitry Andric for (const std::string &name : names_vec) {
7180b57cec5SDimitry Andric names.AppendString(name.c_str());
7190b57cec5SDimitry Andric }
7200b57cec5SDimitry Andric }
7210b57cec5SDimitry Andric }
7220b57cec5SDimitry Andric
EventIsBreakpointEvent(const lldb::SBEvent & event)7230b57cec5SDimitry Andric bool SBBreakpoint::EventIsBreakpointEvent(const lldb::SBEvent &event) {
72404eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(event);
7250b57cec5SDimitry Andric
7260b57cec5SDimitry Andric return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event.get()) !=
7270b57cec5SDimitry Andric nullptr;
7280b57cec5SDimitry Andric }
7290b57cec5SDimitry Andric
7300b57cec5SDimitry Andric BreakpointEventType
GetBreakpointEventTypeFromEvent(const SBEvent & event)7310b57cec5SDimitry Andric SBBreakpoint::GetBreakpointEventTypeFromEvent(const SBEvent &event) {
73204eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(event);
7330b57cec5SDimitry Andric
7340b57cec5SDimitry Andric if (event.IsValid())
7350b57cec5SDimitry Andric return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent(
7360b57cec5SDimitry Andric event.GetSP());
7370b57cec5SDimitry Andric return eBreakpointEventTypeInvalidType;
7380b57cec5SDimitry Andric }
7390b57cec5SDimitry Andric
GetBreakpointFromEvent(const lldb::SBEvent & event)7400b57cec5SDimitry Andric SBBreakpoint SBBreakpoint::GetBreakpointFromEvent(const lldb::SBEvent &event) {
74104eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(event);
7420b57cec5SDimitry Andric
7430b57cec5SDimitry Andric if (event.IsValid())
74404eeddc0SDimitry Andric return SBBreakpoint(
74504eeddc0SDimitry Andric Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event.GetSP()));
74604eeddc0SDimitry Andric return SBBreakpoint();
7470b57cec5SDimitry Andric }
7480b57cec5SDimitry Andric
7490b57cec5SDimitry Andric SBBreakpointLocation
GetBreakpointLocationAtIndexFromEvent(const lldb::SBEvent & event,uint32_t loc_idx)7500b57cec5SDimitry Andric SBBreakpoint::GetBreakpointLocationAtIndexFromEvent(const lldb::SBEvent &event,
7510b57cec5SDimitry Andric uint32_t loc_idx) {
75204eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(event, loc_idx);
7530b57cec5SDimitry Andric
7540b57cec5SDimitry Andric SBBreakpointLocation sb_breakpoint_loc;
7550b57cec5SDimitry Andric if (event.IsValid())
7560b57cec5SDimitry Andric sb_breakpoint_loc.SetLocation(
7570b57cec5SDimitry Andric Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent(
7580b57cec5SDimitry Andric event.GetSP(), loc_idx));
75904eeddc0SDimitry Andric return sb_breakpoint_loc;
7600b57cec5SDimitry Andric }
7610b57cec5SDimitry Andric
7620b57cec5SDimitry Andric uint32_t
GetNumBreakpointLocationsFromEvent(const lldb::SBEvent & event)7630b57cec5SDimitry Andric SBBreakpoint::GetNumBreakpointLocationsFromEvent(const lldb::SBEvent &event) {
76404eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(event);
7650b57cec5SDimitry Andric
7660b57cec5SDimitry Andric uint32_t num_locations = 0;
7670b57cec5SDimitry Andric if (event.IsValid())
7680b57cec5SDimitry Andric num_locations =
7690b57cec5SDimitry Andric (Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(
7700b57cec5SDimitry Andric event.GetSP()));
7710b57cec5SDimitry Andric return num_locations;
7720b57cec5SDimitry Andric }
7730b57cec5SDimitry Andric
IsHardware() const7740b57cec5SDimitry Andric bool SBBreakpoint::IsHardware() const {
77504eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this);
7760b57cec5SDimitry Andric
7770b57cec5SDimitry Andric BreakpointSP bkpt_sp = GetSP();
7780b57cec5SDimitry Andric if (bkpt_sp)
7790b57cec5SDimitry Andric return bkpt_sp->IsHardware();
7800b57cec5SDimitry Andric return false;
7810b57cec5SDimitry Andric }
7820b57cec5SDimitry Andric
GetSP() const7830b57cec5SDimitry Andric BreakpointSP SBBreakpoint::GetSP() const { return m_opaque_wp.lock(); }
7840b57cec5SDimitry Andric
7850b57cec5SDimitry Andric // This is simple collection of breakpoint id's and their target.
7860b57cec5SDimitry Andric class SBBreakpointListImpl {
7870b57cec5SDimitry Andric public:
SBBreakpointListImpl(lldb::TargetSP target_sp)78804eeddc0SDimitry Andric SBBreakpointListImpl(lldb::TargetSP target_sp) {
7890b57cec5SDimitry Andric if (target_sp && target_sp->IsValid())
7900b57cec5SDimitry Andric m_target_wp = target_sp;
7910b57cec5SDimitry Andric }
7920b57cec5SDimitry Andric
7930b57cec5SDimitry Andric ~SBBreakpointListImpl() = default;
7940b57cec5SDimitry Andric
GetSize()7950b57cec5SDimitry Andric size_t GetSize() { return m_break_ids.size(); }
7960b57cec5SDimitry Andric
GetBreakpointAtIndex(size_t idx)7970b57cec5SDimitry Andric BreakpointSP GetBreakpointAtIndex(size_t idx) {
7980b57cec5SDimitry Andric if (idx >= m_break_ids.size())
7990b57cec5SDimitry Andric return BreakpointSP();
8000b57cec5SDimitry Andric TargetSP target_sp = m_target_wp.lock();
8010b57cec5SDimitry Andric if (!target_sp)
8020b57cec5SDimitry Andric return BreakpointSP();
8030b57cec5SDimitry Andric lldb::break_id_t bp_id = m_break_ids[idx];
8040b57cec5SDimitry Andric return target_sp->GetBreakpointList().FindBreakpointByID(bp_id);
8050b57cec5SDimitry Andric }
8060b57cec5SDimitry Andric
FindBreakpointByID(lldb::break_id_t desired_id)8070b57cec5SDimitry Andric BreakpointSP FindBreakpointByID(lldb::break_id_t desired_id) {
8080b57cec5SDimitry Andric TargetSP target_sp = m_target_wp.lock();
8090b57cec5SDimitry Andric if (!target_sp)
8100b57cec5SDimitry Andric return BreakpointSP();
8110b57cec5SDimitry Andric
8120b57cec5SDimitry Andric for (lldb::break_id_t &break_id : m_break_ids) {
8130b57cec5SDimitry Andric if (break_id == desired_id)
8140b57cec5SDimitry Andric return target_sp->GetBreakpointList().FindBreakpointByID(break_id);
8150b57cec5SDimitry Andric }
8160b57cec5SDimitry Andric return BreakpointSP();
8170b57cec5SDimitry Andric }
8180b57cec5SDimitry Andric
Append(BreakpointSP bkpt)8190b57cec5SDimitry Andric bool Append(BreakpointSP bkpt) {
8200b57cec5SDimitry Andric TargetSP target_sp = m_target_wp.lock();
8210b57cec5SDimitry Andric if (!target_sp || !bkpt)
8220b57cec5SDimitry Andric return false;
8230b57cec5SDimitry Andric if (bkpt->GetTargetSP() != target_sp)
8240b57cec5SDimitry Andric return false;
8250b57cec5SDimitry Andric m_break_ids.push_back(bkpt->GetID());
8260b57cec5SDimitry Andric return true;
8270b57cec5SDimitry Andric }
8280b57cec5SDimitry Andric
AppendIfUnique(BreakpointSP bkpt)8290b57cec5SDimitry Andric bool AppendIfUnique(BreakpointSP bkpt) {
8300b57cec5SDimitry Andric TargetSP target_sp = m_target_wp.lock();
8310b57cec5SDimitry Andric if (!target_sp || !bkpt)
8320b57cec5SDimitry Andric return false;
8330b57cec5SDimitry Andric if (bkpt->GetTargetSP() != target_sp)
8340b57cec5SDimitry Andric return false;
8350b57cec5SDimitry Andric lldb::break_id_t bp_id = bkpt->GetID();
836fcaf7f86SDimitry Andric if (!llvm::is_contained(m_break_ids, bp_id))
8370b57cec5SDimitry Andric return false;
8380b57cec5SDimitry Andric
8390b57cec5SDimitry Andric m_break_ids.push_back(bkpt->GetID());
8400b57cec5SDimitry Andric return true;
8410b57cec5SDimitry Andric }
8420b57cec5SDimitry Andric
AppendByID(lldb::break_id_t id)8430b57cec5SDimitry Andric bool AppendByID(lldb::break_id_t id) {
8440b57cec5SDimitry Andric TargetSP target_sp = m_target_wp.lock();
8450b57cec5SDimitry Andric if (!target_sp)
8460b57cec5SDimitry Andric return false;
8470b57cec5SDimitry Andric if (id == LLDB_INVALID_BREAK_ID)
8480b57cec5SDimitry Andric return false;
8490b57cec5SDimitry Andric m_break_ids.push_back(id);
8500b57cec5SDimitry Andric return true;
8510b57cec5SDimitry Andric }
8520b57cec5SDimitry Andric
Clear()8530b57cec5SDimitry Andric void Clear() { m_break_ids.clear(); }
8540b57cec5SDimitry Andric
CopyToBreakpointIDList(lldb_private::BreakpointIDList & bp_list)8550b57cec5SDimitry Andric void CopyToBreakpointIDList(lldb_private::BreakpointIDList &bp_list) {
8560b57cec5SDimitry Andric for (lldb::break_id_t id : m_break_ids) {
8570b57cec5SDimitry Andric bp_list.AddBreakpointID(BreakpointID(id));
8580b57cec5SDimitry Andric }
8590b57cec5SDimitry Andric }
8600b57cec5SDimitry Andric
GetTarget()8610b57cec5SDimitry Andric TargetSP GetTarget() { return m_target_wp.lock(); }
8620b57cec5SDimitry Andric
8630b57cec5SDimitry Andric private:
8640b57cec5SDimitry Andric std::vector<lldb::break_id_t> m_break_ids;
8650b57cec5SDimitry Andric TargetWP m_target_wp;
8660b57cec5SDimitry Andric };
8670b57cec5SDimitry Andric
SBBreakpointList(SBTarget & target)8680b57cec5SDimitry Andric SBBreakpointList::SBBreakpointList(SBTarget &target)
8690b57cec5SDimitry Andric : m_opaque_sp(new SBBreakpointListImpl(target.GetSP())) {
87004eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, target);
8710b57cec5SDimitry Andric }
8720b57cec5SDimitry Andric
8735ffd83dbSDimitry Andric SBBreakpointList::~SBBreakpointList() = default;
8740b57cec5SDimitry Andric
GetSize() const8750b57cec5SDimitry Andric size_t SBBreakpointList::GetSize() const {
87604eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this);
8770b57cec5SDimitry Andric
8780b57cec5SDimitry Andric if (!m_opaque_sp)
8790b57cec5SDimitry Andric return 0;
8800b57cec5SDimitry Andric else
8810b57cec5SDimitry Andric return m_opaque_sp->GetSize();
8820b57cec5SDimitry Andric }
8830b57cec5SDimitry Andric
GetBreakpointAtIndex(size_t idx)8840b57cec5SDimitry Andric SBBreakpoint SBBreakpointList::GetBreakpointAtIndex(size_t idx) {
88504eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, idx);
8860b57cec5SDimitry Andric
8870b57cec5SDimitry Andric if (!m_opaque_sp)
88804eeddc0SDimitry Andric return SBBreakpoint();
8890b57cec5SDimitry Andric
8900b57cec5SDimitry Andric BreakpointSP bkpt_sp = m_opaque_sp->GetBreakpointAtIndex(idx);
89104eeddc0SDimitry Andric return SBBreakpoint(bkpt_sp);
8920b57cec5SDimitry Andric }
8930b57cec5SDimitry Andric
FindBreakpointByID(lldb::break_id_t id)8940b57cec5SDimitry Andric SBBreakpoint SBBreakpointList::FindBreakpointByID(lldb::break_id_t id) {
89504eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, id);
8960b57cec5SDimitry Andric
8970b57cec5SDimitry Andric if (!m_opaque_sp)
89804eeddc0SDimitry Andric return SBBreakpoint();
8990b57cec5SDimitry Andric BreakpointSP bkpt_sp = m_opaque_sp->FindBreakpointByID(id);
90004eeddc0SDimitry Andric return SBBreakpoint(bkpt_sp);
9010b57cec5SDimitry Andric }
9020b57cec5SDimitry Andric
Append(const SBBreakpoint & sb_bkpt)9030b57cec5SDimitry Andric void SBBreakpointList::Append(const SBBreakpoint &sb_bkpt) {
90404eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, sb_bkpt);
9050b57cec5SDimitry Andric
9060b57cec5SDimitry Andric if (!sb_bkpt.IsValid())
9070b57cec5SDimitry Andric return;
9080b57cec5SDimitry Andric if (!m_opaque_sp)
9090b57cec5SDimitry Andric return;
9100b57cec5SDimitry Andric m_opaque_sp->Append(sb_bkpt.m_opaque_wp.lock());
9110b57cec5SDimitry Andric }
9120b57cec5SDimitry Andric
AppendByID(lldb::break_id_t id)9130b57cec5SDimitry Andric void SBBreakpointList::AppendByID(lldb::break_id_t id) {
91404eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, id);
9150b57cec5SDimitry Andric
9160b57cec5SDimitry Andric if (!m_opaque_sp)
9170b57cec5SDimitry Andric return;
9180b57cec5SDimitry Andric m_opaque_sp->AppendByID(id);
9190b57cec5SDimitry Andric }
9200b57cec5SDimitry Andric
AppendIfUnique(const SBBreakpoint & sb_bkpt)9210b57cec5SDimitry Andric bool SBBreakpointList::AppendIfUnique(const SBBreakpoint &sb_bkpt) {
92204eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, sb_bkpt);
9230b57cec5SDimitry Andric
9240b57cec5SDimitry Andric if (!sb_bkpt.IsValid())
9250b57cec5SDimitry Andric return false;
9260b57cec5SDimitry Andric if (!m_opaque_sp)
9270b57cec5SDimitry Andric return false;
9280b57cec5SDimitry Andric return m_opaque_sp->AppendIfUnique(sb_bkpt.GetSP());
9290b57cec5SDimitry Andric }
9300b57cec5SDimitry Andric
Clear()9310b57cec5SDimitry Andric void SBBreakpointList::Clear() {
93204eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this);
9330b57cec5SDimitry Andric
9340b57cec5SDimitry Andric if (m_opaque_sp)
9350b57cec5SDimitry Andric m_opaque_sp->Clear();
9360b57cec5SDimitry Andric }
9370b57cec5SDimitry Andric
CopyToBreakpointIDList(lldb_private::BreakpointIDList & bp_id_list)9380b57cec5SDimitry Andric void SBBreakpointList::CopyToBreakpointIDList(
9390b57cec5SDimitry Andric lldb_private::BreakpointIDList &bp_id_list) {
9400b57cec5SDimitry Andric if (m_opaque_sp)
9410b57cec5SDimitry Andric m_opaque_sp->CopyToBreakpointIDList(bp_id_list);
9420b57cec5SDimitry Andric }
943