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