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/Log.h" 20 #include "lldb/Core/Stream.h" 21 #include "lldb/Core/StreamFile.h" 22 #include "lldb/Target/Process.h" 23 #include "lldb/Target/Target.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() : m_opaque_sp() {} 31 32 SBWatchpoint::SBWatchpoint(const lldb::WatchpointSP &wp_sp) 33 : m_opaque_sp(wp_sp) { 34 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 35 36 if (log) { 37 SBStream sstr; 38 GetDescription(sstr, lldb::eDescriptionLevelBrief); 39 log->Printf("SBWatchpoint::SBWatchpoint (const lldb::WatchpointSP &wp_sp" 40 "=%p) => this.sp = %p (%s)", 41 static_cast<void *>(wp_sp.get()), 42 static_cast<void *>(m_opaque_sp.get()), sstr.GetData()); 43 } 44 } 45 46 SBWatchpoint::SBWatchpoint(const SBWatchpoint &rhs) 47 : m_opaque_sp(rhs.m_opaque_sp) {} 48 49 const SBWatchpoint &SBWatchpoint::operator=(const SBWatchpoint &rhs) { 50 if (this != &rhs) 51 m_opaque_sp = rhs.m_opaque_sp; 52 return *this; 53 } 54 55 SBWatchpoint::~SBWatchpoint() {} 56 57 watch_id_t SBWatchpoint::GetID() { 58 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 59 60 watch_id_t watch_id = LLDB_INVALID_WATCH_ID; 61 lldb::WatchpointSP watchpoint_sp(GetSP()); 62 if (watchpoint_sp) 63 watch_id = watchpoint_sp->GetID(); 64 65 if (log) { 66 if (watch_id == LLDB_INVALID_WATCH_ID) 67 log->Printf("SBWatchpoint(%p)::GetID () => LLDB_INVALID_WATCH_ID", 68 static_cast<void *>(watchpoint_sp.get())); 69 else 70 log->Printf("SBWatchpoint(%p)::GetID () => %u", 71 static_cast<void *>(watchpoint_sp.get()), watch_id); 72 } 73 74 return watch_id; 75 } 76 77 bool SBWatchpoint::IsValid() const { return (bool)m_opaque_sp; } 78 79 SBError SBWatchpoint::GetError() { 80 SBError sb_error; 81 lldb::WatchpointSP watchpoint_sp(GetSP()); 82 if (watchpoint_sp) { 83 sb_error.SetError(watchpoint_sp->GetError()); 84 } 85 return sb_error; 86 } 87 88 int32_t SBWatchpoint::GetHardwareIndex() { 89 int32_t hw_index = -1; 90 91 lldb::WatchpointSP watchpoint_sp(GetSP()); 92 if (watchpoint_sp) { 93 std::lock_guard<std::recursive_mutex> guard( 94 watchpoint_sp->GetTarget().GetAPIMutex()); 95 hw_index = watchpoint_sp->GetHardwareIndex(); 96 } 97 98 return hw_index; 99 } 100 101 addr_t SBWatchpoint::GetWatchAddress() { 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 size_t watch_size = 0; 116 117 lldb::WatchpointSP watchpoint_sp(GetSP()); 118 if (watchpoint_sp) { 119 std::lock_guard<std::recursive_mutex> guard( 120 watchpoint_sp->GetTarget().GetAPIMutex()); 121 watch_size = watchpoint_sp->GetByteSize(); 122 } 123 124 return watch_size; 125 } 126 127 void SBWatchpoint::SetEnabled(bool enabled) { 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::WatchpointSP watchpoint_sp(GetSP()); 147 if (watchpoint_sp) { 148 std::lock_guard<std::recursive_mutex> guard( 149 watchpoint_sp->GetTarget().GetAPIMutex()); 150 return watchpoint_sp->IsEnabled(); 151 } else 152 return false; 153 } 154 155 uint32_t SBWatchpoint::GetHitCount() { 156 uint32_t count = 0; 157 lldb::WatchpointSP watchpoint_sp(GetSP()); 158 if (watchpoint_sp) { 159 std::lock_guard<std::recursive_mutex> guard( 160 watchpoint_sp->GetTarget().GetAPIMutex()); 161 count = watchpoint_sp->GetHitCount(); 162 } 163 164 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 165 if (log) 166 log->Printf("SBWatchpoint(%p)::GetHitCount () => %u", 167 static_cast<void *>(watchpoint_sp.get()), count); 168 169 return count; 170 } 171 172 uint32_t SBWatchpoint::GetIgnoreCount() { 173 lldb::WatchpointSP watchpoint_sp(GetSP()); 174 if (watchpoint_sp) { 175 std::lock_guard<std::recursive_mutex> guard( 176 watchpoint_sp->GetTarget().GetAPIMutex()); 177 return watchpoint_sp->GetIgnoreCount(); 178 } else 179 return 0; 180 } 181 182 void SBWatchpoint::SetIgnoreCount(uint32_t n) { 183 lldb::WatchpointSP watchpoint_sp(GetSP()); 184 if (watchpoint_sp) { 185 std::lock_guard<std::recursive_mutex> guard( 186 watchpoint_sp->GetTarget().GetAPIMutex()); 187 watchpoint_sp->SetIgnoreCount(n); 188 } 189 } 190 191 const char *SBWatchpoint::GetCondition() { 192 lldb::WatchpointSP watchpoint_sp(GetSP()); 193 if (watchpoint_sp) { 194 std::lock_guard<std::recursive_mutex> guard( 195 watchpoint_sp->GetTarget().GetAPIMutex()); 196 return watchpoint_sp->GetConditionText(); 197 } 198 return NULL; 199 } 200 201 void SBWatchpoint::SetCondition(const char *condition) { 202 lldb::WatchpointSP watchpoint_sp(GetSP()); 203 if (watchpoint_sp) { 204 std::lock_guard<std::recursive_mutex> guard( 205 watchpoint_sp->GetTarget().GetAPIMutex()); 206 watchpoint_sp->SetCondition(condition); 207 } 208 } 209 210 bool SBWatchpoint::GetDescription(SBStream &description, 211 DescriptionLevel level) { 212 Stream &strm = description.ref(); 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->GetDescription(&strm, level); 219 strm.EOL(); 220 } else 221 strm.PutCString("No value"); 222 223 return true; 224 } 225 226 void SBWatchpoint::Clear() { m_opaque_sp.reset(); } 227 228 lldb::WatchpointSP SBWatchpoint::GetSP() const { return m_opaque_sp; } 229 230 void SBWatchpoint::SetSP(const lldb::WatchpointSP &sp) { m_opaque_sp = sp; } 231 232 bool SBWatchpoint::EventIsWatchpointEvent(const lldb::SBEvent &event) { 233 return Watchpoint::WatchpointEventData::GetEventDataFromEvent(event.get()) != 234 NULL; 235 } 236 237 WatchpointEventType 238 SBWatchpoint::GetWatchpointEventTypeFromEvent(const SBEvent &event) { 239 if (event.IsValid()) 240 return Watchpoint::WatchpointEventData::GetWatchpointEventTypeFromEvent( 241 event.GetSP()); 242 return eWatchpointEventTypeInvalidType; 243 } 244 245 SBWatchpoint SBWatchpoint::GetWatchpointFromEvent(const lldb::SBEvent &event) { 246 SBWatchpoint sb_watchpoint; 247 if (event.IsValid()) 248 sb_watchpoint.m_opaque_sp = 249 Watchpoint::WatchpointEventData::GetWatchpointFromEvent(event.GetSP()); 250 return sb_watchpoint; 251 } 252