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 66 return bool(m_opaque_wp.lock()); 67 } 68 69 SBError SBWatchpoint::GetError() { 70 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBError, SBWatchpoint, GetError); 71 72 SBError sb_error; 73 lldb::WatchpointSP watchpoint_sp(GetSP()); 74 if (watchpoint_sp) { 75 sb_error.SetError(watchpoint_sp->GetError()); 76 } 77 return LLDB_RECORD_RESULT(sb_error); 78 } 79 80 int32_t SBWatchpoint::GetHardwareIndex() { 81 LLDB_RECORD_METHOD_NO_ARGS(int32_t, SBWatchpoint, GetHardwareIndex); 82 83 int32_t hw_index = -1; 84 85 lldb::WatchpointSP watchpoint_sp(GetSP()); 86 if (watchpoint_sp) { 87 std::lock_guard<std::recursive_mutex> guard( 88 watchpoint_sp->GetTarget().GetAPIMutex()); 89 hw_index = watchpoint_sp->GetHardwareIndex(); 90 } 91 92 return hw_index; 93 } 94 95 addr_t SBWatchpoint::GetWatchAddress() { 96 LLDB_RECORD_METHOD_NO_ARGS(lldb::addr_t, SBWatchpoint, GetWatchAddress); 97 98 addr_t ret_addr = LLDB_INVALID_ADDRESS; 99 100 lldb::WatchpointSP watchpoint_sp(GetSP()); 101 if (watchpoint_sp) { 102 std::lock_guard<std::recursive_mutex> guard( 103 watchpoint_sp->GetTarget().GetAPIMutex()); 104 ret_addr = watchpoint_sp->GetLoadAddress(); 105 } 106 107 return ret_addr; 108 } 109 110 size_t SBWatchpoint::GetWatchSize() { 111 LLDB_RECORD_METHOD_NO_ARGS(size_t, SBWatchpoint, GetWatchSize); 112 113 size_t watch_size = 0; 114 115 lldb::WatchpointSP watchpoint_sp(GetSP()); 116 if (watchpoint_sp) { 117 std::lock_guard<std::recursive_mutex> guard( 118 watchpoint_sp->GetTarget().GetAPIMutex()); 119 watch_size = watchpoint_sp->GetByteSize(); 120 } 121 122 return watch_size; 123 } 124 125 void SBWatchpoint::SetEnabled(bool enabled) { 126 LLDB_RECORD_METHOD(void, SBWatchpoint, SetEnabled, (bool), enabled); 127 128 lldb::WatchpointSP watchpoint_sp(GetSP()); 129 if (watchpoint_sp) { 130 Target &target = watchpoint_sp->GetTarget(); 131 std::lock_guard<std::recursive_mutex> guard(target.GetAPIMutex()); 132 ProcessSP process_sp = target.GetProcessSP(); 133 const bool notify = true; 134 if (process_sp) { 135 if (enabled) 136 process_sp->EnableWatchpoint(watchpoint_sp.get(), notify); 137 else 138 process_sp->DisableWatchpoint(watchpoint_sp.get(), notify); 139 } else { 140 watchpoint_sp->SetEnabled(enabled, notify); 141 } 142 } 143 } 144 145 bool SBWatchpoint::IsEnabled() { 146 LLDB_RECORD_METHOD_NO_ARGS(bool, SBWatchpoint, IsEnabled); 147 148 lldb::WatchpointSP watchpoint_sp(GetSP()); 149 if (watchpoint_sp) { 150 std::lock_guard<std::recursive_mutex> guard( 151 watchpoint_sp->GetTarget().GetAPIMutex()); 152 return watchpoint_sp->IsEnabled(); 153 } else 154 return false; 155 } 156 157 uint32_t SBWatchpoint::GetHitCount() { 158 LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBWatchpoint, GetHitCount); 159 160 uint32_t count = 0; 161 lldb::WatchpointSP watchpoint_sp(GetSP()); 162 if (watchpoint_sp) { 163 std::lock_guard<std::recursive_mutex> guard( 164 watchpoint_sp->GetTarget().GetAPIMutex()); 165 count = watchpoint_sp->GetHitCount(); 166 } 167 168 return count; 169 } 170 171 uint32_t SBWatchpoint::GetIgnoreCount() { 172 LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBWatchpoint, GetIgnoreCount); 173 174 lldb::WatchpointSP watchpoint_sp(GetSP()); 175 if (watchpoint_sp) { 176 std::lock_guard<std::recursive_mutex> guard( 177 watchpoint_sp->GetTarget().GetAPIMutex()); 178 return watchpoint_sp->GetIgnoreCount(); 179 } else 180 return 0; 181 } 182 183 void SBWatchpoint::SetIgnoreCount(uint32_t n) { 184 LLDB_RECORD_METHOD(void, SBWatchpoint, SetIgnoreCount, (uint32_t), n); 185 186 lldb::WatchpointSP watchpoint_sp(GetSP()); 187 if (watchpoint_sp) { 188 std::lock_guard<std::recursive_mutex> guard( 189 watchpoint_sp->GetTarget().GetAPIMutex()); 190 watchpoint_sp->SetIgnoreCount(n); 191 } 192 } 193 194 const char *SBWatchpoint::GetCondition() { 195 LLDB_RECORD_METHOD_NO_ARGS(const char *, SBWatchpoint, GetCondition); 196 197 lldb::WatchpointSP watchpoint_sp(GetSP()); 198 if (watchpoint_sp) { 199 std::lock_guard<std::recursive_mutex> guard( 200 watchpoint_sp->GetTarget().GetAPIMutex()); 201 return watchpoint_sp->GetConditionText(); 202 } 203 return NULL; 204 } 205 206 void SBWatchpoint::SetCondition(const char *condition) { 207 LLDB_RECORD_METHOD(void, SBWatchpoint, SetCondition, (const char *), 208 condition); 209 210 lldb::WatchpointSP watchpoint_sp(GetSP()); 211 if (watchpoint_sp) { 212 std::lock_guard<std::recursive_mutex> guard( 213 watchpoint_sp->GetTarget().GetAPIMutex()); 214 watchpoint_sp->SetCondition(condition); 215 } 216 } 217 218 bool SBWatchpoint::GetDescription(SBStream &description, 219 DescriptionLevel level) { 220 LLDB_RECORD_METHOD(bool, SBWatchpoint, GetDescription, 221 (lldb::SBStream &, lldb::DescriptionLevel), description, 222 level); 223 224 Stream &strm = description.ref(); 225 226 lldb::WatchpointSP watchpoint_sp(GetSP()); 227 if (watchpoint_sp) { 228 std::lock_guard<std::recursive_mutex> guard( 229 watchpoint_sp->GetTarget().GetAPIMutex()); 230 watchpoint_sp->GetDescription(&strm, level); 231 strm.EOL(); 232 } else 233 strm.PutCString("No value"); 234 235 return true; 236 } 237 238 void SBWatchpoint::Clear() { 239 LLDB_RECORD_METHOD_NO_ARGS(void, SBWatchpoint, Clear); 240 241 m_opaque_wp.reset(); 242 } 243 244 lldb::WatchpointSP SBWatchpoint::GetSP() const { 245 LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::WatchpointSP, SBWatchpoint, GetSP); 246 247 return LLDB_RECORD_RESULT(m_opaque_wp.lock()); 248 } 249 250 void SBWatchpoint::SetSP(const lldb::WatchpointSP &sp) { 251 LLDB_RECORD_METHOD(void, SBWatchpoint, SetSP, (const lldb::WatchpointSP &), 252 sp); 253 254 m_opaque_wp = sp; 255 } 256 257 bool SBWatchpoint::EventIsWatchpointEvent(const lldb::SBEvent &event) { 258 LLDB_RECORD_STATIC_METHOD(bool, SBWatchpoint, EventIsWatchpointEvent, 259 (const lldb::SBEvent &), event); 260 261 return Watchpoint::WatchpointEventData::GetEventDataFromEvent(event.get()) != 262 NULL; 263 } 264 265 WatchpointEventType 266 SBWatchpoint::GetWatchpointEventTypeFromEvent(const SBEvent &event) { 267 LLDB_RECORD_STATIC_METHOD(lldb::WatchpointEventType, SBWatchpoint, 268 GetWatchpointEventTypeFromEvent, 269 (const lldb::SBEvent &), event); 270 271 if (event.IsValid()) 272 return Watchpoint::WatchpointEventData::GetWatchpointEventTypeFromEvent( 273 event.GetSP()); 274 return eWatchpointEventTypeInvalidType; 275 } 276 277 SBWatchpoint SBWatchpoint::GetWatchpointFromEvent(const lldb::SBEvent &event) { 278 LLDB_RECORD_STATIC_METHOD(lldb::SBWatchpoint, SBWatchpoint, 279 GetWatchpointFromEvent, (const lldb::SBEvent &), 280 event); 281 282 SBWatchpoint sb_watchpoint; 283 if (event.IsValid()) 284 sb_watchpoint = 285 Watchpoint::WatchpointEventData::GetWatchpointFromEvent(event.GetSP()); 286 return LLDB_RECORD_RESULT(sb_watchpoint); 287 } 288