1 //===-- SBBreakpoint.cpp --------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "lldb/API/SBBreakpoint.h" 10 #include "SBReproducerPrivate.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/SBStructuredData.h" 18 #include "lldb/API/SBThread.h" 19 20 #include "lldb/Breakpoint/Breakpoint.h" 21 #include "lldb/Breakpoint/BreakpointIDList.h" 22 #include "lldb/Breakpoint/BreakpointLocation.h" 23 #include "lldb/Breakpoint/BreakpointResolver.h" 24 #include "lldb/Breakpoint/BreakpointResolverScripted.h" 25 #include "lldb/Breakpoint/StoppointCallbackContext.h" 26 #include "lldb/Core/Address.h" 27 #include "lldb/Core/Debugger.h" 28 #include "lldb/Core/StreamFile.h" 29 #include "lldb/Core/StructuredDataImpl.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/Stream.h" 38 39 #include "SBBreakpointOptionCommon.h" 40 41 #include "lldb/lldb-enumerations.h" 42 43 #include "llvm/ADT/STLExtras.h" 44 45 using namespace lldb; 46 using namespace lldb_private; 47 48 SBBreakpoint::SBBreakpoint() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBBreakpoint); } 49 50 SBBreakpoint::SBBreakpoint(const SBBreakpoint &rhs) 51 : m_opaque_wp(rhs.m_opaque_wp) { 52 LLDB_RECORD_CONSTRUCTOR(SBBreakpoint, (const lldb::SBBreakpoint &), rhs); 53 } 54 55 SBBreakpoint::SBBreakpoint(const lldb::BreakpointSP &bp_sp) 56 : m_opaque_wp(bp_sp) { 57 LLDB_RECORD_CONSTRUCTOR(SBBreakpoint, (const lldb::BreakpointSP &), bp_sp); 58 } 59 60 SBBreakpoint::~SBBreakpoint() = default; 61 62 const SBBreakpoint &SBBreakpoint::operator=(const SBBreakpoint &rhs) { 63 LLDB_RECORD_METHOD(const lldb::SBBreakpoint &, 64 SBBreakpoint, operator=,(const lldb::SBBreakpoint &), rhs); 65 66 m_opaque_wp = rhs.m_opaque_wp; 67 return LLDB_RECORD_RESULT(*this); 68 } 69 70 bool SBBreakpoint::operator==(const lldb::SBBreakpoint &rhs) { 71 LLDB_RECORD_METHOD( 72 bool, SBBreakpoint, operator==,(const lldb::SBBreakpoint &), rhs); 73 74 return m_opaque_wp.lock() == rhs.m_opaque_wp.lock(); 75 } 76 77 bool SBBreakpoint::operator!=(const lldb::SBBreakpoint &rhs) { 78 LLDB_RECORD_METHOD( 79 bool, SBBreakpoint, operator!=,(const lldb::SBBreakpoint &), rhs); 80 81 return m_opaque_wp.lock() != rhs.m_opaque_wp.lock(); 82 } 83 84 break_id_t SBBreakpoint::GetID() const { 85 LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::break_id_t, SBBreakpoint, GetID); 86 87 break_id_t break_id = LLDB_INVALID_BREAK_ID; 88 BreakpointSP bkpt_sp = GetSP(); 89 if (bkpt_sp) 90 break_id = bkpt_sp->GetID(); 91 92 return break_id; 93 } 94 95 bool SBBreakpoint::IsValid() const { 96 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBreakpoint, IsValid); 97 return this->operator bool(); 98 } 99 SBBreakpoint::operator bool() const { 100 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBreakpoint, operator bool); 101 102 BreakpointSP bkpt_sp = GetSP(); 103 if (!bkpt_sp) 104 return false; 105 else if (bkpt_sp->GetTarget().GetBreakpointByID(bkpt_sp->GetID())) 106 return true; 107 else 108 return false; 109 } 110 111 void SBBreakpoint::ClearAllBreakpointSites() { 112 LLDB_RECORD_METHOD_NO_ARGS(void, SBBreakpoint, ClearAllBreakpointSites); 113 114 BreakpointSP bkpt_sp = GetSP(); 115 if (bkpt_sp) { 116 std::lock_guard<std::recursive_mutex> guard( 117 bkpt_sp->GetTarget().GetAPIMutex()); 118 bkpt_sp->ClearAllBreakpointSites(); 119 } 120 } 121 122 SBBreakpointLocation SBBreakpoint::FindLocationByAddress(addr_t vm_addr) { 123 LLDB_RECORD_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, 124 FindLocationByAddress, (lldb::addr_t), vm_addr); 125 126 SBBreakpointLocation sb_bp_location; 127 128 BreakpointSP bkpt_sp = GetSP(); 129 if (bkpt_sp) { 130 if (vm_addr != LLDB_INVALID_ADDRESS) { 131 std::lock_guard<std::recursive_mutex> guard( 132 bkpt_sp->GetTarget().GetAPIMutex()); 133 Address address; 134 Target &target = bkpt_sp->GetTarget(); 135 if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) { 136 address.SetRawAddress(vm_addr); 137 } 138 sb_bp_location.SetLocation(bkpt_sp->FindLocationByAddress(address)); 139 } 140 } 141 return LLDB_RECORD_RESULT(sb_bp_location); 142 } 143 144 break_id_t SBBreakpoint::FindLocationIDByAddress(addr_t vm_addr) { 145 LLDB_RECORD_METHOD(lldb::break_id_t, SBBreakpoint, FindLocationIDByAddress, 146 (lldb::addr_t), vm_addr); 147 148 break_id_t break_id = LLDB_INVALID_BREAK_ID; 149 BreakpointSP bkpt_sp = GetSP(); 150 151 if (bkpt_sp && vm_addr != LLDB_INVALID_ADDRESS) { 152 std::lock_guard<std::recursive_mutex> guard( 153 bkpt_sp->GetTarget().GetAPIMutex()); 154 Address address; 155 Target &target = bkpt_sp->GetTarget(); 156 if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) { 157 address.SetRawAddress(vm_addr); 158 } 159 break_id = bkpt_sp->FindLocationIDByAddress(address); 160 } 161 162 return break_id; 163 } 164 165 SBBreakpointLocation SBBreakpoint::FindLocationByID(break_id_t bp_loc_id) { 166 LLDB_RECORD_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, FindLocationByID, 167 (lldb::break_id_t), bp_loc_id); 168 169 SBBreakpointLocation sb_bp_location; 170 BreakpointSP bkpt_sp = GetSP(); 171 172 if (bkpt_sp) { 173 std::lock_guard<std::recursive_mutex> guard( 174 bkpt_sp->GetTarget().GetAPIMutex()); 175 sb_bp_location.SetLocation(bkpt_sp->FindLocationByID(bp_loc_id)); 176 } 177 178 return LLDB_RECORD_RESULT(sb_bp_location); 179 } 180 181 SBBreakpointLocation SBBreakpoint::GetLocationAtIndex(uint32_t index) { 182 LLDB_RECORD_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, 183 GetLocationAtIndex, (uint32_t), index); 184 185 SBBreakpointLocation sb_bp_location; 186 BreakpointSP bkpt_sp = GetSP(); 187 188 if (bkpt_sp) { 189 std::lock_guard<std::recursive_mutex> guard( 190 bkpt_sp->GetTarget().GetAPIMutex()); 191 sb_bp_location.SetLocation(bkpt_sp->GetLocationAtIndex(index)); 192 } 193 194 return LLDB_RECORD_RESULT(sb_bp_location); 195 } 196 197 void SBBreakpoint::SetEnabled(bool enable) { 198 LLDB_RECORD_METHOD(void, SBBreakpoint, SetEnabled, (bool), enable); 199 200 BreakpointSP bkpt_sp = GetSP(); 201 202 if (bkpt_sp) { 203 std::lock_guard<std::recursive_mutex> guard( 204 bkpt_sp->GetTarget().GetAPIMutex()); 205 bkpt_sp->SetEnabled(enable); 206 } 207 } 208 209 bool SBBreakpoint::IsEnabled() { 210 LLDB_RECORD_METHOD_NO_ARGS(bool, SBBreakpoint, IsEnabled); 211 212 BreakpointSP bkpt_sp = GetSP(); 213 if (bkpt_sp) { 214 std::lock_guard<std::recursive_mutex> guard( 215 bkpt_sp->GetTarget().GetAPIMutex()); 216 return bkpt_sp->IsEnabled(); 217 } else 218 return false; 219 } 220 221 void SBBreakpoint::SetOneShot(bool one_shot) { 222 LLDB_RECORD_METHOD(void, SBBreakpoint, SetOneShot, (bool), one_shot); 223 224 BreakpointSP bkpt_sp = GetSP(); 225 226 if (bkpt_sp) { 227 std::lock_guard<std::recursive_mutex> guard( 228 bkpt_sp->GetTarget().GetAPIMutex()); 229 bkpt_sp->SetOneShot(one_shot); 230 } 231 } 232 233 bool SBBreakpoint::IsOneShot() const { 234 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBreakpoint, IsOneShot); 235 236 BreakpointSP bkpt_sp = GetSP(); 237 if (bkpt_sp) { 238 std::lock_guard<std::recursive_mutex> guard( 239 bkpt_sp->GetTarget().GetAPIMutex()); 240 return bkpt_sp->IsOneShot(); 241 } else 242 return false; 243 } 244 245 bool SBBreakpoint::IsInternal() { 246 LLDB_RECORD_METHOD_NO_ARGS(bool, SBBreakpoint, IsInternal); 247 248 BreakpointSP bkpt_sp = GetSP(); 249 if (bkpt_sp) { 250 std::lock_guard<std::recursive_mutex> guard( 251 bkpt_sp->GetTarget().GetAPIMutex()); 252 return bkpt_sp->IsInternal(); 253 } else 254 return false; 255 } 256 257 void SBBreakpoint::SetIgnoreCount(uint32_t count) { 258 LLDB_RECORD_METHOD(void, SBBreakpoint, SetIgnoreCount, (uint32_t), count); 259 260 BreakpointSP bkpt_sp = GetSP(); 261 262 if (bkpt_sp) { 263 std::lock_guard<std::recursive_mutex> guard( 264 bkpt_sp->GetTarget().GetAPIMutex()); 265 bkpt_sp->SetIgnoreCount(count); 266 } 267 } 268 269 void SBBreakpoint::SetCondition(const char *condition) { 270 LLDB_RECORD_METHOD(void, SBBreakpoint, SetCondition, (const char *), 271 condition); 272 273 BreakpointSP bkpt_sp = GetSP(); 274 if (bkpt_sp) { 275 std::lock_guard<std::recursive_mutex> guard( 276 bkpt_sp->GetTarget().GetAPIMutex()); 277 bkpt_sp->SetCondition(condition); 278 } 279 } 280 281 const char *SBBreakpoint::GetCondition() { 282 LLDB_RECORD_METHOD_NO_ARGS(const char *, SBBreakpoint, GetCondition); 283 284 BreakpointSP bkpt_sp = GetSP(); 285 if (bkpt_sp) { 286 std::lock_guard<std::recursive_mutex> guard( 287 bkpt_sp->GetTarget().GetAPIMutex()); 288 return bkpt_sp->GetConditionText(); 289 } 290 return nullptr; 291 } 292 293 void SBBreakpoint::SetAutoContinue(bool auto_continue) { 294 LLDB_RECORD_METHOD(void, SBBreakpoint, SetAutoContinue, (bool), 295 auto_continue); 296 297 BreakpointSP bkpt_sp = GetSP(); 298 if (bkpt_sp) { 299 std::lock_guard<std::recursive_mutex> guard( 300 bkpt_sp->GetTarget().GetAPIMutex()); 301 bkpt_sp->SetAutoContinue(auto_continue); 302 } 303 } 304 305 bool SBBreakpoint::GetAutoContinue() { 306 LLDB_RECORD_METHOD_NO_ARGS(bool, SBBreakpoint, GetAutoContinue); 307 308 BreakpointSP bkpt_sp = GetSP(); 309 if (bkpt_sp) { 310 std::lock_guard<std::recursive_mutex> guard( 311 bkpt_sp->GetTarget().GetAPIMutex()); 312 return bkpt_sp->IsAutoContinue(); 313 } 314 return false; 315 } 316 317 uint32_t SBBreakpoint::GetHitCount() const { 318 LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBBreakpoint, GetHitCount); 319 320 uint32_t count = 0; 321 BreakpointSP bkpt_sp = GetSP(); 322 if (bkpt_sp) { 323 std::lock_guard<std::recursive_mutex> guard( 324 bkpt_sp->GetTarget().GetAPIMutex()); 325 count = bkpt_sp->GetHitCount(); 326 } 327 328 return count; 329 } 330 331 uint32_t SBBreakpoint::GetIgnoreCount() const { 332 LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBBreakpoint, GetIgnoreCount); 333 334 uint32_t count = 0; 335 BreakpointSP bkpt_sp = GetSP(); 336 if (bkpt_sp) { 337 std::lock_guard<std::recursive_mutex> guard( 338 bkpt_sp->GetTarget().GetAPIMutex()); 339 count = bkpt_sp->GetIgnoreCount(); 340 } 341 342 return count; 343 } 344 345 void SBBreakpoint::SetThreadID(tid_t tid) { 346 LLDB_RECORD_METHOD(void, SBBreakpoint, SetThreadID, (lldb::tid_t), tid); 347 348 BreakpointSP bkpt_sp = GetSP(); 349 if (bkpt_sp) { 350 std::lock_guard<std::recursive_mutex> guard( 351 bkpt_sp->GetTarget().GetAPIMutex()); 352 bkpt_sp->SetThreadID(tid); 353 } 354 } 355 356 tid_t SBBreakpoint::GetThreadID() { 357 LLDB_RECORD_METHOD_NO_ARGS(lldb::tid_t, SBBreakpoint, GetThreadID); 358 359 tid_t tid = LLDB_INVALID_THREAD_ID; 360 BreakpointSP bkpt_sp = GetSP(); 361 if (bkpt_sp) { 362 std::lock_guard<std::recursive_mutex> guard( 363 bkpt_sp->GetTarget().GetAPIMutex()); 364 tid = bkpt_sp->GetThreadID(); 365 } 366 367 return tid; 368 } 369 370 void SBBreakpoint::SetThreadIndex(uint32_t index) { 371 LLDB_RECORD_METHOD(void, SBBreakpoint, SetThreadIndex, (uint32_t), index); 372 373 BreakpointSP bkpt_sp = GetSP(); 374 if (bkpt_sp) { 375 std::lock_guard<std::recursive_mutex> guard( 376 bkpt_sp->GetTarget().GetAPIMutex()); 377 bkpt_sp->GetOptions()->GetThreadSpec()->SetIndex(index); 378 } 379 } 380 381 uint32_t SBBreakpoint::GetThreadIndex() const { 382 LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBBreakpoint, GetThreadIndex); 383 384 uint32_t thread_idx = UINT32_MAX; 385 BreakpointSP bkpt_sp = GetSP(); 386 if (bkpt_sp) { 387 std::lock_guard<std::recursive_mutex> guard( 388 bkpt_sp->GetTarget().GetAPIMutex()); 389 const ThreadSpec *thread_spec = 390 bkpt_sp->GetOptions()->GetThreadSpecNoCreate(); 391 if (thread_spec != nullptr) 392 thread_idx = thread_spec->GetIndex(); 393 } 394 395 return thread_idx; 396 } 397 398 void SBBreakpoint::SetThreadName(const char *thread_name) { 399 LLDB_RECORD_METHOD(void, SBBreakpoint, SetThreadName, (const char *), 400 thread_name); 401 402 BreakpointSP bkpt_sp = GetSP(); 403 404 if (bkpt_sp) { 405 std::lock_guard<std::recursive_mutex> guard( 406 bkpt_sp->GetTarget().GetAPIMutex()); 407 bkpt_sp->GetOptions()->GetThreadSpec()->SetName(thread_name); 408 } 409 } 410 411 const char *SBBreakpoint::GetThreadName() const { 412 LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBBreakpoint, GetThreadName); 413 414 const char *name = nullptr; 415 BreakpointSP bkpt_sp = GetSP(); 416 if (bkpt_sp) { 417 std::lock_guard<std::recursive_mutex> guard( 418 bkpt_sp->GetTarget().GetAPIMutex()); 419 const ThreadSpec *thread_spec = 420 bkpt_sp->GetOptions()->GetThreadSpecNoCreate(); 421 if (thread_spec != nullptr) 422 name = thread_spec->GetName(); 423 } 424 425 return name; 426 } 427 428 void SBBreakpoint::SetQueueName(const char *queue_name) { 429 LLDB_RECORD_METHOD(void, SBBreakpoint, SetQueueName, (const char *), 430 queue_name); 431 432 BreakpointSP bkpt_sp = GetSP(); 433 if (bkpt_sp) { 434 std::lock_guard<std::recursive_mutex> guard( 435 bkpt_sp->GetTarget().GetAPIMutex()); 436 bkpt_sp->GetOptions()->GetThreadSpec()->SetQueueName(queue_name); 437 } 438 } 439 440 const char *SBBreakpoint::GetQueueName() const { 441 LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBBreakpoint, GetQueueName); 442 443 const char *name = nullptr; 444 BreakpointSP bkpt_sp = GetSP(); 445 if (bkpt_sp) { 446 std::lock_guard<std::recursive_mutex> guard( 447 bkpt_sp->GetTarget().GetAPIMutex()); 448 const ThreadSpec *thread_spec = 449 bkpt_sp->GetOptions()->GetThreadSpecNoCreate(); 450 if (thread_spec) 451 name = thread_spec->GetQueueName(); 452 } 453 454 return name; 455 } 456 457 size_t SBBreakpoint::GetNumResolvedLocations() const { 458 LLDB_RECORD_METHOD_CONST_NO_ARGS(size_t, SBBreakpoint, 459 GetNumResolvedLocations); 460 461 size_t num_resolved = 0; 462 BreakpointSP bkpt_sp = GetSP(); 463 if (bkpt_sp) { 464 std::lock_guard<std::recursive_mutex> guard( 465 bkpt_sp->GetTarget().GetAPIMutex()); 466 num_resolved = bkpt_sp->GetNumResolvedLocations(); 467 } 468 return num_resolved; 469 } 470 471 size_t SBBreakpoint::GetNumLocations() const { 472 LLDB_RECORD_METHOD_CONST_NO_ARGS(size_t, SBBreakpoint, GetNumLocations); 473 474 BreakpointSP bkpt_sp = GetSP(); 475 size_t num_locs = 0; 476 if (bkpt_sp) { 477 std::lock_guard<std::recursive_mutex> guard( 478 bkpt_sp->GetTarget().GetAPIMutex()); 479 num_locs = bkpt_sp->GetNumLocations(); 480 } 481 return num_locs; 482 } 483 484 void SBBreakpoint::SetCommandLineCommands(SBStringList &commands) { 485 LLDB_RECORD_METHOD(void, SBBreakpoint, SetCommandLineCommands, 486 (lldb::SBStringList &), commands); 487 488 BreakpointSP bkpt_sp = GetSP(); 489 if (!bkpt_sp) 490 return; 491 if (commands.GetSize() == 0) 492 return; 493 494 std::lock_guard<std::recursive_mutex> guard( 495 bkpt_sp->GetTarget().GetAPIMutex()); 496 std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up( 497 new BreakpointOptions::CommandData(*commands, eScriptLanguageNone)); 498 499 bkpt_sp->GetOptions()->SetCommandDataCallback(cmd_data_up); 500 } 501 502 bool SBBreakpoint::GetCommandLineCommands(SBStringList &commands) { 503 LLDB_RECORD_METHOD(bool, SBBreakpoint, GetCommandLineCommands, 504 (lldb::SBStringList &), commands); 505 506 BreakpointSP bkpt_sp = GetSP(); 507 if (!bkpt_sp) 508 return false; 509 StringList command_list; 510 bool has_commands = 511 bkpt_sp->GetOptions()->GetCommandLineCallbacks(command_list); 512 if (has_commands) 513 commands.AppendList(command_list); 514 return has_commands; 515 } 516 517 bool SBBreakpoint::GetDescription(SBStream &s) { 518 LLDB_RECORD_METHOD(bool, SBBreakpoint, GetDescription, (lldb::SBStream &), s); 519 520 return GetDescription(s, true); 521 } 522 523 bool SBBreakpoint::GetDescription(SBStream &s, bool include_locations) { 524 LLDB_RECORD_METHOD(bool, SBBreakpoint, GetDescription, 525 (lldb::SBStream &, bool), s, include_locations); 526 527 BreakpointSP bkpt_sp = GetSP(); 528 if (bkpt_sp) { 529 std::lock_guard<std::recursive_mutex> guard( 530 bkpt_sp->GetTarget().GetAPIMutex()); 531 s.Printf("SBBreakpoint: id = %i, ", bkpt_sp->GetID()); 532 bkpt_sp->GetResolverDescription(s.get()); 533 bkpt_sp->GetFilterDescription(s.get()); 534 if (include_locations) { 535 const size_t num_locations = bkpt_sp->GetNumLocations(); 536 s.Printf(", locations = %" PRIu64, (uint64_t)num_locations); 537 } 538 return true; 539 } 540 s.Printf("No value"); 541 return false; 542 } 543 544 SBError SBBreakpoint::AddLocation(SBAddress &address) { 545 LLDB_RECORD_METHOD(lldb::SBError, SBBreakpoint, AddLocation, 546 (lldb::SBAddress &), address); 547 548 BreakpointSP bkpt_sp = GetSP(); 549 SBError error; 550 551 if (!address.IsValid()) { 552 error.SetErrorString("Can't add an invalid address."); 553 return LLDB_RECORD_RESULT(error); 554 } 555 556 if (!bkpt_sp) { 557 error.SetErrorString("No breakpoint to add a location to."); 558 return LLDB_RECORD_RESULT(error); 559 } 560 561 if (!llvm::isa<BreakpointResolverScripted>(bkpt_sp->GetResolver().get())) { 562 error.SetErrorString("Only a scripted resolver can add locations."); 563 return LLDB_RECORD_RESULT(error); 564 } 565 566 if (bkpt_sp->GetSearchFilter()->AddressPasses(address.ref())) 567 bkpt_sp->AddLocation(address.ref()); 568 else { 569 StreamString s; 570 address.get()->Dump(&s, &bkpt_sp->GetTarget(), 571 Address::DumpStyleModuleWithFileAddress); 572 error.SetErrorStringWithFormat("Address: %s didn't pass the filter.", 573 s.GetData()); 574 } 575 return LLDB_RECORD_RESULT(error); 576 } 577 578 void SBBreakpoint ::SetCallback(SBBreakpointHitCallback callback, void *baton) { 579 LLDB_RECORD_DUMMY(void, SBBreakpoint, SetCallback, 580 (lldb::SBBreakpointHitCallback, void *), callback, baton); 581 582 BreakpointSP bkpt_sp = GetSP(); 583 584 if (bkpt_sp) { 585 std::lock_guard<std::recursive_mutex> guard( 586 bkpt_sp->GetTarget().GetAPIMutex()); 587 BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton)); 588 bkpt_sp->SetCallback(SBBreakpointCallbackBaton 589 ::PrivateBreakpointHitCallback, baton_sp, 590 false); 591 } 592 } 593 594 void SBBreakpoint::SetScriptCallbackFunction( 595 const char *callback_function_name) { 596 LLDB_RECORD_METHOD(void, SBBreakpoint, SetScriptCallbackFunction, 597 (const char *), callback_function_name); 598 SBStructuredData empty_args; 599 SetScriptCallbackFunction(callback_function_name, empty_args); 600 } 601 602 SBError SBBreakpoint::SetScriptCallbackFunction( 603 const char *callback_function_name, 604 SBStructuredData &extra_args) { 605 LLDB_RECORD_METHOD(SBError, SBBreakpoint, SetScriptCallbackFunction, 606 (const char *, SBStructuredData &), callback_function_name, extra_args); 607 SBError sb_error; 608 BreakpointSP bkpt_sp = GetSP(); 609 610 if (bkpt_sp) { 611 Status error; 612 std::lock_guard<std::recursive_mutex> guard( 613 bkpt_sp->GetTarget().GetAPIMutex()); 614 BreakpointOptions *bp_options = bkpt_sp->GetOptions(); 615 error = bkpt_sp->GetTarget() 616 .GetDebugger() 617 .GetScriptInterpreter() 618 ->SetBreakpointCommandCallbackFunction(bp_options, 619 callback_function_name, 620 extra_args.m_impl_up 621 ->GetObjectSP()); 622 sb_error.SetError(error); 623 } else 624 sb_error.SetErrorString("invalid breakpoint"); 625 626 return LLDB_RECORD_RESULT(sb_error); 627 } 628 629 SBError SBBreakpoint::SetScriptCallbackBody(const char *callback_body_text) { 630 LLDB_RECORD_METHOD(lldb::SBError, SBBreakpoint, SetScriptCallbackBody, 631 (const char *), callback_body_text); 632 633 BreakpointSP bkpt_sp = GetSP(); 634 635 SBError sb_error; 636 if (bkpt_sp) { 637 std::lock_guard<std::recursive_mutex> guard( 638 bkpt_sp->GetTarget().GetAPIMutex()); 639 BreakpointOptions *bp_options = bkpt_sp->GetOptions(); 640 Status error = 641 bkpt_sp->GetTarget() 642 .GetDebugger() 643 .GetScriptInterpreter() 644 ->SetBreakpointCommandCallback(bp_options, callback_body_text); 645 sb_error.SetError(error); 646 } else 647 sb_error.SetErrorString("invalid breakpoint"); 648 649 return LLDB_RECORD_RESULT(sb_error); 650 } 651 652 bool SBBreakpoint::AddName(const char *new_name) { 653 LLDB_RECORD_METHOD(bool, SBBreakpoint, AddName, (const char *), new_name); 654 655 SBError status = AddNameWithErrorHandling(new_name); 656 return status.Success(); 657 } 658 659 SBError SBBreakpoint::AddNameWithErrorHandling(const char *new_name) { 660 LLDB_RECORD_METHOD(SBError, SBBreakpoint, AddNameWithErrorHandling, 661 (const char *), new_name); 662 663 BreakpointSP bkpt_sp = GetSP(); 664 665 SBError status; 666 if (bkpt_sp) { 667 std::lock_guard<std::recursive_mutex> guard( 668 bkpt_sp->GetTarget().GetAPIMutex()); 669 Status error; 670 bkpt_sp->GetTarget().AddNameToBreakpoint(bkpt_sp, new_name, error); 671 status.SetError(error); 672 } else { 673 status.SetErrorString("invalid breakpoint"); 674 } 675 676 return LLDB_RECORD_RESULT(status); 677 } 678 679 void SBBreakpoint::RemoveName(const char *name_to_remove) { 680 LLDB_RECORD_METHOD(void, SBBreakpoint, RemoveName, (const char *), 681 name_to_remove); 682 683 BreakpointSP bkpt_sp = GetSP(); 684 685 if (bkpt_sp) { 686 std::lock_guard<std::recursive_mutex> guard( 687 bkpt_sp->GetTarget().GetAPIMutex()); 688 bkpt_sp->GetTarget().RemoveNameFromBreakpoint(bkpt_sp, 689 ConstString(name_to_remove)); 690 } 691 } 692 693 bool SBBreakpoint::MatchesName(const char *name) { 694 LLDB_RECORD_METHOD(bool, SBBreakpoint, MatchesName, (const char *), name); 695 696 BreakpointSP bkpt_sp = GetSP(); 697 698 if (bkpt_sp) { 699 std::lock_guard<std::recursive_mutex> guard( 700 bkpt_sp->GetTarget().GetAPIMutex()); 701 return bkpt_sp->MatchesName(name); 702 } 703 704 return false; 705 } 706 707 void SBBreakpoint::GetNames(SBStringList &names) { 708 LLDB_RECORD_METHOD(void, SBBreakpoint, GetNames, (lldb::SBStringList &), 709 names); 710 711 BreakpointSP bkpt_sp = GetSP(); 712 713 if (bkpt_sp) { 714 std::lock_guard<std::recursive_mutex> guard( 715 bkpt_sp->GetTarget().GetAPIMutex()); 716 std::vector<std::string> names_vec; 717 bkpt_sp->GetNames(names_vec); 718 for (std::string name : names_vec) { 719 names.AppendString(name.c_str()); 720 } 721 } 722 } 723 724 bool SBBreakpoint::EventIsBreakpointEvent(const lldb::SBEvent &event) { 725 LLDB_RECORD_STATIC_METHOD(bool, SBBreakpoint, EventIsBreakpointEvent, 726 (const lldb::SBEvent &), event); 727 728 return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event.get()) != 729 nullptr; 730 } 731 732 BreakpointEventType 733 SBBreakpoint::GetBreakpointEventTypeFromEvent(const SBEvent &event) { 734 LLDB_RECORD_STATIC_METHOD(lldb::BreakpointEventType, SBBreakpoint, 735 GetBreakpointEventTypeFromEvent, 736 (const lldb::SBEvent &), event); 737 738 if (event.IsValid()) 739 return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent( 740 event.GetSP()); 741 return eBreakpointEventTypeInvalidType; 742 } 743 744 SBBreakpoint SBBreakpoint::GetBreakpointFromEvent(const lldb::SBEvent &event) { 745 LLDB_RECORD_STATIC_METHOD(lldb::SBBreakpoint, SBBreakpoint, 746 GetBreakpointFromEvent, (const lldb::SBEvent &), 747 event); 748 749 if (event.IsValid()) 750 return LLDB_RECORD_RESULT( 751 SBBreakpoint(Breakpoint::BreakpointEventData::GetBreakpointFromEvent( 752 event.GetSP()))); 753 return LLDB_RECORD_RESULT(SBBreakpoint()); 754 } 755 756 SBBreakpointLocation 757 SBBreakpoint::GetBreakpointLocationAtIndexFromEvent(const lldb::SBEvent &event, 758 uint32_t loc_idx) { 759 LLDB_RECORD_STATIC_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, 760 GetBreakpointLocationAtIndexFromEvent, 761 (const lldb::SBEvent &, uint32_t), event, loc_idx); 762 763 SBBreakpointLocation sb_breakpoint_loc; 764 if (event.IsValid()) 765 sb_breakpoint_loc.SetLocation( 766 Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent( 767 event.GetSP(), loc_idx)); 768 return LLDB_RECORD_RESULT(sb_breakpoint_loc); 769 } 770 771 uint32_t 772 SBBreakpoint::GetNumBreakpointLocationsFromEvent(const lldb::SBEvent &event) { 773 LLDB_RECORD_STATIC_METHOD(uint32_t, SBBreakpoint, 774 GetNumBreakpointLocationsFromEvent, 775 (const lldb::SBEvent &), event); 776 777 uint32_t num_locations = 0; 778 if (event.IsValid()) 779 num_locations = 780 (Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent( 781 event.GetSP())); 782 return num_locations; 783 } 784 785 bool SBBreakpoint::IsHardware() const { 786 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBreakpoint, IsHardware); 787 788 BreakpointSP bkpt_sp = GetSP(); 789 if (bkpt_sp) 790 return bkpt_sp->IsHardware(); 791 return false; 792 } 793 794 BreakpointSP SBBreakpoint::GetSP() const { return m_opaque_wp.lock(); } 795 796 // This is simple collection of breakpoint id's and their target. 797 class SBBreakpointListImpl { 798 public: 799 SBBreakpointListImpl(lldb::TargetSP target_sp) : m_target_wp() { 800 if (target_sp && target_sp->IsValid()) 801 m_target_wp = target_sp; 802 } 803 804 ~SBBreakpointListImpl() = default; 805 806 size_t GetSize() { return m_break_ids.size(); } 807 808 BreakpointSP GetBreakpointAtIndex(size_t idx) { 809 if (idx >= m_break_ids.size()) 810 return BreakpointSP(); 811 TargetSP target_sp = m_target_wp.lock(); 812 if (!target_sp) 813 return BreakpointSP(); 814 lldb::break_id_t bp_id = m_break_ids[idx]; 815 return target_sp->GetBreakpointList().FindBreakpointByID(bp_id); 816 } 817 818 BreakpointSP FindBreakpointByID(lldb::break_id_t desired_id) { 819 TargetSP target_sp = m_target_wp.lock(); 820 if (!target_sp) 821 return BreakpointSP(); 822 823 for (lldb::break_id_t &break_id : m_break_ids) { 824 if (break_id == desired_id) 825 return target_sp->GetBreakpointList().FindBreakpointByID(break_id); 826 } 827 return BreakpointSP(); 828 } 829 830 bool Append(BreakpointSP bkpt) { 831 TargetSP target_sp = m_target_wp.lock(); 832 if (!target_sp || !bkpt) 833 return false; 834 if (bkpt->GetTargetSP() != target_sp) 835 return false; 836 m_break_ids.push_back(bkpt->GetID()); 837 return true; 838 } 839 840 bool AppendIfUnique(BreakpointSP bkpt) { 841 TargetSP target_sp = m_target_wp.lock(); 842 if (!target_sp || !bkpt) 843 return false; 844 if (bkpt->GetTargetSP() != target_sp) 845 return false; 846 lldb::break_id_t bp_id = bkpt->GetID(); 847 if (find(m_break_ids.begin(), m_break_ids.end(), bp_id) == 848 m_break_ids.end()) 849 return false; 850 851 m_break_ids.push_back(bkpt->GetID()); 852 return true; 853 } 854 855 bool AppendByID(lldb::break_id_t id) { 856 TargetSP target_sp = m_target_wp.lock(); 857 if (!target_sp) 858 return false; 859 if (id == LLDB_INVALID_BREAK_ID) 860 return false; 861 m_break_ids.push_back(id); 862 return true; 863 } 864 865 void Clear() { m_break_ids.clear(); } 866 867 void CopyToBreakpointIDList(lldb_private::BreakpointIDList &bp_list) { 868 for (lldb::break_id_t id : m_break_ids) { 869 bp_list.AddBreakpointID(BreakpointID(id)); 870 } 871 } 872 873 TargetSP GetTarget() { return m_target_wp.lock(); } 874 875 private: 876 std::vector<lldb::break_id_t> m_break_ids; 877 TargetWP m_target_wp; 878 }; 879 880 SBBreakpointList::SBBreakpointList(SBTarget &target) 881 : m_opaque_sp(new SBBreakpointListImpl(target.GetSP())) { 882 LLDB_RECORD_CONSTRUCTOR(SBBreakpointList, (lldb::SBTarget &), target); 883 } 884 885 SBBreakpointList::~SBBreakpointList() = default; 886 887 size_t SBBreakpointList::GetSize() const { 888 LLDB_RECORD_METHOD_CONST_NO_ARGS(size_t, SBBreakpointList, GetSize); 889 890 if (!m_opaque_sp) 891 return 0; 892 else 893 return m_opaque_sp->GetSize(); 894 } 895 896 SBBreakpoint SBBreakpointList::GetBreakpointAtIndex(size_t idx) { 897 LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBBreakpointList, GetBreakpointAtIndex, 898 (size_t), idx); 899 900 if (!m_opaque_sp) 901 return LLDB_RECORD_RESULT(SBBreakpoint()); 902 903 BreakpointSP bkpt_sp = m_opaque_sp->GetBreakpointAtIndex(idx); 904 return LLDB_RECORD_RESULT(SBBreakpoint(bkpt_sp)); 905 } 906 907 SBBreakpoint SBBreakpointList::FindBreakpointByID(lldb::break_id_t id) { 908 LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBBreakpointList, FindBreakpointByID, 909 (lldb::break_id_t), id); 910 911 if (!m_opaque_sp) 912 return LLDB_RECORD_RESULT(SBBreakpoint()); 913 BreakpointSP bkpt_sp = m_opaque_sp->FindBreakpointByID(id); 914 return LLDB_RECORD_RESULT(SBBreakpoint(bkpt_sp)); 915 } 916 917 void SBBreakpointList::Append(const SBBreakpoint &sb_bkpt) { 918 LLDB_RECORD_METHOD(void, SBBreakpointList, Append, 919 (const lldb::SBBreakpoint &), sb_bkpt); 920 921 if (!sb_bkpt.IsValid()) 922 return; 923 if (!m_opaque_sp) 924 return; 925 m_opaque_sp->Append(sb_bkpt.m_opaque_wp.lock()); 926 } 927 928 void SBBreakpointList::AppendByID(lldb::break_id_t id) { 929 LLDB_RECORD_METHOD(void, SBBreakpointList, AppendByID, (lldb::break_id_t), 930 id); 931 932 if (!m_opaque_sp) 933 return; 934 m_opaque_sp->AppendByID(id); 935 } 936 937 bool SBBreakpointList::AppendIfUnique(const SBBreakpoint &sb_bkpt) { 938 LLDB_RECORD_METHOD(bool, SBBreakpointList, AppendIfUnique, 939 (const lldb::SBBreakpoint &), sb_bkpt); 940 941 if (!sb_bkpt.IsValid()) 942 return false; 943 if (!m_opaque_sp) 944 return false; 945 return m_opaque_sp->AppendIfUnique(sb_bkpt.GetSP()); 946 } 947 948 void SBBreakpointList::Clear() { 949 LLDB_RECORD_METHOD_NO_ARGS(void, SBBreakpointList, Clear); 950 951 if (m_opaque_sp) 952 m_opaque_sp->Clear(); 953 } 954 955 void SBBreakpointList::CopyToBreakpointIDList( 956 lldb_private::BreakpointIDList &bp_id_list) { 957 if (m_opaque_sp) 958 m_opaque_sp->CopyToBreakpointIDList(bp_id_list); 959 } 960 961 namespace lldb_private { 962 namespace repro { 963 964 template <> 965 void RegisterMethods<SBBreakpoint>(Registry &R) { 966 LLDB_REGISTER_CONSTRUCTOR(SBBreakpoint, ()); 967 LLDB_REGISTER_CONSTRUCTOR(SBBreakpoint, (const lldb::SBBreakpoint &)); 968 LLDB_REGISTER_CONSTRUCTOR(SBBreakpoint, (const lldb::BreakpointSP &)); 969 LLDB_REGISTER_METHOD(const lldb::SBBreakpoint &, 970 SBBreakpoint, operator=,(const lldb::SBBreakpoint &)); 971 LLDB_REGISTER_METHOD(bool, 972 SBBreakpoint, operator==,(const lldb::SBBreakpoint &)); 973 LLDB_REGISTER_METHOD(bool, 974 SBBreakpoint, operator!=,(const lldb::SBBreakpoint &)); 975 LLDB_REGISTER_METHOD_CONST(lldb::break_id_t, SBBreakpoint, GetID, ()); 976 LLDB_REGISTER_METHOD_CONST(bool, SBBreakpoint, IsValid, ()); 977 LLDB_REGISTER_METHOD_CONST(bool, SBBreakpoint, operator bool, ()); 978 LLDB_REGISTER_METHOD(void, SBBreakpoint, ClearAllBreakpointSites, ()); 979 LLDB_REGISTER_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, 980 FindLocationByAddress, (lldb::addr_t)); 981 LLDB_REGISTER_METHOD(lldb::break_id_t, SBBreakpoint, 982 FindLocationIDByAddress, (lldb::addr_t)); 983 LLDB_REGISTER_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, 984 FindLocationByID, (lldb::break_id_t)); 985 LLDB_REGISTER_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, 986 GetLocationAtIndex, (uint32_t)); 987 LLDB_REGISTER_METHOD(void, SBBreakpoint, SetEnabled, (bool)); 988 LLDB_REGISTER_METHOD(bool, SBBreakpoint, IsEnabled, ()); 989 LLDB_REGISTER_METHOD(void, SBBreakpoint, SetOneShot, (bool)); 990 LLDB_REGISTER_METHOD_CONST(bool, SBBreakpoint, IsOneShot, ()); 991 LLDB_REGISTER_METHOD(bool, SBBreakpoint, IsInternal, ()); 992 LLDB_REGISTER_METHOD(void, SBBreakpoint, SetIgnoreCount, (uint32_t)); 993 LLDB_REGISTER_METHOD(void, SBBreakpoint, SetCondition, (const char *)); 994 LLDB_REGISTER_METHOD(const char *, SBBreakpoint, GetCondition, ()); 995 LLDB_REGISTER_METHOD(void, SBBreakpoint, SetAutoContinue, (bool)); 996 LLDB_REGISTER_METHOD(bool, SBBreakpoint, GetAutoContinue, ()); 997 LLDB_REGISTER_METHOD_CONST(uint32_t, SBBreakpoint, GetHitCount, ()); 998 LLDB_REGISTER_METHOD_CONST(uint32_t, SBBreakpoint, GetIgnoreCount, ()); 999 LLDB_REGISTER_METHOD(void, SBBreakpoint, SetThreadID, (lldb::tid_t)); 1000 LLDB_REGISTER_METHOD(lldb::tid_t, SBBreakpoint, GetThreadID, ()); 1001 LLDB_REGISTER_METHOD(void, SBBreakpoint, SetThreadIndex, (uint32_t)); 1002 LLDB_REGISTER_METHOD_CONST(uint32_t, SBBreakpoint, GetThreadIndex, ()); 1003 LLDB_REGISTER_METHOD(void, SBBreakpoint, SetThreadName, (const char *)); 1004 LLDB_REGISTER_METHOD_CONST(const char *, SBBreakpoint, GetThreadName, ()); 1005 LLDB_REGISTER_METHOD(void, SBBreakpoint, SetQueueName, (const char *)); 1006 LLDB_REGISTER_METHOD_CONST(const char *, SBBreakpoint, GetQueueName, ()); 1007 LLDB_REGISTER_METHOD_CONST(size_t, SBBreakpoint, GetNumResolvedLocations, 1008 ()); 1009 LLDB_REGISTER_METHOD_CONST(size_t, SBBreakpoint, GetNumLocations, ()); 1010 LLDB_REGISTER_METHOD(void, SBBreakpoint, SetCommandLineCommands, 1011 (lldb::SBStringList &)); 1012 LLDB_REGISTER_METHOD(bool, SBBreakpoint, GetCommandLineCommands, 1013 (lldb::SBStringList &)); 1014 LLDB_REGISTER_METHOD(bool, SBBreakpoint, GetDescription, 1015 (lldb::SBStream &)); 1016 LLDB_REGISTER_METHOD(bool, SBBreakpoint, GetDescription, 1017 (lldb::SBStream &, bool)); 1018 LLDB_REGISTER_METHOD(lldb::SBError, SBBreakpoint, AddLocation, 1019 (lldb::SBAddress &)); 1020 LLDB_REGISTER_METHOD(void, SBBreakpoint, SetScriptCallbackFunction, 1021 (const char *)); 1022 LLDB_REGISTER_METHOD(lldb::SBError, SBBreakpoint, SetScriptCallbackFunction, 1023 (const char *, SBStructuredData &)); 1024 LLDB_REGISTER_METHOD(lldb::SBError, SBBreakpoint, SetScriptCallbackBody, 1025 (const char *)); 1026 LLDB_REGISTER_METHOD(bool, SBBreakpoint, AddName, (const char *)); 1027 LLDB_REGISTER_METHOD(lldb::SBError, SBBreakpoint, AddNameWithErrorHandling, 1028 (const char *)); 1029 LLDB_REGISTER_METHOD(void, SBBreakpoint, RemoveName, (const char *)); 1030 LLDB_REGISTER_METHOD(bool, SBBreakpoint, MatchesName, (const char *)); 1031 LLDB_REGISTER_METHOD(void, SBBreakpoint, GetNames, (lldb::SBStringList &)); 1032 LLDB_REGISTER_STATIC_METHOD(bool, SBBreakpoint, EventIsBreakpointEvent, 1033 (const lldb::SBEvent &)); 1034 LLDB_REGISTER_STATIC_METHOD(lldb::BreakpointEventType, SBBreakpoint, 1035 GetBreakpointEventTypeFromEvent, 1036 (const lldb::SBEvent &)); 1037 LLDB_REGISTER_STATIC_METHOD(lldb::SBBreakpoint, SBBreakpoint, 1038 GetBreakpointFromEvent, 1039 (const lldb::SBEvent &)); 1040 LLDB_REGISTER_STATIC_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, 1041 GetBreakpointLocationAtIndexFromEvent, 1042 (const lldb::SBEvent &, uint32_t)); 1043 LLDB_REGISTER_STATIC_METHOD(uint32_t, SBBreakpoint, 1044 GetNumBreakpointLocationsFromEvent, 1045 (const lldb::SBEvent &)); 1046 LLDB_REGISTER_METHOD_CONST(bool, SBBreakpoint, IsHardware, ()); 1047 } 1048 1049 template <> 1050 void RegisterMethods<SBBreakpointList>(Registry &R) { 1051 LLDB_REGISTER_CONSTRUCTOR(SBBreakpointList, (lldb::SBTarget &)); 1052 LLDB_REGISTER_METHOD_CONST(size_t, SBBreakpointList, GetSize, ()); 1053 LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBBreakpointList, 1054 GetBreakpointAtIndex, (size_t)); 1055 LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBBreakpointList, 1056 FindBreakpointByID, (lldb::break_id_t)); 1057 LLDB_REGISTER_METHOD(void, SBBreakpointList, Append, 1058 (const lldb::SBBreakpoint &)); 1059 LLDB_REGISTER_METHOD(void, SBBreakpointList, AppendByID, 1060 (lldb::break_id_t)); 1061 LLDB_REGISTER_METHOD(bool, SBBreakpointList, AppendIfUnique, 1062 (const lldb::SBBreakpoint &)); 1063 LLDB_REGISTER_METHOD(void, SBBreakpointList, Clear, ()); 1064 } 1065 1066 } 1067 } 1068