Path: blob/main/contrib/llvm-project/lldb/source/Breakpoint/WatchpointOptions.cpp
39587 views
//===-- WatchpointOptions.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/Breakpoint/WatchpointOptions.h"910#include "lldb/Breakpoint/StoppointCallbackContext.h"11#include "lldb/Core/Value.h"12#include "lldb/Target/Process.h"13#include "lldb/Target/Target.h"14#include "lldb/Target/ThreadSpec.h"15#include "lldb/Utility/Stream.h"16#include "lldb/Utility/StringList.h"1718using namespace lldb;19using namespace lldb_private;2021bool WatchpointOptions::NullCallback(void *baton,22StoppointCallbackContext *context,23lldb::user_id_t watch_id) {24return true;25}2627// WatchpointOptions constructor28WatchpointOptions::WatchpointOptions()29: m_callback(WatchpointOptions::NullCallback) {}3031// WatchpointOptions copy constructor32WatchpointOptions::WatchpointOptions(const WatchpointOptions &rhs)33: m_callback(rhs.m_callback), m_callback_baton_sp(rhs.m_callback_baton_sp),34m_callback_is_synchronous(rhs.m_callback_is_synchronous) {35if (rhs.m_thread_spec_up != nullptr)36m_thread_spec_up = std::make_unique<ThreadSpec>(*rhs.m_thread_spec_up);37}3839// WatchpointOptions assignment operator40const WatchpointOptions &WatchpointOptions::41operator=(const WatchpointOptions &rhs) {42m_callback = rhs.m_callback;43m_callback_baton_sp = rhs.m_callback_baton_sp;44m_callback_is_synchronous = rhs.m_callback_is_synchronous;45if (rhs.m_thread_spec_up != nullptr)46m_thread_spec_up = std::make_unique<ThreadSpec>(*rhs.m_thread_spec_up);47return *this;48}4950WatchpointOptions *51WatchpointOptions::CopyOptionsNoCallback(WatchpointOptions &orig) {52WatchpointHitCallback orig_callback = orig.m_callback;53lldb::BatonSP orig_callback_baton_sp = orig.m_callback_baton_sp;54bool orig_is_sync = orig.m_callback_is_synchronous;5556orig.ClearCallback();57WatchpointOptions *ret_val = new WatchpointOptions(orig);5859orig.SetCallback(orig_callback, orig_callback_baton_sp, orig_is_sync);6061return ret_val;62}6364// Destructor65WatchpointOptions::~WatchpointOptions() = default;6667// Callbacks68void WatchpointOptions::SetCallback(WatchpointHitCallback callback,69const BatonSP &callback_baton_sp,70bool callback_is_synchronous) {71m_callback_is_synchronous = callback_is_synchronous;72m_callback = callback;73m_callback_baton_sp = callback_baton_sp;74}7576void WatchpointOptions::ClearCallback() {77m_callback = WatchpointOptions::NullCallback;78m_callback_is_synchronous = false;79m_callback_baton_sp.reset();80}8182Baton *WatchpointOptions::GetBaton() { return m_callback_baton_sp.get(); }8384const Baton *WatchpointOptions::GetBaton() const {85return m_callback_baton_sp.get();86}8788bool WatchpointOptions::InvokeCallback(StoppointCallbackContext *context,89lldb::user_id_t watch_id) {90if (m_callback && context->is_synchronous == IsCallbackSynchronous()) {91return m_callback(m_callback_baton_sp ? m_callback_baton_sp->data()92: nullptr,93context, watch_id);94} else95return true;96}9798bool WatchpointOptions::HasCallback() {99return m_callback != WatchpointOptions::NullCallback;100}101102const ThreadSpec *WatchpointOptions::GetThreadSpecNoCreate() const {103return m_thread_spec_up.get();104}105106ThreadSpec *WatchpointOptions::GetThreadSpec() {107if (m_thread_spec_up == nullptr)108m_thread_spec_up = std::make_unique<ThreadSpec>();109110return m_thread_spec_up.get();111}112113void WatchpointOptions::SetThreadID(lldb::tid_t thread_id) {114GetThreadSpec()->SetTID(thread_id);115}116117void WatchpointOptions::GetCallbackDescription(118Stream *s, lldb::DescriptionLevel level) const {119if (m_callback_baton_sp.get()) {120s->EOL();121m_callback_baton_sp->GetDescription(s->AsRawOstream(), level,122s->GetIndentLevel());123}124}125126void WatchpointOptions::GetDescription(Stream *s,127lldb::DescriptionLevel level) const {128// Figure out if there are any options not at their default value, and only129// print anything if there are:130131if ((GetThreadSpecNoCreate() != nullptr &&132GetThreadSpecNoCreate()->HasSpecification())) {133if (level == lldb::eDescriptionLevelVerbose) {134s->EOL();135s->IndentMore();136s->Indent();137s->PutCString("Watchpoint Options:\n");138s->IndentMore();139s->Indent();140} else141s->PutCString(" Options: ");142143if (m_thread_spec_up)144m_thread_spec_up->GetDescription(s, level);145else if (level == eDescriptionLevelBrief)146s->PutCString("thread spec: no ");147if (level == lldb::eDescriptionLevelFull) {148s->IndentLess();149s->IndentMore();150}151}152153GetCallbackDescription(s, level);154}155156void WatchpointOptions::CommandBaton::GetDescription(157llvm::raw_ostream &s, lldb::DescriptionLevel level,158unsigned indentation) const {159const CommandData *data = getItem();160161if (level == eDescriptionLevelBrief) {162s << ", commands = %s"163<< ((data && data->user_source.GetSize() > 0) ? "yes" : "no");164return;165}166167indentation += 2;168s.indent(indentation);169s << "watchpoint commands:\n";170171indentation += 2;172if (data && data->user_source.GetSize() > 0) {173for (const std::string &line : data->user_source) {174s.indent(indentation);175s << line << "\n";176}177} else178s << "No commands.\n";179}180181182