1 //===-- SBBreakpoint.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 // C Includes 11 // C++ Includes 12 // Other libraries and framework includes 13 // Project includes 14 #include "lldb/API/SBBreakpoint.h" 15 #include "lldb/API/SBBreakpointLocation.h" 16 #include "lldb/API/SBDebugger.h" 17 #include "lldb/API/SBEvent.h" 18 #include "lldb/API/SBProcess.h" 19 #include "lldb/API/SBStream.h" 20 #include "lldb/API/SBStringList.h" 21 #include "lldb/API/SBThread.h" 22 23 #include "lldb/Breakpoint/Breakpoint.h" 24 #include "lldb/Breakpoint/BreakpointIDList.h" 25 #include "lldb/Breakpoint/BreakpointLocation.h" 26 #include "lldb/Breakpoint/StoppointCallbackContext.h" 27 #include "lldb/Core/Address.h" 28 #include "lldb/Core/Debugger.h" 29 #include "lldb/Core/StreamFile.h" 30 #include "lldb/Interpreter/CommandInterpreter.h" 31 #include "lldb/Interpreter/ScriptInterpreter.h" 32 #include "lldb/Target/Process.h" 33 #include "lldb/Target/SectionLoadList.h" 34 #include "lldb/Target/Target.h" 35 #include "lldb/Target/Thread.h" 36 #include "lldb/Target/ThreadSpec.h" 37 #include "lldb/Utility/Log.h" 38 #include "lldb/Utility/Stream.h" 39 40 #include "SBBreakpointOptionCommon.h" 41 42 #include "lldb/lldb-enumerations.h" 43 44 #include "llvm/ADT/STLExtras.h" 45 46 using namespace lldb; 47 using namespace lldb_private; 48 49 SBBreakpoint::SBBreakpoint() {} 50 51 SBBreakpoint::SBBreakpoint(const SBBreakpoint &rhs) 52 : m_opaque_wp(rhs.m_opaque_wp) {} 53 54 SBBreakpoint::SBBreakpoint(const lldb::BreakpointSP &bp_sp) 55 : m_opaque_wp(bp_sp) {} 56 57 SBBreakpoint::~SBBreakpoint() = default; 58 59 const SBBreakpoint &SBBreakpoint::operator=(const SBBreakpoint &rhs) { 60 m_opaque_wp = rhs.m_opaque_wp; 61 return *this; 62 } 63 64 bool SBBreakpoint::operator==(const lldb::SBBreakpoint &rhs) { 65 return m_opaque_wp.lock() == rhs.m_opaque_wp.lock(); 66 } 67 68 bool SBBreakpoint::operator!=(const lldb::SBBreakpoint &rhs) { 69 return m_opaque_wp.lock() != rhs.m_opaque_wp.lock(); 70 } 71 72 break_id_t SBBreakpoint::GetID() const { 73 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 74 75 break_id_t break_id = LLDB_INVALID_BREAK_ID; 76 BreakpointSP bkpt_sp = GetSP(); 77 if (bkpt_sp) 78 break_id = bkpt_sp->GetID(); 79 80 LLDB_LOG(log, "breakpoint = {0}, id = {1}", bkpt_sp.get(), break_id); 81 return break_id; 82 } 83 84 bool SBBreakpoint::IsValid() const { 85 BreakpointSP bkpt_sp = GetSP(); 86 if (!bkpt_sp) 87 return false; 88 else if (bkpt_sp->GetTarget().GetBreakpointByID(bkpt_sp->GetID())) 89 return true; 90 else 91 return false; 92 } 93 94 void SBBreakpoint::ClearAllBreakpointSites() { 95 BreakpointSP bkpt_sp = GetSP(); 96 if (bkpt_sp) { 97 std::lock_guard<std::recursive_mutex> guard( 98 bkpt_sp->GetTarget().GetAPIMutex()); 99 bkpt_sp->ClearAllBreakpointSites(); 100 } 101 } 102 103 SBBreakpointLocation SBBreakpoint::FindLocationByAddress(addr_t vm_addr) { 104 SBBreakpointLocation sb_bp_location; 105 106 BreakpointSP bkpt_sp = GetSP(); 107 if (bkpt_sp) { 108 if (vm_addr != LLDB_INVALID_ADDRESS) { 109 std::lock_guard<std::recursive_mutex> guard( 110 bkpt_sp->GetTarget().GetAPIMutex()); 111 Address address; 112 Target &target = bkpt_sp->GetTarget(); 113 if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) { 114 address.SetRawAddress(vm_addr); 115 } 116 sb_bp_location.SetLocation(bkpt_sp->FindLocationByAddress(address)); 117 } 118 } 119 return sb_bp_location; 120 } 121 122 break_id_t SBBreakpoint::FindLocationIDByAddress(addr_t vm_addr) { 123 break_id_t break_id = LLDB_INVALID_BREAK_ID; 124 BreakpointSP bkpt_sp = GetSP(); 125 126 if (bkpt_sp && vm_addr != LLDB_INVALID_ADDRESS) { 127 std::lock_guard<std::recursive_mutex> guard( 128 bkpt_sp->GetTarget().GetAPIMutex()); 129 Address address; 130 Target &target = bkpt_sp->GetTarget(); 131 if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) { 132 address.SetRawAddress(vm_addr); 133 } 134 break_id = bkpt_sp->FindLocationIDByAddress(address); 135 } 136 137 return break_id; 138 } 139 140 SBBreakpointLocation SBBreakpoint::FindLocationByID(break_id_t bp_loc_id) { 141 SBBreakpointLocation sb_bp_location; 142 BreakpointSP bkpt_sp = GetSP(); 143 144 if (bkpt_sp) { 145 std::lock_guard<std::recursive_mutex> guard( 146 bkpt_sp->GetTarget().GetAPIMutex()); 147 sb_bp_location.SetLocation(bkpt_sp->FindLocationByID(bp_loc_id)); 148 } 149 150 return sb_bp_location; 151 } 152 153 SBBreakpointLocation SBBreakpoint::GetLocationAtIndex(uint32_t index) { 154 SBBreakpointLocation sb_bp_location; 155 BreakpointSP bkpt_sp = GetSP(); 156 157 if (bkpt_sp) { 158 std::lock_guard<std::recursive_mutex> guard( 159 bkpt_sp->GetTarget().GetAPIMutex()); 160 sb_bp_location.SetLocation(bkpt_sp->GetLocationAtIndex(index)); 161 } 162 163 return sb_bp_location; 164 } 165 166 void SBBreakpoint::SetEnabled(bool enable) { 167 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 168 BreakpointSP bkpt_sp = GetSP(); 169 170 LLDB_LOG(log, "breakpoint = {0}, enable = {1}", bkpt_sp.get(), enable); 171 172 if (bkpt_sp) { 173 std::lock_guard<std::recursive_mutex> guard( 174 bkpt_sp->GetTarget().GetAPIMutex()); 175 bkpt_sp->SetEnabled(enable); 176 } 177 } 178 179 bool SBBreakpoint::IsEnabled() { 180 BreakpointSP bkpt_sp = GetSP(); 181 if (bkpt_sp) { 182 std::lock_guard<std::recursive_mutex> guard( 183 bkpt_sp->GetTarget().GetAPIMutex()); 184 return bkpt_sp->IsEnabled(); 185 } else 186 return false; 187 } 188 189 void SBBreakpoint::SetOneShot(bool one_shot) { 190 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 191 BreakpointSP bkpt_sp = GetSP(); 192 193 LLDB_LOG(log, "breakpoint = {0}, one_shot = {1}", bkpt_sp.get(), one_shot); 194 195 if (bkpt_sp) { 196 std::lock_guard<std::recursive_mutex> guard( 197 bkpt_sp->GetTarget().GetAPIMutex()); 198 bkpt_sp->SetOneShot(one_shot); 199 } 200 } 201 202 bool SBBreakpoint::IsOneShot() const { 203 BreakpointSP bkpt_sp = GetSP(); 204 if (bkpt_sp) { 205 std::lock_guard<std::recursive_mutex> guard( 206 bkpt_sp->GetTarget().GetAPIMutex()); 207 return bkpt_sp->IsOneShot(); 208 } else 209 return false; 210 } 211 212 bool SBBreakpoint::IsInternal() { 213 BreakpointSP bkpt_sp = GetSP(); 214 if (bkpt_sp) { 215 std::lock_guard<std::recursive_mutex> guard( 216 bkpt_sp->GetTarget().GetAPIMutex()); 217 return bkpt_sp->IsInternal(); 218 } else 219 return false; 220 } 221 222 void SBBreakpoint::SetIgnoreCount(uint32_t count) { 223 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 224 BreakpointSP bkpt_sp = GetSP(); 225 226 LLDB_LOG(log, "breakpoint = {0}, count = {1}", bkpt_sp.get(), count); 227 228 if (bkpt_sp) { 229 std::lock_guard<std::recursive_mutex> guard( 230 bkpt_sp->GetTarget().GetAPIMutex()); 231 bkpt_sp->SetIgnoreCount(count); 232 } 233 } 234 235 void SBBreakpoint::SetCondition(const char *condition) { 236 BreakpointSP bkpt_sp = GetSP(); 237 if (bkpt_sp) { 238 std::lock_guard<std::recursive_mutex> guard( 239 bkpt_sp->GetTarget().GetAPIMutex()); 240 bkpt_sp->SetCondition(condition); 241 } 242 } 243 244 const char *SBBreakpoint::GetCondition() { 245 BreakpointSP bkpt_sp = GetSP(); 246 if (bkpt_sp) { 247 std::lock_guard<std::recursive_mutex> guard( 248 bkpt_sp->GetTarget().GetAPIMutex()); 249 return bkpt_sp->GetConditionText(); 250 } 251 return nullptr; 252 } 253 254 void SBBreakpoint::SetAutoContinue(bool auto_continue) { 255 BreakpointSP bkpt_sp = GetSP(); 256 if (bkpt_sp) { 257 std::lock_guard<std::recursive_mutex> guard( 258 bkpt_sp->GetTarget().GetAPIMutex()); 259 bkpt_sp->SetAutoContinue(auto_continue); 260 } 261 } 262 263 bool SBBreakpoint::GetAutoContinue() { 264 BreakpointSP bkpt_sp = GetSP(); 265 if (bkpt_sp) { 266 std::lock_guard<std::recursive_mutex> guard( 267 bkpt_sp->GetTarget().GetAPIMutex()); 268 return bkpt_sp->IsAutoContinue(); 269 } 270 return false; 271 } 272 273 uint32_t SBBreakpoint::GetHitCount() const { 274 uint32_t count = 0; 275 BreakpointSP bkpt_sp = GetSP(); 276 if (bkpt_sp) { 277 std::lock_guard<std::recursive_mutex> guard( 278 bkpt_sp->GetTarget().GetAPIMutex()); 279 count = bkpt_sp->GetHitCount(); 280 } 281 282 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 283 LLDB_LOG(log, "breakpoint = {0}, count = {1}", bkpt_sp.get(), count); 284 285 return count; 286 } 287 288 uint32_t SBBreakpoint::GetIgnoreCount() const { 289 uint32_t count = 0; 290 BreakpointSP bkpt_sp = GetSP(); 291 if (bkpt_sp) { 292 std::lock_guard<std::recursive_mutex> guard( 293 bkpt_sp->GetTarget().GetAPIMutex()); 294 count = bkpt_sp->GetIgnoreCount(); 295 } 296 297 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 298 LLDB_LOG(log, "breakpoint = {0}, count = {1}", bkpt_sp.get(), count); 299 300 return count; 301 } 302 303 void SBBreakpoint::SetThreadID(tid_t tid) { 304 BreakpointSP bkpt_sp = GetSP(); 305 if (bkpt_sp) { 306 std::lock_guard<std::recursive_mutex> guard( 307 bkpt_sp->GetTarget().GetAPIMutex()); 308 bkpt_sp->SetThreadID(tid); 309 } 310 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 311 LLDB_LOG(log, "breakpoint = {0}, tid = {1:x}", bkpt_sp.get(), tid); 312 } 313 314 tid_t SBBreakpoint::GetThreadID() { 315 tid_t tid = LLDB_INVALID_THREAD_ID; 316 BreakpointSP bkpt_sp = GetSP(); 317 if (bkpt_sp) { 318 std::lock_guard<std::recursive_mutex> guard( 319 bkpt_sp->GetTarget().GetAPIMutex()); 320 tid = bkpt_sp->GetThreadID(); 321 } 322 323 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 324 LLDB_LOG(log, "breakpoint = {0}, tid = {1:x}", bkpt_sp.get(), tid); 325 return tid; 326 } 327 328 void SBBreakpoint::SetThreadIndex(uint32_t index) { 329 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 330 BreakpointSP bkpt_sp = GetSP(); 331 LLDB_LOG(log, "breakpoint = {0}, index = {1}", bkpt_sp.get(), index); 332 if (bkpt_sp) { 333 std::lock_guard<std::recursive_mutex> guard( 334 bkpt_sp->GetTarget().GetAPIMutex()); 335 bkpt_sp->GetOptions()->GetThreadSpec()->SetIndex(index); 336 } 337 } 338 339 uint32_t SBBreakpoint::GetThreadIndex() const { 340 uint32_t thread_idx = UINT32_MAX; 341 BreakpointSP bkpt_sp = GetSP(); 342 if (bkpt_sp) { 343 std::lock_guard<std::recursive_mutex> guard( 344 bkpt_sp->GetTarget().GetAPIMutex()); 345 const ThreadSpec *thread_spec = 346 bkpt_sp->GetOptions()->GetThreadSpecNoCreate(); 347 if (thread_spec != nullptr) 348 thread_idx = thread_spec->GetIndex(); 349 } 350 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 351 LLDB_LOG(log, "breakpoint = {0}, index = {1}", bkpt_sp.get(), thread_idx); 352 353 return thread_idx; 354 } 355 356 void SBBreakpoint::SetThreadName(const char *thread_name) { 357 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 358 BreakpointSP bkpt_sp = GetSP(); 359 LLDB_LOG(log, "breakpoint = {0}, name = {1}", bkpt_sp.get(), thread_name); 360 361 if (bkpt_sp) { 362 std::lock_guard<std::recursive_mutex> guard( 363 bkpt_sp->GetTarget().GetAPIMutex()); 364 bkpt_sp->GetOptions()->GetThreadSpec()->SetName(thread_name); 365 } 366 } 367 368 const char *SBBreakpoint::GetThreadName() const { 369 const char *name = nullptr; 370 BreakpointSP bkpt_sp = GetSP(); 371 if (bkpt_sp) { 372 std::lock_guard<std::recursive_mutex> guard( 373 bkpt_sp->GetTarget().GetAPIMutex()); 374 const ThreadSpec *thread_spec = 375 bkpt_sp->GetOptions()->GetThreadSpecNoCreate(); 376 if (thread_spec != nullptr) 377 name = thread_spec->GetName(); 378 } 379 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 380 LLDB_LOG(log, "breakpoint = {0}, name = {1}", bkpt_sp.get(), name); 381 382 return name; 383 } 384 385 void SBBreakpoint::SetQueueName(const char *queue_name) { 386 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 387 BreakpointSP bkpt_sp = GetSP(); 388 LLDB_LOG(log, "breakpoint = {0}, queue_name = {1}", bkpt_sp.get(), 389 queue_name); 390 if (bkpt_sp) { 391 std::lock_guard<std::recursive_mutex> guard( 392 bkpt_sp->GetTarget().GetAPIMutex()); 393 bkpt_sp->GetOptions()->GetThreadSpec()->SetQueueName(queue_name); 394 } 395 } 396 397 const char *SBBreakpoint::GetQueueName() const { 398 const char *name = nullptr; 399 BreakpointSP bkpt_sp = GetSP(); 400 if (bkpt_sp) { 401 std::lock_guard<std::recursive_mutex> guard( 402 bkpt_sp->GetTarget().GetAPIMutex()); 403 const ThreadSpec *thread_spec = 404 bkpt_sp->GetOptions()->GetThreadSpecNoCreate(); 405 if (thread_spec) 406 name = thread_spec->GetQueueName(); 407 } 408 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 409 LLDB_LOG(log, "breakpoint = {0}, name = {1}", bkpt_sp.get(), name); 410 411 return name; 412 } 413 414 size_t SBBreakpoint::GetNumResolvedLocations() const { 415 size_t num_resolved = 0; 416 BreakpointSP bkpt_sp = GetSP(); 417 if (bkpt_sp) { 418 std::lock_guard<std::recursive_mutex> guard( 419 bkpt_sp->GetTarget().GetAPIMutex()); 420 num_resolved = bkpt_sp->GetNumResolvedLocations(); 421 } 422 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 423 LLDB_LOG(log, "breakpoint = {0}, num_resolved = {1}", bkpt_sp.get(), 424 num_resolved); 425 return num_resolved; 426 } 427 428 size_t SBBreakpoint::GetNumLocations() const { 429 BreakpointSP bkpt_sp = GetSP(); 430 size_t num_locs = 0; 431 if (bkpt_sp) { 432 std::lock_guard<std::recursive_mutex> guard( 433 bkpt_sp->GetTarget().GetAPIMutex()); 434 num_locs = bkpt_sp->GetNumLocations(); 435 } 436 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 437 LLDB_LOG(log, "breakpoint = {0}, num_locs = {1}", bkpt_sp.get(), num_locs); 438 return num_locs; 439 } 440 441 void SBBreakpoint::SetCommandLineCommands(SBStringList &commands) { 442 BreakpointSP bkpt_sp = GetSP(); 443 if (!bkpt_sp) 444 return; 445 if (commands.GetSize() == 0) 446 return; 447 448 std::lock_guard<std::recursive_mutex> guard( 449 bkpt_sp->GetTarget().GetAPIMutex()); 450 std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up( 451 new BreakpointOptions::CommandData(*commands, eScriptLanguageNone)); 452 453 bkpt_sp->GetOptions()->SetCommandDataCallback(cmd_data_up); 454 } 455 456 bool SBBreakpoint::GetCommandLineCommands(SBStringList &commands) { 457 BreakpointSP bkpt_sp = GetSP(); 458 if (!bkpt_sp) 459 return false; 460 StringList command_list; 461 bool has_commands = 462 bkpt_sp->GetOptions()->GetCommandLineCallbacks(command_list); 463 if (has_commands) 464 commands.AppendList(command_list); 465 return has_commands; 466 } 467 468 bool SBBreakpoint::GetDescription(SBStream &s) { 469 return GetDescription(s, true); 470 } 471 472 bool SBBreakpoint::GetDescription(SBStream &s, bool include_locations) { 473 BreakpointSP bkpt_sp = GetSP(); 474 if (bkpt_sp) { 475 std::lock_guard<std::recursive_mutex> guard( 476 bkpt_sp->GetTarget().GetAPIMutex()); 477 s.Printf("SBBreakpoint: id = %i, ", bkpt_sp->GetID()); 478 bkpt_sp->GetResolverDescription(s.get()); 479 bkpt_sp->GetFilterDescription(s.get()); 480 if (include_locations) { 481 const size_t num_locations = bkpt_sp->GetNumLocations(); 482 s.Printf(", locations = %" PRIu64, (uint64_t)num_locations); 483 } 484 return true; 485 } 486 s.Printf("No value"); 487 return false; 488 } 489 490 void SBBreakpoint 491 ::SetCallback(SBBreakpointHitCallback callback, 492 void *baton) { 493 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 494 BreakpointSP bkpt_sp = GetSP(); 495 LLDB_LOG(log, "breakpoint = {0}, callback = {1}, baton = {2}", bkpt_sp.get(), 496 callback, baton); 497 498 if (bkpt_sp) { 499 std::lock_guard<std::recursive_mutex> guard( 500 bkpt_sp->GetTarget().GetAPIMutex()); 501 BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton)); 502 bkpt_sp->SetCallback(SBBreakpointCallbackBaton 503 ::PrivateBreakpointHitCallback, baton_sp, 504 false); 505 } 506 } 507 508 void SBBreakpoint::SetScriptCallbackFunction( 509 const char *callback_function_name) { 510 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 511 BreakpointSP bkpt_sp = GetSP(); 512 LLDB_LOG(log, "breakpoint = {0}, callback = {1}", bkpt_sp.get(), 513 callback_function_name); 514 515 if (bkpt_sp) { 516 std::lock_guard<std::recursive_mutex> guard( 517 bkpt_sp->GetTarget().GetAPIMutex()); 518 BreakpointOptions *bp_options = bkpt_sp->GetOptions(); 519 bkpt_sp->GetTarget() 520 .GetDebugger() 521 .GetCommandInterpreter() 522 .GetScriptInterpreter() 523 ->SetBreakpointCommandCallbackFunction(bp_options, 524 callback_function_name); 525 } 526 } 527 528 SBError SBBreakpoint::SetScriptCallbackBody(const char *callback_body_text) { 529 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 530 BreakpointSP bkpt_sp = GetSP(); 531 LLDB_LOG(log, "breakpoint = {0}, callback body:\n{1}", bkpt_sp.get(), 532 callback_body_text); 533 534 SBError sb_error; 535 if (bkpt_sp) { 536 std::lock_guard<std::recursive_mutex> guard( 537 bkpt_sp->GetTarget().GetAPIMutex()); 538 BreakpointOptions *bp_options = bkpt_sp->GetOptions(); 539 Status error = 540 bkpt_sp->GetTarget() 541 .GetDebugger() 542 .GetCommandInterpreter() 543 .GetScriptInterpreter() 544 ->SetBreakpointCommandCallback(bp_options, callback_body_text); 545 sb_error.SetError(error); 546 } else 547 sb_error.SetErrorString("invalid breakpoint"); 548 549 return sb_error; 550 } 551 552 bool SBBreakpoint::AddName(const char *new_name) { 553 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 554 BreakpointSP bkpt_sp = GetSP(); 555 LLDB_LOG(log, "breakpoint = {0}, name = {1}", bkpt_sp.get(), new_name); 556 557 if (bkpt_sp) { 558 std::lock_guard<std::recursive_mutex> guard( 559 bkpt_sp->GetTarget().GetAPIMutex()); 560 Status error; // Think I'm just going to swallow the error here, it's 561 // probably more annoying to have to provide it. 562 bkpt_sp->GetTarget().AddNameToBreakpoint(bkpt_sp, new_name, error); 563 if (error.Fail()) 564 { 565 if (log) 566 log->Printf("Failed to add name: '%s' to breakpoint: %s", 567 new_name, error.AsCString()); 568 return false; 569 } 570 } 571 572 return true; 573 } 574 575 void SBBreakpoint::RemoveName(const char *name_to_remove) { 576 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 577 BreakpointSP bkpt_sp = GetSP(); 578 LLDB_LOG(log, "breakpoint = {0}, name = {1}", bkpt_sp.get(), name_to_remove); 579 580 if (bkpt_sp) { 581 std::lock_guard<std::recursive_mutex> guard( 582 bkpt_sp->GetTarget().GetAPIMutex()); 583 bkpt_sp->GetTarget().RemoveNameFromBreakpoint(bkpt_sp, 584 ConstString(name_to_remove)); 585 } 586 } 587 588 bool SBBreakpoint::MatchesName(const char *name) { 589 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 590 BreakpointSP bkpt_sp = GetSP(); 591 LLDB_LOG(log, "breakpoint = {0}, name = {1}", bkpt_sp.get(), name); 592 593 if (bkpt_sp) { 594 std::lock_guard<std::recursive_mutex> guard( 595 bkpt_sp->GetTarget().GetAPIMutex()); 596 return bkpt_sp->MatchesName(name); 597 } 598 599 return false; 600 } 601 602 void SBBreakpoint::GetNames(SBStringList &names) { 603 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 604 BreakpointSP bkpt_sp = GetSP(); 605 LLDB_LOG(log, "breakpoint = {0}", bkpt_sp.get()); 606 607 if (bkpt_sp) { 608 std::lock_guard<std::recursive_mutex> guard( 609 bkpt_sp->GetTarget().GetAPIMutex()); 610 std::vector<std::string> names_vec; 611 bkpt_sp->GetNames(names_vec); 612 for (std::string name : names_vec) { 613 names.AppendString(name.c_str()); 614 } 615 } 616 } 617 618 bool SBBreakpoint::EventIsBreakpointEvent(const lldb::SBEvent &event) { 619 return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event.get()) != 620 nullptr; 621 } 622 623 BreakpointEventType 624 SBBreakpoint::GetBreakpointEventTypeFromEvent(const SBEvent &event) { 625 if (event.IsValid()) 626 return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent( 627 event.GetSP()); 628 return eBreakpointEventTypeInvalidType; 629 } 630 631 SBBreakpoint SBBreakpoint::GetBreakpointFromEvent(const lldb::SBEvent &event) { 632 if (event.IsValid()) 633 return SBBreakpoint( 634 Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event.GetSP())); 635 return SBBreakpoint(); 636 } 637 638 SBBreakpointLocation 639 SBBreakpoint::GetBreakpointLocationAtIndexFromEvent(const lldb::SBEvent &event, 640 uint32_t loc_idx) { 641 SBBreakpointLocation sb_breakpoint_loc; 642 if (event.IsValid()) 643 sb_breakpoint_loc.SetLocation( 644 Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent( 645 event.GetSP(), loc_idx)); 646 return sb_breakpoint_loc; 647 } 648 649 uint32_t 650 SBBreakpoint::GetNumBreakpointLocationsFromEvent(const lldb::SBEvent &event) { 651 uint32_t num_locations = 0; 652 if (event.IsValid()) 653 num_locations = 654 (Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent( 655 event.GetSP())); 656 return num_locations; 657 } 658 659 BreakpointSP SBBreakpoint::GetSP() const { return m_opaque_wp.lock(); } 660 661 // This is simple collection of breakpoint id's and their target. 662 class SBBreakpointListImpl { 663 public: 664 SBBreakpointListImpl(lldb::TargetSP target_sp) : m_target_wp() { 665 if (target_sp && target_sp->IsValid()) 666 m_target_wp = target_sp; 667 } 668 669 ~SBBreakpointListImpl() = default; 670 671 size_t GetSize() { return m_break_ids.size(); } 672 673 BreakpointSP GetBreakpointAtIndex(size_t idx) { 674 if (idx >= m_break_ids.size()) 675 return BreakpointSP(); 676 TargetSP target_sp = m_target_wp.lock(); 677 if (!target_sp) 678 return BreakpointSP(); 679 lldb::break_id_t bp_id = m_break_ids[idx]; 680 return target_sp->GetBreakpointList().FindBreakpointByID(bp_id); 681 } 682 683 BreakpointSP FindBreakpointByID(lldb::break_id_t desired_id) { 684 TargetSP target_sp = m_target_wp.lock(); 685 if (!target_sp) 686 return BreakpointSP(); 687 688 for (lldb::break_id_t &break_id : m_break_ids) { 689 if (break_id == desired_id) 690 return target_sp->GetBreakpointList().FindBreakpointByID(break_id); 691 } 692 return BreakpointSP(); 693 } 694 695 bool Append(BreakpointSP bkpt) { 696 TargetSP target_sp = m_target_wp.lock(); 697 if (!target_sp || !bkpt) 698 return false; 699 if (bkpt->GetTargetSP() != target_sp) 700 return false; 701 m_break_ids.push_back(bkpt->GetID()); 702 return true; 703 } 704 705 bool AppendIfUnique(BreakpointSP bkpt) { 706 TargetSP target_sp = m_target_wp.lock(); 707 if (!target_sp || !bkpt) 708 return false; 709 if (bkpt->GetTargetSP() != target_sp) 710 return false; 711 lldb::break_id_t bp_id = bkpt->GetID(); 712 if (find(m_break_ids.begin(), m_break_ids.end(), bp_id) == 713 m_break_ids.end()) 714 return false; 715 716 m_break_ids.push_back(bkpt->GetID()); 717 return true; 718 } 719 720 bool AppendByID(lldb::break_id_t id) { 721 TargetSP target_sp = m_target_wp.lock(); 722 if (!target_sp) 723 return false; 724 if (id == LLDB_INVALID_BREAK_ID) 725 return false; 726 m_break_ids.push_back(id); 727 return true; 728 } 729 730 void Clear() { m_break_ids.clear(); } 731 732 void CopyToBreakpointIDList(lldb_private::BreakpointIDList &bp_list) { 733 for (lldb::break_id_t id : m_break_ids) { 734 bp_list.AddBreakpointID(BreakpointID(id)); 735 } 736 } 737 738 TargetSP GetTarget() { return m_target_wp.lock(); } 739 740 private: 741 std::vector<lldb::break_id_t> m_break_ids; 742 TargetWP m_target_wp; 743 }; 744 745 SBBreakpointList::SBBreakpointList(SBTarget &target) 746 : m_opaque_sp(new SBBreakpointListImpl(target.GetSP())) {} 747 748 SBBreakpointList::~SBBreakpointList() {} 749 750 size_t SBBreakpointList::GetSize() const { 751 if (!m_opaque_sp) 752 return 0; 753 else 754 return m_opaque_sp->GetSize(); 755 } 756 757 SBBreakpoint SBBreakpointList::GetBreakpointAtIndex(size_t idx) { 758 if (!m_opaque_sp) 759 return SBBreakpoint(); 760 761 BreakpointSP bkpt_sp = m_opaque_sp->GetBreakpointAtIndex(idx); 762 return SBBreakpoint(bkpt_sp); 763 } 764 765 SBBreakpoint SBBreakpointList::FindBreakpointByID(lldb::break_id_t id) { 766 if (!m_opaque_sp) 767 return SBBreakpoint(); 768 BreakpointSP bkpt_sp = m_opaque_sp->FindBreakpointByID(id); 769 return SBBreakpoint(bkpt_sp); 770 } 771 772 void SBBreakpointList::Append(const SBBreakpoint &sb_bkpt) { 773 if (!sb_bkpt.IsValid()) 774 return; 775 if (!m_opaque_sp) 776 return; 777 m_opaque_sp->Append(sb_bkpt.m_opaque_wp.lock()); 778 } 779 780 void SBBreakpointList::AppendByID(lldb::break_id_t id) { 781 if (!m_opaque_sp) 782 return; 783 m_opaque_sp->AppendByID(id); 784 } 785 786 bool SBBreakpointList::AppendIfUnique(const SBBreakpoint &sb_bkpt) { 787 if (!sb_bkpt.IsValid()) 788 return false; 789 if (!m_opaque_sp) 790 return false; 791 return m_opaque_sp->AppendIfUnique(sb_bkpt.GetSP()); 792 } 793 794 void SBBreakpointList::Clear() { 795 if (m_opaque_sp) 796 m_opaque_sp->Clear(); 797 } 798 799 void SBBreakpointList::CopyToBreakpointIDList( 800 lldb_private::BreakpointIDList &bp_id_list) { 801 if (m_opaque_sp) 802 m_opaque_sp->CopyToBreakpointIDList(bp_id_list); 803 } 804