1 //===-- SBWatchpoint.cpp --------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/API/SBWatchpoint.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() {} 31 32 SBWatchpoint::SBWatchpoint(const lldb::WatchpointSP &wp_sp) 33 : m_opaque_wp(wp_sp) { 34 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 35 36 if (log) { 37 SBStream sstr; 38 GetDescription(sstr, lldb::eDescriptionLevelBrief); 39 LLDB_LOG(log, "watchpoint = {0} ({1})", wp_sp.get(), sstr.GetData()); 40 } 41 } 42 43 SBWatchpoint::SBWatchpoint(const SBWatchpoint &rhs) 44 : m_opaque_wp(rhs.m_opaque_wp) {} 45 46 const SBWatchpoint &SBWatchpoint::operator=(const SBWatchpoint &rhs) { 47 m_opaque_wp = rhs.m_opaque_wp; 48 return *this; 49 } 50 51 SBWatchpoint::~SBWatchpoint() {} 52 53 watch_id_t SBWatchpoint::GetID() { 54 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 55 56 watch_id_t watch_id = LLDB_INVALID_WATCH_ID; 57 lldb::WatchpointSP watchpoint_sp(GetSP()); 58 if (watchpoint_sp) 59 watch_id = watchpoint_sp->GetID(); 60 61 if (log) { 62 if (watch_id == LLDB_INVALID_WATCH_ID) 63 log->Printf("SBWatchpoint(%p)::GetID () => LLDB_INVALID_WATCH_ID", 64 static_cast<void *>(watchpoint_sp.get())); 65 else 66 log->Printf("SBWatchpoint(%p)::GetID () => %u", 67 static_cast<void *>(watchpoint_sp.get()), watch_id); 68 } 69 70 return watch_id; 71 } 72 73 bool SBWatchpoint::IsValid() const { return bool(m_opaque_wp.lock()); } 74 75 SBError SBWatchpoint::GetError() { 76 SBError sb_error; 77 lldb::WatchpointSP watchpoint_sp(GetSP()); 78 if (watchpoint_sp) { 79 sb_error.SetError(watchpoint_sp->GetError()); 80 } 81 return sb_error; 82 } 83 84 int32_t SBWatchpoint::GetHardwareIndex() { 85 int32_t hw_index = -1; 86 87 lldb::WatchpointSP watchpoint_sp(GetSP()); 88 if (watchpoint_sp) { 89 std::lock_guard<std::recursive_mutex> guard( 90 watchpoint_sp->GetTarget().GetAPIMutex()); 91 hw_index = watchpoint_sp->GetHardwareIndex(); 92 } 93 94 return hw_index; 95 } 96 97 addr_t SBWatchpoint::GetWatchAddress() { 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 size_t watch_size = 0; 112 113 lldb::WatchpointSP watchpoint_sp(GetSP()); 114 if (watchpoint_sp) { 115 std::lock_guard<std::recursive_mutex> guard( 116 watchpoint_sp->GetTarget().GetAPIMutex()); 117 watch_size = watchpoint_sp->GetByteSize(); 118 } 119 120 return watch_size; 121 } 122 123 void SBWatchpoint::SetEnabled(bool enabled) { 124 lldb::WatchpointSP watchpoint_sp(GetSP()); 125 if (watchpoint_sp) { 126 Target &target = watchpoint_sp->GetTarget(); 127 std::lock_guard<std::recursive_mutex> guard(target.GetAPIMutex()); 128 ProcessSP process_sp = target.GetProcessSP(); 129 const bool notify = true; 130 if (process_sp) { 131 if (enabled) 132 process_sp->EnableWatchpoint(watchpoint_sp.get(), notify); 133 else 134 process_sp->DisableWatchpoint(watchpoint_sp.get(), notify); 135 } else { 136 watchpoint_sp->SetEnabled(enabled, notify); 137 } 138 } 139 } 140 141 bool SBWatchpoint::IsEnabled() { 142 lldb::WatchpointSP watchpoint_sp(GetSP()); 143 if (watchpoint_sp) { 144 std::lock_guard<std::recursive_mutex> guard( 145 watchpoint_sp->GetTarget().GetAPIMutex()); 146 return watchpoint_sp->IsEnabled(); 147 } else 148 return false; 149 } 150 151 uint32_t SBWatchpoint::GetHitCount() { 152 uint32_t count = 0; 153 lldb::WatchpointSP watchpoint_sp(GetSP()); 154 if (watchpoint_sp) { 155 std::lock_guard<std::recursive_mutex> guard( 156 watchpoint_sp->GetTarget().GetAPIMutex()); 157 count = watchpoint_sp->GetHitCount(); 158 } 159 160 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 161 if (log) 162 log->Printf("SBWatchpoint(%p)::GetHitCount () => %u", 163 static_cast<void *>(watchpoint_sp.get()), count); 164 165 return count; 166 } 167 168 uint32_t SBWatchpoint::GetIgnoreCount() { 169 lldb::WatchpointSP watchpoint_sp(GetSP()); 170 if (watchpoint_sp) { 171 std::lock_guard<std::recursive_mutex> guard( 172 watchpoint_sp->GetTarget().GetAPIMutex()); 173 return watchpoint_sp->GetIgnoreCount(); 174 } else 175 return 0; 176 } 177 178 void SBWatchpoint::SetIgnoreCount(uint32_t n) { 179 lldb::WatchpointSP watchpoint_sp(GetSP()); 180 if (watchpoint_sp) { 181 std::lock_guard<std::recursive_mutex> guard( 182 watchpoint_sp->GetTarget().GetAPIMutex()); 183 watchpoint_sp->SetIgnoreCount(n); 184 } 185 } 186 187 const char *SBWatchpoint::GetCondition() { 188 lldb::WatchpointSP watchpoint_sp(GetSP()); 189 if (watchpoint_sp) { 190 std::lock_guard<std::recursive_mutex> guard( 191 watchpoint_sp->GetTarget().GetAPIMutex()); 192 return watchpoint_sp->GetConditionText(); 193 } 194 return NULL; 195 } 196 197 void SBWatchpoint::SetCondition(const char *condition) { 198 lldb::WatchpointSP watchpoint_sp(GetSP()); 199 if (watchpoint_sp) { 200 std::lock_guard<std::recursive_mutex> guard( 201 watchpoint_sp->GetTarget().GetAPIMutex()); 202 watchpoint_sp->SetCondition(condition); 203 } 204 } 205 206 bool SBWatchpoint::GetDescription(SBStream &description, 207 DescriptionLevel level) { 208 Stream &strm = description.ref(); 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->GetDescription(&strm, level); 215 strm.EOL(); 216 } else 217 strm.PutCString("No value"); 218 219 return true; 220 } 221 222 void SBWatchpoint::Clear() { m_opaque_wp.reset(); } 223 224 lldb::WatchpointSP SBWatchpoint::GetSP() const { return m_opaque_wp.lock(); } 225 226 void SBWatchpoint::SetSP(const lldb::WatchpointSP &sp) { m_opaque_wp = sp; } 227 228 bool SBWatchpoint::EventIsWatchpointEvent(const lldb::SBEvent &event) { 229 return Watchpoint::WatchpointEventData::GetEventDataFromEvent(event.get()) != 230 NULL; 231 } 232 233 WatchpointEventType 234 SBWatchpoint::GetWatchpointEventTypeFromEvent(const SBEvent &event) { 235 if (event.IsValid()) 236 return Watchpoint::WatchpointEventData::GetWatchpointEventTypeFromEvent( 237 event.GetSP()); 238 return eWatchpointEventTypeInvalidType; 239 } 240 241 SBWatchpoint SBWatchpoint::GetWatchpointFromEvent(const lldb::SBEvent &event) { 242 SBWatchpoint sb_watchpoint; 243 if (event.IsValid()) 244 sb_watchpoint = 245 Watchpoint::WatchpointEventData::GetWatchpointFromEvent(event.GetSP()); 246 return sb_watchpoint; 247 } 248