brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.6 KiB · 321aab0 Raw
181 lines · cpp
1//===-- WatchpointOptions.cpp ---------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "lldb/Breakpoint/WatchpointOptions.h"10 11#include "lldb/Breakpoint/StoppointCallbackContext.h"12#include "lldb/Core/Value.h"13#include "lldb/Target/Process.h"14#include "lldb/Target/Target.h"15#include "lldb/Target/ThreadSpec.h"16#include "lldb/Utility/Stream.h"17#include "lldb/Utility/StringList.h"18 19using namespace lldb;20using namespace lldb_private;21 22bool WatchpointOptions::NullCallback(void *baton,23                                     StoppointCallbackContext *context,24                                     lldb::user_id_t watch_id) {25  return true;26}27 28// WatchpointOptions constructor29WatchpointOptions::WatchpointOptions()30    : m_callback(WatchpointOptions::NullCallback) {}31 32// WatchpointOptions copy constructor33WatchpointOptions::WatchpointOptions(const WatchpointOptions &rhs)34    : m_callback(rhs.m_callback), m_callback_baton_sp(rhs.m_callback_baton_sp),35      m_callback_is_synchronous(rhs.m_callback_is_synchronous) {36  if (rhs.m_thread_spec_up != nullptr)37    m_thread_spec_up = std::make_unique<ThreadSpec>(*rhs.m_thread_spec_up);38}39 40// WatchpointOptions assignment operator41const WatchpointOptions &WatchpointOptions::42operator=(const WatchpointOptions &rhs) {43  m_callback = rhs.m_callback;44  m_callback_baton_sp = rhs.m_callback_baton_sp;45  m_callback_is_synchronous = rhs.m_callback_is_synchronous;46  if (rhs.m_thread_spec_up != nullptr)47    m_thread_spec_up = std::make_unique<ThreadSpec>(*rhs.m_thread_spec_up);48  return *this;49}50 51WatchpointOptions *52WatchpointOptions::CopyOptionsNoCallback(WatchpointOptions &orig) {53  WatchpointHitCallback orig_callback = orig.m_callback;54  lldb::BatonSP orig_callback_baton_sp = orig.m_callback_baton_sp;55  bool orig_is_sync = orig.m_callback_is_synchronous;56 57  orig.ClearCallback();58  WatchpointOptions *ret_val = new WatchpointOptions(orig);59 60  orig.SetCallback(orig_callback, orig_callback_baton_sp, orig_is_sync);61 62  return ret_val;63}64 65// Destructor66WatchpointOptions::~WatchpointOptions() = default;67 68// Callbacks69void WatchpointOptions::SetCallback(WatchpointHitCallback callback,70                                    const BatonSP &callback_baton_sp,71                                    bool callback_is_synchronous) {72  m_callback_is_synchronous = callback_is_synchronous;73  m_callback = callback;74  m_callback_baton_sp = callback_baton_sp;75}76 77void WatchpointOptions::ClearCallback() {78  m_callback = WatchpointOptions::NullCallback;79  m_callback_is_synchronous = false;80  m_callback_baton_sp.reset();81}82 83Baton *WatchpointOptions::GetBaton() { return m_callback_baton_sp.get(); }84 85const Baton *WatchpointOptions::GetBaton() const {86  return m_callback_baton_sp.get();87}88 89bool WatchpointOptions::InvokeCallback(StoppointCallbackContext *context,90                                       lldb::user_id_t watch_id) {91  if (m_callback && context->is_synchronous == IsCallbackSynchronous()) {92    return m_callback(m_callback_baton_sp ? m_callback_baton_sp->data()93                                          : nullptr,94                      context, watch_id);95  }96  return true;97}98 99bool WatchpointOptions::HasCallback() {100  return m_callback != WatchpointOptions::NullCallback;101}102 103const ThreadSpec *WatchpointOptions::GetThreadSpecNoCreate() const {104  return m_thread_spec_up.get();105}106 107ThreadSpec *WatchpointOptions::GetThreadSpec() {108  if (m_thread_spec_up == nullptr)109    m_thread_spec_up = std::make_unique<ThreadSpec>();110 111  return m_thread_spec_up.get();112}113 114void WatchpointOptions::SetThreadID(lldb::tid_t thread_id) {115  GetThreadSpec()->SetTID(thread_id);116}117 118void WatchpointOptions::GetCallbackDescription(119    Stream *s, lldb::DescriptionLevel level) const {120  if (m_callback_baton_sp.get()) {121    s->EOL();122    m_callback_baton_sp->GetDescription(s->AsRawOstream(), level,123                                        s->GetIndentLevel());124  }125}126 127void WatchpointOptions::GetDescription(Stream *s,128                                       lldb::DescriptionLevel level) const {129  // Figure out if there are any options not at their default value, and only130  // print anything if there are:131 132  if ((GetThreadSpecNoCreate() != nullptr &&133       GetThreadSpecNoCreate()->HasSpecification())) {134    if (level == lldb::eDescriptionLevelVerbose) {135      s->EOL();136      s->IndentMore();137      s->Indent();138      s->PutCString("Watchpoint Options:\n");139      s->IndentMore();140      s->Indent();141    } else142      s->PutCString(" Options: ");143 144    if (m_thread_spec_up)145      m_thread_spec_up->GetDescription(s, level);146    else if (level == eDescriptionLevelBrief)147      s->PutCString("thread spec: no ");148    if (level == lldb::eDescriptionLevelFull) {149      s->IndentLess();150      s->IndentMore();151    }152  }153 154  GetCallbackDescription(s, level);155}156 157void WatchpointOptions::CommandBaton::GetDescription(158    llvm::raw_ostream &s, lldb::DescriptionLevel level,159    unsigned indentation) const {160  const CommandData *data = getItem();161 162  if (level == eDescriptionLevelBrief) {163    s << ", commands = %s"164      << ((data && data->user_source.GetSize() > 0) ? "yes" : "no");165    return;166  }167 168  indentation += 2;169  s.indent(indentation);170  s << "watchpoint commands:\n";171 172  indentation += 2;173  if (data && data->user_source.GetSize() > 0) {174    for (const std::string &line : data->user_source) {175      s.indent(indentation);176      s << line << "\n";177    }178  } else179    s << "No commands.\n";180}181