1//===-- SBWatchpoint.cpp --------------------------------*- C++ -*-===// 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-exception 6// 7//===----------------------------------------------------------------------===// 8 9#include "lldb/API/SBWatchpoint.h" 10#include "SBReproducerPrivate.h" 11#include "lldb/API/SBAddress.h" 12#include "lldb/API/SBDebugger.h" 13#include "lldb/API/SBDefines.h" 14#include "lldb/API/SBEvent.h" 15#include "lldb/API/SBStream.h" 16 17#include "lldb/Breakpoint/Watchpoint.h" 18#include "lldb/Breakpoint/WatchpointList.h" 19#include "lldb/Core/StreamFile.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_RECORD_CONSTRUCTOR_NO_ARGS(SBWatchpoint); } 30 31SBWatchpoint::SBWatchpoint(const lldb::WatchpointSP &wp_sp) 32 : m_opaque_wp(wp_sp) { 33 LLDB_RECORD_CONSTRUCTOR(SBWatchpoint, (const lldb::WatchpointSP &), wp_sp); 34} 35 36SBWatchpoint::SBWatchpoint(const SBWatchpoint &rhs) 37 : m_opaque_wp(rhs.m_opaque_wp) { 38 LLDB_RECORD_CONSTRUCTOR(SBWatchpoint, (const lldb::SBWatchpoint &), rhs); 39} 40 41const SBWatchpoint &SBWatchpoint::operator=(const SBWatchpoint &rhs) { 42 LLDB_RECORD_METHOD(const lldb::SBWatchpoint &, 43 SBWatchpoint, operator=,(const lldb::SBWatchpoint &), rhs); 44 45 m_opaque_wp = rhs.m_opaque_wp; 46 return LLDB_RECORD_RESULT(*this); 47} 48 49SBWatchpoint::~SBWatchpoint() {} 50 51watch_id_t SBWatchpoint::GetID() { 52 LLDB_RECORD_METHOD_NO_ARGS(lldb::watch_id_t, SBWatchpoint, GetID); 53 54 55 watch_id_t watch_id = LLDB_INVALID_WATCH_ID; 56 lldb::WatchpointSP watchpoint_sp(GetSP()); 57 if (watchpoint_sp) 58 watch_id = watchpoint_sp->GetID(); 59 60 return watch_id; 61} 62 63bool SBWatchpoint::IsValid() const { 64 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBWatchpoint, IsValid); 65 return this->operator bool(); 66} 67SBWatchpoint::operator bool() const { 68 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBWatchpoint, operator bool); 69 70 return bool(m_opaque_wp.lock()); 71} 72 73bool SBWatchpoint::operator==(const SBWatchpoint &rhs) const { 74 LLDB_RECORD_METHOD_CONST( 75 bool, SBWatchpoint, operator==,(const SBWatchpoint &), rhs); 76 77 return GetSP() == rhs.GetSP(); 78} 79 80bool SBWatchpoint::operator!=(const SBWatchpoint &rhs) const { 81 LLDB_RECORD_METHOD_CONST( 82 bool, SBWatchpoint, operator!=,(const SBWatchpoint &), rhs); 83 84 return !(*this == rhs); 85} 86 87SBError SBWatchpoint::GetError() { 88 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBError, SBWatchpoint, GetError); 89 90 SBError sb_error; 91 lldb::WatchpointSP watchpoint_sp(GetSP()); 92 if (watchpoint_sp) { 93 sb_error.SetError(watchpoint_sp->GetError()); 94 } 95 return LLDB_RECORD_RESULT(sb_error); 96} 97 98int32_t SBWatchpoint::GetHardwareIndex() { 99 LLDB_RECORD_METHOD_NO_ARGS(int32_t, SBWatchpoint, GetHardwareIndex); 100 101 int32_t hw_index = -1; 102 103 lldb::WatchpointSP watchpoint_sp(GetSP()); 104 if (watchpoint_sp) { 105 std::lock_guard<std::recursive_mutex> guard( 106 watchpoint_sp->GetTarget().GetAPIMutex()); 107 hw_index = watchpoint_sp->GetHardwareIndex(); 108 } 109 110 return hw_index; 111} 112 113addr_t SBWatchpoint::GetWatchAddress() { 114 LLDB_RECORD_METHOD_NO_ARGS(lldb::addr_t, SBWatchpoint, GetWatchAddress); 115 116 addr_t ret_addr = LLDB_INVALID_ADDRESS; 117 118 lldb::WatchpointSP watchpoint_sp(GetSP()); 119 if (watchpoint_sp) { 120 std::lock_guard<std::recursive_mutex> guard( 121 watchpoint_sp->GetTarget().GetAPIMutex()); 122 ret_addr = watchpoint_sp->GetLoadAddress(); 123 } 124 125 return ret_addr; 126} 127 128size_t SBWatchpoint::GetWatchSize() { 129 LLDB_RECORD_METHOD_NO_ARGS(size_t, SBWatchpoint, GetWatchSize); 130 131 size_t watch_size = 0; 132 133 lldb::WatchpointSP watchpoint_sp(GetSP()); 134 if (watchpoint_sp) { 135 std::lock_guard<std::recursive_mutex> guard( 136 watchpoint_sp->GetTarget().GetAPIMutex()); 137 watch_size = watchpoint_sp->GetByteSize(); 138 } 139 140 return watch_size; 141} 142 143void SBWatchpoint::SetEnabled(bool enabled) { 144 LLDB_RECORD_METHOD(void, SBWatchpoint, SetEnabled, (bool), enabled); 145 146 lldb::WatchpointSP watchpoint_sp(GetSP()); 147 if (watchpoint_sp) { 148 Target &target = watchpoint_sp->GetTarget(); 149 std::lock_guard<std::recursive_mutex> guard(target.GetAPIMutex()); 150 ProcessSP process_sp = target.GetProcessSP(); 151 const bool notify = true; 152 if (process_sp) { 153 if (enabled) 154 process_sp->EnableWatchpoint(watchpoint_sp.get(), notify); 155 else 156 process_sp->DisableWatchpoint(watchpoint_sp.get(), notify); 157 } else { 158 watchpoint_sp->SetEnabled(enabled, notify); 159 } 160 } 161} 162 163bool SBWatchpoint::IsEnabled() { 164 LLDB_RECORD_METHOD_NO_ARGS(bool, SBWatchpoint, IsEnabled); 165 166 lldb::WatchpointSP watchpoint_sp(GetSP()); 167 if (watchpoint_sp) { 168 std::lock_guard<std::recursive_mutex> guard( 169 watchpoint_sp->GetTarget().GetAPIMutex()); 170 return watchpoint_sp->IsEnabled(); 171 } else 172 return false; 173} 174 175uint32_t SBWatchpoint::GetHitCount() { 176 LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBWatchpoint, GetHitCount); 177 178 uint32_t count = 0; 179 lldb::WatchpointSP watchpoint_sp(GetSP()); 180 if (watchpoint_sp) { 181 std::lock_guard<std::recursive_mutex> guard( 182 watchpoint_sp->GetTarget().GetAPIMutex()); 183 count = watchpoint_sp->GetHitCount(); 184 } 185 186 return count; 187} 188 189uint32_t SBWatchpoint::GetIgnoreCount() { 190 LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBWatchpoint, GetIgnoreCount); 191 192 lldb::WatchpointSP watchpoint_sp(GetSP()); 193 if (watchpoint_sp) { 194 std::lock_guard<std::recursive_mutex> guard( 195 watchpoint_sp->GetTarget().GetAPIMutex()); 196 return watchpoint_sp->GetIgnoreCount(); 197 } else 198 return 0; 199} 200 201void SBWatchpoint::SetIgnoreCount(uint32_t n) { 202 LLDB_RECORD_METHOD(void, SBWatchpoint, SetIgnoreCount, (uint32_t), n); 203 204 lldb::WatchpointSP watchpoint_sp(GetSP()); 205 if (watchpoint_sp) { 206 std::lock_guard<std::recursive_mutex> guard( 207 watchpoint_sp->GetTarget().GetAPIMutex()); 208 watchpoint_sp->SetIgnoreCount(n); 209 } 210} 211 212const char *SBWatchpoint::GetCondition() { 213 LLDB_RECORD_METHOD_NO_ARGS(const char *, SBWatchpoint, GetCondition); 214 215 lldb::WatchpointSP watchpoint_sp(GetSP()); 216 if (watchpoint_sp) { 217 std::lock_guard<std::recursive_mutex> guard( 218 watchpoint_sp->GetTarget().GetAPIMutex()); 219 return watchpoint_sp->GetConditionText(); 220 } 221 return nullptr; 222} 223 224void SBWatchpoint::SetCondition(const char *condition) { 225 LLDB_RECORD_METHOD(void, SBWatchpoint, SetCondition, (const char *), 226 condition); 227 228 lldb::WatchpointSP watchpoint_sp(GetSP()); 229 if (watchpoint_sp) { 230 std::lock_guard<std::recursive_mutex> guard( 231 watchpoint_sp->GetTarget().GetAPIMutex()); 232 watchpoint_sp->SetCondition(condition); 233 } 234} 235 236bool SBWatchpoint::GetDescription(SBStream &description, 237 DescriptionLevel level) { 238 LLDB_RECORD_METHOD(bool, SBWatchpoint, GetDescription, 239 (lldb::SBStream &, lldb::DescriptionLevel), description, 240 level); 241 242 Stream &strm = description.ref(); 243 244 lldb::WatchpointSP watchpoint_sp(GetSP()); 245 if (watchpoint_sp) { 246 std::lock_guard<std::recursive_mutex> guard( 247 watchpoint_sp->GetTarget().GetAPIMutex()); 248 watchpoint_sp->GetDescription(&strm, level); 249 strm.EOL(); 250 } else 251 strm.PutCString("No value"); 252 253 return true; 254} 255 256void SBWatchpoint::Clear() { 257 LLDB_RECORD_METHOD_NO_ARGS(void, SBWatchpoint, Clear); 258 259 m_opaque_wp.reset(); 260} 261 262lldb::WatchpointSP SBWatchpoint::GetSP() const { 263 LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::WatchpointSP, SBWatchpoint, GetSP); 264 265 return LLDB_RECORD_RESULT(m_opaque_wp.lock()); 266} 267 268void SBWatchpoint::SetSP(const lldb::WatchpointSP &sp) { 269 LLDB_RECORD_METHOD(void, SBWatchpoint, SetSP, (const lldb::WatchpointSP &), 270 sp); 271 272 m_opaque_wp = sp; 273} 274 275bool SBWatchpoint::EventIsWatchpointEvent(const lldb::SBEvent &event) { 276 LLDB_RECORD_STATIC_METHOD(bool, SBWatchpoint, EventIsWatchpointEvent, 277 (const lldb::SBEvent &), event); 278 279 return Watchpoint::WatchpointEventData::GetEventDataFromEvent(event.get()) != 280 nullptr; 281} 282 283WatchpointEventType 284SBWatchpoint::GetWatchpointEventTypeFromEvent(const SBEvent &event) { 285 LLDB_RECORD_STATIC_METHOD(lldb::WatchpointEventType, SBWatchpoint, 286 GetWatchpointEventTypeFromEvent, 287 (const lldb::SBEvent &), event); 288 289 if (event.IsValid()) 290 return Watchpoint::WatchpointEventData::GetWatchpointEventTypeFromEvent( 291 event.GetSP()); 292 return eWatchpointEventTypeInvalidType; 293} 294 295SBWatchpoint SBWatchpoint::GetWatchpointFromEvent(const lldb::SBEvent &event) { 296 LLDB_RECORD_STATIC_METHOD(lldb::SBWatchpoint, SBWatchpoint, 297 GetWatchpointFromEvent, (const lldb::SBEvent &), 298 event); 299 300 SBWatchpoint sb_watchpoint; 301 if (event.IsValid()) 302 sb_watchpoint = 303 Watchpoint::WatchpointEventData::GetWatchpointFromEvent(event.GetSP()); 304 return LLDB_RECORD_RESULT(sb_watchpoint); 305} 306 307namespace lldb_private { 308namespace repro { 309 310template <> 311void RegisterMethods<SBWatchpoint>(Registry &R) { 312 LLDB_REGISTER_CONSTRUCTOR(SBWatchpoint, ()); 313 LLDB_REGISTER_CONSTRUCTOR(SBWatchpoint, (const lldb::WatchpointSP &)); 314 LLDB_REGISTER_CONSTRUCTOR(SBWatchpoint, (const lldb::SBWatchpoint &)); 315 LLDB_REGISTER_METHOD(const lldb::SBWatchpoint &, 316 SBWatchpoint, operator=,(const lldb::SBWatchpoint &)); 317 LLDB_REGISTER_METHOD(lldb::watch_id_t, SBWatchpoint, GetID, ()); 318 LLDB_REGISTER_METHOD_CONST(bool, SBWatchpoint, IsValid, ()); 319 LLDB_REGISTER_METHOD_CONST(bool, SBWatchpoint, operator bool, ()); 320 LLDB_REGISTER_METHOD_CONST( 321 bool, SBWatchpoint, operator==,(const lldb::SBWatchpoint &)); 322 LLDB_REGISTER_METHOD_CONST( 323 bool, SBWatchpoint, operator!=,(const lldb::SBWatchpoint &)); 324 LLDB_REGISTER_METHOD(lldb::SBError, SBWatchpoint, GetError, ()); 325 LLDB_REGISTER_METHOD(int32_t, SBWatchpoint, GetHardwareIndex, ()); 326 LLDB_REGISTER_METHOD(lldb::addr_t, SBWatchpoint, GetWatchAddress, ()); 327 LLDB_REGISTER_METHOD(size_t, SBWatchpoint, GetWatchSize, ()); 328 LLDB_REGISTER_METHOD(void, SBWatchpoint, SetEnabled, (bool)); 329 LLDB_REGISTER_METHOD(bool, SBWatchpoint, IsEnabled, ()); 330 LLDB_REGISTER_METHOD(uint32_t, SBWatchpoint, GetHitCount, ()); 331 LLDB_REGISTER_METHOD(uint32_t, SBWatchpoint, GetIgnoreCount, ()); 332 LLDB_REGISTER_METHOD(void, SBWatchpoint, SetIgnoreCount, (uint32_t)); 333 LLDB_REGISTER_METHOD(const char *, SBWatchpoint, GetCondition, ()); 334 LLDB_REGISTER_METHOD(void, SBWatchpoint, SetCondition, (const char *)); 335 LLDB_REGISTER_METHOD(bool, SBWatchpoint, GetDescription, 336 (lldb::SBStream &, lldb::DescriptionLevel)); 337 LLDB_REGISTER_METHOD(void, SBWatchpoint, Clear, ()); 338 LLDB_REGISTER_METHOD_CONST(lldb::WatchpointSP, SBWatchpoint, GetSP, ()); 339 LLDB_REGISTER_METHOD(void, SBWatchpoint, SetSP, 340 (const lldb::WatchpointSP &)); 341 LLDB_REGISTER_STATIC_METHOD(bool, SBWatchpoint, EventIsWatchpointEvent, 342 (const lldb::SBEvent &)); 343 LLDB_REGISTER_STATIC_METHOD(lldb::WatchpointEventType, SBWatchpoint, 344 GetWatchpointEventTypeFromEvent, 345 (const lldb::SBEvent &)); 346 LLDB_REGISTER_STATIC_METHOD(lldb::SBWatchpoint, SBWatchpoint, 347 GetWatchpointFromEvent, 348 (const lldb::SBEvent &)); 349} 350 351} 352} 353