| //===-- SBWatchpoint.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/SBWatchpoint.h" |
| #include "SBReproducerPrivate.h" |
| #include "lldb/API/SBAddress.h" |
| #include "lldb/API/SBDebugger.h" |
| #include "lldb/API/SBDefines.h" |
| #include "lldb/API/SBEvent.h" |
| #include "lldb/API/SBStream.h" |
| |
| #include "lldb/Breakpoint/Watchpoint.h" |
| #include "lldb/Breakpoint/WatchpointList.h" |
| #include "lldb/Core/StreamFile.h" |
| #include "lldb/Target/Process.h" |
| #include "lldb/Target/Target.h" |
| #include "lldb/Utility/Stream.h" |
| #include "lldb/lldb-defines.h" |
| #include "lldb/lldb-types.h" |
| |
| using namespace lldb; |
| using namespace lldb_private; |
| |
| SBWatchpoint::SBWatchpoint() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBWatchpoint); } |
| |
| SBWatchpoint::SBWatchpoint(const lldb::WatchpointSP &wp_sp) |
| : m_opaque_wp(wp_sp) { |
| LLDB_RECORD_CONSTRUCTOR(SBWatchpoint, (const lldb::WatchpointSP &), wp_sp); |
| } |
| |
| SBWatchpoint::SBWatchpoint(const SBWatchpoint &rhs) |
| : m_opaque_wp(rhs.m_opaque_wp) { |
| LLDB_RECORD_CONSTRUCTOR(SBWatchpoint, (const lldb::SBWatchpoint &), rhs); |
| } |
| |
| const SBWatchpoint &SBWatchpoint::operator=(const SBWatchpoint &rhs) { |
| LLDB_RECORD_METHOD(const lldb::SBWatchpoint &, |
| SBWatchpoint, operator=,(const lldb::SBWatchpoint &), rhs); |
| |
| m_opaque_wp = rhs.m_opaque_wp; |
| return LLDB_RECORD_RESULT(*this); |
| } |
| |
| SBWatchpoint::~SBWatchpoint() = default; |
| |
| watch_id_t SBWatchpoint::GetID() { |
| LLDB_RECORD_METHOD_NO_ARGS(lldb::watch_id_t, SBWatchpoint, GetID); |
| |
| |
| watch_id_t watch_id = LLDB_INVALID_WATCH_ID; |
| lldb::WatchpointSP watchpoint_sp(GetSP()); |
| if (watchpoint_sp) |
| watch_id = watchpoint_sp->GetID(); |
| |
| return watch_id; |
| } |
| |
| bool SBWatchpoint::IsValid() const { |
| LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBWatchpoint, IsValid); |
| return this->operator bool(); |
| } |
| SBWatchpoint::operator bool() const { |
| LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBWatchpoint, operator bool); |
| |
| return bool(m_opaque_wp.lock()); |
| } |
| |
| bool SBWatchpoint::operator==(const SBWatchpoint &rhs) const { |
| LLDB_RECORD_METHOD_CONST( |
| bool, SBWatchpoint, operator==,(const SBWatchpoint &), rhs); |
| |
| return GetSP() == rhs.GetSP(); |
| } |
| |
| bool SBWatchpoint::operator!=(const SBWatchpoint &rhs) const { |
| LLDB_RECORD_METHOD_CONST( |
| bool, SBWatchpoint, operator!=,(const SBWatchpoint &), rhs); |
| |
| return !(*this == rhs); |
| } |
| |
| SBError SBWatchpoint::GetError() { |
| LLDB_RECORD_METHOD_NO_ARGS(lldb::SBError, SBWatchpoint, GetError); |
| |
| SBError sb_error; |
| lldb::WatchpointSP watchpoint_sp(GetSP()); |
| if (watchpoint_sp) { |
| sb_error.SetError(watchpoint_sp->GetError()); |
| } |
| return LLDB_RECORD_RESULT(sb_error); |
| } |
| |
| int32_t SBWatchpoint::GetHardwareIndex() { |
| LLDB_RECORD_METHOD_NO_ARGS(int32_t, SBWatchpoint, GetHardwareIndex); |
| |
| int32_t hw_index = -1; |
| |
| lldb::WatchpointSP watchpoint_sp(GetSP()); |
| if (watchpoint_sp) { |
| std::lock_guard<std::recursive_mutex> guard( |
| watchpoint_sp->GetTarget().GetAPIMutex()); |
| hw_index = watchpoint_sp->GetHardwareIndex(); |
| } |
| |
| return hw_index; |
| } |
| |
| addr_t SBWatchpoint::GetWatchAddress() { |
| LLDB_RECORD_METHOD_NO_ARGS(lldb::addr_t, SBWatchpoint, GetWatchAddress); |
| |
| addr_t ret_addr = LLDB_INVALID_ADDRESS; |
| |
| lldb::WatchpointSP watchpoint_sp(GetSP()); |
| if (watchpoint_sp) { |
| std::lock_guard<std::recursive_mutex> guard( |
| watchpoint_sp->GetTarget().GetAPIMutex()); |
| ret_addr = watchpoint_sp->GetLoadAddress(); |
| } |
| |
| return ret_addr; |
| } |
| |
| size_t SBWatchpoint::GetWatchSize() { |
| LLDB_RECORD_METHOD_NO_ARGS(size_t, SBWatchpoint, GetWatchSize); |
| |
| size_t watch_size = 0; |
| |
| lldb::WatchpointSP watchpoint_sp(GetSP()); |
| if (watchpoint_sp) { |
| std::lock_guard<std::recursive_mutex> guard( |
| watchpoint_sp->GetTarget().GetAPIMutex()); |
| watch_size = watchpoint_sp->GetByteSize(); |
| } |
| |
| return watch_size; |
| } |
| |
| void SBWatchpoint::SetEnabled(bool enabled) { |
| LLDB_RECORD_METHOD(void, SBWatchpoint, SetEnabled, (bool), enabled); |
| |
| lldb::WatchpointSP watchpoint_sp(GetSP()); |
| if (watchpoint_sp) { |
| Target &target = watchpoint_sp->GetTarget(); |
| std::lock_guard<std::recursive_mutex> guard(target.GetAPIMutex()); |
| ProcessSP process_sp = target.GetProcessSP(); |
| const bool notify = true; |
| if (process_sp) { |
| if (enabled) |
| process_sp->EnableWatchpoint(watchpoint_sp.get(), notify); |
| else |
| process_sp->DisableWatchpoint(watchpoint_sp.get(), notify); |
| } else { |
| watchpoint_sp->SetEnabled(enabled, notify); |
| } |
| } |
| } |
| |
| bool SBWatchpoint::IsEnabled() { |
| LLDB_RECORD_METHOD_NO_ARGS(bool, SBWatchpoint, IsEnabled); |
| |
| lldb::WatchpointSP watchpoint_sp(GetSP()); |
| if (watchpoint_sp) { |
| std::lock_guard<std::recursive_mutex> guard( |
| watchpoint_sp->GetTarget().GetAPIMutex()); |
| return watchpoint_sp->IsEnabled(); |
| } else |
| return false; |
| } |
| |
| uint32_t SBWatchpoint::GetHitCount() { |
| LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBWatchpoint, GetHitCount); |
| |
| uint32_t count = 0; |
| lldb::WatchpointSP watchpoint_sp(GetSP()); |
| if (watchpoint_sp) { |
| std::lock_guard<std::recursive_mutex> guard( |
| watchpoint_sp->GetTarget().GetAPIMutex()); |
| count = watchpoint_sp->GetHitCount(); |
| } |
| |
| return count; |
| } |
| |
| uint32_t SBWatchpoint::GetIgnoreCount() { |
| LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBWatchpoint, GetIgnoreCount); |
| |
| lldb::WatchpointSP watchpoint_sp(GetSP()); |
| if (watchpoint_sp) { |
| std::lock_guard<std::recursive_mutex> guard( |
| watchpoint_sp->GetTarget().GetAPIMutex()); |
| return watchpoint_sp->GetIgnoreCount(); |
| } else |
| return 0; |
| } |
| |
| void SBWatchpoint::SetIgnoreCount(uint32_t n) { |
| LLDB_RECORD_METHOD(void, SBWatchpoint, SetIgnoreCount, (uint32_t), n); |
| |
| lldb::WatchpointSP watchpoint_sp(GetSP()); |
| if (watchpoint_sp) { |
| std::lock_guard<std::recursive_mutex> guard( |
| watchpoint_sp->GetTarget().GetAPIMutex()); |
| watchpoint_sp->SetIgnoreCount(n); |
| } |
| } |
| |
| const char *SBWatchpoint::GetCondition() { |
| LLDB_RECORD_METHOD_NO_ARGS(const char *, SBWatchpoint, GetCondition); |
| |
| lldb::WatchpointSP watchpoint_sp(GetSP()); |
| if (watchpoint_sp) { |
| std::lock_guard<std::recursive_mutex> guard( |
| watchpoint_sp->GetTarget().GetAPIMutex()); |
| return watchpoint_sp->GetConditionText(); |
| } |
| return nullptr; |
| } |
| |
| void SBWatchpoint::SetCondition(const char *condition) { |
| LLDB_RECORD_METHOD(void, SBWatchpoint, SetCondition, (const char *), |
| condition); |
| |
| lldb::WatchpointSP watchpoint_sp(GetSP()); |
| if (watchpoint_sp) { |
| std::lock_guard<std::recursive_mutex> guard( |
| watchpoint_sp->GetTarget().GetAPIMutex()); |
| watchpoint_sp->SetCondition(condition); |
| } |
| } |
| |
| bool SBWatchpoint::GetDescription(SBStream &description, |
| DescriptionLevel level) { |
| LLDB_RECORD_METHOD(bool, SBWatchpoint, GetDescription, |
| (lldb::SBStream &, lldb::DescriptionLevel), description, |
| level); |
| |
| Stream &strm = description.ref(); |
| |
| lldb::WatchpointSP watchpoint_sp(GetSP()); |
| if (watchpoint_sp) { |
| std::lock_guard<std::recursive_mutex> guard( |
| watchpoint_sp->GetTarget().GetAPIMutex()); |
| watchpoint_sp->GetDescription(&strm, level); |
| strm.EOL(); |
| } else |
| strm.PutCString("No value"); |
| |
| return true; |
| } |
| |
| void SBWatchpoint::Clear() { |
| LLDB_RECORD_METHOD_NO_ARGS(void, SBWatchpoint, Clear); |
| |
| m_opaque_wp.reset(); |
| } |
| |
| lldb::WatchpointSP SBWatchpoint::GetSP() const { |
| LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::WatchpointSP, SBWatchpoint, GetSP); |
| |
| return LLDB_RECORD_RESULT(m_opaque_wp.lock()); |
| } |
| |
| void SBWatchpoint::SetSP(const lldb::WatchpointSP &sp) { |
| LLDB_RECORD_METHOD(void, SBWatchpoint, SetSP, (const lldb::WatchpointSP &), |
| sp); |
| |
| m_opaque_wp = sp; |
| } |
| |
| bool SBWatchpoint::EventIsWatchpointEvent(const lldb::SBEvent &event) { |
| LLDB_RECORD_STATIC_METHOD(bool, SBWatchpoint, EventIsWatchpointEvent, |
| (const lldb::SBEvent &), event); |
| |
| return Watchpoint::WatchpointEventData::GetEventDataFromEvent(event.get()) != |
| nullptr; |
| } |
| |
| WatchpointEventType |
| SBWatchpoint::GetWatchpointEventTypeFromEvent(const SBEvent &event) { |
| LLDB_RECORD_STATIC_METHOD(lldb::WatchpointEventType, SBWatchpoint, |
| GetWatchpointEventTypeFromEvent, |
| (const lldb::SBEvent &), event); |
| |
| if (event.IsValid()) |
| return Watchpoint::WatchpointEventData::GetWatchpointEventTypeFromEvent( |
| event.GetSP()); |
| return eWatchpointEventTypeInvalidType; |
| } |
| |
| SBWatchpoint SBWatchpoint::GetWatchpointFromEvent(const lldb::SBEvent &event) { |
| LLDB_RECORD_STATIC_METHOD(lldb::SBWatchpoint, SBWatchpoint, |
| GetWatchpointFromEvent, (const lldb::SBEvent &), |
| event); |
| |
| SBWatchpoint sb_watchpoint; |
| if (event.IsValid()) |
| sb_watchpoint = |
| Watchpoint::WatchpointEventData::GetWatchpointFromEvent(event.GetSP()); |
| return LLDB_RECORD_RESULT(sb_watchpoint); |
| } |
| |
| namespace lldb_private { |
| namespace repro { |
| |
| template <> |
| void RegisterMethods<SBWatchpoint>(Registry &R) { |
| LLDB_REGISTER_CONSTRUCTOR(SBWatchpoint, ()); |
| LLDB_REGISTER_CONSTRUCTOR(SBWatchpoint, (const lldb::WatchpointSP &)); |
| LLDB_REGISTER_CONSTRUCTOR(SBWatchpoint, (const lldb::SBWatchpoint &)); |
| LLDB_REGISTER_METHOD(const lldb::SBWatchpoint &, |
| SBWatchpoint, operator=,(const lldb::SBWatchpoint &)); |
| LLDB_REGISTER_METHOD(lldb::watch_id_t, SBWatchpoint, GetID, ()); |
| LLDB_REGISTER_METHOD_CONST(bool, SBWatchpoint, IsValid, ()); |
| LLDB_REGISTER_METHOD_CONST(bool, SBWatchpoint, operator bool, ()); |
| LLDB_REGISTER_METHOD_CONST( |
| bool, SBWatchpoint, operator==,(const lldb::SBWatchpoint &)); |
| LLDB_REGISTER_METHOD_CONST( |
| bool, SBWatchpoint, operator!=,(const lldb::SBWatchpoint &)); |
| LLDB_REGISTER_METHOD(lldb::SBError, SBWatchpoint, GetError, ()); |
| LLDB_REGISTER_METHOD(int32_t, SBWatchpoint, GetHardwareIndex, ()); |
| LLDB_REGISTER_METHOD(lldb::addr_t, SBWatchpoint, GetWatchAddress, ()); |
| LLDB_REGISTER_METHOD(size_t, SBWatchpoint, GetWatchSize, ()); |
| LLDB_REGISTER_METHOD(void, SBWatchpoint, SetEnabled, (bool)); |
| LLDB_REGISTER_METHOD(bool, SBWatchpoint, IsEnabled, ()); |
| LLDB_REGISTER_METHOD(uint32_t, SBWatchpoint, GetHitCount, ()); |
| LLDB_REGISTER_METHOD(uint32_t, SBWatchpoint, GetIgnoreCount, ()); |
| LLDB_REGISTER_METHOD(void, SBWatchpoint, SetIgnoreCount, (uint32_t)); |
| LLDB_REGISTER_METHOD(const char *, SBWatchpoint, GetCondition, ()); |
| LLDB_REGISTER_METHOD(void, SBWatchpoint, SetCondition, (const char *)); |
| LLDB_REGISTER_METHOD(bool, SBWatchpoint, GetDescription, |
| (lldb::SBStream &, lldb::DescriptionLevel)); |
| LLDB_REGISTER_METHOD(void, SBWatchpoint, Clear, ()); |
| LLDB_REGISTER_METHOD_CONST(lldb::WatchpointSP, SBWatchpoint, GetSP, ()); |
| LLDB_REGISTER_METHOD(void, SBWatchpoint, SetSP, |
| (const lldb::WatchpointSP &)); |
| LLDB_REGISTER_STATIC_METHOD(bool, SBWatchpoint, EventIsWatchpointEvent, |
| (const lldb::SBEvent &)); |
| LLDB_REGISTER_STATIC_METHOD(lldb::WatchpointEventType, SBWatchpoint, |
| GetWatchpointEventTypeFromEvent, |
| (const lldb::SBEvent &)); |
| LLDB_REGISTER_STATIC_METHOD(lldb::SBWatchpoint, SBWatchpoint, |
| GetWatchpointFromEvent, |
| (const lldb::SBEvent &)); |
| } |
| |
| } |
| } |