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