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 if (load) 321 { 322 // The logic for handling new modules is: 323 // 1) If the filter rejects this module, then skip it. 324 // 2) Run through the current location list and if there are any locations 325 // for that module, we mark the module as "seen" and we don't try to re-resolve 326 // breakpoint locations for that module. 327 // However, we do add breakpoint sites to these locations if needed. 328 // 3) If we don't see this module in our breakpoint location list, call ResolveInModules. 329 330 ModuleList new_modules; // We'll stuff the "unseen" modules in this list, and then resolve 331 // them after the locations pass. Have to do it this way because 332 // resolving breakpoints will add new locations potentially. 333 334 const size_t num_locs = m_locations.GetSize(); 335 336 for (size_t i = 0; i < module_list.GetSize(); i++) 337 { 338 bool seen = false; 339 ModuleSP module_sp (module_list.GetModuleAtIndex (i)); 340 if (!m_filter_sp->ModulePasses (module_sp)) 341 continue; 342 343 for (size_t loc_idx = 0; loc_idx < num_locs; loc_idx++) 344 { 345 BreakpointLocationSP break_loc = m_locations.GetByIndex(loc_idx); 346 if (!break_loc->IsEnabled()) 347 continue; 348 SectionSP section_sp (break_loc->GetAddress().GetSection()); 349 if (!section_sp || section_sp->GetModule() == module_sp) 350 { 351 if (!seen) 352 seen = true; 353 354 if (!break_loc->ResolveBreakpointSite()) 355 { 356 LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); 357 if (log) 358 log->Printf ("Warning: could not set breakpoint site for breakpoint location %d of breakpoint %d.\n", 359 break_loc->GetID(), GetID()); 360 } 361 } 362 } 363 364 if (!seen) 365 new_modules.AppendIfNeeded (module_sp); 366 367 } 368 369 if (new_modules.GetSize() > 0) 370 { 371 // If this is not an internal breakpoint, set up to record the new locations, then dispatch 372 // an event with the new locations. 373 if (!IsInternal()) 374 { 375 BreakpointEventData *new_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsAdded, 376 shared_from_this()); 377 378 m_locations.StartRecordingNewLocations(new_locations_event->GetBreakpointLocationCollection()); 379 380 ResolveBreakpointInModules(new_modules); 381 382 m_locations.StopRecordingNewLocations(); 383 if (new_locations_event->GetBreakpointLocationCollection().GetSize() != 0) 384 { 385 SendBreakpointChangedEvent (new_locations_event); 386 } 387 else 388 delete new_locations_event; 389 } 390 else 391 ResolveBreakpointInModules(new_modules); 392 393 } 394 } 395 else 396 { 397 // Go through the currently set locations and if any have breakpoints in 398 // the module list, then remove their breakpoint sites, and their locations if asked to. 399 400 BreakpointEventData *removed_locations_event; 401 if (!IsInternal()) 402 removed_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsRemoved, 403 shared_from_this()); 404 else 405 removed_locations_event = NULL; 406 407 for (size_t i = 0; i < module_list.GetSize(); i++) 408 { 409 ModuleSP module_sp (module_list.GetModuleAtIndex (i)); 410 if (m_filter_sp->ModulePasses (module_sp)) 411 { 412 size_t loc_idx = 0; 413 size_t num_locations = m_locations.GetSize(); 414 BreakpointLocationCollection locations_to_remove; 415 for (loc_idx = 0; loc_idx < num_locations; loc_idx++) 416 { 417 BreakpointLocationSP break_loc_sp (m_locations.GetByIndex(loc_idx)); 418 SectionSP section_sp (break_loc_sp->GetAddress().GetSection()); 419 if (section_sp && section_sp->GetModule() == module_sp) 420 { 421 // Remove this breakpoint since the shared library is 422 // unloaded, but keep the breakpoint location around 423 // so we always get complete hit count and breakpoint 424 // lifetime info 425 break_loc_sp->ClearBreakpointSite(); 426 if (removed_locations_event) 427 { 428 removed_locations_event->GetBreakpointLocationCollection().Add(break_loc_sp); 429 } 430 if (delete_locations) 431 locations_to_remove.Add (break_loc_sp); 432 433 } 434 } 435 436 if (delete_locations) 437 { 438 size_t num_locations_to_remove = locations_to_remove.GetSize(); 439 for (loc_idx = 0; loc_idx < num_locations_to_remove; loc_idx++) 440 m_locations.RemoveLocation (locations_to_remove.GetByIndex(loc_idx)); 441 } 442 } 443 } 444 SendBreakpointChangedEvent (removed_locations_event); 445 } 446 } 447 448 void 449 Breakpoint::ModuleReplaced (ModuleSP old_module_sp, ModuleSP new_module_sp) 450 { 451 ModuleList temp_list; 452 temp_list.Append (new_module_sp); 453 ModulesChanged (temp_list, true); 454 455 // TO DO: For now I'm just adding locations for the new module and removing the 456 // breakpoint locations that were in the old module. 457 // We should really go find the ones that are in the new module & if we can determine that they are "equivalent" 458 // carry over the options from the old location to the new. 459 460 temp_list.Clear(); 461 temp_list.Append (old_module_sp); 462 ModulesChanged (temp_list, false, true); 463 } 464 465 void 466 Breakpoint::Dump (Stream *) 467 { 468 } 469 470 size_t 471 Breakpoint::GetNumResolvedLocations() const 472 { 473 // Return the number of breakpoints that are actually resolved and set 474 // down in the inferior process. 475 return m_locations.GetNumResolvedLocations(); 476 } 477 478 size_t 479 Breakpoint::GetNumLocations() const 480 { 481 return m_locations.GetSize(); 482 } 483 484 void 485 Breakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_locations) 486 { 487 assert (s != NULL); 488 s->Printf("%i: ", GetID()); 489 GetResolverDescription (s); 490 GetFilterDescription (s); 491 492 const size_t num_locations = GetNumLocations (); 493 const size_t num_resolved_locations = GetNumResolvedLocations (); 494 495 switch (level) 496 { 497 case lldb::eDescriptionLevelBrief: 498 case lldb::eDescriptionLevelFull: 499 if (num_locations > 0) 500 { 501 s->Printf(", locations = %zu", num_locations); 502 if (num_resolved_locations > 0) 503 s->Printf(", resolved = %zu", num_resolved_locations); 504 } 505 else 506 { 507 // Don't print the pending notification for exception resolvers since we don't generally 508 // know how to set them until the target is run. 509 if (m_resolver_sp->getResolverID() != BreakpointResolver::ExceptionResolver) 510 s->Printf(", locations = 0 (pending)"); 511 } 512 513 GetOptions()->GetDescription(s, level); 514 515 if (level == lldb::eDescriptionLevelFull) 516 { 517 s->IndentLess(); 518 s->EOL(); 519 } 520 break; 521 522 case lldb::eDescriptionLevelVerbose: 523 // Verbose mode does a debug dump of the breakpoint 524 Dump (s); 525 s->EOL (); 526 //s->Indent(); 527 GetOptions()->GetDescription(s, level); 528 break; 529 530 default: 531 break; 532 } 533 534 // The brief description is just the location name (1.2 or whatever). That's pointless to 535 // show in the breakpoint's description, so suppress it. 536 if (show_locations && level != lldb::eDescriptionLevelBrief) 537 { 538 s->IndentMore(); 539 for (size_t i = 0; i < num_locations; ++i) 540 { 541 BreakpointLocation *loc = GetLocationAtIndex(i).get(); 542 loc->GetDescription(s, level); 543 s->EOL(); 544 } 545 s->IndentLess(); 546 } 547 } 548 549 void 550 Breakpoint::GetResolverDescription (Stream *s) 551 { 552 if (m_resolver_sp) 553 m_resolver_sp->GetDescription (s); 554 } 555 556 557 bool 558 Breakpoint::GetMatchingFileLine (const ConstString &filename, uint32_t line_number, BreakpointLocationCollection &loc_coll) 559 { 560 // TODO: To be correct, this method needs to fill the breakpoint location collection 561 // with the location IDs which match the filename and line_number. 562 // 563 564 if (m_resolver_sp) 565 { 566 BreakpointResolverFileLine *resolverFileLine = dyn_cast<BreakpointResolverFileLine>(m_resolver_sp.get()); 567 if (resolverFileLine && 568 resolverFileLine->m_file_spec.GetFilename() == filename && 569 resolverFileLine->m_line_number == line_number) 570 { 571 return true; 572 } 573 } 574 return false; 575 } 576 577 void 578 Breakpoint::GetFilterDescription (Stream *s) 579 { 580 m_filter_sp->GetDescription (s); 581 } 582 583 void 584 Breakpoint::SendBreakpointChangedEvent (lldb::BreakpointEventType eventKind) 585 { 586 if (!m_being_created 587 && !IsInternal() 588 && GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged)) 589 { 590 BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind, shared_from_this()); 591 592 GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data); 593 } 594 } 595 596 void 597 Breakpoint::SendBreakpointChangedEvent (BreakpointEventData *data) 598 { 599 600 if (data == NULL) 601 return; 602 603 if (!m_being_created 604 && !IsInternal() 605 && GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged)) 606 GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data); 607 else 608 delete data; 609 } 610 611 Breakpoint::BreakpointEventData::BreakpointEventData (BreakpointEventType sub_type, 612 const BreakpointSP &new_breakpoint_sp) : 613 EventData (), 614 m_breakpoint_event (sub_type), 615 m_new_breakpoint_sp (new_breakpoint_sp) 616 { 617 } 618 619 Breakpoint::BreakpointEventData::~BreakpointEventData () 620 { 621 } 622 623 const ConstString & 624 Breakpoint::BreakpointEventData::GetFlavorString () 625 { 626 static ConstString g_flavor ("Breakpoint::BreakpointEventData"); 627 return g_flavor; 628 } 629 630 const ConstString & 631 Breakpoint::BreakpointEventData::GetFlavor () const 632 { 633 return BreakpointEventData::GetFlavorString (); 634 } 635 636 637 BreakpointSP & 638 Breakpoint::BreakpointEventData::GetBreakpoint () 639 { 640 return m_new_breakpoint_sp; 641 } 642 643 BreakpointEventType 644 Breakpoint::BreakpointEventData::GetBreakpointEventType () const 645 { 646 return m_breakpoint_event; 647 } 648 649 void 650 Breakpoint::BreakpointEventData::Dump (Stream *s) const 651 { 652 } 653 654 const Breakpoint::BreakpointEventData * 655 Breakpoint::BreakpointEventData::GetEventDataFromEvent (const Event *event) 656 { 657 if (event) 658 { 659 const EventData *event_data = event->GetData(); 660 if (event_data && event_data->GetFlavor() == BreakpointEventData::GetFlavorString()) 661 return static_cast <const BreakpointEventData *> (event->GetData()); 662 } 663 return NULL; 664 } 665 666 BreakpointEventType 667 Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (const EventSP &event_sp) 668 { 669 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get()); 670 671 if (data == NULL) 672 return eBreakpointEventTypeInvalidType; 673 else 674 return data->GetBreakpointEventType(); 675 } 676 677 BreakpointSP 678 Breakpoint::BreakpointEventData::GetBreakpointFromEvent (const EventSP &event_sp) 679 { 680 BreakpointSP bp_sp; 681 682 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get()); 683 if (data) 684 bp_sp = data->m_new_breakpoint_sp; 685 686 return bp_sp; 687 } 688 689 uint32_t 690 Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent (const EventSP &event_sp) 691 { 692 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get()); 693 if (data) 694 return data->m_locations.GetSize(); 695 696 return 0; 697 } 698 699 lldb::BreakpointLocationSP 700 Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (const lldb::EventSP &event_sp, uint32_t bp_loc_idx) 701 { 702 lldb::BreakpointLocationSP bp_loc_sp; 703 704 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get()); 705 if (data) 706 { 707 bp_loc_sp = data->m_locations.GetByIndex(bp_loc_idx); 708 } 709 710 return bp_loc_sp; 711 } 712