1 //===-- SBBreakpointName.cpp ----------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // C Includes 11 // C++ Includes 12 // Other libraries and framework includes 13 // Project includes 14 #include "lldb/API/SBBreakpointName.h" 15 #include "lldb/API/SBDebugger.h" 16 #include "lldb/API/SBError.h" 17 #include "lldb/API/SBStream.h" 18 #include "lldb/API/SBStringList.h" 19 #include "lldb/API/SBTarget.h" 20 21 #include "lldb/Breakpoint/BreakpointName.h" 22 #include "lldb/Breakpoint/StoppointCallbackContext.h" 23 #include "lldb/Core/Debugger.h" 24 #include "lldb/Interpreter/CommandInterpreter.h" 25 #include "lldb/Interpreter/ScriptInterpreter.h" 26 #include "lldb/Target/Target.h" 27 #include "lldb/Target/ThreadSpec.h" 28 #include "lldb/Utility/Log.h" 29 #include "lldb/Utility/Stream.h" 30 31 #include "SBBreakpointOptionCommon.h" 32 33 using namespace lldb; 34 using namespace lldb_private; 35 36 namespace lldb 37 { 38 class SBBreakpointNameImpl { 39 public: 40 SBBreakpointNameImpl(SBTarget &sb_target, const char *name) 41 { 42 if (!name || name[0] == '\0') 43 return; 44 m_name.assign(name); 45 46 if (!sb_target.IsValid()) 47 return; 48 49 TargetSP target_sp = sb_target.GetSP(); 50 if (!target_sp) 51 return; 52 53 m_target_wp = target_sp; 54 } 55 56 SBBreakpointNameImpl(TargetSP target_sp, const char *name) 57 { 58 if (!name || name[0] == '\0') 59 return; 60 m_name.assign(name); 61 62 if (!target_sp) 63 return; 64 65 m_target_wp = target_sp; 66 } 67 68 bool operator==(const SBBreakpointNameImpl &rhs) { 69 return m_name == rhs.m_name 70 && m_target_wp.lock() == rhs.m_target_wp.lock(); 71 } 72 73 bool operator!=(const SBBreakpointNameImpl &rhs) { 74 return m_name != rhs.m_name 75 || m_target_wp.lock() != rhs.m_target_wp.lock(); 76 } 77 // For now we take a simple approach and only keep the name, and relook 78 // up the location when we need it. 79 80 TargetSP GetTarget() { 81 return m_target_wp.lock(); 82 } 83 84 const char *GetName() { 85 return m_name.c_str(); 86 } 87 88 bool IsValid() { 89 return !m_name.empty() && m_target_wp.lock(); 90 } 91 92 lldb_private::BreakpointName *GetBreakpointName() 93 { 94 if (!IsValid()) 95 return nullptr; 96 TargetSP target_sp = GetTarget(); 97 if (!target_sp) 98 return nullptr; 99 Status error; 100 return target_sp->FindBreakpointName(ConstString(m_name), true, error); 101 } 102 103 const lldb_private::BreakpointName *GetBreakpointName() const 104 { 105 return GetBreakpointName(); 106 } 107 108 private: 109 TargetWP m_target_wp; 110 std::string m_name; 111 }; 112 } // namespace lldb 113 114 SBBreakpointName::SBBreakpointName() {} 115 116 SBBreakpointName::SBBreakpointName(SBTarget &sb_target, const char *name) 117 { 118 m_impl_up.reset(new SBBreakpointNameImpl(sb_target, name)); 119 // Call FindBreakpointName here to make sure the name is valid, reset if 120 // not: 121 BreakpointName *bp_name = GetBreakpointName(); 122 if (!bp_name) 123 m_impl_up.reset(); 124 } 125 126 SBBreakpointName::SBBreakpointName(SBBreakpoint &sb_bkpt, const char *name) 127 { 128 if (!sb_bkpt.IsValid()) { 129 m_impl_up.reset(); 130 return; 131 } 132 BreakpointSP bkpt_sp = sb_bkpt.GetSP(); 133 Target &target = bkpt_sp->GetTarget(); 134 135 m_impl_up.reset(new SBBreakpointNameImpl(target.shared_from_this(), name)); 136 137 // Call FindBreakpointName here to make sure the name is valid, reset if 138 // not: 139 BreakpointName *bp_name = GetBreakpointName(); 140 if (!bp_name) { 141 m_impl_up.reset(); 142 return; 143 } 144 145 // Now copy over the breakpoint's options: 146 target.ConfigureBreakpointName(*bp_name, *bkpt_sp->GetOptions(), 147 BreakpointName::Permissions()); 148 } 149 150 SBBreakpointName::SBBreakpointName(const SBBreakpointName &rhs) 151 { 152 if (!rhs.m_impl_up) 153 return; 154 else 155 m_impl_up.reset(new SBBreakpointNameImpl(rhs.m_impl_up->GetTarget(), 156 rhs.m_impl_up->GetName())); 157 } 158 159 SBBreakpointName::~SBBreakpointName() = default; 160 161 const SBBreakpointName &SBBreakpointName::operator=(const SBBreakpointName &rhs) 162 { 163 if (!rhs.m_impl_up) { 164 m_impl_up.reset(); 165 return *this; 166 } 167 168 m_impl_up.reset(new SBBreakpointNameImpl(rhs.m_impl_up->GetTarget(), 169 rhs.m_impl_up->GetName())); 170 return *this; 171 } 172 173 bool SBBreakpointName::operator==(const lldb::SBBreakpointName &rhs) { 174 return *m_impl_up.get() == *rhs.m_impl_up.get(); 175 } 176 177 bool SBBreakpointName::operator!=(const lldb::SBBreakpointName &rhs) { 178 return *m_impl_up.get() != *rhs.m_impl_up.get(); 179 } 180 181 bool SBBreakpointName::IsValid() const { 182 if (!m_impl_up) 183 return false; 184 return m_impl_up->IsValid(); 185 } 186 187 const char *SBBreakpointName::GetName() const { 188 if (!m_impl_up) 189 return "<Invalid Breakpoint Name Object>"; 190 return m_impl_up->GetName(); 191 } 192 193 void SBBreakpointName::SetEnabled(bool enable) { 194 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 195 196 BreakpointName *bp_name = GetBreakpointName(); 197 if (!bp_name) 198 return; 199 200 LLDB_LOG(log, "Name: {0} enabled: {1}\n", bp_name->GetName(), enable); 201 std::lock_guard<std::recursive_mutex> guard( 202 m_impl_up->GetTarget()->GetAPIMutex()); 203 204 bp_name->GetOptions().SetEnabled(enable); 205 } 206 207 void SBBreakpointName::UpdateName(BreakpointName &bp_name) { 208 if (!IsValid()) 209 return; 210 211 TargetSP target_sp = m_impl_up->GetTarget(); 212 if (!target_sp) 213 return; 214 target_sp->ApplyNameToBreakpoints(bp_name); 215 216 } 217 218 bool SBBreakpointName::IsEnabled() { 219 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 220 221 BreakpointName *bp_name = GetBreakpointName(); 222 if (!bp_name) 223 return false; 224 225 LLDB_LOG(log, "Name: {0}\n", bp_name->GetName()); 226 std::lock_guard<std::recursive_mutex> guard( 227 m_impl_up->GetTarget()->GetAPIMutex()); 228 229 return bp_name->GetOptions().IsEnabled(); 230 } 231 232 void SBBreakpointName::SetOneShot(bool one_shot) { 233 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 234 235 BreakpointName *bp_name = GetBreakpointName(); 236 if (!bp_name) 237 return; 238 239 LLDB_LOG(log, "Name: {0} one_shot: {1}\n", bp_name->GetName(), one_shot); 240 std::lock_guard<std::recursive_mutex> guard( 241 m_impl_up->GetTarget()->GetAPIMutex()); 242 243 bp_name->GetOptions().SetOneShot(one_shot); 244 UpdateName(*bp_name); 245 } 246 247 bool SBBreakpointName::IsOneShot() const { 248 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 249 250 const BreakpointName *bp_name = GetBreakpointName(); 251 if (!bp_name) 252 return false; 253 254 LLDB_LOG(log, "Name: {0}\n", bp_name->GetName()); 255 std::lock_guard<std::recursive_mutex> guard( 256 m_impl_up->GetTarget()->GetAPIMutex()); 257 258 return bp_name->GetOptions().IsOneShot(); 259 } 260 261 void SBBreakpointName::SetIgnoreCount(uint32_t count) { 262 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 263 264 BreakpointName *bp_name = GetBreakpointName(); 265 if (!bp_name) 266 return; 267 268 LLDB_LOG(log, "Name: {0} one_shot: {1}\n", bp_name->GetName(), count); 269 std::lock_guard<std::recursive_mutex> guard( 270 m_impl_up->GetTarget()->GetAPIMutex()); 271 272 bp_name->GetOptions().SetIgnoreCount(count); 273 UpdateName(*bp_name); 274 } 275 276 uint32_t SBBreakpointName::GetIgnoreCount() const { 277 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 278 279 BreakpointName *bp_name = GetBreakpointName(); 280 if (!bp_name) 281 return false; 282 283 LLDB_LOG(log, "Name: {0}\n", bp_name->GetName()); 284 std::lock_guard<std::recursive_mutex> guard( 285 m_impl_up->GetTarget()->GetAPIMutex()); 286 287 return bp_name->GetOptions().GetIgnoreCount(); 288 } 289 290 void SBBreakpointName::SetCondition(const char *condition) { 291 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 292 293 BreakpointName *bp_name = GetBreakpointName(); 294 if (!bp_name) 295 return; 296 297 LLDB_LOG(log, "Name: {0} one_shot: {1}\n", bp_name->GetName(), 298 condition ? condition : "<NULL>"); 299 300 std::lock_guard<std::recursive_mutex> guard( 301 m_impl_up->GetTarget()->GetAPIMutex()); 302 303 bp_name->GetOptions().SetCondition(condition); 304 UpdateName(*bp_name); 305 } 306 307 const char *SBBreakpointName::GetCondition() { 308 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 309 310 BreakpointName *bp_name = GetBreakpointName(); 311 if (!bp_name) 312 return nullptr; 313 314 LLDB_LOG(log, "Name: {0}\n", bp_name->GetName()); 315 std::lock_guard<std::recursive_mutex> guard( 316 m_impl_up->GetTarget()->GetAPIMutex()); 317 318 return bp_name->GetOptions().GetConditionText(); 319 } 320 321 void SBBreakpointName::SetAutoContinue(bool auto_continue) { 322 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 323 324 BreakpointName *bp_name = GetBreakpointName(); 325 if (!bp_name) 326 return; 327 328 LLDB_LOG(log, "Name: {0} auto-continue: {1}\n", bp_name->GetName(), auto_continue); 329 330 std::lock_guard<std::recursive_mutex> guard( 331 m_impl_up->GetTarget()->GetAPIMutex()); 332 333 bp_name->GetOptions().SetAutoContinue(auto_continue); 334 UpdateName(*bp_name); 335 } 336 337 bool SBBreakpointName::GetAutoContinue() { 338 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 339 340 BreakpointName *bp_name = GetBreakpointName(); 341 if (!bp_name) 342 return nullptr; 343 344 LLDB_LOG(log, "Name: {0}\n", bp_name->GetName()); 345 std::lock_guard<std::recursive_mutex> guard( 346 m_impl_up->GetTarget()->GetAPIMutex()); 347 348 return bp_name->GetOptions().IsAutoContinue(); 349 } 350 351 void SBBreakpointName::SetThreadID(tid_t tid) { 352 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 353 354 BreakpointName *bp_name = GetBreakpointName(); 355 if (!bp_name) 356 return; 357 358 LLDB_LOG(log, "Name: {0} tid: {1:x}\n", bp_name->GetName(), tid); 359 360 std::lock_guard<std::recursive_mutex> guard( 361 m_impl_up->GetTarget()->GetAPIMutex()); 362 363 bp_name->GetOptions().SetThreadID(tid); 364 UpdateName(*bp_name); 365 } 366 367 tid_t SBBreakpointName::GetThreadID() { 368 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 369 370 BreakpointName *bp_name = GetBreakpointName(); 371 if (!bp_name) 372 return LLDB_INVALID_THREAD_ID; 373 374 LLDB_LOG(log, "Name: {0}\n", bp_name->GetName()); 375 std::lock_guard<std::recursive_mutex> guard( 376 m_impl_up->GetTarget()->GetAPIMutex()); 377 378 return bp_name->GetOptions().GetThreadSpec()->GetTID(); 379 } 380 381 void SBBreakpointName::SetThreadIndex(uint32_t index) { 382 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 383 384 BreakpointName *bp_name = GetBreakpointName(); 385 if (!bp_name) 386 return; 387 388 LLDB_LOG(log, "Name: {0} thread index: {1}\n", bp_name->GetName(), index); 389 390 std::lock_guard<std::recursive_mutex> guard( 391 m_impl_up->GetTarget()->GetAPIMutex()); 392 393 bp_name->GetOptions().GetThreadSpec()->SetIndex(index); 394 UpdateName(*bp_name); 395 } 396 397 uint32_t SBBreakpointName::GetThreadIndex() const { 398 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 399 400 BreakpointName *bp_name = GetBreakpointName(); 401 if (!bp_name) 402 return LLDB_INVALID_THREAD_ID; 403 404 LLDB_LOG(log, "Name: {0}\n", bp_name->GetName()); 405 std::lock_guard<std::recursive_mutex> guard( 406 m_impl_up->GetTarget()->GetAPIMutex()); 407 408 return bp_name->GetOptions().GetThreadSpec()->GetIndex(); 409 } 410 411 void SBBreakpointName::SetThreadName(const char *thread_name) { 412 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 413 414 BreakpointName *bp_name = GetBreakpointName(); 415 if (!bp_name) 416 return; 417 418 LLDB_LOG(log, "Name: {0} thread name: {1}\n", bp_name->GetName(), thread_name); 419 420 std::lock_guard<std::recursive_mutex> guard( 421 m_impl_up->GetTarget()->GetAPIMutex()); 422 423 bp_name->GetOptions().GetThreadSpec()->SetName(thread_name); 424 UpdateName(*bp_name); 425 } 426 427 const char *SBBreakpointName::GetThreadName() const { 428 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 429 430 BreakpointName *bp_name = GetBreakpointName(); 431 if (!bp_name) 432 return nullptr; 433 434 LLDB_LOG(log, "Name: {0}\n", bp_name->GetName()); 435 std::lock_guard<std::recursive_mutex> guard( 436 m_impl_up->GetTarget()->GetAPIMutex()); 437 438 return bp_name->GetOptions().GetThreadSpec()->GetName(); 439 } 440 441 void SBBreakpointName::SetQueueName(const char *queue_name) { 442 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 443 444 BreakpointName *bp_name = GetBreakpointName(); 445 if (!bp_name) 446 return; 447 448 LLDB_LOG(log, "Name: {0} queue name: {1}\n", bp_name->GetName(), queue_name); 449 450 std::lock_guard<std::recursive_mutex> guard( 451 m_impl_up->GetTarget()->GetAPIMutex()); 452 453 bp_name->GetOptions().GetThreadSpec()->SetQueueName(queue_name); 454 UpdateName(*bp_name); 455 } 456 457 const char *SBBreakpointName::GetQueueName() const { 458 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 459 460 BreakpointName *bp_name = GetBreakpointName(); 461 if (!bp_name) 462 return nullptr; 463 464 LLDB_LOG(log, "Name: {0}\n", bp_name->GetName()); 465 std::lock_guard<std::recursive_mutex> guard( 466 m_impl_up->GetTarget()->GetAPIMutex()); 467 468 return bp_name->GetOptions().GetThreadSpec()->GetQueueName(); 469 } 470 471 void SBBreakpointName::SetCommandLineCommands(SBStringList &commands) { 472 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 473 BreakpointName *bp_name = GetBreakpointName(); 474 if (!bp_name) 475 return; 476 if (commands.GetSize() == 0) 477 return; 478 479 LLDB_LOG(log, "Name: {0} commands\n", bp_name->GetName()); 480 481 std::lock_guard<std::recursive_mutex> guard( 482 m_impl_up->GetTarget()->GetAPIMutex()); 483 std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up( 484 new BreakpointOptions::CommandData(*commands, eScriptLanguageNone)); 485 486 bp_name->GetOptions().SetCommandDataCallback(cmd_data_up); 487 UpdateName(*bp_name); 488 } 489 490 bool SBBreakpointName::GetCommandLineCommands(SBStringList &commands) { 491 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 492 493 BreakpointName *bp_name = GetBreakpointName(); 494 if (!bp_name) 495 return false; 496 497 LLDB_LOG(log, "Name: {0}\n", bp_name->GetName()); 498 StringList command_list; 499 bool has_commands = 500 bp_name->GetOptions().GetCommandLineCallbacks(command_list); 501 if (has_commands) 502 commands.AppendList(command_list); 503 return has_commands; 504 } 505 506 bool SBBreakpointName::GetDescription(SBStream &s) { 507 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 508 509 BreakpointName *bp_name = GetBreakpointName(); 510 if (!bp_name) 511 { 512 s.Printf("No value"); 513 return false; 514 } 515 516 LLDB_LOG(log, "Name: {0}\n", bp_name->GetName()); 517 std::lock_guard<std::recursive_mutex> guard( 518 m_impl_up->GetTarget()->GetAPIMutex()); 519 bp_name->GetDescription(s.get(), eDescriptionLevelFull); 520 return true; 521 } 522 523 void SBBreakpointName::SetCallback(SBBreakpointHitCallback callback, 524 void *baton) { 525 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 526 BreakpointName *bp_name = GetBreakpointName(); 527 if (!bp_name) 528 return; 529 LLDB_LOG(log, "callback = {1}, baton = {2}", callback, baton); 530 std::lock_guard<std::recursive_mutex> guard( 531 m_impl_up->GetTarget()->GetAPIMutex()); 532 533 BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton)); 534 bp_name->GetOptions().SetCallback(SBBreakpointCallbackBaton 535 ::PrivateBreakpointHitCallback, 536 baton_sp, 537 false); 538 UpdateName(*bp_name); 539 } 540 541 void SBBreakpointName::SetScriptCallbackFunction( 542 const char *callback_function_name) { 543 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 544 545 BreakpointName *bp_name = GetBreakpointName(); 546 if (!bp_name) 547 return; 548 549 LLDB_LOG(log, "Name: {0} callback: {1}\n", bp_name->GetName(), 550 callback_function_name); 551 552 std::lock_guard<std::recursive_mutex> guard( 553 m_impl_up->GetTarget()->GetAPIMutex()); 554 555 BreakpointOptions &bp_options = bp_name->GetOptions(); 556 m_impl_up->GetTarget() 557 ->GetDebugger() 558 .GetCommandInterpreter() 559 .GetScriptInterpreter() 560 ->SetBreakpointCommandCallbackFunction(&bp_options, 561 callback_function_name); 562 UpdateName(*bp_name); 563 } 564 565 SBError SBBreakpointName::SetScriptCallbackBody(const char *callback_body_text) 566 { 567 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 568 SBError sb_error; 569 BreakpointName *bp_name = GetBreakpointName(); 570 if (!bp_name) 571 return sb_error; 572 573 LLDB_LOG(log, "Name: {0} callback: {1}\n", bp_name->GetName(), 574 callback_body_text); 575 576 std::lock_guard<std::recursive_mutex> guard( 577 m_impl_up->GetTarget()->GetAPIMutex()); 578 579 BreakpointOptions &bp_options = bp_name->GetOptions(); 580 Status error = 581 m_impl_up->GetTarget() 582 ->GetDebugger() 583 .GetCommandInterpreter() 584 .GetScriptInterpreter() 585 ->SetBreakpointCommandCallback(&bp_options, callback_body_text); 586 sb_error.SetError(error); 587 if (!sb_error.Fail()) 588 UpdateName(*bp_name); 589 590 return sb_error; 591 } 592 593 bool SBBreakpointName::GetAllowList() const 594 { 595 BreakpointName *bp_name = GetBreakpointName(); 596 if (!bp_name) 597 return false; 598 return bp_name->GetPermissions().GetAllowList(); 599 } 600 601 void SBBreakpointName::SetAllowList(bool value) 602 { 603 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 604 605 BreakpointName *bp_name = GetBreakpointName(); 606 if (!bp_name) 607 return; 608 if (log) 609 log->Printf("Setting allow list to %u for %s.", value, 610 bp_name->GetName().AsCString()); 611 bp_name->GetPermissions().SetAllowList(value); 612 } 613 614 bool SBBreakpointName::GetAllowDelete() 615 { 616 BreakpointName *bp_name = GetBreakpointName(); 617 if (!bp_name) 618 return false; 619 return bp_name->GetPermissions().GetAllowDelete(); 620 } 621 622 void SBBreakpointName::SetAllowDelete(bool value) 623 { 624 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 625 626 BreakpointName *bp_name = GetBreakpointName(); 627 if (!bp_name) 628 return; 629 if (log) 630 log->Printf("Setting allow delete to %u for %s.", value, 631 bp_name->GetName().AsCString()); 632 bp_name->GetPermissions().SetAllowDelete(value); 633 } 634 635 bool SBBreakpointName::GetAllowDisable() 636 { 637 BreakpointName *bp_name = GetBreakpointName(); 638 if (!bp_name) 639 return false; 640 return bp_name->GetPermissions().GetAllowDisable(); 641 } 642 643 void SBBreakpointName::SetAllowDisable(bool value) 644 { 645 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 646 647 BreakpointName *bp_name = GetBreakpointName(); 648 if (!bp_name) 649 return; 650 if (log) 651 log->Printf("Setting allow disable to %u for %s.", value, 652 bp_name->GetName().AsCString()); 653 bp_name->GetPermissions().SetAllowDisable(value); 654 } 655 656 lldb_private::BreakpointName *SBBreakpointName::GetBreakpointName() const 657 { 658 if (!IsValid()) 659 return nullptr; 660 return m_impl_up->GetBreakpointName(); 661 } 662 663