1 //===-- Breakpoint.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 11 // C Includes 12 // C++ Includes 13 // Other libraries and framework includes 14 // Project includes 15 16 #include "lldb/Core/Address.h" 17 #include "lldb/Breakpoint/Breakpoint.h" 18 #include "lldb/Breakpoint/BreakpointLocation.h" 19 #include "lldb/Breakpoint/BreakpointLocationCollection.h" 20 #include "lldb/Breakpoint/BreakpointResolver.h" 21 #include "lldb/Breakpoint/BreakpointResolverFileLine.h" 22 #include "lldb/Core/Log.h" 23 #include "lldb/Core/ModuleList.h" 24 #include "lldb/Core/SearchFilter.h" 25 #include "lldb/Core/Stream.h" 26 #include "lldb/Core/StreamString.h" 27 #include "lldb/Symbol/SymbolContext.h" 28 #include "lldb/Target/Target.h" 29 #include "lldb/Target/ThreadSpec.h" 30 #include "lldb/lldb-private-log.h" 31 #include "llvm/Support/Casting.h" 32 33 using namespace lldb; 34 using namespace lldb_private; 35 using namespace llvm; 36 37 const ConstString & 38 Breakpoint::GetEventIdentifier () 39 { 40 static ConstString g_identifier("event-identifier.breakpoint.changed"); 41 return g_identifier; 42 } 43 44 //---------------------------------------------------------------------- 45 // Breakpoint constructor 46 //---------------------------------------------------------------------- 47 Breakpoint::Breakpoint(Target &target, SearchFilterSP &filter_sp, BreakpointResolverSP &resolver_sp) : 48 m_being_created(true), 49 m_target (target), 50 m_filter_sp (filter_sp), 51 m_resolver_sp (resolver_sp), 52 m_options (), 53 m_locations (*this) 54 { 55 m_being_created = false; 56 } 57 58 //---------------------------------------------------------------------- 59 // Destructor 60 //---------------------------------------------------------------------- 61 Breakpoint::~Breakpoint() 62 { 63 } 64 65 bool 66 Breakpoint::IsInternal () const 67 { 68 return LLDB_BREAK_ID_IS_INTERNAL(m_bid); 69 } 70 71 72 73 Target& 74 Breakpoint::GetTarget () 75 { 76 return m_target; 77 } 78 79 const Target& 80 Breakpoint::GetTarget () const 81 { 82 return m_target; 83 } 84 85 BreakpointLocationSP 86 Breakpoint::AddLocation (const Address &addr, bool *new_location) 87 { 88 return m_locations.AddLocation (addr, new_location); 89 } 90 91 BreakpointLocationSP 92 Breakpoint::FindLocationByAddress (const Address &addr) 93 { 94 return m_locations.FindByAddress(addr); 95 } 96 97 break_id_t 98 Breakpoint::FindLocationIDByAddress (const Address &addr) 99 { 100 return m_locations.FindIDByAddress(addr); 101 } 102 103 BreakpointLocationSP 104 Breakpoint::FindLocationByID (break_id_t bp_loc_id) 105 { 106 return m_locations.FindByID(bp_loc_id); 107 } 108 109 BreakpointLocationSP 110 Breakpoint::GetLocationAtIndex (uint32_t index) 111 { 112 return m_locations.GetByIndex(index); 113 } 114 115 // For each of the overall options we need to decide how they propagate to 116 // the location options. This will determine the precedence of options on 117 // the breakpoint vs. its locations. 118 119 // Disable at the breakpoint level should override the location settings. 120 // That way you can conveniently turn off a whole breakpoint without messing 121 // up the individual settings. 122 123 void 124 Breakpoint::SetEnabled (bool enable) 125 { 126 if (enable == m_options.IsEnabled()) 127 return; 128 129 m_options.SetEnabled(enable); 130 if (enable) 131 m_locations.ResolveAllBreakpointSites(); 132 else 133 m_locations.ClearAllBreakpointSites(); 134 135 SendBreakpointChangedEvent (enable ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled); 136 137 } 138 139 bool 140 Breakpoint::IsEnabled () 141 { 142 return m_options.IsEnabled(); 143 } 144 145 void 146 Breakpoint::SetIgnoreCount (uint32_t n) 147 { 148 if (m_options.GetIgnoreCount() == n) 149 return; 150 151 m_options.SetIgnoreCount(n); 152 SendBreakpointChangedEvent (eBreakpointEventTypeIgnoreChanged); 153 } 154 155 uint32_t 156 Breakpoint::GetIgnoreCount () const 157 { 158 return m_options.GetIgnoreCount(); 159 } 160 161 uint32_t 162 Breakpoint::GetHitCount () const 163 { 164 return m_locations.GetHitCount(); 165 } 166 167 void 168 Breakpoint::SetThreadID (lldb::tid_t thread_id) 169 { 170 if (m_options.GetThreadSpec()->GetTID() == thread_id) 171 return; 172 173 m_options.GetThreadSpec()->SetTID(thread_id); 174 SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged); 175 } 176 177 lldb::tid_t 178 Breakpoint::GetThreadID () const 179 { 180 if (m_options.GetThreadSpecNoCreate() == NULL) 181 return LLDB_INVALID_THREAD_ID; 182 else 183 return m_options.GetThreadSpecNoCreate()->GetTID(); 184 } 185 186 void 187 Breakpoint::SetThreadIndex (uint32_t index) 188 { 189 if (m_options.GetThreadSpec()->GetIndex() == index) 190 return; 191 192 m_options.GetThreadSpec()->SetIndex(index); 193 SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged); 194 } 195 196 uint32_t 197 Breakpoint::GetThreadIndex() const 198 { 199 if (m_options.GetThreadSpecNoCreate() == NULL) 200 return 0; 201 else 202 return m_options.GetThreadSpecNoCreate()->GetIndex(); 203 } 204 205 void 206 Breakpoint::SetThreadName (const char *thread_name) 207 { 208 if (::strcmp (m_options.GetThreadSpec()->GetName(), thread_name) == 0) 209 return; 210 211 m_options.GetThreadSpec()->SetName (thread_name); 212 SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged); 213 } 214 215 const char * 216 Breakpoint::GetThreadName () const 217 { 218 if (m_options.GetThreadSpecNoCreate() == NULL) 219 return NULL; 220 else 221 return m_options.GetThreadSpecNoCreate()->GetName(); 222 } 223 224 void 225 Breakpoint::SetQueueName (const char *queue_name) 226 { 227 if (::strcmp (m_options.GetThreadSpec()->GetQueueName(), queue_name) == 0) 228 return; 229 230 m_options.GetThreadSpec()->SetQueueName (queue_name); 231 SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged); 232 } 233 234 const char * 235 Breakpoint::GetQueueName () const 236 { 237 if (m_options.GetThreadSpecNoCreate() == NULL) 238 return NULL; 239 else 240 return m_options.GetThreadSpecNoCreate()->GetQueueName(); 241 } 242 243 void 244 Breakpoint::SetCondition (const char *condition) 245 { 246 m_options.SetCondition (condition); 247 SendBreakpointChangedEvent (eBreakpointEventTypeConditionChanged); 248 } 249 250 const char * 251 Breakpoint::GetConditionText () const 252 { 253 return m_options.GetConditionText(); 254 } 255 256 // This function is used when "baton" doesn't need to be freed 257 void 258 Breakpoint::SetCallback (BreakpointHitCallback callback, void *baton, bool is_synchronous) 259 { 260 // The default "Baton" class will keep a copy of "baton" and won't free 261 // or delete it when it goes goes out of scope. 262 m_options.SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous); 263 264 SendBreakpointChangedEvent (eBreakpointEventTypeCommandChanged); 265 } 266 267 // This function is used when a baton needs to be freed and therefore is 268 // contained in a "Baton" subclass. 269 void 270 Breakpoint::SetCallback (BreakpointHitCallback callback, const BatonSP &callback_baton_sp, bool is_synchronous) 271 { 272 m_options.SetCallback(callback, callback_baton_sp, is_synchronous); 273 } 274 275 void 276 Breakpoint::ClearCallback () 277 { 278 m_options.ClearCallback (); 279 } 280 281 bool 282 Breakpoint::InvokeCallback (StoppointCallbackContext *context, break_id_t bp_loc_id) 283 { 284 return m_options.InvokeCallback (context, GetID(), bp_loc_id); 285 } 286 287 BreakpointOptions * 288 Breakpoint::GetOptions () 289 { 290 return &m_options; 291 } 292 293 void 294 Breakpoint::ResolveBreakpoint () 295 { 296 if (m_resolver_sp) 297 m_resolver_sp->ResolveBreakpoint(*m_filter_sp); 298 } 299 300 void 301 Breakpoint::ResolveBreakpointInModules (ModuleList &module_list) 302 { 303 if (m_resolver_sp) 304 m_resolver_sp->ResolveBreakpointInModules(*m_filter_sp, module_list); 305 } 306 307 void 308 Breakpoint::ClearAllBreakpointSites () 309 { 310 m_locations.ClearAllBreakpointSites(); 311 } 312 313 //---------------------------------------------------------------------- 314 // ModulesChanged: Pass in a list of new modules, and 315 //---------------------------------------------------------------------- 316 317 void 318 Breakpoint::ModulesChanged (ModuleList &module_list, bool load, bool delete_locations) 319 { 320 Mutex::Locker modules_mutex(module_list.GetMutex()); 321 if (load) 322 { 323 // The logic for handling new modules is: 324 // 1) If the filter rejects this module, then skip it. 325 // 2) Run through the current location list and if there are any locations 326 // for that module, we mark the module as "seen" and we don't try to re-resolve 327 // breakpoint locations for that module. 328 // However, we do add breakpoint sites to these locations if needed. 329 // 3) If we don't see this module in our breakpoint location list, call ResolveInModules. 330 331 ModuleList new_modules; // We'll stuff the "unseen" modules in this list, and then resolve 332 // them after the locations pass. Have to do it this way because 333 // resolving breakpoints will add new locations potentially. 334 335 const size_t num_locs = m_locations.GetSize(); 336 size_t num_modules = module_list.GetSize(); 337 for (size_t i = 0; i < num_modules; i++) 338 { 339 bool seen = false; 340 ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (i)); 341 if (!m_filter_sp->ModulePasses (module_sp)) 342 continue; 343 344 for (size_t loc_idx = 0; loc_idx < num_locs; loc_idx++) 345 { 346 BreakpointLocationSP break_loc = m_locations.GetByIndex(loc_idx); 347 if (!break_loc->IsEnabled()) 348 continue; 349 SectionSP section_sp (break_loc->GetAddress().GetSection()); 350 if (!section_sp || section_sp->GetModule() == module_sp) 351 { 352 if (!seen) 353 seen = true; 354 355 if (!break_loc->ResolveBreakpointSite()) 356 { 357 LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); 358 if (log) 359 log->Printf ("Warning: could not set breakpoint site for breakpoint location %d of breakpoint %d.\n", 360 break_loc->GetID(), GetID()); 361 } 362 } 363 } 364 365 if (!seen) 366 new_modules.AppendIfNeeded (module_sp); 367 368 } 369 370 if (new_modules.GetSize() > 0) 371 { 372 // If this is not an internal breakpoint, set up to record the new locations, then dispatch 373 // an event with the new locations. 374 if (!IsInternal()) 375 { 376 BreakpointEventData *new_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsAdded, 377 shared_from_this()); 378 379 m_locations.StartRecordingNewLocations(new_locations_event->GetBreakpointLocationCollection()); 380 381 ResolveBreakpointInModules(new_modules); 382 383 m_locations.StopRecordingNewLocations(); 384 if (new_locations_event->GetBreakpointLocationCollection().GetSize() != 0) 385 { 386 SendBreakpointChangedEvent (new_locations_event); 387 } 388 else 389 delete new_locations_event; 390 } 391 else 392 ResolveBreakpointInModules(new_modules); 393 394 } 395 } 396 else 397 { 398 // Go through the currently set locations and if any have breakpoints in 399 // the module list, then remove their breakpoint sites, and their locations if asked to. 400 401 BreakpointEventData *removed_locations_event; 402 if (!IsInternal()) 403 removed_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsRemoved, 404 shared_from_this()); 405 else 406 removed_locations_event = NULL; 407 408 size_t num_modules = module_list.GetSize(); 409 for (size_t i = 0; i < num_modules; i++) 410 { 411 ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (i)); 412 if (m_filter_sp->ModulePasses (module_sp)) 413 { 414 size_t loc_idx = 0; 415 size_t num_locations = m_locations.GetSize(); 416 BreakpointLocationCollection locations_to_remove; 417 for (loc_idx = 0; loc_idx < num_locations; loc_idx++) 418 { 419 BreakpointLocationSP break_loc_sp (m_locations.GetByIndex(loc_idx)); 420 SectionSP section_sp (break_loc_sp->GetAddress().GetSection()); 421 if (section_sp && section_sp->GetModule() == module_sp) 422 { 423 // Remove this breakpoint since the shared library is 424 // unloaded, but keep the breakpoint location around 425 // so we always get complete hit count and breakpoint 426 // lifetime info 427 break_loc_sp->ClearBreakpointSite(); 428 if (removed_locations_event) 429 { 430 removed_locations_event->GetBreakpointLocationCollection().Add(break_loc_sp); 431 } 432 if (delete_locations) 433 locations_to_remove.Add (break_loc_sp); 434 435 } 436 } 437 438 if (delete_locations) 439 { 440 size_t num_locations_to_remove = locations_to_remove.GetSize(); 441 for (loc_idx = 0; loc_idx < num_locations_to_remove; loc_idx++) 442 m_locations.RemoveLocation (locations_to_remove.GetByIndex(loc_idx)); 443 } 444 } 445 } 446 SendBreakpointChangedEvent (removed_locations_event); 447 } 448 } 449 450 void 451 Breakpoint::ModuleReplaced (ModuleSP old_module_sp, ModuleSP new_module_sp) 452 { 453 ModuleList temp_list; 454 temp_list.Append (new_module_sp); 455 ModulesChanged (temp_list, true); 456 457 // TO DO: For now I'm just adding locations for the new module and removing the 458 // breakpoint locations that were in the old module. 459 // We should really go find the ones that are in the new module & if we can determine that they are "equivalent" 460 // carry over the options from the old location to the new. 461 462 temp_list.Clear(); 463 temp_list.Append (old_module_sp); 464 ModulesChanged (temp_list, false, true); 465 } 466 467 void 468 Breakpoint::Dump (Stream *) 469 { 470 } 471 472 size_t 473 Breakpoint::GetNumResolvedLocations() const 474 { 475 // Return the number of breakpoints that are actually resolved and set 476 // down in the inferior process. 477 return m_locations.GetNumResolvedLocations(); 478 } 479 480 size_t 481 Breakpoint::GetNumLocations() const 482 { 483 return m_locations.GetSize(); 484 } 485 486 void 487 Breakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_locations) 488 { 489 assert (s != NULL); 490 s->Printf("%i: ", GetID()); 491 GetResolverDescription (s); 492 GetFilterDescription (s); 493 494 const size_t num_locations = GetNumLocations (); 495 const size_t num_resolved_locations = GetNumResolvedLocations (); 496 497 switch (level) 498 { 499 case lldb::eDescriptionLevelBrief: 500 case lldb::eDescriptionLevelFull: 501 if (num_locations > 0) 502 { 503 s->Printf(", locations = %zu", num_locations); 504 if (num_resolved_locations > 0) 505 s->Printf(", resolved = %zu", num_resolved_locations); 506 } 507 else 508 { 509 // Don't print the pending notification for exception resolvers since we don't generally 510 // know how to set them until the target is run. 511 if (m_resolver_sp->getResolverID() != BreakpointResolver::ExceptionResolver) 512 s->Printf(", locations = 0 (pending)"); 513 } 514 515 GetOptions()->GetDescription(s, level); 516 517 if (level == lldb::eDescriptionLevelFull) 518 { 519 s->IndentLess(); 520 s->EOL(); 521 } 522 break; 523 524 case lldb::eDescriptionLevelVerbose: 525 // Verbose mode does a debug dump of the breakpoint 526 Dump (s); 527 s->EOL (); 528 //s->Indent(); 529 GetOptions()->GetDescription(s, level); 530 break; 531 532 default: 533 break; 534 } 535 536 // The brief description is just the location name (1.2 or whatever). That's pointless to 537 // show in the breakpoint's description, so suppress it. 538 if (show_locations && level != lldb::eDescriptionLevelBrief) 539 { 540 s->IndentMore(); 541 for (size_t i = 0; i < num_locations; ++i) 542 { 543 BreakpointLocation *loc = GetLocationAtIndex(i).get(); 544 loc->GetDescription(s, level); 545 s->EOL(); 546 } 547 s->IndentLess(); 548 } 549 } 550 551 void 552 Breakpoint::GetResolverDescription (Stream *s) 553 { 554 if (m_resolver_sp) 555 m_resolver_sp->GetDescription (s); 556 } 557 558 559 bool 560 Breakpoint::GetMatchingFileLine (const ConstString &filename, uint32_t line_number, BreakpointLocationCollection &loc_coll) 561 { 562 // TODO: To be correct, this method needs to fill the breakpoint location collection 563 // with the location IDs which match the filename and line_number. 564 // 565 566 if (m_resolver_sp) 567 { 568 BreakpointResolverFileLine *resolverFileLine = dyn_cast<BreakpointResolverFileLine>(m_resolver_sp.get()); 569 if (resolverFileLine && 570 resolverFileLine->m_file_spec.GetFilename() == filename && 571 resolverFileLine->m_line_number == line_number) 572 { 573 return true; 574 } 575 } 576 return false; 577 } 578 579 void 580 Breakpoint::GetFilterDescription (Stream *s) 581 { 582 m_filter_sp->GetDescription (s); 583 } 584 585 void 586 Breakpoint::SendBreakpointChangedEvent (lldb::BreakpointEventType eventKind) 587 { 588 if (!m_being_created 589 && !IsInternal() 590 && GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged)) 591 { 592 BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind, shared_from_this()); 593 594 GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data); 595 } 596 } 597 598 void 599 Breakpoint::SendBreakpointChangedEvent (BreakpointEventData *data) 600 { 601 602 if (data == NULL) 603 return; 604 605 if (!m_being_created 606 && !IsInternal() 607 && GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged)) 608 GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data); 609 else 610 delete data; 611 } 612 613 Breakpoint::BreakpointEventData::BreakpointEventData (BreakpointEventType sub_type, 614 const BreakpointSP &new_breakpoint_sp) : 615 EventData (), 616 m_breakpoint_event (sub_type), 617 m_new_breakpoint_sp (new_breakpoint_sp) 618 { 619 } 620 621 Breakpoint::BreakpointEventData::~BreakpointEventData () 622 { 623 } 624 625 const ConstString & 626 Breakpoint::BreakpointEventData::GetFlavorString () 627 { 628 static ConstString g_flavor ("Breakpoint::BreakpointEventData"); 629 return g_flavor; 630 } 631 632 const ConstString & 633 Breakpoint::BreakpointEventData::GetFlavor () const 634 { 635 return BreakpointEventData::GetFlavorString (); 636 } 637 638 639 BreakpointSP & 640 Breakpoint::BreakpointEventData::GetBreakpoint () 641 { 642 return m_new_breakpoint_sp; 643 } 644 645 BreakpointEventType 646 Breakpoint::BreakpointEventData::GetBreakpointEventType () const 647 { 648 return m_breakpoint_event; 649 } 650 651 void 652 Breakpoint::BreakpointEventData::Dump (Stream *s) const 653 { 654 } 655 656 const Breakpoint::BreakpointEventData * 657 Breakpoint::BreakpointEventData::GetEventDataFromEvent (const Event *event) 658 { 659 if (event) 660 { 661 const EventData *event_data = event->GetData(); 662 if (event_data && event_data->GetFlavor() == BreakpointEventData::GetFlavorString()) 663 return static_cast <const BreakpointEventData *> (event->GetData()); 664 } 665 return NULL; 666 } 667 668 BreakpointEventType 669 Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (const EventSP &event_sp) 670 { 671 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get()); 672 673 if (data == NULL) 674 return eBreakpointEventTypeInvalidType; 675 else 676 return data->GetBreakpointEventType(); 677 } 678 679 BreakpointSP 680 Breakpoint::BreakpointEventData::GetBreakpointFromEvent (const EventSP &event_sp) 681 { 682 BreakpointSP bp_sp; 683 684 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get()); 685 if (data) 686 bp_sp = data->m_new_breakpoint_sp; 687 688 return bp_sp; 689 } 690 691 uint32_t 692 Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent (const EventSP &event_sp) 693 { 694 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get()); 695 if (data) 696 return data->m_locations.GetSize(); 697 698 return 0; 699 } 700 701 lldb::BreakpointLocationSP 702 Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (const lldb::EventSP &event_sp, uint32_t bp_loc_idx) 703 { 704 lldb::BreakpointLocationSP bp_loc_sp; 705 706 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get()); 707 if (data) 708 { 709 bp_loc_sp = data->m_locations.GetByIndex(bp_loc_idx); 710 } 711 712 return bp_loc_sp; 713 } 714