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 4704eeddc0SDimitry Andric SBBreakpoint::SBBreakpoint() { LLDB_INSTRUMENT_VA(this); } 480b57cec5SDimitry Andric 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 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 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 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 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 80e8d8bef9SDimitry 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 900b57cec5SDimitry 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 1010b57cec5SDimitry Andric bool SBBreakpoint::IsValid() const { 10204eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this); 1030b57cec5SDimitry Andric return this->operator bool(); 1040b57cec5SDimitry Andric } 1050b57cec5SDimitry 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 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 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 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 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 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 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 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 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 2350b57cec5SDimitry 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 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 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 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 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 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 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 3170b57cec5SDimitry 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 3310b57cec5SDimitry 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 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 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 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 3810b57cec5SDimitry 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 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 4100b57cec5SDimitry 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 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 4370b57cec5SDimitry 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 4530b57cec5SDimitry 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 4660b57cec5SDimitry 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 7740b57cec5SDimitry 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 7830b57cec5SDimitry 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: 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 7950b57cec5SDimitry Andric size_t GetSize() { return m_break_ids.size(); } 7960b57cec5SDimitry Andric 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 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 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 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 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 8530b57cec5SDimitry Andric void Clear() { m_break_ids.clear(); } 8540b57cec5SDimitry Andric 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 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 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 8750b57cec5SDimitry 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 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 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 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 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 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 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 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