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