brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.6 KiB · 2feaa5c Raw
468 lines · cpp
1//===-- SBBreakpointLocation.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/SBBreakpointLocation.h"10#include "lldb/API/SBAddress.h"11#include "lldb/API/SBDebugger.h"12#include "lldb/API/SBDefines.h"13#include "lldb/API/SBStream.h"14#include "lldb/API/SBStringList.h"15#include "lldb/API/SBStructuredData.h"16#include "lldb/Utility/Instrumentation.h"17 18#include "lldb/Breakpoint/Breakpoint.h"19#include "lldb/Breakpoint/BreakpointLocation.h"20#include "lldb/Core/Debugger.h"21#include "lldb/Core/StructuredDataImpl.h"22#include "lldb/Interpreter/CommandInterpreter.h"23#include "lldb/Interpreter/ScriptInterpreter.h"24#include "lldb/Target/Target.h"25#include "lldb/Target/ThreadSpec.h"26#include "lldb/Utility/Stream.h"27#include "lldb/lldb-defines.h"28#include "lldb/lldb-types.h"29 30#include "SBBreakpointOptionCommon.h"31 32using namespace lldb;33using namespace lldb_private;34 35SBBreakpointLocation::SBBreakpointLocation() { LLDB_INSTRUMENT_VA(this); }36 37SBBreakpointLocation::SBBreakpointLocation(38    const lldb::BreakpointLocationSP &break_loc_sp)39    : m_opaque_wp(break_loc_sp) {40  LLDB_INSTRUMENT_VA(this, break_loc_sp);41}42 43SBBreakpointLocation::SBBreakpointLocation(const SBBreakpointLocation &rhs)44    : m_opaque_wp(rhs.m_opaque_wp) {45  LLDB_INSTRUMENT_VA(this, rhs);46}47 48const SBBreakpointLocation &SBBreakpointLocation::49operator=(const SBBreakpointLocation &rhs) {50  LLDB_INSTRUMENT_VA(this, rhs);51 52  m_opaque_wp = rhs.m_opaque_wp;53  return *this;54}55 56SBBreakpointLocation::~SBBreakpointLocation() = default;57 58BreakpointLocationSP SBBreakpointLocation::GetSP() const {59  return m_opaque_wp.lock();60}61 62bool SBBreakpointLocation::IsValid() const {63  LLDB_INSTRUMENT_VA(this);64  return this->operator bool();65}66SBBreakpointLocation::operator bool() const {67  LLDB_INSTRUMENT_VA(this);68 69  return bool(GetSP());70}71 72SBAddress SBBreakpointLocation::GetAddress() {73  LLDB_INSTRUMENT_VA(this);74 75  BreakpointLocationSP loc_sp = GetSP();76  if (loc_sp) {77    return SBAddress(loc_sp->GetAddress());78  }79 80  return SBAddress();81}82 83addr_t SBBreakpointLocation::GetLoadAddress() {84  LLDB_INSTRUMENT_VA(this);85 86  addr_t ret_addr = LLDB_INVALID_ADDRESS;87  BreakpointLocationSP loc_sp = GetSP();88 89  if (loc_sp) {90    std::lock_guard<std::recursive_mutex> guard(91        loc_sp->GetTarget().GetAPIMutex());92    ret_addr = loc_sp->GetLoadAddress();93  }94 95  return ret_addr;96}97 98void SBBreakpointLocation::SetEnabled(bool enabled) {99  LLDB_INSTRUMENT_VA(this, enabled);100 101  BreakpointLocationSP loc_sp = GetSP();102  if (loc_sp) {103    std::lock_guard<std::recursive_mutex> guard(104        loc_sp->GetTarget().GetAPIMutex());105    llvm::consumeError(loc_sp->SetEnabled(enabled));106  }107}108 109bool SBBreakpointLocation::IsEnabled() {110  LLDB_INSTRUMENT_VA(this);111 112  BreakpointLocationSP loc_sp = GetSP();113  if (loc_sp) {114    std::lock_guard<std::recursive_mutex> guard(115        loc_sp->GetTarget().GetAPIMutex());116    return loc_sp->IsEnabled();117  } else118    return false;119}120 121uint32_t SBBreakpointLocation::GetHitCount() {122  LLDB_INSTRUMENT_VA(this);123 124  BreakpointLocationSP loc_sp = GetSP();125  if (loc_sp) {126    std::lock_guard<std::recursive_mutex> guard(127        loc_sp->GetTarget().GetAPIMutex());128    return loc_sp->GetHitCount();129  } else130    return 0;131}132 133uint32_t SBBreakpointLocation::GetIgnoreCount() {134  LLDB_INSTRUMENT_VA(this);135 136  BreakpointLocationSP loc_sp = GetSP();137  if (loc_sp) {138    std::lock_guard<std::recursive_mutex> guard(139        loc_sp->GetTarget().GetAPIMutex());140    return loc_sp->GetIgnoreCount();141  } else142    return 0;143}144 145void SBBreakpointLocation::SetIgnoreCount(uint32_t n) {146  LLDB_INSTRUMENT_VA(this, n);147 148  BreakpointLocationSP loc_sp = GetSP();149  if (loc_sp) {150    std::lock_guard<std::recursive_mutex> guard(151        loc_sp->GetTarget().GetAPIMutex());152    loc_sp->SetIgnoreCount(n);153  }154}155 156void SBBreakpointLocation::SetCondition(const char *condition) {157  LLDB_INSTRUMENT_VA(this, condition);158 159  BreakpointLocationSP loc_sp = GetSP();160  if (loc_sp) {161    std::lock_guard<std::recursive_mutex> guard(162        loc_sp->GetTarget().GetAPIMutex());163    // Treat a nullptr as clearing the condition164    if (!condition)165      loc_sp->SetCondition(StopCondition());166    else167      loc_sp->SetCondition(StopCondition(condition));168  }169}170 171const char *SBBreakpointLocation::GetCondition() {172  LLDB_INSTRUMENT_VA(this);173 174  BreakpointLocationSP loc_sp = GetSP();175  if (!loc_sp)176    return nullptr;177 178  std::lock_guard<std::recursive_mutex> guard(179      loc_sp->GetTarget().GetAPIMutex());180  StopCondition cond = loc_sp->GetCondition();181  if (!cond)182    return nullptr;183  return ConstString(cond.GetText()).GetCString();184}185 186void SBBreakpointLocation::SetAutoContinue(bool auto_continue) {187  LLDB_INSTRUMENT_VA(this, auto_continue);188 189  BreakpointLocationSP loc_sp = GetSP();190  if (loc_sp) {191    std::lock_guard<std::recursive_mutex> guard(192        loc_sp->GetTarget().GetAPIMutex());193    loc_sp->SetAutoContinue(auto_continue);194  }195}196 197bool SBBreakpointLocation::GetAutoContinue() {198  LLDB_INSTRUMENT_VA(this);199 200  BreakpointLocationSP loc_sp = GetSP();201  if (loc_sp) {202    std::lock_guard<std::recursive_mutex> guard(203        loc_sp->GetTarget().GetAPIMutex());204    return loc_sp->IsAutoContinue();205  }206  return false;207}208 209void SBBreakpointLocation::SetCallback(SBBreakpointHitCallback callback,210                                       void *baton) {211  LLDB_INSTRUMENT_VA(this, callback, baton);212 213  BreakpointLocationSP loc_sp = GetSP();214 215  if (loc_sp) {216    std::lock_guard<std::recursive_mutex> guard(217        loc_sp->GetTarget().GetAPIMutex());218    BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton));219    loc_sp->SetCallback(SBBreakpointCallbackBaton::PrivateBreakpointHitCallback,220                        baton_sp, false);221  }222}223 224void SBBreakpointLocation::SetScriptCallbackFunction(225  const char *callback_function_name) {226  LLDB_INSTRUMENT_VA(this, callback_function_name);227}228 229SBError SBBreakpointLocation::SetScriptCallbackFunction(230    const char *callback_function_name,231    SBStructuredData &extra_args) {232  LLDB_INSTRUMENT_VA(this, callback_function_name, extra_args);233  SBError sb_error;234  BreakpointLocationSP loc_sp = GetSP();235 236  if (loc_sp) {237    Status error;238    std::lock_guard<std::recursive_mutex> guard(239        loc_sp->GetTarget().GetAPIMutex());240    BreakpointOptions &bp_options = loc_sp->GetLocationOptions();241    error = loc_sp->GetBreakpoint()242        .GetTarget()243        .GetDebugger()244        .GetScriptInterpreter()245        ->SetBreakpointCommandCallbackFunction(bp_options,246                                               callback_function_name,247                                               extra_args.m_impl_up248                                                   ->GetObjectSP());249    sb_error.SetError(std::move(error));250    } else251      sb_error = Status::FromErrorString("invalid breakpoint");252 253    return sb_error;254}255 256SBError257SBBreakpointLocation::SetScriptCallbackBody(const char *callback_body_text) {258  LLDB_INSTRUMENT_VA(this, callback_body_text);259 260  BreakpointLocationSP loc_sp = GetSP();261 262  SBError sb_error;263  if (loc_sp) {264    std::lock_guard<std::recursive_mutex> guard(265        loc_sp->GetTarget().GetAPIMutex());266    BreakpointOptions &bp_options = loc_sp->GetLocationOptions();267    Status error =268        loc_sp->GetBreakpoint()269            .GetTarget()270            .GetDebugger()271            .GetScriptInterpreter()272            ->SetBreakpointCommandCallback(bp_options, callback_body_text,273                                           /*is_callback=*/false);274    sb_error.SetError(std::move(error));275  } else276    sb_error = Status::FromErrorString("invalid breakpoint");277 278  return sb_error;279}280 281void SBBreakpointLocation::SetCommandLineCommands(SBStringList &commands) {282  LLDB_INSTRUMENT_VA(this, commands);283 284  BreakpointLocationSP loc_sp = GetSP();285  if (!loc_sp)286    return;287  if (commands.GetSize() == 0)288    return;289 290  std::lock_guard<std::recursive_mutex> guard(291      loc_sp->GetTarget().GetAPIMutex());292  std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up(293      new BreakpointOptions::CommandData(*commands, eScriptLanguageNone));294 295  loc_sp->GetLocationOptions().SetCommandDataCallback(cmd_data_up);296}297 298bool SBBreakpointLocation::GetCommandLineCommands(SBStringList &commands) {299  LLDB_INSTRUMENT_VA(this, commands);300 301  BreakpointLocationSP loc_sp = GetSP();302  if (!loc_sp)303    return false;304  StringList command_list;305  bool has_commands =306      loc_sp->GetLocationOptions().GetCommandLineCallbacks(command_list);307  if (has_commands)308    commands.AppendList(command_list);309  return has_commands;310}311 312void SBBreakpointLocation::SetThreadID(lldb::tid_t thread_id) {313  LLDB_INSTRUMENT_VA(this, thread_id);314 315  BreakpointLocationSP loc_sp = GetSP();316  if (loc_sp) {317    std::lock_guard<std::recursive_mutex> guard(318        loc_sp->GetTarget().GetAPIMutex());319    loc_sp->SetThreadID(thread_id);320  }321}322 323lldb::tid_t SBBreakpointLocation::GetThreadID() {324  LLDB_INSTRUMENT_VA(this);325 326  lldb::tid_t tid = LLDB_INVALID_THREAD_ID;327  BreakpointLocationSP loc_sp = GetSP();328  if (loc_sp) {329    std::lock_guard<std::recursive_mutex> guard(330        loc_sp->GetTarget().GetAPIMutex());331    return loc_sp->GetThreadID();332  }333  return tid;334}335 336void SBBreakpointLocation::SetThreadIndex(uint32_t index) {337  LLDB_INSTRUMENT_VA(this, index);338 339  BreakpointLocationSP loc_sp = GetSP();340  if (loc_sp) {341    std::lock_guard<std::recursive_mutex> guard(342        loc_sp->GetTarget().GetAPIMutex());343    loc_sp->SetThreadIndex(index);344  }345}346 347uint32_t SBBreakpointLocation::GetThreadIndex() const {348  LLDB_INSTRUMENT_VA(this);349 350  uint32_t thread_idx = UINT32_MAX;351  BreakpointLocationSP loc_sp = GetSP();352  if (loc_sp) {353    std::lock_guard<std::recursive_mutex> guard(354        loc_sp->GetTarget().GetAPIMutex());355    return loc_sp->GetThreadIndex();356  }357  return thread_idx;358}359 360void SBBreakpointLocation::SetThreadName(const char *thread_name) {361  LLDB_INSTRUMENT_VA(this, thread_name);362 363  BreakpointLocationSP loc_sp = GetSP();364  if (loc_sp) {365    std::lock_guard<std::recursive_mutex> guard(366        loc_sp->GetTarget().GetAPIMutex());367    loc_sp->SetThreadName(thread_name);368  }369}370 371const char *SBBreakpointLocation::GetThreadName() const {372  LLDB_INSTRUMENT_VA(this);373 374  BreakpointLocationSP loc_sp = GetSP();375  if (!loc_sp)376    return nullptr;377 378  std::lock_guard<std::recursive_mutex> guard(379      loc_sp->GetTarget().GetAPIMutex());380  return ConstString(loc_sp->GetThreadName()).GetCString();381}382 383void SBBreakpointLocation::SetQueueName(const char *queue_name) {384  LLDB_INSTRUMENT_VA(this, queue_name);385 386  BreakpointLocationSP loc_sp = GetSP();387  if (loc_sp) {388    std::lock_guard<std::recursive_mutex> guard(389        loc_sp->GetTarget().GetAPIMutex());390    loc_sp->SetQueueName(queue_name);391  }392}393 394const char *SBBreakpointLocation::GetQueueName() const {395  LLDB_INSTRUMENT_VA(this);396 397  BreakpointLocationSP loc_sp = GetSP();398  if (!loc_sp)399    return nullptr;400 401  std::lock_guard<std::recursive_mutex> guard(402      loc_sp->GetTarget().GetAPIMutex());403  return ConstString(loc_sp->GetQueueName()).GetCString();404}405 406bool SBBreakpointLocation::IsResolved() {407  LLDB_INSTRUMENT_VA(this);408 409  BreakpointLocationSP loc_sp = GetSP();410  if (loc_sp) {411    std::lock_guard<std::recursive_mutex> guard(412        loc_sp->GetTarget().GetAPIMutex());413    return loc_sp->IsResolved();414  }415  return false;416}417 418void SBBreakpointLocation::SetLocation(419    const lldb::BreakpointLocationSP &break_loc_sp) {420  // Uninstall the callbacks?421  m_opaque_wp = break_loc_sp;422}423 424bool SBBreakpointLocation::GetDescription(SBStream &description,425                                          DescriptionLevel level) {426  LLDB_INSTRUMENT_VA(this, description, level);427 428  Stream &strm = description.ref();429  BreakpointLocationSP loc_sp = GetSP();430 431  if (loc_sp) {432    std::lock_guard<std::recursive_mutex> guard(433        loc_sp->GetTarget().GetAPIMutex());434    loc_sp->GetDescription(&strm, level);435    strm.EOL();436  } else437    strm.PutCString("No value");438 439  return true;440}441 442break_id_t SBBreakpointLocation::GetID() {443  LLDB_INSTRUMENT_VA(this);444 445  BreakpointLocationSP loc_sp = GetSP();446  if (loc_sp) {447    std::lock_guard<std::recursive_mutex> guard(448        loc_sp->GetTarget().GetAPIMutex());449    return loc_sp->GetID();450  } else451    return LLDB_INVALID_BREAK_ID;452}453 454SBBreakpoint SBBreakpointLocation::GetBreakpoint() {455  LLDB_INSTRUMENT_VA(this);456 457  BreakpointLocationSP loc_sp = GetSP();458 459  SBBreakpoint sb_bp;460  if (loc_sp) {461    std::lock_guard<std::recursive_mutex> guard(462        loc_sp->GetTarget().GetAPIMutex());463    sb_bp = loc_sp->GetBreakpoint().shared_from_this();464  }465 466  return sb_bp;467}468