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::GetIgnoreCount() { 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->GetIgnoreCount(); 109 } else 110 return 0; 111 } 112 113 void SBBreakpointLocation::SetIgnoreCount(uint32_t n) { 114 BreakpointLocationSP loc_sp = GetSP(); 115 if (loc_sp) { 116 std::lock_guard<std::recursive_mutex> guard( 117 loc_sp->GetTarget().GetAPIMutex()); 118 loc_sp->SetIgnoreCount(n); 119 } 120 } 121 122 void SBBreakpointLocation::SetCondition(const char *condition) { 123 BreakpointLocationSP loc_sp = GetSP(); 124 if (loc_sp) { 125 std::lock_guard<std::recursive_mutex> guard( 126 loc_sp->GetTarget().GetAPIMutex()); 127 loc_sp->SetCondition(condition); 128 } 129 } 130 131 const char *SBBreakpointLocation::GetCondition() { 132 BreakpointLocationSP loc_sp = GetSP(); 133 if (loc_sp) { 134 std::lock_guard<std::recursive_mutex> guard( 135 loc_sp->GetTarget().GetAPIMutex()); 136 return loc_sp->GetConditionText(); 137 } 138 return NULL; 139 } 140 141 void SBBreakpointLocation::SetScriptCallbackFunction( 142 const char *callback_function_name) { 143 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 144 BreakpointLocationSP loc_sp = GetSP(); 145 LLDB_LOG(log, "location = {0}, callback = {1}", loc_sp.get(), 146 callback_function_name); 147 148 if (loc_sp) { 149 std::lock_guard<std::recursive_mutex> guard( 150 loc_sp->GetTarget().GetAPIMutex()); 151 BreakpointOptions *bp_options = loc_sp->GetLocationOptions(); 152 loc_sp->GetBreakpoint() 153 .GetTarget() 154 .GetDebugger() 155 .GetCommandInterpreter() 156 .GetScriptInterpreter() 157 ->SetBreakpointCommandCallbackFunction(bp_options, 158 callback_function_name); 159 } 160 } 161 162 SBError 163 SBBreakpointLocation::SetScriptCallbackBody(const char *callback_body_text) { 164 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 165 BreakpointLocationSP loc_sp = GetSP(); 166 LLDB_LOG(log, "location = {0}: callback body:\n{1}", loc_sp.get(), 167 callback_body_text); 168 169 SBError sb_error; 170 if (loc_sp) { 171 std::lock_guard<std::recursive_mutex> guard( 172 loc_sp->GetTarget().GetAPIMutex()); 173 BreakpointOptions *bp_options = loc_sp->GetLocationOptions(); 174 Error error = 175 loc_sp->GetBreakpoint() 176 .GetTarget() 177 .GetDebugger() 178 .GetCommandInterpreter() 179 .GetScriptInterpreter() 180 ->SetBreakpointCommandCallback(bp_options, callback_body_text); 181 sb_error.SetError(error); 182 } else 183 sb_error.SetErrorString("invalid breakpoint"); 184 185 return sb_error; 186 } 187 188 void SBBreakpointLocation::SetThreadID(tid_t thread_id) { 189 BreakpointLocationSP loc_sp = GetSP(); 190 if (loc_sp) { 191 std::lock_guard<std::recursive_mutex> guard( 192 loc_sp->GetTarget().GetAPIMutex()); 193 loc_sp->SetThreadID(thread_id); 194 } 195 } 196 197 tid_t SBBreakpointLocation::GetThreadID() { 198 tid_t tid = LLDB_INVALID_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 return loc_sp->GetThreadID(); 204 } 205 return tid; 206 } 207 208 void SBBreakpointLocation::SetThreadIndex(uint32_t index) { 209 BreakpointLocationSP loc_sp = GetSP(); 210 if (loc_sp) { 211 std::lock_guard<std::recursive_mutex> guard( 212 loc_sp->GetTarget().GetAPIMutex()); 213 loc_sp->SetThreadIndex(index); 214 } 215 } 216 217 uint32_t SBBreakpointLocation::GetThreadIndex() const { 218 uint32_t thread_idx = UINT32_MAX; 219 BreakpointLocationSP loc_sp = GetSP(); 220 if (loc_sp) { 221 std::lock_guard<std::recursive_mutex> guard( 222 loc_sp->GetTarget().GetAPIMutex()); 223 return loc_sp->GetThreadIndex(); 224 } 225 return thread_idx; 226 } 227 228 void SBBreakpointLocation::SetThreadName(const char *thread_name) { 229 BreakpointLocationSP loc_sp = GetSP(); 230 if (loc_sp) { 231 std::lock_guard<std::recursive_mutex> guard( 232 loc_sp->GetTarget().GetAPIMutex()); 233 loc_sp->SetThreadName(thread_name); 234 } 235 } 236 237 const char *SBBreakpointLocation::GetThreadName() const { 238 BreakpointLocationSP loc_sp = GetSP(); 239 if (loc_sp) { 240 std::lock_guard<std::recursive_mutex> guard( 241 loc_sp->GetTarget().GetAPIMutex()); 242 return loc_sp->GetThreadName(); 243 } 244 return NULL; 245 } 246 247 void SBBreakpointLocation::SetQueueName(const char *queue_name) { 248 BreakpointLocationSP loc_sp = GetSP(); 249 if (loc_sp) { 250 std::lock_guard<std::recursive_mutex> guard( 251 loc_sp->GetTarget().GetAPIMutex()); 252 loc_sp->SetQueueName(queue_name); 253 } 254 } 255 256 const char *SBBreakpointLocation::GetQueueName() const { 257 BreakpointLocationSP loc_sp = GetSP(); 258 if (loc_sp) { 259 std::lock_guard<std::recursive_mutex> guard( 260 loc_sp->GetTarget().GetAPIMutex()); 261 loc_sp->GetQueueName(); 262 } 263 return NULL; 264 } 265 266 bool SBBreakpointLocation::IsResolved() { 267 BreakpointLocationSP loc_sp = GetSP(); 268 if (loc_sp) { 269 std::lock_guard<std::recursive_mutex> guard( 270 loc_sp->GetTarget().GetAPIMutex()); 271 return loc_sp->IsResolved(); 272 } 273 return false; 274 } 275 276 void SBBreakpointLocation::SetLocation( 277 const lldb::BreakpointLocationSP &break_loc_sp) { 278 // Uninstall the callbacks? 279 m_opaque_wp = break_loc_sp; 280 } 281 282 bool SBBreakpointLocation::GetDescription(SBStream &description, 283 DescriptionLevel level) { 284 Stream &strm = description.ref(); 285 BreakpointLocationSP loc_sp = GetSP(); 286 287 if (loc_sp) { 288 std::lock_guard<std::recursive_mutex> guard( 289 loc_sp->GetTarget().GetAPIMutex()); 290 loc_sp->GetDescription(&strm, level); 291 strm.EOL(); 292 } else 293 strm.PutCString("No value"); 294 295 return true; 296 } 297 298 break_id_t SBBreakpointLocation::GetID() { 299 BreakpointLocationSP loc_sp = GetSP(); 300 if (loc_sp) { 301 std::lock_guard<std::recursive_mutex> guard( 302 loc_sp->GetTarget().GetAPIMutex()); 303 return loc_sp->GetID(); 304 } else 305 return LLDB_INVALID_BREAK_ID; 306 } 307 308 SBBreakpoint SBBreakpointLocation::GetBreakpoint() { 309 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 310 BreakpointLocationSP loc_sp = GetSP(); 311 312 SBBreakpoint sb_bp; 313 if (loc_sp) { 314 std::lock_guard<std::recursive_mutex> guard( 315 loc_sp->GetTarget().GetAPIMutex()); 316 sb_bp = loc_sp->GetBreakpoint().shared_from_this(); 317 } 318 319 if (log) { 320 SBStream sstr; 321 sb_bp.GetDescription(sstr); 322 LLDB_LOG(log, "location = {0}, breakpoint = {1} ({2})", loc_sp.get(), 323 sb_bp.GetSP().get(), sstr.GetData()); 324 } 325 return sb_bp; 326 } 327