1 //===-- SBBreakpointLocation.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/SBBreakpointLocation.h" 11 #include "lldb/API/SBAddress.h" 12 #include "lldb/API/SBDebugger.h" 13 #include "lldb/API/SBDefines.h" 14 #include "lldb/API/SBStream.h" 15 16 #include "lldb/Breakpoint/Breakpoint.h" 17 #include "lldb/Breakpoint/BreakpointLocation.h" 18 #include "lldb/Core/Debugger.h" 19 #include "lldb/Core/StreamFile.h" 20 #include "lldb/Interpreter/CommandInterpreter.h" 21 #include "lldb/Interpreter/ScriptInterpreter.h" 22 #include "lldb/Target/Target.h" 23 #include "lldb/Target/ThreadSpec.h" 24 #include "lldb/Utility/Log.h" 25 #include "lldb/Utility/Stream.h" 26 #include "lldb/lldb-defines.h" 27 #include "lldb/lldb-types.h" 28 29 using namespace lldb; 30 using namespace lldb_private; 31 32 SBBreakpointLocation::SBBreakpointLocation() {} 33 34 SBBreakpointLocation::SBBreakpointLocation( 35 const lldb::BreakpointLocationSP &break_loc_sp) 36 : m_opaque_wp(break_loc_sp) { 37 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 38 39 if (log) { 40 SBStream sstr; 41 GetDescription(sstr, lldb::eDescriptionLevelBrief); 42 LLDB_LOG(log, "location = {0} ({1})", break_loc_sp.get(), sstr.GetData()); 43 } 44 } 45 46 SBBreakpointLocation::SBBreakpointLocation(const SBBreakpointLocation &rhs) 47 : m_opaque_wp(rhs.m_opaque_wp) {} 48 49 const SBBreakpointLocation &SBBreakpointLocation:: 50 operator=(const SBBreakpointLocation &rhs) { 51 m_opaque_wp = rhs.m_opaque_wp; 52 return *this; 53 } 54 55 SBBreakpointLocation::~SBBreakpointLocation() {} 56 57 BreakpointLocationSP SBBreakpointLocation::GetSP() const { 58 return m_opaque_wp.lock(); 59 } 60 61 bool SBBreakpointLocation::IsValid() const { return bool(GetSP()); } 62 63 SBAddress SBBreakpointLocation::GetAddress() { 64 BreakpointLocationSP loc_sp = GetSP(); 65 if (loc_sp) 66 return SBAddress(&loc_sp->GetAddress()); 67 else 68 return SBAddress(); 69 } 70 71 addr_t SBBreakpointLocation::GetLoadAddress() { 72 addr_t ret_addr = LLDB_INVALID_ADDRESS; 73 BreakpointLocationSP loc_sp = GetSP(); 74 75 if (loc_sp) { 76 std::lock_guard<std::recursive_mutex> guard( 77 loc_sp->GetTarget().GetAPIMutex()); 78 ret_addr = loc_sp->GetLoadAddress(); 79 } 80 81 return ret_addr; 82 } 83 84 void SBBreakpointLocation::SetEnabled(bool enabled) { 85 BreakpointLocationSP loc_sp = GetSP(); 86 if (loc_sp) { 87 std::lock_guard<std::recursive_mutex> guard( 88 loc_sp->GetTarget().GetAPIMutex()); 89 loc_sp->SetEnabled(enabled); 90 } 91 } 92 93 bool SBBreakpointLocation::IsEnabled() { 94 BreakpointLocationSP loc_sp = GetSP(); 95 if (loc_sp) { 96 std::lock_guard<std::recursive_mutex> guard( 97 loc_sp->GetTarget().GetAPIMutex()); 98 return loc_sp->IsEnabled(); 99 } else 100 return false; 101 } 102 103 uint32_t SBBreakpointLocation::GetHitCount() { 104 BreakpointLocationSP loc_sp = GetSP(); 105 if (loc_sp) { 106 std::lock_guard<std::recursive_mutex> guard( 107 loc_sp->GetTarget().GetAPIMutex()); 108 return loc_sp->GetHitCount(); 109 } else 110 return 0; 111 } 112 113 uint32_t SBBreakpointLocation::GetIgnoreCount() { 114 BreakpointLocationSP loc_sp = GetSP(); 115 if (loc_sp) { 116 std::lock_guard<std::recursive_mutex> guard( 117 loc_sp->GetTarget().GetAPIMutex()); 118 return loc_sp->GetIgnoreCount(); 119 } else 120 return 0; 121 } 122 123 void SBBreakpointLocation::SetIgnoreCount(uint32_t n) { 124 BreakpointLocationSP loc_sp = GetSP(); 125 if (loc_sp) { 126 std::lock_guard<std::recursive_mutex> guard( 127 loc_sp->GetTarget().GetAPIMutex()); 128 loc_sp->SetIgnoreCount(n); 129 } 130 } 131 132 void SBBreakpointLocation::SetCondition(const char *condition) { 133 BreakpointLocationSP loc_sp = GetSP(); 134 if (loc_sp) { 135 std::lock_guard<std::recursive_mutex> guard( 136 loc_sp->GetTarget().GetAPIMutex()); 137 loc_sp->SetCondition(condition); 138 } 139 } 140 141 const char *SBBreakpointLocation::GetCondition() { 142 BreakpointLocationSP loc_sp = GetSP(); 143 if (loc_sp) { 144 std::lock_guard<std::recursive_mutex> guard( 145 loc_sp->GetTarget().GetAPIMutex()); 146 return loc_sp->GetConditionText(); 147 } 148 return NULL; 149 } 150 151 void SBBreakpointLocation::SetScriptCallbackFunction( 152 const char *callback_function_name) { 153 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 154 BreakpointLocationSP loc_sp = GetSP(); 155 LLDB_LOG(log, "location = {0}, callback = {1}", loc_sp.get(), 156 callback_function_name); 157 158 if (loc_sp) { 159 std::lock_guard<std::recursive_mutex> guard( 160 loc_sp->GetTarget().GetAPIMutex()); 161 BreakpointOptions *bp_options = loc_sp->GetLocationOptions(); 162 loc_sp->GetBreakpoint() 163 .GetTarget() 164 .GetDebugger() 165 .GetCommandInterpreter() 166 .GetScriptInterpreter() 167 ->SetBreakpointCommandCallbackFunction(bp_options, 168 callback_function_name); 169 } 170 } 171 172 SBError 173 SBBreakpointLocation::SetScriptCallbackBody(const char *callback_body_text) { 174 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 175 BreakpointLocationSP loc_sp = GetSP(); 176 LLDB_LOG(log, "location = {0}: callback body:\n{1}", loc_sp.get(), 177 callback_body_text); 178 179 SBError sb_error; 180 if (loc_sp) { 181 std::lock_guard<std::recursive_mutex> guard( 182 loc_sp->GetTarget().GetAPIMutex()); 183 BreakpointOptions *bp_options = loc_sp->GetLocationOptions(); 184 Status error = 185 loc_sp->GetBreakpoint() 186 .GetTarget() 187 .GetDebugger() 188 .GetCommandInterpreter() 189 .GetScriptInterpreter() 190 ->SetBreakpointCommandCallback(bp_options, callback_body_text); 191 sb_error.SetError(error); 192 } else 193 sb_error.SetErrorString("invalid breakpoint"); 194 195 return sb_error; 196 } 197 198 void SBBreakpointLocation::SetThreadID(tid_t thread_id) { 199 BreakpointLocationSP loc_sp = GetSP(); 200 if (loc_sp) { 201 std::lock_guard<std::recursive_mutex> guard( 202 loc_sp->GetTarget().GetAPIMutex()); 203 loc_sp->SetThreadID(thread_id); 204 } 205 } 206 207 tid_t SBBreakpointLocation::GetThreadID() { 208 tid_t tid = LLDB_INVALID_THREAD_ID; 209 BreakpointLocationSP loc_sp = GetSP(); 210 if (loc_sp) { 211 std::lock_guard<std::recursive_mutex> guard( 212 loc_sp->GetTarget().GetAPIMutex()); 213 return loc_sp->GetThreadID(); 214 } 215 return tid; 216 } 217 218 void SBBreakpointLocation::SetThreadIndex(uint32_t index) { 219 BreakpointLocationSP loc_sp = GetSP(); 220 if (loc_sp) { 221 std::lock_guard<std::recursive_mutex> guard( 222 loc_sp->GetTarget().GetAPIMutex()); 223 loc_sp->SetThreadIndex(index); 224 } 225 } 226 227 uint32_t SBBreakpointLocation::GetThreadIndex() const { 228 uint32_t thread_idx = UINT32_MAX; 229 BreakpointLocationSP loc_sp = GetSP(); 230 if (loc_sp) { 231 std::lock_guard<std::recursive_mutex> guard( 232 loc_sp->GetTarget().GetAPIMutex()); 233 return loc_sp->GetThreadIndex(); 234 } 235 return thread_idx; 236 } 237 238 void SBBreakpointLocation::SetThreadName(const char *thread_name) { 239 BreakpointLocationSP loc_sp = GetSP(); 240 if (loc_sp) { 241 std::lock_guard<std::recursive_mutex> guard( 242 loc_sp->GetTarget().GetAPIMutex()); 243 loc_sp->SetThreadName(thread_name); 244 } 245 } 246 247 const char *SBBreakpointLocation::GetThreadName() const { 248 BreakpointLocationSP loc_sp = GetSP(); 249 if (loc_sp) { 250 std::lock_guard<std::recursive_mutex> guard( 251 loc_sp->GetTarget().GetAPIMutex()); 252 return loc_sp->GetThreadName(); 253 } 254 return NULL; 255 } 256 257 void SBBreakpointLocation::SetQueueName(const char *queue_name) { 258 BreakpointLocationSP loc_sp = GetSP(); 259 if (loc_sp) { 260 std::lock_guard<std::recursive_mutex> guard( 261 loc_sp->GetTarget().GetAPIMutex()); 262 loc_sp->SetQueueName(queue_name); 263 } 264 } 265 266 const char *SBBreakpointLocation::GetQueueName() const { 267 BreakpointLocationSP loc_sp = GetSP(); 268 if (loc_sp) { 269 std::lock_guard<std::recursive_mutex> guard( 270 loc_sp->GetTarget().GetAPIMutex()); 271 loc_sp->GetQueueName(); 272 } 273 return NULL; 274 } 275 276 bool SBBreakpointLocation::IsResolved() { 277 BreakpointLocationSP loc_sp = GetSP(); 278 if (loc_sp) { 279 std::lock_guard<std::recursive_mutex> guard( 280 loc_sp->GetTarget().GetAPIMutex()); 281 return loc_sp->IsResolved(); 282 } 283 return false; 284 } 285 286 void SBBreakpointLocation::SetLocation( 287 const lldb::BreakpointLocationSP &break_loc_sp) { 288 // Uninstall the callbacks? 289 m_opaque_wp = break_loc_sp; 290 } 291 292 bool SBBreakpointLocation::GetDescription(SBStream &description, 293 DescriptionLevel level) { 294 Stream &strm = description.ref(); 295 BreakpointLocationSP loc_sp = GetSP(); 296 297 if (loc_sp) { 298 std::lock_guard<std::recursive_mutex> guard( 299 loc_sp->GetTarget().GetAPIMutex()); 300 loc_sp->GetDescription(&strm, level); 301 strm.EOL(); 302 } else 303 strm.PutCString("No value"); 304 305 return true; 306 } 307 308 break_id_t SBBreakpointLocation::GetID() { 309 BreakpointLocationSP loc_sp = GetSP(); 310 if (loc_sp) { 311 std::lock_guard<std::recursive_mutex> guard( 312 loc_sp->GetTarget().GetAPIMutex()); 313 return loc_sp->GetID(); 314 } else 315 return LLDB_INVALID_BREAK_ID; 316 } 317 318 SBBreakpoint SBBreakpointLocation::GetBreakpoint() { 319 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 320 BreakpointLocationSP loc_sp = GetSP(); 321 322 SBBreakpoint sb_bp; 323 if (loc_sp) { 324 std::lock_guard<std::recursive_mutex> guard( 325 loc_sp->GetTarget().GetAPIMutex()); 326 sb_bp = loc_sp->GetBreakpoint().shared_from_this(); 327 } 328 329 if (log) { 330 SBStream sstr; 331 sb_bp.GetDescription(sstr); 332 LLDB_LOG(log, "location = {0}, breakpoint = {1} ({2})", loc_sp.get(), 333 sb_bp.GetSP().get(), sstr.GetData()); 334 } 335 return sb_bp; 336 } 337