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 "lldb/API/SBAddress.h" 11 #include "lldb/API/SBDebugger.h" 12 #include "lldb/API/SBDefines.h" 13 #include "lldb/API/SBEvent.h" 14 #include "lldb/API/SBStream.h" 15 16 #include "lldb/Breakpoint/Watchpoint.h" 17 #include "lldb/Breakpoint/WatchpointList.h" 18 #include "lldb/Core/StreamFile.h" 19 #include "lldb/Target/Process.h" 20 #include "lldb/Target/Target.h" 21 #include "lldb/Utility/Log.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() {} 30 31 SBWatchpoint::SBWatchpoint(const lldb::WatchpointSP &wp_sp) 32 : m_opaque_wp(wp_sp) { 33 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 34 35 if (log) { 36 SBStream sstr; 37 GetDescription(sstr, lldb::eDescriptionLevelBrief); 38 LLDB_LOG(log, "watchpoint = {0} ({1})", wp_sp.get(), sstr.GetData()); 39 } 40 } 41 42 SBWatchpoint::SBWatchpoint(const SBWatchpoint &rhs) 43 : m_opaque_wp(rhs.m_opaque_wp) {} 44 45 const SBWatchpoint &SBWatchpoint::operator=(const SBWatchpoint &rhs) { 46 m_opaque_wp = rhs.m_opaque_wp; 47 return *this; 48 } 49 50 SBWatchpoint::~SBWatchpoint() {} 51 52 watch_id_t SBWatchpoint::GetID() { 53 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 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 if (log) { 61 if (watch_id == LLDB_INVALID_WATCH_ID) 62 log->Printf("SBWatchpoint(%p)::GetID () => LLDB_INVALID_WATCH_ID", 63 static_cast<void *>(watchpoint_sp.get())); 64 else 65 log->Printf("SBWatchpoint(%p)::GetID () => %u", 66 static_cast<void *>(watchpoint_sp.get()), watch_id); 67 } 68 69 return watch_id; 70 } 71 72 bool SBWatchpoint::IsValid() const { return bool(m_opaque_wp.lock()); } 73 74 SBError SBWatchpoint::GetError() { 75 SBError sb_error; 76 lldb::WatchpointSP watchpoint_sp(GetSP()); 77 if (watchpoint_sp) { 78 sb_error.SetError(watchpoint_sp->GetError()); 79 } 80 return sb_error; 81 } 82 83 int32_t SBWatchpoint::GetHardwareIndex() { 84 int32_t hw_index = -1; 85 86 lldb::WatchpointSP watchpoint_sp(GetSP()); 87 if (watchpoint_sp) { 88 std::lock_guard<std::recursive_mutex> guard( 89 watchpoint_sp->GetTarget().GetAPIMutex()); 90 hw_index = watchpoint_sp->GetHardwareIndex(); 91 } 92 93 return hw_index; 94 } 95 96 addr_t SBWatchpoint::GetWatchAddress() { 97 addr_t ret_addr = LLDB_INVALID_ADDRESS; 98 99 lldb::WatchpointSP watchpoint_sp(GetSP()); 100 if (watchpoint_sp) { 101 std::lock_guard<std::recursive_mutex> guard( 102 watchpoint_sp->GetTarget().GetAPIMutex()); 103 ret_addr = watchpoint_sp->GetLoadAddress(); 104 } 105 106 return ret_addr; 107 } 108 109 size_t SBWatchpoint::GetWatchSize() { 110 size_t watch_size = 0; 111 112 lldb::WatchpointSP watchpoint_sp(GetSP()); 113 if (watchpoint_sp) { 114 std::lock_guard<std::recursive_mutex> guard( 115 watchpoint_sp->GetTarget().GetAPIMutex()); 116 watch_size = watchpoint_sp->GetByteSize(); 117 } 118 119 return watch_size; 120 } 121 122 void SBWatchpoint::SetEnabled(bool enabled) { 123 lldb::WatchpointSP watchpoint_sp(GetSP()); 124 if (watchpoint_sp) { 125 Target &target = watchpoint_sp->GetTarget(); 126 std::lock_guard<std::recursive_mutex> guard(target.GetAPIMutex()); 127 ProcessSP process_sp = target.GetProcessSP(); 128 const bool notify = true; 129 if (process_sp) { 130 if (enabled) 131 process_sp->EnableWatchpoint(watchpoint_sp.get(), notify); 132 else 133 process_sp->DisableWatchpoint(watchpoint_sp.get(), notify); 134 } else { 135 watchpoint_sp->SetEnabled(enabled, notify); 136 } 137 } 138 } 139 140 bool SBWatchpoint::IsEnabled() { 141 lldb::WatchpointSP watchpoint_sp(GetSP()); 142 if (watchpoint_sp) { 143 std::lock_guard<std::recursive_mutex> guard( 144 watchpoint_sp->GetTarget().GetAPIMutex()); 145 return watchpoint_sp->IsEnabled(); 146 } else 147 return false; 148 } 149 150 uint32_t SBWatchpoint::GetHitCount() { 151 uint32_t count = 0; 152 lldb::WatchpointSP watchpoint_sp(GetSP()); 153 if (watchpoint_sp) { 154 std::lock_guard<std::recursive_mutex> guard( 155 watchpoint_sp->GetTarget().GetAPIMutex()); 156 count = watchpoint_sp->GetHitCount(); 157 } 158 159 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 160 if (log) 161 log->Printf("SBWatchpoint(%p)::GetHitCount () => %u", 162 static_cast<void *>(watchpoint_sp.get()), count); 163 164 return count; 165 } 166 167 uint32_t SBWatchpoint::GetIgnoreCount() { 168 lldb::WatchpointSP watchpoint_sp(GetSP()); 169 if (watchpoint_sp) { 170 std::lock_guard<std::recursive_mutex> guard( 171 watchpoint_sp->GetTarget().GetAPIMutex()); 172 return watchpoint_sp->GetIgnoreCount(); 173 } else 174 return 0; 175 } 176 177 void SBWatchpoint::SetIgnoreCount(uint32_t n) { 178 lldb::WatchpointSP watchpoint_sp(GetSP()); 179 if (watchpoint_sp) { 180 std::lock_guard<std::recursive_mutex> guard( 181 watchpoint_sp->GetTarget().GetAPIMutex()); 182 watchpoint_sp->SetIgnoreCount(n); 183 } 184 } 185 186 const char *SBWatchpoint::GetCondition() { 187 lldb::WatchpointSP watchpoint_sp(GetSP()); 188 if (watchpoint_sp) { 189 std::lock_guard<std::recursive_mutex> guard( 190 watchpoint_sp->GetTarget().GetAPIMutex()); 191 return watchpoint_sp->GetConditionText(); 192 } 193 return NULL; 194 } 195 196 void SBWatchpoint::SetCondition(const char *condition) { 197 lldb::WatchpointSP watchpoint_sp(GetSP()); 198 if (watchpoint_sp) { 199 std::lock_guard<std::recursive_mutex> guard( 200 watchpoint_sp->GetTarget().GetAPIMutex()); 201 watchpoint_sp->SetCondition(condition); 202 } 203 } 204 205 bool SBWatchpoint::GetDescription(SBStream &description, 206 DescriptionLevel level) { 207 Stream &strm = description.ref(); 208 209 lldb::WatchpointSP watchpoint_sp(GetSP()); 210 if (watchpoint_sp) { 211 std::lock_guard<std::recursive_mutex> guard( 212 watchpoint_sp->GetTarget().GetAPIMutex()); 213 watchpoint_sp->GetDescription(&strm, level); 214 strm.EOL(); 215 } else 216 strm.PutCString("No value"); 217 218 return true; 219 } 220 221 void SBWatchpoint::Clear() { m_opaque_wp.reset(); } 222 223 lldb::WatchpointSP SBWatchpoint::GetSP() const { return m_opaque_wp.lock(); } 224 225 void SBWatchpoint::SetSP(const lldb::WatchpointSP &sp) { m_opaque_wp = sp; } 226 227 bool SBWatchpoint::EventIsWatchpointEvent(const lldb::SBEvent &event) { 228 return Watchpoint::WatchpointEventData::GetEventDataFromEvent(event.get()) != 229 NULL; 230 } 231 232 WatchpointEventType 233 SBWatchpoint::GetWatchpointEventTypeFromEvent(const SBEvent &event) { 234 if (event.IsValid()) 235 return Watchpoint::WatchpointEventData::GetWatchpointEventTypeFromEvent( 236 event.GetSP()); 237 return eWatchpointEventTypeInvalidType; 238 } 239 240 SBWatchpoint SBWatchpoint::GetWatchpointFromEvent(const lldb::SBEvent &event) { 241 SBWatchpoint sb_watchpoint; 242 if (event.IsValid()) 243 sb_watchpoint = 244 Watchpoint::WatchpointEventData::GetWatchpointFromEvent(event.GetSP()); 245 return sb_watchpoint; 246 } 247