diff options
Diffstat (limited to 'contrib/llvm-project/lldb/source/API/SBBreakpoint.cpp')
| -rw-r--r-- | contrib/llvm-project/lldb/source/API/SBBreakpoint.cpp | 1067 | 
1 files changed, 1067 insertions, 0 deletions
| diff --git a/contrib/llvm-project/lldb/source/API/SBBreakpoint.cpp b/contrib/llvm-project/lldb/source/API/SBBreakpoint.cpp new file mode 100644 index 000000000000..eb75bf8b33f4 --- /dev/null +++ b/contrib/llvm-project/lldb/source/API/SBBreakpoint.cpp @@ -0,0 +1,1067 @@ +//===-- SBBreakpoint.cpp --------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/API/SBBreakpoint.h" +#include "SBReproducerPrivate.h" +#include "lldb/API/SBBreakpointLocation.h" +#include "lldb/API/SBDebugger.h" +#include "lldb/API/SBEvent.h" +#include "lldb/API/SBProcess.h" +#include "lldb/API/SBStream.h" +#include "lldb/API/SBStringList.h" +#include "lldb/API/SBStructuredData.h" +#include "lldb/API/SBThread.h" + +#include "lldb/Breakpoint/Breakpoint.h" +#include "lldb/Breakpoint/BreakpointIDList.h" +#include "lldb/Breakpoint/BreakpointLocation.h" +#include "lldb/Breakpoint/BreakpointResolver.h" +#include "lldb/Breakpoint/BreakpointResolverScripted.h" +#include "lldb/Breakpoint/StoppointCallbackContext.h" +#include "lldb/Core/Address.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Core/StructuredDataImpl.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/ScriptInterpreter.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/SectionLoadList.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Target/ThreadSpec.h" +#include "lldb/Utility/Stream.h" + +#include "SBBreakpointOptionCommon.h" + +#include "lldb/lldb-enumerations.h" + +#include "llvm/ADT/STLExtras.h" + +using namespace lldb; +using namespace lldb_private; + +SBBreakpoint::SBBreakpoint() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBBreakpoint); } + +SBBreakpoint::SBBreakpoint(const SBBreakpoint &rhs) +    : m_opaque_wp(rhs.m_opaque_wp) { +  LLDB_RECORD_CONSTRUCTOR(SBBreakpoint, (const lldb::SBBreakpoint &), rhs); +} + +SBBreakpoint::SBBreakpoint(const lldb::BreakpointSP &bp_sp) +    : m_opaque_wp(bp_sp) { +  LLDB_RECORD_CONSTRUCTOR(SBBreakpoint, (const lldb::BreakpointSP &), bp_sp); +} + +SBBreakpoint::~SBBreakpoint() = default; + +const SBBreakpoint &SBBreakpoint::operator=(const SBBreakpoint &rhs) { +  LLDB_RECORD_METHOD(const lldb::SBBreakpoint &, +                     SBBreakpoint, operator=,(const lldb::SBBreakpoint &), rhs); + +  m_opaque_wp = rhs.m_opaque_wp; +  return LLDB_RECORD_RESULT(*this); +} + +bool SBBreakpoint::operator==(const lldb::SBBreakpoint &rhs) { +  LLDB_RECORD_METHOD( +      bool, SBBreakpoint, operator==,(const lldb::SBBreakpoint &), rhs); + +  return m_opaque_wp.lock() == rhs.m_opaque_wp.lock(); +} + +bool SBBreakpoint::operator!=(const lldb::SBBreakpoint &rhs) { +  LLDB_RECORD_METHOD( +      bool, SBBreakpoint, operator!=,(const lldb::SBBreakpoint &), rhs); + +  return m_opaque_wp.lock() != rhs.m_opaque_wp.lock(); +} + +break_id_t SBBreakpoint::GetID() const { +  LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::break_id_t, SBBreakpoint, GetID); + +  break_id_t break_id = LLDB_INVALID_BREAK_ID; +  BreakpointSP bkpt_sp = GetSP(); +  if (bkpt_sp) +    break_id = bkpt_sp->GetID(); + +  return break_id; +} + +bool SBBreakpoint::IsValid() const { +  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBreakpoint, IsValid); +  return this->operator bool(); +} +SBBreakpoint::operator bool() const { +  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBreakpoint, operator bool); + +  BreakpointSP bkpt_sp = GetSP(); +  if (!bkpt_sp) +    return false; +  else if (bkpt_sp->GetTarget().GetBreakpointByID(bkpt_sp->GetID())) +    return true; +  else +    return false; +} + +void SBBreakpoint::ClearAllBreakpointSites() { +  LLDB_RECORD_METHOD_NO_ARGS(void, SBBreakpoint, ClearAllBreakpointSites); + +  BreakpointSP bkpt_sp = GetSP(); +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    bkpt_sp->ClearAllBreakpointSites(); +  } +} + +SBBreakpointLocation SBBreakpoint::FindLocationByAddress(addr_t vm_addr) { +  LLDB_RECORD_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, +                     FindLocationByAddress, (lldb::addr_t), vm_addr); + +  SBBreakpointLocation sb_bp_location; + +  BreakpointSP bkpt_sp = GetSP(); +  if (bkpt_sp) { +    if (vm_addr != LLDB_INVALID_ADDRESS) { +      std::lock_guard<std::recursive_mutex> guard( +          bkpt_sp->GetTarget().GetAPIMutex()); +      Address address; +      Target &target = bkpt_sp->GetTarget(); +      if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) { +        address.SetRawAddress(vm_addr); +      } +      sb_bp_location.SetLocation(bkpt_sp->FindLocationByAddress(address)); +    } +  } +  return LLDB_RECORD_RESULT(sb_bp_location); +} + +break_id_t SBBreakpoint::FindLocationIDByAddress(addr_t vm_addr) { +  LLDB_RECORD_METHOD(lldb::break_id_t, SBBreakpoint, FindLocationIDByAddress, +                     (lldb::addr_t), vm_addr); + +  break_id_t break_id = LLDB_INVALID_BREAK_ID; +  BreakpointSP bkpt_sp = GetSP(); + +  if (bkpt_sp && vm_addr != LLDB_INVALID_ADDRESS) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    Address address; +    Target &target = bkpt_sp->GetTarget(); +    if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) { +      address.SetRawAddress(vm_addr); +    } +    break_id = bkpt_sp->FindLocationIDByAddress(address); +  } + +  return break_id; +} + +SBBreakpointLocation SBBreakpoint::FindLocationByID(break_id_t bp_loc_id) { +  LLDB_RECORD_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, FindLocationByID, +                     (lldb::break_id_t), bp_loc_id); + +  SBBreakpointLocation sb_bp_location; +  BreakpointSP bkpt_sp = GetSP(); + +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    sb_bp_location.SetLocation(bkpt_sp->FindLocationByID(bp_loc_id)); +  } + +  return LLDB_RECORD_RESULT(sb_bp_location); +} + +SBBreakpointLocation SBBreakpoint::GetLocationAtIndex(uint32_t index) { +  LLDB_RECORD_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, +                     GetLocationAtIndex, (uint32_t), index); + +  SBBreakpointLocation sb_bp_location; +  BreakpointSP bkpt_sp = GetSP(); + +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    sb_bp_location.SetLocation(bkpt_sp->GetLocationAtIndex(index)); +  } + +  return LLDB_RECORD_RESULT(sb_bp_location); +} + +void SBBreakpoint::SetEnabled(bool enable) { +  LLDB_RECORD_METHOD(void, SBBreakpoint, SetEnabled, (bool), enable); + +  BreakpointSP bkpt_sp = GetSP(); + +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    bkpt_sp->SetEnabled(enable); +  } +} + +bool SBBreakpoint::IsEnabled() { +  LLDB_RECORD_METHOD_NO_ARGS(bool, SBBreakpoint, IsEnabled); + +  BreakpointSP bkpt_sp = GetSP(); +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    return bkpt_sp->IsEnabled(); +  } else +    return false; +} + +void SBBreakpoint::SetOneShot(bool one_shot) { +  LLDB_RECORD_METHOD(void, SBBreakpoint, SetOneShot, (bool), one_shot); + +  BreakpointSP bkpt_sp = GetSP(); + +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    bkpt_sp->SetOneShot(one_shot); +  } +} + +bool SBBreakpoint::IsOneShot() const { +  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBreakpoint, IsOneShot); + +  BreakpointSP bkpt_sp = GetSP(); +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    return bkpt_sp->IsOneShot(); +  } else +    return false; +} + +bool SBBreakpoint::IsInternal() { +  LLDB_RECORD_METHOD_NO_ARGS(bool, SBBreakpoint, IsInternal); + +  BreakpointSP bkpt_sp = GetSP(); +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    return bkpt_sp->IsInternal(); +  } else +    return false; +} + +void SBBreakpoint::SetIgnoreCount(uint32_t count) { +  LLDB_RECORD_METHOD(void, SBBreakpoint, SetIgnoreCount, (uint32_t), count); + +  BreakpointSP bkpt_sp = GetSP(); + +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    bkpt_sp->SetIgnoreCount(count); +  } +} + +void SBBreakpoint::SetCondition(const char *condition) { +  LLDB_RECORD_METHOD(void, SBBreakpoint, SetCondition, (const char *), +                     condition); + +  BreakpointSP bkpt_sp = GetSP(); +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    bkpt_sp->SetCondition(condition); +  } +} + +const char *SBBreakpoint::GetCondition() { +  LLDB_RECORD_METHOD_NO_ARGS(const char *, SBBreakpoint, GetCondition); + +  BreakpointSP bkpt_sp = GetSP(); +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    return bkpt_sp->GetConditionText(); +  } +  return nullptr; +} + +void SBBreakpoint::SetAutoContinue(bool auto_continue) { +  LLDB_RECORD_METHOD(void, SBBreakpoint, SetAutoContinue, (bool), +                     auto_continue); + +  BreakpointSP bkpt_sp = GetSP(); +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    bkpt_sp->SetAutoContinue(auto_continue); +  } +} + +bool SBBreakpoint::GetAutoContinue() { +  LLDB_RECORD_METHOD_NO_ARGS(bool, SBBreakpoint, GetAutoContinue); + +  BreakpointSP bkpt_sp = GetSP(); +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    return bkpt_sp->IsAutoContinue(); +  } +  return false; +} + +uint32_t SBBreakpoint::GetHitCount() const { +  LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBBreakpoint, GetHitCount); + +  uint32_t count = 0; +  BreakpointSP bkpt_sp = GetSP(); +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    count = bkpt_sp->GetHitCount(); +  } + +  return count; +} + +uint32_t SBBreakpoint::GetIgnoreCount() const { +  LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBBreakpoint, GetIgnoreCount); + +  uint32_t count = 0; +  BreakpointSP bkpt_sp = GetSP(); +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    count = bkpt_sp->GetIgnoreCount(); +  } + +  return count; +} + +void SBBreakpoint::SetThreadID(tid_t tid) { +  LLDB_RECORD_METHOD(void, SBBreakpoint, SetThreadID, (lldb::tid_t), tid); + +  BreakpointSP bkpt_sp = GetSP(); +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    bkpt_sp->SetThreadID(tid); +  } +} + +tid_t SBBreakpoint::GetThreadID() { +  LLDB_RECORD_METHOD_NO_ARGS(lldb::tid_t, SBBreakpoint, GetThreadID); + +  tid_t tid = LLDB_INVALID_THREAD_ID; +  BreakpointSP bkpt_sp = GetSP(); +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    tid = bkpt_sp->GetThreadID(); +  } + +  return tid; +} + +void SBBreakpoint::SetThreadIndex(uint32_t index) { +  LLDB_RECORD_METHOD(void, SBBreakpoint, SetThreadIndex, (uint32_t), index); + +  BreakpointSP bkpt_sp = GetSP(); +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    bkpt_sp->GetOptions()->GetThreadSpec()->SetIndex(index); +  } +} + +uint32_t SBBreakpoint::GetThreadIndex() const { +  LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBBreakpoint, GetThreadIndex); + +  uint32_t thread_idx = UINT32_MAX; +  BreakpointSP bkpt_sp = GetSP(); +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    const ThreadSpec *thread_spec = +        bkpt_sp->GetOptions()->GetThreadSpecNoCreate(); +    if (thread_spec != nullptr) +      thread_idx = thread_spec->GetIndex(); +  } + +  return thread_idx; +} + +void SBBreakpoint::SetThreadName(const char *thread_name) { +  LLDB_RECORD_METHOD(void, SBBreakpoint, SetThreadName, (const char *), +                     thread_name); + +  BreakpointSP bkpt_sp = GetSP(); + +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    bkpt_sp->GetOptions()->GetThreadSpec()->SetName(thread_name); +  } +} + +const char *SBBreakpoint::GetThreadName() const { +  LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBBreakpoint, GetThreadName); + +  const char *name = nullptr; +  BreakpointSP bkpt_sp = GetSP(); +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    const ThreadSpec *thread_spec = +        bkpt_sp->GetOptions()->GetThreadSpecNoCreate(); +    if (thread_spec != nullptr) +      name = thread_spec->GetName(); +  } + +  return name; +} + +void SBBreakpoint::SetQueueName(const char *queue_name) { +  LLDB_RECORD_METHOD(void, SBBreakpoint, SetQueueName, (const char *), +                     queue_name); + +  BreakpointSP bkpt_sp = GetSP(); +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    bkpt_sp->GetOptions()->GetThreadSpec()->SetQueueName(queue_name); +  } +} + +const char *SBBreakpoint::GetQueueName() const { +  LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBBreakpoint, GetQueueName); + +  const char *name = nullptr; +  BreakpointSP bkpt_sp = GetSP(); +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    const ThreadSpec *thread_spec = +        bkpt_sp->GetOptions()->GetThreadSpecNoCreate(); +    if (thread_spec) +      name = thread_spec->GetQueueName(); +  } + +  return name; +} + +size_t SBBreakpoint::GetNumResolvedLocations() const { +  LLDB_RECORD_METHOD_CONST_NO_ARGS(size_t, SBBreakpoint, +                                   GetNumResolvedLocations); + +  size_t num_resolved = 0; +  BreakpointSP bkpt_sp = GetSP(); +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    num_resolved = bkpt_sp->GetNumResolvedLocations(); +  } +  return num_resolved; +} + +size_t SBBreakpoint::GetNumLocations() const { +  LLDB_RECORD_METHOD_CONST_NO_ARGS(size_t, SBBreakpoint, GetNumLocations); + +  BreakpointSP bkpt_sp = GetSP(); +  size_t num_locs = 0; +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    num_locs = bkpt_sp->GetNumLocations(); +  } +  return num_locs; +} + +void SBBreakpoint::SetCommandLineCommands(SBStringList &commands) { +  LLDB_RECORD_METHOD(void, SBBreakpoint, SetCommandLineCommands, +                     (lldb::SBStringList &), commands); + +  BreakpointSP bkpt_sp = GetSP(); +  if (!bkpt_sp) +    return; +  if (commands.GetSize() == 0) +    return; + +  std::lock_guard<std::recursive_mutex> guard( +      bkpt_sp->GetTarget().GetAPIMutex()); +  std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up( +      new BreakpointOptions::CommandData(*commands, eScriptLanguageNone)); + +  bkpt_sp->GetOptions()->SetCommandDataCallback(cmd_data_up); +} + +bool SBBreakpoint::GetCommandLineCommands(SBStringList &commands) { +  LLDB_RECORD_METHOD(bool, SBBreakpoint, GetCommandLineCommands, +                     (lldb::SBStringList &), commands); + +  BreakpointSP bkpt_sp = GetSP(); +  if (!bkpt_sp) +    return false; +  StringList command_list; +  bool has_commands = +      bkpt_sp->GetOptions()->GetCommandLineCallbacks(command_list); +  if (has_commands) +    commands.AppendList(command_list); +  return has_commands; +} + +bool SBBreakpoint::GetDescription(SBStream &s) { +  LLDB_RECORD_METHOD(bool, SBBreakpoint, GetDescription, (lldb::SBStream &), s); + +  return GetDescription(s, true); +} + +bool SBBreakpoint::GetDescription(SBStream &s, bool include_locations) { +  LLDB_RECORD_METHOD(bool, SBBreakpoint, GetDescription, +                     (lldb::SBStream &, bool), s, include_locations); + +  BreakpointSP bkpt_sp = GetSP(); +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    s.Printf("SBBreakpoint: id = %i, ", bkpt_sp->GetID()); +    bkpt_sp->GetResolverDescription(s.get()); +    bkpt_sp->GetFilterDescription(s.get()); +    if (include_locations) { +      const size_t num_locations = bkpt_sp->GetNumLocations(); +      s.Printf(", locations = %" PRIu64, (uint64_t)num_locations); +    } +    return true; +  } +  s.Printf("No value"); +  return false; +} + +SBError SBBreakpoint::AddLocation(SBAddress &address) { +  LLDB_RECORD_METHOD(lldb::SBError, SBBreakpoint, AddLocation, +                     (lldb::SBAddress &), address); + +  BreakpointSP bkpt_sp = GetSP(); +  SBError error; + +  if (!address.IsValid()) { +    error.SetErrorString("Can't add an invalid address."); +    return LLDB_RECORD_RESULT(error); +  } + +  if (!bkpt_sp) { +    error.SetErrorString("No breakpoint to add a location to."); +    return LLDB_RECORD_RESULT(error); +  } + +  if (!llvm::isa<BreakpointResolverScripted>(bkpt_sp->GetResolver().get())) { +    error.SetErrorString("Only a scripted resolver can add locations."); +    return LLDB_RECORD_RESULT(error); +  } + +  if (bkpt_sp->GetSearchFilter()->AddressPasses(address.ref())) +    bkpt_sp->AddLocation(address.ref()); +  else { +    StreamString s; +    address.get()->Dump(&s, &bkpt_sp->GetTarget(), +                        Address::DumpStyleModuleWithFileAddress); +    error.SetErrorStringWithFormat("Address: %s didn't pass the filter.", +                                   s.GetData()); +  } +  return LLDB_RECORD_RESULT(error); +} + +void SBBreakpoint ::SetCallback(SBBreakpointHitCallback callback, void *baton) { +  LLDB_RECORD_DUMMY(void, SBBreakpoint, SetCallback, +                    (lldb::SBBreakpointHitCallback, void *), callback, baton); + +  BreakpointSP bkpt_sp = GetSP(); + +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton)); +    bkpt_sp->SetCallback(SBBreakpointCallbackBaton +      ::PrivateBreakpointHitCallback, baton_sp, +                         false); +  } +} + +void SBBreakpoint::SetScriptCallbackFunction( +  const char *callback_function_name) { +LLDB_RECORD_METHOD(void, SBBreakpoint, SetScriptCallbackFunction, +                   (const char *), callback_function_name); +  SBStructuredData empty_args; +  SetScriptCallbackFunction(callback_function_name, empty_args); +} + +SBError SBBreakpoint::SetScriptCallbackFunction( +    const char *callback_function_name, +    SBStructuredData &extra_args) { +  LLDB_RECORD_METHOD(SBError, SBBreakpoint, SetScriptCallbackFunction, +  (const char *, SBStructuredData &), callback_function_name, extra_args); +  SBError sb_error; +  BreakpointSP bkpt_sp = GetSP(); + +  if (bkpt_sp) { +    Status error; +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    BreakpointOptions *bp_options = bkpt_sp->GetOptions(); +    error = bkpt_sp->GetTarget() +        .GetDebugger() +        .GetScriptInterpreter() +        ->SetBreakpointCommandCallbackFunction(bp_options, +                                               callback_function_name, +                                               extra_args.m_impl_up +                                                   ->GetObjectSP()); +    sb_error.SetError(error); +  } else +    sb_error.SetErrorString("invalid breakpoint"); +   +  return LLDB_RECORD_RESULT(sb_error); +} + +SBError SBBreakpoint::SetScriptCallbackBody(const char *callback_body_text) { +  LLDB_RECORD_METHOD(lldb::SBError, SBBreakpoint, SetScriptCallbackBody, +                     (const char *), callback_body_text); + +  BreakpointSP bkpt_sp = GetSP(); + +  SBError sb_error; +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    BreakpointOptions *bp_options = bkpt_sp->GetOptions(); +    Status error = +        bkpt_sp->GetTarget() +            .GetDebugger() +            .GetScriptInterpreter() +            ->SetBreakpointCommandCallback(bp_options, callback_body_text); +    sb_error.SetError(error); +  } else +    sb_error.SetErrorString("invalid breakpoint"); + +  return LLDB_RECORD_RESULT(sb_error); +} + +bool SBBreakpoint::AddName(const char *new_name) { +  LLDB_RECORD_METHOD(bool, SBBreakpoint, AddName, (const char *), new_name); + +  SBError status = AddNameWithErrorHandling(new_name); +  return status.Success(); +} + +SBError SBBreakpoint::AddNameWithErrorHandling(const char *new_name) { +  LLDB_RECORD_METHOD(SBError, SBBreakpoint, AddNameWithErrorHandling, +                     (const char *), new_name); + +  BreakpointSP bkpt_sp = GetSP(); + +  SBError status; +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    Status error; +    bkpt_sp->GetTarget().AddNameToBreakpoint(bkpt_sp, new_name, error); +    status.SetError(error); +  } else { +    status.SetErrorString("invalid breakpoint"); +  } + +  return LLDB_RECORD_RESULT(status); +} + +void SBBreakpoint::RemoveName(const char *name_to_remove) { +  LLDB_RECORD_METHOD(void, SBBreakpoint, RemoveName, (const char *), +                     name_to_remove); + +  BreakpointSP bkpt_sp = GetSP(); + +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    bkpt_sp->GetTarget().RemoveNameFromBreakpoint(bkpt_sp, +                                                  ConstString(name_to_remove)); +  } +} + +bool SBBreakpoint::MatchesName(const char *name) { +  LLDB_RECORD_METHOD(bool, SBBreakpoint, MatchesName, (const char *), name); + +  BreakpointSP bkpt_sp = GetSP(); + +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    return bkpt_sp->MatchesName(name); +  } + +  return false; +} + +void SBBreakpoint::GetNames(SBStringList &names) { +  LLDB_RECORD_METHOD(void, SBBreakpoint, GetNames, (lldb::SBStringList &), +                     names); + +  BreakpointSP bkpt_sp = GetSP(); + +  if (bkpt_sp) { +    std::lock_guard<std::recursive_mutex> guard( +        bkpt_sp->GetTarget().GetAPIMutex()); +    std::vector<std::string> names_vec; +    bkpt_sp->GetNames(names_vec); +    for (std::string name : names_vec) { +      names.AppendString(name.c_str()); +    } +  } +} + +bool SBBreakpoint::EventIsBreakpointEvent(const lldb::SBEvent &event) { +  LLDB_RECORD_STATIC_METHOD(bool, SBBreakpoint, EventIsBreakpointEvent, +                            (const lldb::SBEvent &), event); + +  return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event.get()) != +         nullptr; +} + +BreakpointEventType +SBBreakpoint::GetBreakpointEventTypeFromEvent(const SBEvent &event) { +  LLDB_RECORD_STATIC_METHOD(lldb::BreakpointEventType, SBBreakpoint, +                            GetBreakpointEventTypeFromEvent, +                            (const lldb::SBEvent &), event); + +  if (event.IsValid()) +    return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent( +        event.GetSP()); +  return eBreakpointEventTypeInvalidType; +} + +SBBreakpoint SBBreakpoint::GetBreakpointFromEvent(const lldb::SBEvent &event) { +  LLDB_RECORD_STATIC_METHOD(lldb::SBBreakpoint, SBBreakpoint, +                            GetBreakpointFromEvent, (const lldb::SBEvent &), +                            event); + +  if (event.IsValid()) +    return LLDB_RECORD_RESULT( +        SBBreakpoint(Breakpoint::BreakpointEventData::GetBreakpointFromEvent( +            event.GetSP()))); +  return LLDB_RECORD_RESULT(SBBreakpoint()); +} + +SBBreakpointLocation +SBBreakpoint::GetBreakpointLocationAtIndexFromEvent(const lldb::SBEvent &event, +                                                    uint32_t loc_idx) { +  LLDB_RECORD_STATIC_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, +                            GetBreakpointLocationAtIndexFromEvent, +                            (const lldb::SBEvent &, uint32_t), event, loc_idx); + +  SBBreakpointLocation sb_breakpoint_loc; +  if (event.IsValid()) +    sb_breakpoint_loc.SetLocation( +        Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent( +            event.GetSP(), loc_idx)); +  return LLDB_RECORD_RESULT(sb_breakpoint_loc); +} + +uint32_t +SBBreakpoint::GetNumBreakpointLocationsFromEvent(const lldb::SBEvent &event) { +  LLDB_RECORD_STATIC_METHOD(uint32_t, SBBreakpoint, +                            GetNumBreakpointLocationsFromEvent, +                            (const lldb::SBEvent &), event); + +  uint32_t num_locations = 0; +  if (event.IsValid()) +    num_locations = +        (Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent( +            event.GetSP())); +  return num_locations; +} + +bool SBBreakpoint::IsHardware() const { +  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBreakpoint, IsHardware); + +  BreakpointSP bkpt_sp = GetSP(); +  if (bkpt_sp) +    return bkpt_sp->IsHardware(); +  return false; +} + +BreakpointSP SBBreakpoint::GetSP() const { return m_opaque_wp.lock(); } + +// This is simple collection of breakpoint id's and their target. +class SBBreakpointListImpl { +public: +  SBBreakpointListImpl(lldb::TargetSP target_sp) : m_target_wp() { +    if (target_sp && target_sp->IsValid()) +      m_target_wp = target_sp; +  } + +  ~SBBreakpointListImpl() = default; + +  size_t GetSize() { return m_break_ids.size(); } + +  BreakpointSP GetBreakpointAtIndex(size_t idx) { +    if (idx >= m_break_ids.size()) +      return BreakpointSP(); +    TargetSP target_sp = m_target_wp.lock(); +    if (!target_sp) +      return BreakpointSP(); +    lldb::break_id_t bp_id = m_break_ids[idx]; +    return target_sp->GetBreakpointList().FindBreakpointByID(bp_id); +  } + +  BreakpointSP FindBreakpointByID(lldb::break_id_t desired_id) { +    TargetSP target_sp = m_target_wp.lock(); +    if (!target_sp) +      return BreakpointSP(); + +    for (lldb::break_id_t &break_id : m_break_ids) { +      if (break_id == desired_id) +        return target_sp->GetBreakpointList().FindBreakpointByID(break_id); +    } +    return BreakpointSP(); +  } + +  bool Append(BreakpointSP bkpt) { +    TargetSP target_sp = m_target_wp.lock(); +    if (!target_sp || !bkpt) +      return false; +    if (bkpt->GetTargetSP() != target_sp) +      return false; +    m_break_ids.push_back(bkpt->GetID()); +    return true; +  } + +  bool AppendIfUnique(BreakpointSP bkpt) { +    TargetSP target_sp = m_target_wp.lock(); +    if (!target_sp || !bkpt) +      return false; +    if (bkpt->GetTargetSP() != target_sp) +      return false; +    lldb::break_id_t bp_id = bkpt->GetID(); +    if (find(m_break_ids.begin(), m_break_ids.end(), bp_id) == +        m_break_ids.end()) +      return false; + +    m_break_ids.push_back(bkpt->GetID()); +    return true; +  } + +  bool AppendByID(lldb::break_id_t id) { +    TargetSP target_sp = m_target_wp.lock(); +    if (!target_sp) +      return false; +    if (id == LLDB_INVALID_BREAK_ID) +      return false; +    m_break_ids.push_back(id); +    return true; +  } + +  void Clear() { m_break_ids.clear(); } + +  void CopyToBreakpointIDList(lldb_private::BreakpointIDList &bp_list) { +    for (lldb::break_id_t id : m_break_ids) { +      bp_list.AddBreakpointID(BreakpointID(id)); +    } +  } + +  TargetSP GetTarget() { return m_target_wp.lock(); } + +private: +  std::vector<lldb::break_id_t> m_break_ids; +  TargetWP m_target_wp; +}; + +SBBreakpointList::SBBreakpointList(SBTarget &target) +    : m_opaque_sp(new SBBreakpointListImpl(target.GetSP())) { +  LLDB_RECORD_CONSTRUCTOR(SBBreakpointList, (lldb::SBTarget &), target); +} + +SBBreakpointList::~SBBreakpointList() = default; + +size_t SBBreakpointList::GetSize() const { +  LLDB_RECORD_METHOD_CONST_NO_ARGS(size_t, SBBreakpointList, GetSize); + +  if (!m_opaque_sp) +    return 0; +  else +    return m_opaque_sp->GetSize(); +} + +SBBreakpoint SBBreakpointList::GetBreakpointAtIndex(size_t idx) { +  LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBBreakpointList, GetBreakpointAtIndex, +                     (size_t), idx); + +  if (!m_opaque_sp) +    return LLDB_RECORD_RESULT(SBBreakpoint()); + +  BreakpointSP bkpt_sp = m_opaque_sp->GetBreakpointAtIndex(idx); +  return LLDB_RECORD_RESULT(SBBreakpoint(bkpt_sp)); +} + +SBBreakpoint SBBreakpointList::FindBreakpointByID(lldb::break_id_t id) { +  LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBBreakpointList, FindBreakpointByID, +                     (lldb::break_id_t), id); + +  if (!m_opaque_sp) +    return LLDB_RECORD_RESULT(SBBreakpoint()); +  BreakpointSP bkpt_sp = m_opaque_sp->FindBreakpointByID(id); +  return LLDB_RECORD_RESULT(SBBreakpoint(bkpt_sp)); +} + +void SBBreakpointList::Append(const SBBreakpoint &sb_bkpt) { +  LLDB_RECORD_METHOD(void, SBBreakpointList, Append, +                     (const lldb::SBBreakpoint &), sb_bkpt); + +  if (!sb_bkpt.IsValid()) +    return; +  if (!m_opaque_sp) +    return; +  m_opaque_sp->Append(sb_bkpt.m_opaque_wp.lock()); +} + +void SBBreakpointList::AppendByID(lldb::break_id_t id) { +  LLDB_RECORD_METHOD(void, SBBreakpointList, AppendByID, (lldb::break_id_t), +                     id); + +  if (!m_opaque_sp) +    return; +  m_opaque_sp->AppendByID(id); +} + +bool SBBreakpointList::AppendIfUnique(const SBBreakpoint &sb_bkpt) { +  LLDB_RECORD_METHOD(bool, SBBreakpointList, AppendIfUnique, +                     (const lldb::SBBreakpoint &), sb_bkpt); + +  if (!sb_bkpt.IsValid()) +    return false; +  if (!m_opaque_sp) +    return false; +  return m_opaque_sp->AppendIfUnique(sb_bkpt.GetSP()); +} + +void SBBreakpointList::Clear() { +  LLDB_RECORD_METHOD_NO_ARGS(void, SBBreakpointList, Clear); + +  if (m_opaque_sp) +    m_opaque_sp->Clear(); +} + +void SBBreakpointList::CopyToBreakpointIDList( +    lldb_private::BreakpointIDList &bp_id_list) { +  if (m_opaque_sp) +    m_opaque_sp->CopyToBreakpointIDList(bp_id_list); +} + +namespace lldb_private { +namespace repro { + +template <> +void RegisterMethods<SBBreakpoint>(Registry &R) { +  LLDB_REGISTER_CONSTRUCTOR(SBBreakpoint, ()); +  LLDB_REGISTER_CONSTRUCTOR(SBBreakpoint, (const lldb::SBBreakpoint &)); +  LLDB_REGISTER_CONSTRUCTOR(SBBreakpoint, (const lldb::BreakpointSP &)); +  LLDB_REGISTER_METHOD(const lldb::SBBreakpoint &, +                       SBBreakpoint, operator=,(const lldb::SBBreakpoint &)); +  LLDB_REGISTER_METHOD(bool, +                       SBBreakpoint, operator==,(const lldb::SBBreakpoint &)); +  LLDB_REGISTER_METHOD(bool, +                       SBBreakpoint, operator!=,(const lldb::SBBreakpoint &)); +  LLDB_REGISTER_METHOD_CONST(lldb::break_id_t, SBBreakpoint, GetID, ()); +  LLDB_REGISTER_METHOD_CONST(bool, SBBreakpoint, IsValid, ()); +  LLDB_REGISTER_METHOD_CONST(bool, SBBreakpoint, operator bool, ()); +  LLDB_REGISTER_METHOD(void, SBBreakpoint, ClearAllBreakpointSites, ()); +  LLDB_REGISTER_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, +                       FindLocationByAddress, (lldb::addr_t)); +  LLDB_REGISTER_METHOD(lldb::break_id_t, SBBreakpoint, +                       FindLocationIDByAddress, (lldb::addr_t)); +  LLDB_REGISTER_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, +                       FindLocationByID, (lldb::break_id_t)); +  LLDB_REGISTER_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, +                       GetLocationAtIndex, (uint32_t)); +  LLDB_REGISTER_METHOD(void, SBBreakpoint, SetEnabled, (bool)); +  LLDB_REGISTER_METHOD(bool, SBBreakpoint, IsEnabled, ()); +  LLDB_REGISTER_METHOD(void, SBBreakpoint, SetOneShot, (bool)); +  LLDB_REGISTER_METHOD_CONST(bool, SBBreakpoint, IsOneShot, ()); +  LLDB_REGISTER_METHOD(bool, SBBreakpoint, IsInternal, ()); +  LLDB_REGISTER_METHOD(void, SBBreakpoint, SetIgnoreCount, (uint32_t)); +  LLDB_REGISTER_METHOD(void, SBBreakpoint, SetCondition, (const char *)); +  LLDB_REGISTER_METHOD(const char *, SBBreakpoint, GetCondition, ()); +  LLDB_REGISTER_METHOD(void, SBBreakpoint, SetAutoContinue, (bool)); +  LLDB_REGISTER_METHOD(bool, SBBreakpoint, GetAutoContinue, ()); +  LLDB_REGISTER_METHOD_CONST(uint32_t, SBBreakpoint, GetHitCount, ()); +  LLDB_REGISTER_METHOD_CONST(uint32_t, SBBreakpoint, GetIgnoreCount, ()); +  LLDB_REGISTER_METHOD(void, SBBreakpoint, SetThreadID, (lldb::tid_t)); +  LLDB_REGISTER_METHOD(lldb::tid_t, SBBreakpoint, GetThreadID, ()); +  LLDB_REGISTER_METHOD(void, SBBreakpoint, SetThreadIndex, (uint32_t)); +  LLDB_REGISTER_METHOD_CONST(uint32_t, SBBreakpoint, GetThreadIndex, ()); +  LLDB_REGISTER_METHOD(void, SBBreakpoint, SetThreadName, (const char *)); +  LLDB_REGISTER_METHOD_CONST(const char *, SBBreakpoint, GetThreadName, ()); +  LLDB_REGISTER_METHOD(void, SBBreakpoint, SetQueueName, (const char *)); +  LLDB_REGISTER_METHOD_CONST(const char *, SBBreakpoint, GetQueueName, ()); +  LLDB_REGISTER_METHOD_CONST(size_t, SBBreakpoint, GetNumResolvedLocations, +                             ()); +  LLDB_REGISTER_METHOD_CONST(size_t, SBBreakpoint, GetNumLocations, ()); +  LLDB_REGISTER_METHOD(void, SBBreakpoint, SetCommandLineCommands, +                       (lldb::SBStringList &)); +  LLDB_REGISTER_METHOD(bool, SBBreakpoint, GetCommandLineCommands, +                       (lldb::SBStringList &)); +  LLDB_REGISTER_METHOD(bool, SBBreakpoint, GetDescription, +                       (lldb::SBStream &)); +  LLDB_REGISTER_METHOD(bool, SBBreakpoint, GetDescription, +                       (lldb::SBStream &, bool)); +  LLDB_REGISTER_METHOD(lldb::SBError, SBBreakpoint, AddLocation, +                       (lldb::SBAddress &)); +  LLDB_REGISTER_METHOD(void, SBBreakpoint, SetScriptCallbackFunction, +                       (const char *)); +  LLDB_REGISTER_METHOD(lldb::SBError, SBBreakpoint, SetScriptCallbackFunction, +                       (const char *, SBStructuredData &)); +  LLDB_REGISTER_METHOD(lldb::SBError, SBBreakpoint, SetScriptCallbackBody, +                       (const char *)); +  LLDB_REGISTER_METHOD(bool, SBBreakpoint, AddName, (const char *)); +  LLDB_REGISTER_METHOD(lldb::SBError, SBBreakpoint, AddNameWithErrorHandling, +                       (const char *)); +  LLDB_REGISTER_METHOD(void, SBBreakpoint, RemoveName, (const char *)); +  LLDB_REGISTER_METHOD(bool, SBBreakpoint, MatchesName, (const char *)); +  LLDB_REGISTER_METHOD(void, SBBreakpoint, GetNames, (lldb::SBStringList &)); +  LLDB_REGISTER_STATIC_METHOD(bool, SBBreakpoint, EventIsBreakpointEvent, +                              (const lldb::SBEvent &)); +  LLDB_REGISTER_STATIC_METHOD(lldb::BreakpointEventType, SBBreakpoint, +                              GetBreakpointEventTypeFromEvent, +                              (const lldb::SBEvent &)); +  LLDB_REGISTER_STATIC_METHOD(lldb::SBBreakpoint, SBBreakpoint, +                              GetBreakpointFromEvent, +                              (const lldb::SBEvent &)); +  LLDB_REGISTER_STATIC_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, +                              GetBreakpointLocationAtIndexFromEvent, +                              (const lldb::SBEvent &, uint32_t)); +  LLDB_REGISTER_STATIC_METHOD(uint32_t, SBBreakpoint, +                              GetNumBreakpointLocationsFromEvent, +                              (const lldb::SBEvent &)); +  LLDB_REGISTER_METHOD_CONST(bool, SBBreakpoint, IsHardware, ()); +} + +template <> +void RegisterMethods<SBBreakpointList>(Registry &R) { +  LLDB_REGISTER_CONSTRUCTOR(SBBreakpointList, (lldb::SBTarget &)); +  LLDB_REGISTER_METHOD_CONST(size_t, SBBreakpointList, GetSize, ()); +  LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBBreakpointList, +                       GetBreakpointAtIndex, (size_t)); +  LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBBreakpointList, +                       FindBreakpointByID, (lldb::break_id_t)); +  LLDB_REGISTER_METHOD(void, SBBreakpointList, Append, +                       (const lldb::SBBreakpoint &)); +  LLDB_REGISTER_METHOD(void, SBBreakpointList, AppendByID, +                       (lldb::break_id_t)); +  LLDB_REGISTER_METHOD(bool, SBBreakpointList, AppendIfUnique, +                       (const lldb::SBBreakpoint &)); +  LLDB_REGISTER_METHOD(void, SBBreakpointList, Clear, ()); +} + +} +} | 
