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