Path: blob/main/contrib/llvm-project/lldb/source/API/SBBreakpointName.cpp
39587 views
//===-- SBBreakpointName.cpp ----------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "lldb/API/SBBreakpointName.h"9#include "lldb/API/SBDebugger.h"10#include "lldb/API/SBError.h"11#include "lldb/API/SBStream.h"12#include "lldb/API/SBStringList.h"13#include "lldb/API/SBStructuredData.h"14#include "lldb/API/SBTarget.h"15#include "lldb/Utility/Instrumentation.h"1617#include "lldb/Breakpoint/BreakpointName.h"18#include "lldb/Breakpoint/StoppointCallbackContext.h"19#include "lldb/Core/Debugger.h"20#include "lldb/Core/StructuredDataImpl.h"21#include "lldb/Interpreter/CommandInterpreter.h"22#include "lldb/Interpreter/ScriptInterpreter.h"23#include "lldb/Target/Target.h"24#include "lldb/Target/ThreadSpec.h"25#include "lldb/Utility/Stream.h"2627#include "SBBreakpointOptionCommon.h"2829using namespace lldb;30using namespace lldb_private;3132namespace lldb33{34class SBBreakpointNameImpl {35public:36SBBreakpointNameImpl(TargetSP target_sp, const char *name) {37if (!name || name[0] == '\0')38return;39m_name.assign(name);4041if (!target_sp)42return;4344m_target_wp = target_sp;45}4647SBBreakpointNameImpl(SBTarget &sb_target, const char *name);48bool operator==(const SBBreakpointNameImpl &rhs);49bool operator!=(const SBBreakpointNameImpl &rhs);5051// For now we take a simple approach and only keep the name, and relook up52// the location when we need it.5354TargetSP GetTarget() const {55return m_target_wp.lock();56}5758const char *GetName() const {59return m_name.c_str();60}6162bool IsValid() const {63return !m_name.empty() && m_target_wp.lock();64}6566lldb_private::BreakpointName *GetBreakpointName() const;6768private:69TargetWP m_target_wp;70std::string m_name;71};7273SBBreakpointNameImpl::SBBreakpointNameImpl(SBTarget &sb_target,74const char *name) {75if (!name || name[0] == '\0')76return;77m_name.assign(name);7879if (!sb_target.IsValid())80return;8182TargetSP target_sp = sb_target.GetSP();83if (!target_sp)84return;8586m_target_wp = target_sp;87}8889bool SBBreakpointNameImpl::operator==(const SBBreakpointNameImpl &rhs) {90return m_name == rhs.m_name && m_target_wp.lock() == rhs.m_target_wp.lock();91}9293bool SBBreakpointNameImpl::operator!=(const SBBreakpointNameImpl &rhs) {94return m_name != rhs.m_name || m_target_wp.lock() != rhs.m_target_wp.lock();95}9697lldb_private::BreakpointName *SBBreakpointNameImpl::GetBreakpointName() const {98if (!IsValid())99return nullptr;100TargetSP target_sp = GetTarget();101if (!target_sp)102return nullptr;103Status error;104return target_sp->FindBreakpointName(ConstString(m_name), true, error);105}106107} // namespace lldb108109SBBreakpointName::SBBreakpointName() { LLDB_INSTRUMENT_VA(this); }110111SBBreakpointName::SBBreakpointName(SBTarget &sb_target, const char *name) {112LLDB_INSTRUMENT_VA(this, sb_target, name);113114m_impl_up = std::make_unique<SBBreakpointNameImpl>(sb_target, name);115// Call FindBreakpointName here to make sure the name is valid, reset if not:116BreakpointName *bp_name = GetBreakpointName();117if (!bp_name)118m_impl_up.reset();119}120121SBBreakpointName::SBBreakpointName(SBBreakpoint &sb_bkpt, const char *name) {122LLDB_INSTRUMENT_VA(this, sb_bkpt, name);123124if (!sb_bkpt.IsValid()) {125m_impl_up.reset();126return;127}128BreakpointSP bkpt_sp = sb_bkpt.GetSP();129Target &target = bkpt_sp->GetTarget();130131m_impl_up =132std::make_unique<SBBreakpointNameImpl>(target.shared_from_this(), name);133134// Call FindBreakpointName here to make sure the name is valid, reset if not:135BreakpointName *bp_name = GetBreakpointName();136if (!bp_name) {137m_impl_up.reset();138return;139}140141// Now copy over the breakpoint's options:142target.ConfigureBreakpointName(*bp_name, bkpt_sp->GetOptions(),143BreakpointName::Permissions());144}145146SBBreakpointName::SBBreakpointName(const SBBreakpointName &rhs) {147LLDB_INSTRUMENT_VA(this, rhs);148149if (!rhs.m_impl_up)150return;151else152m_impl_up = std::make_unique<SBBreakpointNameImpl>(153rhs.m_impl_up->GetTarget(), rhs.m_impl_up->GetName());154}155156SBBreakpointName::~SBBreakpointName() = default;157158const SBBreakpointName &SBBreakpointName::159operator=(const SBBreakpointName &rhs) {160LLDB_INSTRUMENT_VA(this, rhs);161162if (!rhs.m_impl_up) {163m_impl_up.reset();164return *this;165}166167m_impl_up = std::make_unique<SBBreakpointNameImpl>(rhs.m_impl_up->GetTarget(),168rhs.m_impl_up->GetName());169return *this;170}171172bool SBBreakpointName::operator==(const lldb::SBBreakpointName &rhs) {173LLDB_INSTRUMENT_VA(this, rhs);174175return *m_impl_up == *rhs.m_impl_up;176}177178bool SBBreakpointName::operator!=(const lldb::SBBreakpointName &rhs) {179LLDB_INSTRUMENT_VA(this, rhs);180181return *m_impl_up != *rhs.m_impl_up;182}183184bool SBBreakpointName::IsValid() const {185LLDB_INSTRUMENT_VA(this);186return this->operator bool();187}188SBBreakpointName::operator bool() const {189LLDB_INSTRUMENT_VA(this);190191if (!m_impl_up)192return false;193return m_impl_up->IsValid();194}195196const char *SBBreakpointName::GetName() const {197LLDB_INSTRUMENT_VA(this);198199if (!m_impl_up)200return "<Invalid Breakpoint Name Object>";201return ConstString(m_impl_up->GetName()).GetCString();202}203204void SBBreakpointName::SetEnabled(bool enable) {205LLDB_INSTRUMENT_VA(this, enable);206207BreakpointName *bp_name = GetBreakpointName();208if (!bp_name)209return;210211std::lock_guard<std::recursive_mutex> guard(212m_impl_up->GetTarget()->GetAPIMutex());213214bp_name->GetOptions().SetEnabled(enable);215}216217void SBBreakpointName::UpdateName(BreakpointName &bp_name) {218if (!IsValid())219return;220221TargetSP target_sp = m_impl_up->GetTarget();222if (!target_sp)223return;224target_sp->ApplyNameToBreakpoints(bp_name);225226}227228bool SBBreakpointName::IsEnabled() {229LLDB_INSTRUMENT_VA(this);230231BreakpointName *bp_name = GetBreakpointName();232if (!bp_name)233return false;234235std::lock_guard<std::recursive_mutex> guard(236m_impl_up->GetTarget()->GetAPIMutex());237238return bp_name->GetOptions().IsEnabled();239}240241void SBBreakpointName::SetOneShot(bool one_shot) {242LLDB_INSTRUMENT_VA(this, one_shot);243244BreakpointName *bp_name = GetBreakpointName();245if (!bp_name)246return;247248std::lock_guard<std::recursive_mutex> guard(249m_impl_up->GetTarget()->GetAPIMutex());250251bp_name->GetOptions().SetOneShot(one_shot);252UpdateName(*bp_name);253}254255bool SBBreakpointName::IsOneShot() const {256LLDB_INSTRUMENT_VA(this);257258const BreakpointName *bp_name = GetBreakpointName();259if (!bp_name)260return false;261262std::lock_guard<std::recursive_mutex> guard(263m_impl_up->GetTarget()->GetAPIMutex());264265return bp_name->GetOptions().IsOneShot();266}267268void SBBreakpointName::SetIgnoreCount(uint32_t count) {269LLDB_INSTRUMENT_VA(this, count);270271BreakpointName *bp_name = GetBreakpointName();272if (!bp_name)273return;274275std::lock_guard<std::recursive_mutex> guard(276m_impl_up->GetTarget()->GetAPIMutex());277278bp_name->GetOptions().SetIgnoreCount(count);279UpdateName(*bp_name);280}281282uint32_t SBBreakpointName::GetIgnoreCount() const {283LLDB_INSTRUMENT_VA(this);284285BreakpointName *bp_name = GetBreakpointName();286if (!bp_name)287return false;288289std::lock_guard<std::recursive_mutex> guard(290m_impl_up->GetTarget()->GetAPIMutex());291292return bp_name->GetOptions().GetIgnoreCount();293}294295void SBBreakpointName::SetCondition(const char *condition) {296LLDB_INSTRUMENT_VA(this, condition);297298BreakpointName *bp_name = GetBreakpointName();299if (!bp_name)300return;301302std::lock_guard<std::recursive_mutex> guard(303m_impl_up->GetTarget()->GetAPIMutex());304305bp_name->GetOptions().SetCondition(condition);306UpdateName(*bp_name);307}308309const char *SBBreakpointName::GetCondition() {310LLDB_INSTRUMENT_VA(this);311312BreakpointName *bp_name = GetBreakpointName();313if (!bp_name)314return nullptr;315316std::lock_guard<std::recursive_mutex> guard(317m_impl_up->GetTarget()->GetAPIMutex());318319return ConstString(bp_name->GetOptions().GetConditionText()).GetCString();320}321322void SBBreakpointName::SetAutoContinue(bool auto_continue) {323LLDB_INSTRUMENT_VA(this, auto_continue);324325BreakpointName *bp_name = GetBreakpointName();326if (!bp_name)327return;328329std::lock_guard<std::recursive_mutex> guard(330m_impl_up->GetTarget()->GetAPIMutex());331332bp_name->GetOptions().SetAutoContinue(auto_continue);333UpdateName(*bp_name);334}335336bool SBBreakpointName::GetAutoContinue() {337LLDB_INSTRUMENT_VA(this);338339BreakpointName *bp_name = GetBreakpointName();340if (!bp_name)341return false;342343std::lock_guard<std::recursive_mutex> guard(344m_impl_up->GetTarget()->GetAPIMutex());345346return bp_name->GetOptions().IsAutoContinue();347}348349void SBBreakpointName::SetThreadID(tid_t tid) {350LLDB_INSTRUMENT_VA(this, tid);351352BreakpointName *bp_name = GetBreakpointName();353if (!bp_name)354return;355356std::lock_guard<std::recursive_mutex> guard(357m_impl_up->GetTarget()->GetAPIMutex());358359bp_name->GetOptions().SetThreadID(tid);360UpdateName(*bp_name);361}362363tid_t SBBreakpointName::GetThreadID() {364LLDB_INSTRUMENT_VA(this);365366BreakpointName *bp_name = GetBreakpointName();367if (!bp_name)368return LLDB_INVALID_THREAD_ID;369370std::lock_guard<std::recursive_mutex> guard(371m_impl_up->GetTarget()->GetAPIMutex());372373return bp_name->GetOptions().GetThreadSpec()->GetTID();374}375376void SBBreakpointName::SetThreadIndex(uint32_t index) {377LLDB_INSTRUMENT_VA(this, index);378379BreakpointName *bp_name = GetBreakpointName();380if (!bp_name)381return;382383std::lock_guard<std::recursive_mutex> guard(384m_impl_up->GetTarget()->GetAPIMutex());385386bp_name->GetOptions().GetThreadSpec()->SetIndex(index);387UpdateName(*bp_name);388}389390uint32_t SBBreakpointName::GetThreadIndex() const {391LLDB_INSTRUMENT_VA(this);392393BreakpointName *bp_name = GetBreakpointName();394if (!bp_name)395return LLDB_INVALID_THREAD_ID;396397std::lock_guard<std::recursive_mutex> guard(398m_impl_up->GetTarget()->GetAPIMutex());399400return bp_name->GetOptions().GetThreadSpec()->GetIndex();401}402403void SBBreakpointName::SetThreadName(const char *thread_name) {404LLDB_INSTRUMENT_VA(this, thread_name);405406BreakpointName *bp_name = GetBreakpointName();407if (!bp_name)408return;409410std::lock_guard<std::recursive_mutex> guard(411m_impl_up->GetTarget()->GetAPIMutex());412413bp_name->GetOptions().GetThreadSpec()->SetName(thread_name);414UpdateName(*bp_name);415}416417const char *SBBreakpointName::GetThreadName() const {418LLDB_INSTRUMENT_VA(this);419420BreakpointName *bp_name = GetBreakpointName();421if (!bp_name)422return nullptr;423424std::lock_guard<std::recursive_mutex> guard(425m_impl_up->GetTarget()->GetAPIMutex());426427return ConstString(bp_name->GetOptions().GetThreadSpec()->GetName())428.GetCString();429}430431void SBBreakpointName::SetQueueName(const char *queue_name) {432LLDB_INSTRUMENT_VA(this, queue_name);433434BreakpointName *bp_name = GetBreakpointName();435if (!bp_name)436return;437438std::lock_guard<std::recursive_mutex> guard(439m_impl_up->GetTarget()->GetAPIMutex());440441bp_name->GetOptions().GetThreadSpec()->SetQueueName(queue_name);442UpdateName(*bp_name);443}444445const char *SBBreakpointName::GetQueueName() const {446LLDB_INSTRUMENT_VA(this);447448BreakpointName *bp_name = GetBreakpointName();449if (!bp_name)450return nullptr;451452std::lock_guard<std::recursive_mutex> guard(453m_impl_up->GetTarget()->GetAPIMutex());454455return ConstString(bp_name->GetOptions().GetThreadSpec()->GetQueueName())456.GetCString();457}458459void SBBreakpointName::SetCommandLineCommands(SBStringList &commands) {460LLDB_INSTRUMENT_VA(this, commands);461462BreakpointName *bp_name = GetBreakpointName();463if (!bp_name)464return;465if (commands.GetSize() == 0)466return;467468469std::lock_guard<std::recursive_mutex> guard(470m_impl_up->GetTarget()->GetAPIMutex());471std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up(472new BreakpointOptions::CommandData(*commands, eScriptLanguageNone));473474bp_name->GetOptions().SetCommandDataCallback(cmd_data_up);475UpdateName(*bp_name);476}477478bool SBBreakpointName::GetCommandLineCommands(SBStringList &commands) {479LLDB_INSTRUMENT_VA(this, commands);480481BreakpointName *bp_name = GetBreakpointName();482if (!bp_name)483return false;484485StringList command_list;486bool has_commands =487bp_name->GetOptions().GetCommandLineCallbacks(command_list);488if (has_commands)489commands.AppendList(command_list);490return has_commands;491}492493const char *SBBreakpointName::GetHelpString() const {494LLDB_INSTRUMENT_VA(this);495496BreakpointName *bp_name = GetBreakpointName();497if (!bp_name)498return "";499500return ConstString(bp_name->GetHelp()).GetCString();501}502503void SBBreakpointName::SetHelpString(const char *help_string) {504LLDB_INSTRUMENT_VA(this, help_string);505506BreakpointName *bp_name = GetBreakpointName();507if (!bp_name)508return;509510511std::lock_guard<std::recursive_mutex> guard(512m_impl_up->GetTarget()->GetAPIMutex());513bp_name->SetHelp(help_string);514}515516bool SBBreakpointName::GetDescription(SBStream &s) {517LLDB_INSTRUMENT_VA(this, s);518519BreakpointName *bp_name = GetBreakpointName();520if (!bp_name)521{522s.Printf("No value");523return false;524}525526std::lock_guard<std::recursive_mutex> guard(527m_impl_up->GetTarget()->GetAPIMutex());528bp_name->GetDescription(s.get(), eDescriptionLevelFull);529return true;530}531532void SBBreakpointName::SetCallback(SBBreakpointHitCallback callback,533void *baton) {534LLDB_INSTRUMENT_VA(this, callback, baton);535536BreakpointName *bp_name = GetBreakpointName();537if (!bp_name)538return;539std::lock_guard<std::recursive_mutex> guard(540m_impl_up->GetTarget()->GetAPIMutex());541542BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton));543bp_name->GetOptions().SetCallback(SBBreakpointCallbackBaton544::PrivateBreakpointHitCallback,545baton_sp,546false);547UpdateName(*bp_name);548}549550void SBBreakpointName::SetScriptCallbackFunction(551const char *callback_function_name) {552LLDB_INSTRUMENT_VA(this, callback_function_name);553SBStructuredData empty_args;554SetScriptCallbackFunction(callback_function_name, empty_args);555}556557SBError SBBreakpointName::SetScriptCallbackFunction(558const char *callback_function_name,559SBStructuredData &extra_args) {560LLDB_INSTRUMENT_VA(this, callback_function_name, extra_args);561SBError sb_error;562BreakpointName *bp_name = GetBreakpointName();563if (!bp_name) {564sb_error.SetErrorString("unrecognized breakpoint name");565return sb_error;566}567568std::lock_guard<std::recursive_mutex> guard(569m_impl_up->GetTarget()->GetAPIMutex());570571BreakpointOptions &bp_options = bp_name->GetOptions();572Status error;573error = m_impl_up->GetTarget()574->GetDebugger()575.GetScriptInterpreter()576->SetBreakpointCommandCallbackFunction(577bp_options, callback_function_name,578extra_args.m_impl_up->GetObjectSP());579sb_error.SetError(error);580UpdateName(*bp_name);581return sb_error;582}583584SBError585SBBreakpointName::SetScriptCallbackBody(const char *callback_body_text) {586LLDB_INSTRUMENT_VA(this, callback_body_text);587588SBError sb_error;589BreakpointName *bp_name = GetBreakpointName();590if (!bp_name)591return sb_error;592593std::lock_guard<std::recursive_mutex> guard(594m_impl_up->GetTarget()->GetAPIMutex());595596BreakpointOptions &bp_options = bp_name->GetOptions();597Status error = m_impl_up->GetTarget()598->GetDebugger()599.GetScriptInterpreter()600->SetBreakpointCommandCallback(601bp_options, callback_body_text, /*is_callback=*/false);602sb_error.SetError(error);603if (!sb_error.Fail())604UpdateName(*bp_name);605606return sb_error;607}608609bool SBBreakpointName::GetAllowList() const {610LLDB_INSTRUMENT_VA(this);611612BreakpointName *bp_name = GetBreakpointName();613if (!bp_name)614return false;615return bp_name->GetPermissions().GetAllowList();616}617618void SBBreakpointName::SetAllowList(bool value) {619LLDB_INSTRUMENT_VA(this, value);620621BreakpointName *bp_name = GetBreakpointName();622if (!bp_name)623return;624bp_name->GetPermissions().SetAllowList(value);625}626627bool SBBreakpointName::GetAllowDelete() {628LLDB_INSTRUMENT_VA(this);629630BreakpointName *bp_name = GetBreakpointName();631if (!bp_name)632return false;633return bp_name->GetPermissions().GetAllowDelete();634}635636void SBBreakpointName::SetAllowDelete(bool value) {637LLDB_INSTRUMENT_VA(this, value);638639BreakpointName *bp_name = GetBreakpointName();640if (!bp_name)641return;642bp_name->GetPermissions().SetAllowDelete(value);643}644645bool SBBreakpointName::GetAllowDisable() {646LLDB_INSTRUMENT_VA(this);647648BreakpointName *bp_name = GetBreakpointName();649if (!bp_name)650return false;651return bp_name->GetPermissions().GetAllowDisable();652}653654void SBBreakpointName::SetAllowDisable(bool value) {655LLDB_INSTRUMENT_VA(this, value);656657BreakpointName *bp_name = GetBreakpointName();658if (!bp_name)659return;660bp_name->GetPermissions().SetAllowDisable(value);661}662663lldb_private::BreakpointName *SBBreakpointName::GetBreakpointName() const664{665if (!IsValid())666return nullptr;667return m_impl_up->GetBreakpointName();668}669670671