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