brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.2 KiB · 21e2dcc Raw
358 lines · cpp
1//===-- SBWatchpoint.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/API/SBWatchpoint.h"10#include "lldb/API/SBAddress.h"11#include "lldb/API/SBDebugger.h"12#include "lldb/API/SBDefines.h"13#include "lldb/API/SBEvent.h"14#include "lldb/API/SBStream.h"15#include "lldb/Utility/Instrumentation.h"16 17#include "lldb/Breakpoint/Watchpoint.h"18#include "lldb/Breakpoint/WatchpointList.h"19#include "lldb/Symbol/CompilerType.h"20#include "lldb/Target/Process.h"21#include "lldb/Target/Target.h"22#include "lldb/Utility/Stream.h"23#include "lldb/lldb-defines.h"24#include "lldb/lldb-types.h"25 26using namespace lldb;27using namespace lldb_private;28 29SBWatchpoint::SBWatchpoint() { LLDB_INSTRUMENT_VA(this); }30 31SBWatchpoint::SBWatchpoint(const lldb::WatchpointSP &wp_sp)32    : m_opaque_wp(wp_sp) {33  LLDB_INSTRUMENT_VA(this, wp_sp);34}35 36SBWatchpoint::SBWatchpoint(const SBWatchpoint &rhs)37    : m_opaque_wp(rhs.m_opaque_wp) {38  LLDB_INSTRUMENT_VA(this, rhs);39}40 41const SBWatchpoint &SBWatchpoint::operator=(const SBWatchpoint &rhs) {42  LLDB_INSTRUMENT_VA(this, rhs);43 44  m_opaque_wp = rhs.m_opaque_wp;45  return *this;46}47 48SBWatchpoint::~SBWatchpoint() = default;49 50watch_id_t SBWatchpoint::GetID() {51  LLDB_INSTRUMENT_VA(this);52 53  watch_id_t watch_id = LLDB_INVALID_WATCH_ID;54  lldb::WatchpointSP watchpoint_sp(GetSP());55  if (watchpoint_sp)56    watch_id = watchpoint_sp->GetID();57 58  return watch_id;59}60 61bool SBWatchpoint::IsValid() const {62  LLDB_INSTRUMENT_VA(this);63  return this->operator bool();64}65SBWatchpoint::operator bool() const {66  LLDB_INSTRUMENT_VA(this);67 68  return bool(m_opaque_wp.lock());69}70 71bool SBWatchpoint::operator==(const SBWatchpoint &rhs) const {72  LLDB_INSTRUMENT_VA(this, rhs);73 74  return GetSP() == rhs.GetSP();75}76 77bool SBWatchpoint::operator!=(const SBWatchpoint &rhs) const {78  LLDB_INSTRUMENT_VA(this, rhs);79 80  return !(*this == rhs);81}82 83SBError SBWatchpoint::GetError() {84  LLDB_INSTRUMENT_VA(this);85 86  SBError sb_error;87  lldb::WatchpointSP watchpoint_sp(GetSP());88  if (watchpoint_sp) {89    sb_error.SetError(watchpoint_sp->GetError().Clone());90  }91  return sb_error;92}93 94int32_t SBWatchpoint::GetHardwareIndex() {95  LLDB_INSTRUMENT_VA(this);96 97  // For processes using gdb remote protocol,98  // we cannot determine the hardware breakpoint99  // index reliably; providing possibly correct100  // guesses is not useful to anyone.101  return -1;102}103 104addr_t SBWatchpoint::GetWatchAddress() {105  LLDB_INSTRUMENT_VA(this);106 107  addr_t ret_addr = LLDB_INVALID_ADDRESS;108 109  lldb::WatchpointSP watchpoint_sp(GetSP());110  if (watchpoint_sp) {111    std::lock_guard<std::recursive_mutex> guard(112        watchpoint_sp->GetTarget().GetAPIMutex());113    ret_addr = watchpoint_sp->GetLoadAddress();114  }115 116  return ret_addr;117}118 119size_t SBWatchpoint::GetWatchSize() {120  LLDB_INSTRUMENT_VA(this);121 122  size_t watch_size = 0;123 124  lldb::WatchpointSP watchpoint_sp(GetSP());125  if (watchpoint_sp) {126    std::lock_guard<std::recursive_mutex> guard(127        watchpoint_sp->GetTarget().GetAPIMutex());128    watch_size = watchpoint_sp->GetByteSize();129  }130 131  return watch_size;132}133 134void SBWatchpoint::SetEnabled(bool enabled) {135  LLDB_INSTRUMENT_VA(this, enabled);136 137  lldb::WatchpointSP watchpoint_sp(GetSP());138  if (watchpoint_sp) {139    Target &target = watchpoint_sp->GetTarget();140    std::lock_guard<std::recursive_mutex> guard(target.GetAPIMutex());141    ProcessSP process_sp = target.GetProcessSP();142    const bool notify = true;143    if (process_sp) {144      if (enabled)145        process_sp->EnableWatchpoint(watchpoint_sp, notify);146      else147        process_sp->DisableWatchpoint(watchpoint_sp, notify);148    } else {149      watchpoint_sp->SetEnabled(enabled, notify);150    }151  }152}153 154bool SBWatchpoint::IsEnabled() {155  LLDB_INSTRUMENT_VA(this);156 157  lldb::WatchpointSP watchpoint_sp(GetSP());158  if (watchpoint_sp) {159    std::lock_guard<std::recursive_mutex> guard(160        watchpoint_sp->GetTarget().GetAPIMutex());161    return watchpoint_sp->IsEnabled();162  } else163    return false;164}165 166uint32_t SBWatchpoint::GetHitCount() {167  LLDB_INSTRUMENT_VA(this);168 169  uint32_t count = 0;170  lldb::WatchpointSP watchpoint_sp(GetSP());171  if (watchpoint_sp) {172    std::lock_guard<std::recursive_mutex> guard(173        watchpoint_sp->GetTarget().GetAPIMutex());174    count = watchpoint_sp->GetHitCount();175  }176 177  return count;178}179 180uint32_t SBWatchpoint::GetIgnoreCount() {181  LLDB_INSTRUMENT_VA(this);182 183  lldb::WatchpointSP watchpoint_sp(GetSP());184  if (watchpoint_sp) {185    std::lock_guard<std::recursive_mutex> guard(186        watchpoint_sp->GetTarget().GetAPIMutex());187    return watchpoint_sp->GetIgnoreCount();188  } else189    return 0;190}191 192void SBWatchpoint::SetIgnoreCount(uint32_t n) {193  LLDB_INSTRUMENT_VA(this, n);194 195  lldb::WatchpointSP watchpoint_sp(GetSP());196  if (watchpoint_sp) {197    std::lock_guard<std::recursive_mutex> guard(198        watchpoint_sp->GetTarget().GetAPIMutex());199    watchpoint_sp->SetIgnoreCount(n);200  }201}202 203const char *SBWatchpoint::GetCondition() {204  LLDB_INSTRUMENT_VA(this);205 206  lldb::WatchpointSP watchpoint_sp(GetSP());207  if (!watchpoint_sp)208    return nullptr;209 210  std::lock_guard<std::recursive_mutex> guard(211      watchpoint_sp->GetTarget().GetAPIMutex());212  return ConstString(watchpoint_sp->GetConditionText()).GetCString();213}214 215void SBWatchpoint::SetCondition(const char *condition) {216  LLDB_INSTRUMENT_VA(this, condition);217 218  lldb::WatchpointSP watchpoint_sp(GetSP());219  if (watchpoint_sp) {220    std::lock_guard<std::recursive_mutex> guard(221        watchpoint_sp->GetTarget().GetAPIMutex());222    watchpoint_sp->SetCondition(condition);223  }224}225 226bool SBWatchpoint::GetDescription(SBStream &description,227                                  DescriptionLevel level) {228  LLDB_INSTRUMENT_VA(this, description, level);229 230  Stream &strm = description.ref();231 232  lldb::WatchpointSP watchpoint_sp(GetSP());233  if (watchpoint_sp) {234    std::lock_guard<std::recursive_mutex> guard(235        watchpoint_sp->GetTarget().GetAPIMutex());236    watchpoint_sp->GetDescription(&strm, level);237    strm.EOL();238  } else239    strm.PutCString("No value");240 241  return true;242}243 244void SBWatchpoint::Clear() {245  LLDB_INSTRUMENT_VA(this);246 247  m_opaque_wp.reset();248}249 250lldb::WatchpointSP SBWatchpoint::GetSP() const {251  LLDB_INSTRUMENT_VA(this);252 253  return m_opaque_wp.lock();254}255 256void SBWatchpoint::SetSP(const lldb::WatchpointSP &sp) {257  LLDB_INSTRUMENT_VA(this, sp);258 259  m_opaque_wp = sp;260}261 262bool SBWatchpoint::EventIsWatchpointEvent(const lldb::SBEvent &event) {263  LLDB_INSTRUMENT_VA(event);264 265  return Watchpoint::WatchpointEventData::GetEventDataFromEvent(event.get()) !=266         nullptr;267}268 269WatchpointEventType270SBWatchpoint::GetWatchpointEventTypeFromEvent(const SBEvent &event) {271  LLDB_INSTRUMENT_VA(event);272 273  if (event.IsValid())274    return Watchpoint::WatchpointEventData::GetWatchpointEventTypeFromEvent(275        event.GetSP());276  return eWatchpointEventTypeInvalidType;277}278 279SBWatchpoint SBWatchpoint::GetWatchpointFromEvent(const lldb::SBEvent &event) {280  LLDB_INSTRUMENT_VA(event);281 282  SBWatchpoint sb_watchpoint;283  if (event.IsValid())284    sb_watchpoint =285        Watchpoint::WatchpointEventData::GetWatchpointFromEvent(event.GetSP());286  return sb_watchpoint;287}288 289lldb::SBType SBWatchpoint::GetType() {290  LLDB_INSTRUMENT_VA(this);291 292  lldb::WatchpointSP watchpoint_sp(GetSP());293  if (watchpoint_sp) {294    std::lock_guard<std::recursive_mutex> guard(295        watchpoint_sp->GetTarget().GetAPIMutex());296    const CompilerType &type = watchpoint_sp->GetCompilerType();297    return lldb::SBType(type);298  }299  return lldb::SBType();300}301 302WatchpointValueKind SBWatchpoint::GetWatchValueKind() {303  LLDB_INSTRUMENT_VA(this);304 305  lldb::WatchpointSP watchpoint_sp(GetSP());306  if (watchpoint_sp) {307    std::lock_guard<std::recursive_mutex> guard(308        watchpoint_sp->GetTarget().GetAPIMutex());309    if (watchpoint_sp->IsWatchVariable())310      return WatchpointValueKind::eWatchPointValueKindVariable;311    return WatchpointValueKind::eWatchPointValueKindExpression;312  }313  return WatchpointValueKind::eWatchPointValueKindInvalid;314}315 316const char *SBWatchpoint::GetWatchSpec() {317  LLDB_INSTRUMENT_VA(this);318 319  lldb::WatchpointSP watchpoint_sp(GetSP());320  if (!watchpoint_sp)321    return nullptr;322 323  std::lock_guard<std::recursive_mutex> guard(324      watchpoint_sp->GetTarget().GetAPIMutex());325  // Store the result of `GetWatchSpec()` as a ConstString326  // so that the C string we return has a sufficiently long327  // lifetime. Note this a memory leak but should be fairly328  // low impact.329  return ConstString(watchpoint_sp->GetWatchSpec()).AsCString();330}331 332bool SBWatchpoint::IsWatchingReads() {333  LLDB_INSTRUMENT_VA(this);334  lldb::WatchpointSP watchpoint_sp(GetSP());335  if (watchpoint_sp) {336    std::lock_guard<std::recursive_mutex> guard(337        watchpoint_sp->GetTarget().GetAPIMutex());338 339    return watchpoint_sp->WatchpointRead();340  }341 342  return false;343}344 345bool SBWatchpoint::IsWatchingWrites() {346  LLDB_INSTRUMENT_VA(this);347  lldb::WatchpointSP watchpoint_sp(GetSP());348  if (watchpoint_sp) {349    std::lock_guard<std::recursive_mutex> guard(350        watchpoint_sp->GetTarget().GetAPIMutex());351 352    return watchpoint_sp->WatchpointWrite() ||353           watchpoint_sp->WatchpointModify();354  }355 356  return false;357}358