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 #include "lldb/API/SBStringList.h" 16 17 #include "lldb/Breakpoint/Breakpoint.h" 18 #include "lldb/Breakpoint/BreakpointLocation.h" 19 #include "lldb/Core/Debugger.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/Utility/Log.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::GetHitCount() { 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->GetHitCount(); 110 } else 111 return 0; 112 } 113 114 uint32_t SBBreakpointLocation::GetIgnoreCount() { 115 BreakpointLocationSP loc_sp = GetSP(); 116 if (loc_sp) { 117 std::lock_guard<std::recursive_mutex> guard( 118 loc_sp->GetTarget().GetAPIMutex()); 119 return loc_sp->GetIgnoreCount(); 120 } else 121 return 0; 122 } 123 124 void SBBreakpointLocation::SetIgnoreCount(uint32_t n) { 125 BreakpointLocationSP loc_sp = GetSP(); 126 if (loc_sp) { 127 std::lock_guard<std::recursive_mutex> guard( 128 loc_sp->GetTarget().GetAPIMutex()); 129 loc_sp->SetIgnoreCount(n); 130 } 131 } 132 133 void SBBreakpointLocation::SetCondition(const char *condition) { 134 BreakpointLocationSP loc_sp = GetSP(); 135 if (loc_sp) { 136 std::lock_guard<std::recursive_mutex> guard( 137 loc_sp->GetTarget().GetAPIMutex()); 138 loc_sp->SetCondition(condition); 139 } 140 } 141 142 const char *SBBreakpointLocation::GetCondition() { 143 BreakpointLocationSP loc_sp = GetSP(); 144 if (loc_sp) { 145 std::lock_guard<std::recursive_mutex> guard( 146 loc_sp->GetTarget().GetAPIMutex()); 147 return loc_sp->GetConditionText(); 148 } 149 return NULL; 150 } 151 152 void SBBreakpointLocation::SetAutoContinue(bool auto_continue) { 153 BreakpointLocationSP loc_sp = GetSP(); 154 if (loc_sp) { 155 std::lock_guard<std::recursive_mutex> guard( 156 loc_sp->GetTarget().GetAPIMutex()); 157 loc_sp->SetAutoContinue(auto_continue); 158 } 159 } 160 161 bool SBBreakpointLocation::GetAutoContinue() { 162 BreakpointLocationSP loc_sp = GetSP(); 163 if (loc_sp) { 164 std::lock_guard<std::recursive_mutex> guard( 165 loc_sp->GetTarget().GetAPIMutex()); 166 return loc_sp->IsAutoContinue(); 167 } 168 return false; 169 } 170 171 void SBBreakpointLocation::SetScriptCallbackFunction( 172 const char *callback_function_name) { 173 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 174 BreakpointLocationSP loc_sp = GetSP(); 175 LLDB_LOG(log, "location = {0}, callback = {1}", loc_sp.get(), 176 callback_function_name); 177 178 if (loc_sp) { 179 std::lock_guard<std::recursive_mutex> guard( 180 loc_sp->GetTarget().GetAPIMutex()); 181 BreakpointOptions *bp_options = loc_sp->GetLocationOptions(); 182 loc_sp->GetBreakpoint() 183 .GetTarget() 184 .GetDebugger() 185 .GetCommandInterpreter() 186 .GetScriptInterpreter() 187 ->SetBreakpointCommandCallbackFunction(bp_options, 188 callback_function_name); 189 } 190 } 191 192 SBError 193 SBBreakpointLocation::SetScriptCallbackBody(const char *callback_body_text) { 194 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 195 BreakpointLocationSP loc_sp = GetSP(); 196 LLDB_LOG(log, "location = {0}: callback body:\n{1}", loc_sp.get(), 197 callback_body_text); 198 199 SBError sb_error; 200 if (loc_sp) { 201 std::lock_guard<std::recursive_mutex> guard( 202 loc_sp->GetTarget().GetAPIMutex()); 203 BreakpointOptions *bp_options = loc_sp->GetLocationOptions(); 204 Status error = 205 loc_sp->GetBreakpoint() 206 .GetTarget() 207 .GetDebugger() 208 .GetCommandInterpreter() 209 .GetScriptInterpreter() 210 ->SetBreakpointCommandCallback(bp_options, callback_body_text); 211 sb_error.SetError(error); 212 } else 213 sb_error.SetErrorString("invalid breakpoint"); 214 215 return sb_error; 216 } 217 218 void SBBreakpointLocation::SetCommandLineCommands(SBStringList &commands) { 219 BreakpointLocationSP loc_sp = GetSP(); 220 if (!loc_sp) 221 return; 222 if (commands.GetSize() == 0) 223 return; 224 225 std::lock_guard<std::recursive_mutex> guard( 226 loc_sp->GetTarget().GetAPIMutex()); 227 std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up( 228 new BreakpointOptions::CommandData(*commands, eScriptLanguageNone)); 229 230 loc_sp->GetLocationOptions()->SetCommandDataCallback(cmd_data_up); 231 } 232 233 bool SBBreakpointLocation::GetCommandLineCommands(SBStringList &commands) { 234 BreakpointLocationSP loc_sp = GetSP(); 235 if (!loc_sp) 236 return false; 237 StringList command_list; 238 bool has_commands = 239 loc_sp->GetLocationOptions()->GetCommandLineCallbacks(command_list); 240 if (has_commands) 241 commands.AppendList(command_list); 242 return has_commands; 243 } 244 245 void SBBreakpointLocation::SetThreadID(tid_t thread_id) { 246 BreakpointLocationSP loc_sp = GetSP(); 247 if (loc_sp) { 248 std::lock_guard<std::recursive_mutex> guard( 249 loc_sp->GetTarget().GetAPIMutex()); 250 loc_sp->SetThreadID(thread_id); 251 } 252 } 253 254 tid_t SBBreakpointLocation::GetThreadID() { 255 tid_t tid = LLDB_INVALID_THREAD_ID; 256 BreakpointLocationSP loc_sp = GetSP(); 257 if (loc_sp) { 258 std::lock_guard<std::recursive_mutex> guard( 259 loc_sp->GetTarget().GetAPIMutex()); 260 return loc_sp->GetThreadID(); 261 } 262 return tid; 263 } 264 265 void SBBreakpointLocation::SetThreadIndex(uint32_t index) { 266 BreakpointLocationSP loc_sp = GetSP(); 267 if (loc_sp) { 268 std::lock_guard<std::recursive_mutex> guard( 269 loc_sp->GetTarget().GetAPIMutex()); 270 loc_sp->SetThreadIndex(index); 271 } 272 } 273 274 uint32_t SBBreakpointLocation::GetThreadIndex() const { 275 uint32_t thread_idx = UINT32_MAX; 276 BreakpointLocationSP loc_sp = GetSP(); 277 if (loc_sp) { 278 std::lock_guard<std::recursive_mutex> guard( 279 loc_sp->GetTarget().GetAPIMutex()); 280 return loc_sp->GetThreadIndex(); 281 } 282 return thread_idx; 283 } 284 285 void SBBreakpointLocation::SetThreadName(const char *thread_name) { 286 BreakpointLocationSP loc_sp = GetSP(); 287 if (loc_sp) { 288 std::lock_guard<std::recursive_mutex> guard( 289 loc_sp->GetTarget().GetAPIMutex()); 290 loc_sp->SetThreadName(thread_name); 291 } 292 } 293 294 const char *SBBreakpointLocation::GetThreadName() const { 295 BreakpointLocationSP loc_sp = GetSP(); 296 if (loc_sp) { 297 std::lock_guard<std::recursive_mutex> guard( 298 loc_sp->GetTarget().GetAPIMutex()); 299 return loc_sp->GetThreadName(); 300 } 301 return NULL; 302 } 303 304 void SBBreakpointLocation::SetQueueName(const char *queue_name) { 305 BreakpointLocationSP loc_sp = GetSP(); 306 if (loc_sp) { 307 std::lock_guard<std::recursive_mutex> guard( 308 loc_sp->GetTarget().GetAPIMutex()); 309 loc_sp->SetQueueName(queue_name); 310 } 311 } 312 313 const char *SBBreakpointLocation::GetQueueName() const { 314 BreakpointLocationSP loc_sp = GetSP(); 315 if (loc_sp) { 316 std::lock_guard<std::recursive_mutex> guard( 317 loc_sp->GetTarget().GetAPIMutex()); 318 loc_sp->GetQueueName(); 319 } 320 return NULL; 321 } 322 323 bool SBBreakpointLocation::IsResolved() { 324 BreakpointLocationSP loc_sp = GetSP(); 325 if (loc_sp) { 326 std::lock_guard<std::recursive_mutex> guard( 327 loc_sp->GetTarget().GetAPIMutex()); 328 return loc_sp->IsResolved(); 329 } 330 return false; 331 } 332 333 void SBBreakpointLocation::SetLocation( 334 const lldb::BreakpointLocationSP &break_loc_sp) { 335 // Uninstall the callbacks? 336 m_opaque_wp = break_loc_sp; 337 } 338 339 bool SBBreakpointLocation::GetDescription(SBStream &description, 340 DescriptionLevel level) { 341 Stream &strm = description.ref(); 342 BreakpointLocationSP loc_sp = GetSP(); 343 344 if (loc_sp) { 345 std::lock_guard<std::recursive_mutex> guard( 346 loc_sp->GetTarget().GetAPIMutex()); 347 loc_sp->GetDescription(&strm, level); 348 strm.EOL(); 349 } else 350 strm.PutCString("No value"); 351 352 return true; 353 } 354 355 break_id_t SBBreakpointLocation::GetID() { 356 BreakpointLocationSP loc_sp = GetSP(); 357 if (loc_sp) { 358 std::lock_guard<std::recursive_mutex> guard( 359 loc_sp->GetTarget().GetAPIMutex()); 360 return loc_sp->GetID(); 361 } else 362 return LLDB_INVALID_BREAK_ID; 363 } 364 365 SBBreakpoint SBBreakpointLocation::GetBreakpoint() { 366 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 367 BreakpointLocationSP loc_sp = GetSP(); 368 369 SBBreakpoint sb_bp; 370 if (loc_sp) { 371 std::lock_guard<std::recursive_mutex> guard( 372 loc_sp->GetTarget().GetAPIMutex()); 373 sb_bp = loc_sp->GetBreakpoint().shared_from_this(); 374 } 375 376 if (log) { 377 SBStream sstr; 378 sb_bp.GetDescription(sstr); 379 LLDB_LOG(log, "location = {0}, breakpoint = {1} ({2})", loc_sp.get(), 380 sb_bp.GetSP().get(), sstr.GetData()); 381 } 382 return sb_bp; 383 } 384