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 if (process_sp) { 134 if (enabled) 135 process_sp->EnableWatchpoint(watchpoint_sp.get(), false); 136 else 137 process_sp->DisableWatchpoint(watchpoint_sp.get(), false); 138 } else { 139 watchpoint_sp->SetEnabled(enabled); 140 } 141 } 142 } 143 144 bool SBWatchpoint::IsEnabled() { 145 lldb::WatchpointSP watchpoint_sp(GetSP()); 146 if (watchpoint_sp) { 147 std::lock_guard<std::recursive_mutex> guard( 148 watchpoint_sp->GetTarget().GetAPIMutex()); 149 return watchpoint_sp->IsEnabled(); 150 } else 151 return false; 152 } 153 154 uint32_t SBWatchpoint::GetHitCount() { 155 uint32_t count = 0; 156 lldb::WatchpointSP watchpoint_sp(GetSP()); 157 if (watchpoint_sp) { 158 std::lock_guard<std::recursive_mutex> guard( 159 watchpoint_sp->GetTarget().GetAPIMutex()); 160 count = watchpoint_sp->GetHitCount(); 161 } 162 163 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 164 if (log) 165 log->Printf("SBWatchpoint(%p)::GetHitCount () => %u", 166 static_cast<void *>(watchpoint_sp.get()), count); 167 168 return count; 169 } 170 171 uint32_t SBWatchpoint::GetIgnoreCount() { 172 lldb::WatchpointSP watchpoint_sp(GetSP()); 173 if (watchpoint_sp) { 174 std::lock_guard<std::recursive_mutex> guard( 175 watchpoint_sp->GetTarget().GetAPIMutex()); 176 return watchpoint_sp->GetIgnoreCount(); 177 } else 178 return 0; 179 } 180 181 void SBWatchpoint::SetIgnoreCount(uint32_t n) { 182 lldb::WatchpointSP watchpoint_sp(GetSP()); 183 if (watchpoint_sp) { 184 std::lock_guard<std::recursive_mutex> guard( 185 watchpoint_sp->GetTarget().GetAPIMutex()); 186 watchpoint_sp->SetIgnoreCount(n); 187 } 188 } 189 190 const char *SBWatchpoint::GetCondition() { 191 lldb::WatchpointSP watchpoint_sp(GetSP()); 192 if (watchpoint_sp) { 193 std::lock_guard<std::recursive_mutex> guard( 194 watchpoint_sp->GetTarget().GetAPIMutex()); 195 return watchpoint_sp->GetConditionText(); 196 } 197 return NULL; 198 } 199 200 void SBWatchpoint::SetCondition(const char *condition) { 201 lldb::WatchpointSP watchpoint_sp(GetSP()); 202 if (watchpoint_sp) { 203 std::lock_guard<std::recursive_mutex> guard( 204 watchpoint_sp->GetTarget().GetAPIMutex()); 205 watchpoint_sp->SetCondition(condition); 206 } 207 } 208 209 bool SBWatchpoint::GetDescription(SBStream &description, 210 DescriptionLevel level) { 211 Stream &strm = description.ref(); 212 213 lldb::WatchpointSP watchpoint_sp(GetSP()); 214 if (watchpoint_sp) { 215 std::lock_guard<std::recursive_mutex> guard( 216 watchpoint_sp->GetTarget().GetAPIMutex()); 217 watchpoint_sp->GetDescription(&strm, level); 218 strm.EOL(); 219 } else 220 strm.PutCString("No value"); 221 222 return true; 223 } 224 225 void SBWatchpoint::Clear() { m_opaque_sp.reset(); } 226 227 lldb::WatchpointSP SBWatchpoint::GetSP() const { return m_opaque_sp; } 228 229 void SBWatchpoint::SetSP(const lldb::WatchpointSP &sp) { m_opaque_sp = sp; } 230 231 bool SBWatchpoint::EventIsWatchpointEvent(const lldb::SBEvent &event) { 232 return Watchpoint::WatchpointEventData::GetEventDataFromEvent(event.get()) != 233 NULL; 234 } 235 236 WatchpointEventType 237 SBWatchpoint::GetWatchpointEventTypeFromEvent(const SBEvent &event) { 238 if (event.IsValid()) 239 return Watchpoint::WatchpointEventData::GetWatchpointEventTypeFromEvent( 240 event.GetSP()); 241 return eWatchpointEventTypeInvalidType; 242 } 243 244 SBWatchpoint SBWatchpoint::GetWatchpointFromEvent(const lldb::SBEvent &event) { 245 SBWatchpoint sb_watchpoint; 246 if (event.IsValid()) 247 sb_watchpoint.m_opaque_sp = 248 Watchpoint::WatchpointEventData::GetWatchpointFromEvent(event.GetSP()); 249 return sb_watchpoint; 250 } 251