1 //===-- SBBreakpoint.cpp ----------------------------------------*- C++ -*-===// 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 BreakpointSP bkpt_sp = GetSP(); 656 657 if (bkpt_sp) { 658 std::lock_guard<std::recursive_mutex> guard( 659 bkpt_sp->GetTarget().GetAPIMutex()); 660 Status error; // Think I'm just going to swallow the error here, it's 661 // probably more annoying to have to provide it. 662 bkpt_sp->GetTarget().AddNameToBreakpoint(bkpt_sp, new_name, error); 663 if (error.Fail()) 664 return false; 665 } 666 667 return true; 668 } 669 670 void SBBreakpoint::RemoveName(const char *name_to_remove) { 671 LLDB_RECORD_METHOD(void, SBBreakpoint, RemoveName, (const char *), 672 name_to_remove); 673 674 BreakpointSP bkpt_sp = GetSP(); 675 676 if (bkpt_sp) { 677 std::lock_guard<std::recursive_mutex> guard( 678 bkpt_sp->GetTarget().GetAPIMutex()); 679 bkpt_sp->GetTarget().RemoveNameFromBreakpoint(bkpt_sp, 680 ConstString(name_to_remove)); 681 } 682 } 683 684 bool SBBreakpoint::MatchesName(const char *name) { 685 LLDB_RECORD_METHOD(bool, SBBreakpoint, MatchesName, (const char *), name); 686 687 BreakpointSP bkpt_sp = GetSP(); 688 689 if (bkpt_sp) { 690 std::lock_guard<std::recursive_mutex> guard( 691 bkpt_sp->GetTarget().GetAPIMutex()); 692 return bkpt_sp->MatchesName(name); 693 } 694 695 return false; 696 } 697 698 void SBBreakpoint::GetNames(SBStringList &names) { 699 LLDB_RECORD_METHOD(void, SBBreakpoint, GetNames, (lldb::SBStringList &), 700 names); 701 702 BreakpointSP bkpt_sp = GetSP(); 703 704 if (bkpt_sp) { 705 std::lock_guard<std::recursive_mutex> guard( 706 bkpt_sp->GetTarget().GetAPIMutex()); 707 std::vector<std::string> names_vec; 708 bkpt_sp->GetNames(names_vec); 709 for (std::string name : names_vec) { 710 names.AppendString(name.c_str()); 711 } 712 } 713 } 714 715 bool SBBreakpoint::EventIsBreakpointEvent(const lldb::SBEvent &event) { 716 LLDB_RECORD_STATIC_METHOD(bool, SBBreakpoint, EventIsBreakpointEvent, 717 (const lldb::SBEvent &), event); 718 719 return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event.get()) != 720 nullptr; 721 } 722 723 BreakpointEventType 724 SBBreakpoint::GetBreakpointEventTypeFromEvent(const SBEvent &event) { 725 LLDB_RECORD_STATIC_METHOD(lldb::BreakpointEventType, SBBreakpoint, 726 GetBreakpointEventTypeFromEvent, 727 (const lldb::SBEvent &), event); 728 729 if (event.IsValid()) 730 return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent( 731 event.GetSP()); 732 return eBreakpointEventTypeInvalidType; 733 } 734 735 SBBreakpoint SBBreakpoint::GetBreakpointFromEvent(const lldb::SBEvent &event) { 736 LLDB_RECORD_STATIC_METHOD(lldb::SBBreakpoint, SBBreakpoint, 737 GetBreakpointFromEvent, (const lldb::SBEvent &), 738 event); 739 740 if (event.IsValid()) 741 return LLDB_RECORD_RESULT( 742 SBBreakpoint(Breakpoint::BreakpointEventData::GetBreakpointFromEvent( 743 event.GetSP()))); 744 return LLDB_RECORD_RESULT(SBBreakpoint()); 745 } 746 747 SBBreakpointLocation 748 SBBreakpoint::GetBreakpointLocationAtIndexFromEvent(const lldb::SBEvent &event, 749 uint32_t loc_idx) { 750 LLDB_RECORD_STATIC_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, 751 GetBreakpointLocationAtIndexFromEvent, 752 (const lldb::SBEvent &, uint32_t), event, loc_idx); 753 754 SBBreakpointLocation sb_breakpoint_loc; 755 if (event.IsValid()) 756 sb_breakpoint_loc.SetLocation( 757 Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent( 758 event.GetSP(), loc_idx)); 759 return LLDB_RECORD_RESULT(sb_breakpoint_loc); 760 } 761 762 uint32_t 763 SBBreakpoint::GetNumBreakpointLocationsFromEvent(const lldb::SBEvent &event) { 764 LLDB_RECORD_STATIC_METHOD(uint32_t, SBBreakpoint, 765 GetNumBreakpointLocationsFromEvent, 766 (const lldb::SBEvent &), event); 767 768 uint32_t num_locations = 0; 769 if (event.IsValid()) 770 num_locations = 771 (Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent( 772 event.GetSP())); 773 return num_locations; 774 } 775 776 bool SBBreakpoint::IsHardware() const { 777 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBreakpoint, IsHardware); 778 779 BreakpointSP bkpt_sp = GetSP(); 780 if (bkpt_sp) 781 return bkpt_sp->IsHardware(); 782 return false; 783 } 784 785 BreakpointSP SBBreakpoint::GetSP() const { return m_opaque_wp.lock(); } 786 787 // This is simple collection of breakpoint id's and their target. 788 class SBBreakpointListImpl { 789 public: 790 SBBreakpointListImpl(lldb::TargetSP target_sp) : m_target_wp() { 791 if (target_sp && target_sp->IsValid()) 792 m_target_wp = target_sp; 793 } 794 795 ~SBBreakpointListImpl() = default; 796 797 size_t GetSize() { return m_break_ids.size(); } 798 799 BreakpointSP GetBreakpointAtIndex(size_t idx) { 800 if (idx >= m_break_ids.size()) 801 return BreakpointSP(); 802 TargetSP target_sp = m_target_wp.lock(); 803 if (!target_sp) 804 return BreakpointSP(); 805 lldb::break_id_t bp_id = m_break_ids[idx]; 806 return target_sp->GetBreakpointList().FindBreakpointByID(bp_id); 807 } 808 809 BreakpointSP FindBreakpointByID(lldb::break_id_t desired_id) { 810 TargetSP target_sp = m_target_wp.lock(); 811 if (!target_sp) 812 return BreakpointSP(); 813 814 for (lldb::break_id_t &break_id : m_break_ids) { 815 if (break_id == desired_id) 816 return target_sp->GetBreakpointList().FindBreakpointByID(break_id); 817 } 818 return BreakpointSP(); 819 } 820 821 bool Append(BreakpointSP bkpt) { 822 TargetSP target_sp = m_target_wp.lock(); 823 if (!target_sp || !bkpt) 824 return false; 825 if (bkpt->GetTargetSP() != target_sp) 826 return false; 827 m_break_ids.push_back(bkpt->GetID()); 828 return true; 829 } 830 831 bool AppendIfUnique(BreakpointSP bkpt) { 832 TargetSP target_sp = m_target_wp.lock(); 833 if (!target_sp || !bkpt) 834 return false; 835 if (bkpt->GetTargetSP() != target_sp) 836 return false; 837 lldb::break_id_t bp_id = bkpt->GetID(); 838 if (find(m_break_ids.begin(), m_break_ids.end(), bp_id) == 839 m_break_ids.end()) 840 return false; 841 842 m_break_ids.push_back(bkpt->GetID()); 843 return true; 844 } 845 846 bool AppendByID(lldb::break_id_t id) { 847 TargetSP target_sp = m_target_wp.lock(); 848 if (!target_sp) 849 return false; 850 if (id == LLDB_INVALID_BREAK_ID) 851 return false; 852 m_break_ids.push_back(id); 853 return true; 854 } 855 856 void Clear() { m_break_ids.clear(); } 857 858 void CopyToBreakpointIDList(lldb_private::BreakpointIDList &bp_list) { 859 for (lldb::break_id_t id : m_break_ids) { 860 bp_list.AddBreakpointID(BreakpointID(id)); 861 } 862 } 863 864 TargetSP GetTarget() { return m_target_wp.lock(); } 865 866 private: 867 std::vector<lldb::break_id_t> m_break_ids; 868 TargetWP m_target_wp; 869 }; 870 871 SBBreakpointList::SBBreakpointList(SBTarget &target) 872 : m_opaque_sp(new SBBreakpointListImpl(target.GetSP())) { 873 LLDB_RECORD_CONSTRUCTOR(SBBreakpointList, (lldb::SBTarget &), target); 874 } 875 876 SBBreakpointList::~SBBreakpointList() {} 877 878 size_t SBBreakpointList::GetSize() const { 879 LLDB_RECORD_METHOD_CONST_NO_ARGS(size_t, SBBreakpointList, GetSize); 880 881 if (!m_opaque_sp) 882 return 0; 883 else 884 return m_opaque_sp->GetSize(); 885 } 886 887 SBBreakpoint SBBreakpointList::GetBreakpointAtIndex(size_t idx) { 888 LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBBreakpointList, GetBreakpointAtIndex, 889 (size_t), idx); 890 891 if (!m_opaque_sp) 892 return LLDB_RECORD_RESULT(SBBreakpoint()); 893 894 BreakpointSP bkpt_sp = m_opaque_sp->GetBreakpointAtIndex(idx); 895 return LLDB_RECORD_RESULT(SBBreakpoint(bkpt_sp)); 896 } 897 898 SBBreakpoint SBBreakpointList::FindBreakpointByID(lldb::break_id_t id) { 899 LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBBreakpointList, FindBreakpointByID, 900 (lldb::break_id_t), id); 901 902 if (!m_opaque_sp) 903 return LLDB_RECORD_RESULT(SBBreakpoint()); 904 BreakpointSP bkpt_sp = m_opaque_sp->FindBreakpointByID(id); 905 return LLDB_RECORD_RESULT(SBBreakpoint(bkpt_sp)); 906 } 907 908 void SBBreakpointList::Append(const SBBreakpoint &sb_bkpt) { 909 LLDB_RECORD_METHOD(void, SBBreakpointList, Append, 910 (const lldb::SBBreakpoint &), sb_bkpt); 911 912 if (!sb_bkpt.IsValid()) 913 return; 914 if (!m_opaque_sp) 915 return; 916 m_opaque_sp->Append(sb_bkpt.m_opaque_wp.lock()); 917 } 918 919 void SBBreakpointList::AppendByID(lldb::break_id_t id) { 920 LLDB_RECORD_METHOD(void, SBBreakpointList, AppendByID, (lldb::break_id_t), 921 id); 922 923 if (!m_opaque_sp) 924 return; 925 m_opaque_sp->AppendByID(id); 926 } 927 928 bool SBBreakpointList::AppendIfUnique(const SBBreakpoint &sb_bkpt) { 929 LLDB_RECORD_METHOD(bool, SBBreakpointList, AppendIfUnique, 930 (const lldb::SBBreakpoint &), sb_bkpt); 931 932 if (!sb_bkpt.IsValid()) 933 return false; 934 if (!m_opaque_sp) 935 return false; 936 return m_opaque_sp->AppendIfUnique(sb_bkpt.GetSP()); 937 } 938 939 void SBBreakpointList::Clear() { 940 LLDB_RECORD_METHOD_NO_ARGS(void, SBBreakpointList, Clear); 941 942 if (m_opaque_sp) 943 m_opaque_sp->Clear(); 944 } 945 946 void SBBreakpointList::CopyToBreakpointIDList( 947 lldb_private::BreakpointIDList &bp_id_list) { 948 if (m_opaque_sp) 949 m_opaque_sp->CopyToBreakpointIDList(bp_id_list); 950 } 951 952 namespace lldb_private { 953 namespace repro { 954 955 template <> 956 void RegisterMethods<SBBreakpoint>(Registry &R) { 957 LLDB_REGISTER_CONSTRUCTOR(SBBreakpoint, ()); 958 LLDB_REGISTER_CONSTRUCTOR(SBBreakpoint, (const lldb::SBBreakpoint &)); 959 LLDB_REGISTER_CONSTRUCTOR(SBBreakpoint, (const lldb::BreakpointSP &)); 960 LLDB_REGISTER_METHOD(const lldb::SBBreakpoint &, 961 SBBreakpoint, operator=,(const lldb::SBBreakpoint &)); 962 LLDB_REGISTER_METHOD(bool, 963 SBBreakpoint, operator==,(const lldb::SBBreakpoint &)); 964 LLDB_REGISTER_METHOD(bool, 965 SBBreakpoint, operator!=,(const lldb::SBBreakpoint &)); 966 LLDB_REGISTER_METHOD_CONST(lldb::break_id_t, SBBreakpoint, GetID, ()); 967 LLDB_REGISTER_METHOD_CONST(bool, SBBreakpoint, IsValid, ()); 968 LLDB_REGISTER_METHOD_CONST(bool, SBBreakpoint, operator bool, ()); 969 LLDB_REGISTER_METHOD(void, SBBreakpoint, ClearAllBreakpointSites, ()); 970 LLDB_REGISTER_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, 971 FindLocationByAddress, (lldb::addr_t)); 972 LLDB_REGISTER_METHOD(lldb::break_id_t, SBBreakpoint, 973 FindLocationIDByAddress, (lldb::addr_t)); 974 LLDB_REGISTER_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, 975 FindLocationByID, (lldb::break_id_t)); 976 LLDB_REGISTER_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, 977 GetLocationAtIndex, (uint32_t)); 978 LLDB_REGISTER_METHOD(void, SBBreakpoint, SetEnabled, (bool)); 979 LLDB_REGISTER_METHOD(bool, SBBreakpoint, IsEnabled, ()); 980 LLDB_REGISTER_METHOD(void, SBBreakpoint, SetOneShot, (bool)); 981 LLDB_REGISTER_METHOD_CONST(bool, SBBreakpoint, IsOneShot, ()); 982 LLDB_REGISTER_METHOD(bool, SBBreakpoint, IsInternal, ()); 983 LLDB_REGISTER_METHOD(void, SBBreakpoint, SetIgnoreCount, (uint32_t)); 984 LLDB_REGISTER_METHOD(void, SBBreakpoint, SetCondition, (const char *)); 985 LLDB_REGISTER_METHOD(const char *, SBBreakpoint, GetCondition, ()); 986 LLDB_REGISTER_METHOD(void, SBBreakpoint, SetAutoContinue, (bool)); 987 LLDB_REGISTER_METHOD(bool, SBBreakpoint, GetAutoContinue, ()); 988 LLDB_REGISTER_METHOD_CONST(uint32_t, SBBreakpoint, GetHitCount, ()); 989 LLDB_REGISTER_METHOD_CONST(uint32_t, SBBreakpoint, GetIgnoreCount, ()); 990 LLDB_REGISTER_METHOD(void, SBBreakpoint, SetThreadID, (lldb::tid_t)); 991 LLDB_REGISTER_METHOD(lldb::tid_t, SBBreakpoint, GetThreadID, ()); 992 LLDB_REGISTER_METHOD(void, SBBreakpoint, SetThreadIndex, (uint32_t)); 993 LLDB_REGISTER_METHOD_CONST(uint32_t, SBBreakpoint, GetThreadIndex, ()); 994 LLDB_REGISTER_METHOD(void, SBBreakpoint, SetThreadName, (const char *)); 995 LLDB_REGISTER_METHOD_CONST(const char *, SBBreakpoint, GetThreadName, ()); 996 LLDB_REGISTER_METHOD(void, SBBreakpoint, SetQueueName, (const char *)); 997 LLDB_REGISTER_METHOD_CONST(const char *, SBBreakpoint, GetQueueName, ()); 998 LLDB_REGISTER_METHOD_CONST(size_t, SBBreakpoint, GetNumResolvedLocations, 999 ()); 1000 LLDB_REGISTER_METHOD_CONST(size_t, SBBreakpoint, GetNumLocations, ()); 1001 LLDB_REGISTER_METHOD(void, SBBreakpoint, SetCommandLineCommands, 1002 (lldb::SBStringList &)); 1003 LLDB_REGISTER_METHOD(bool, SBBreakpoint, GetCommandLineCommands, 1004 (lldb::SBStringList &)); 1005 LLDB_REGISTER_METHOD(bool, SBBreakpoint, GetDescription, 1006 (lldb::SBStream &)); 1007 LLDB_REGISTER_METHOD(bool, SBBreakpoint, GetDescription, 1008 (lldb::SBStream &, bool)); 1009 LLDB_REGISTER_METHOD(lldb::SBError, SBBreakpoint, AddLocation, 1010 (lldb::SBAddress &)); 1011 LLDB_REGISTER_METHOD(void, SBBreakpoint, SetScriptCallbackFunction, 1012 (const char *)); 1013 LLDB_REGISTER_METHOD(lldb::SBError, SBBreakpoint, SetScriptCallbackFunction, 1014 (const char *, SBStructuredData &)); 1015 LLDB_REGISTER_METHOD(lldb::SBError, SBBreakpoint, SetScriptCallbackBody, 1016 (const char *)); 1017 LLDB_REGISTER_METHOD(bool, SBBreakpoint, AddName, (const char *)); 1018 LLDB_REGISTER_METHOD(void, SBBreakpoint, RemoveName, (const char *)); 1019 LLDB_REGISTER_METHOD(bool, SBBreakpoint, MatchesName, (const char *)); 1020 LLDB_REGISTER_METHOD(void, SBBreakpoint, GetNames, (lldb::SBStringList &)); 1021 LLDB_REGISTER_STATIC_METHOD(bool, SBBreakpoint, EventIsBreakpointEvent, 1022 (const lldb::SBEvent &)); 1023 LLDB_REGISTER_STATIC_METHOD(lldb::BreakpointEventType, SBBreakpoint, 1024 GetBreakpointEventTypeFromEvent, 1025 (const lldb::SBEvent &)); 1026 LLDB_REGISTER_STATIC_METHOD(lldb::SBBreakpoint, SBBreakpoint, 1027 GetBreakpointFromEvent, 1028 (const lldb::SBEvent &)); 1029 LLDB_REGISTER_STATIC_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, 1030 GetBreakpointLocationAtIndexFromEvent, 1031 (const lldb::SBEvent &, uint32_t)); 1032 LLDB_REGISTER_STATIC_METHOD(uint32_t, SBBreakpoint, 1033 GetNumBreakpointLocationsFromEvent, 1034 (const lldb::SBEvent &)); 1035 LLDB_REGISTER_METHOD_CONST(bool, SBBreakpoint, IsHardware, ()); 1036 } 1037 1038 template <> 1039 void RegisterMethods<SBBreakpointList>(Registry &R) { 1040 LLDB_REGISTER_CONSTRUCTOR(SBBreakpointList, (lldb::SBTarget &)); 1041 LLDB_REGISTER_METHOD_CONST(size_t, SBBreakpointList, GetSize, ()); 1042 LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBBreakpointList, 1043 GetBreakpointAtIndex, (size_t)); 1044 LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBBreakpointList, 1045 FindBreakpointByID, (lldb::break_id_t)); 1046 LLDB_REGISTER_METHOD(void, SBBreakpointList, Append, 1047 (const lldb::SBBreakpoint &)); 1048 LLDB_REGISTER_METHOD(void, SBBreakpointList, AppendByID, 1049 (lldb::break_id_t)); 1050 LLDB_REGISTER_METHOD(bool, SBBreakpointList, AppendIfUnique, 1051 (const lldb::SBBreakpoint &)); 1052 LLDB_REGISTER_METHOD(void, SBBreakpointList, Clear, ()); 1053 } 1054 1055 } 1056 } 1057