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