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