1254721Semaste//===-- Breakpoint.cpp ------------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste 11254721Semaste// C Includes 12254721Semaste// C++ Includes 13254721Semaste// Other libraries and framework includes 14254721Semaste// Project includes 15254721Semaste 16254721Semaste#include "lldb/Core/Address.h" 17254721Semaste#include "lldb/Breakpoint/Breakpoint.h" 18254721Semaste#include "lldb/Breakpoint/BreakpointLocation.h" 19254721Semaste#include "lldb/Breakpoint/BreakpointLocationCollection.h" 20254721Semaste#include "lldb/Breakpoint/BreakpointResolver.h" 21254721Semaste#include "lldb/Breakpoint/BreakpointResolverFileLine.h" 22254721Semaste#include "lldb/Core/Log.h" 23254721Semaste#include "lldb/Core/ModuleList.h" 24254721Semaste#include "lldb/Core/SearchFilter.h" 25254721Semaste#include "lldb/Core/Section.h" 26254721Semaste#include "lldb/Core/Stream.h" 27254721Semaste#include "lldb/Core/StreamString.h" 28254721Semaste#include "lldb/Symbol/SymbolContext.h" 29254721Semaste#include "lldb/Target/Target.h" 30254721Semaste#include "lldb/Target/ThreadSpec.h" 31254721Semaste#include "lldb/lldb-private-log.h" 32254721Semaste#include "llvm/Support/Casting.h" 33254721Semaste 34254721Semasteusing namespace lldb; 35254721Semasteusing namespace lldb_private; 36254721Semasteusing namespace llvm; 37254721Semaste 38254721Semasteconst ConstString & 39254721SemasteBreakpoint::GetEventIdentifier () 40254721Semaste{ 41254721Semaste static ConstString g_identifier("event-identifier.breakpoint.changed"); 42254721Semaste return g_identifier; 43254721Semaste} 44254721Semaste 45254721Semaste//---------------------------------------------------------------------- 46254721Semaste// Breakpoint constructor 47254721Semaste//---------------------------------------------------------------------- 48269024SemasteBreakpoint::Breakpoint(Target &target, 49269024Semaste SearchFilterSP &filter_sp, 50269024Semaste BreakpointResolverSP &resolver_sp, 51269024Semaste bool hardware, 52269024Semaste bool resolve_indirect_symbols) : 53254721Semaste m_being_created(true), 54263363Semaste m_hardware(hardware), 55254721Semaste m_target (target), 56254721Semaste m_filter_sp (filter_sp), 57254721Semaste m_resolver_sp (resolver_sp), 58254721Semaste m_options (), 59269024Semaste m_locations (*this), 60269024Semaste m_resolve_indirect_symbols(resolve_indirect_symbols) 61254721Semaste{ 62254721Semaste m_being_created = false; 63254721Semaste} 64254721Semaste 65254721Semaste//---------------------------------------------------------------------- 66254721Semaste// Destructor 67254721Semaste//---------------------------------------------------------------------- 68254721SemasteBreakpoint::~Breakpoint() 69254721Semaste{ 70254721Semaste} 71254721Semaste 72254721Semastebool 73254721SemasteBreakpoint::IsInternal () const 74254721Semaste{ 75254721Semaste return LLDB_BREAK_ID_IS_INTERNAL(m_bid); 76254721Semaste} 77254721Semaste 78254721Semaste 79254721Semaste 80254721SemasteTarget& 81254721SemasteBreakpoint::GetTarget () 82254721Semaste{ 83254721Semaste return m_target; 84254721Semaste} 85254721Semaste 86254721Semasteconst Target& 87254721SemasteBreakpoint::GetTarget () const 88254721Semaste{ 89254721Semaste return m_target; 90254721Semaste} 91254721Semaste 92254721SemasteBreakpointLocationSP 93254721SemasteBreakpoint::AddLocation (const Address &addr, bool *new_location) 94254721Semaste{ 95269024Semaste return m_locations.AddLocation (addr, m_resolve_indirect_symbols, new_location); 96254721Semaste} 97254721Semaste 98254721SemasteBreakpointLocationSP 99254721SemasteBreakpoint::FindLocationByAddress (const Address &addr) 100254721Semaste{ 101254721Semaste return m_locations.FindByAddress(addr); 102254721Semaste} 103254721Semaste 104254721Semastebreak_id_t 105254721SemasteBreakpoint::FindLocationIDByAddress (const Address &addr) 106254721Semaste{ 107254721Semaste return m_locations.FindIDByAddress(addr); 108254721Semaste} 109254721Semaste 110254721SemasteBreakpointLocationSP 111254721SemasteBreakpoint::FindLocationByID (break_id_t bp_loc_id) 112254721Semaste{ 113254721Semaste return m_locations.FindByID(bp_loc_id); 114254721Semaste} 115254721Semaste 116254721SemasteBreakpointLocationSP 117254721SemasteBreakpoint::GetLocationAtIndex (size_t index) 118254721Semaste{ 119254721Semaste return m_locations.GetByIndex(index); 120254721Semaste} 121254721Semaste 122263367Semastevoid 123263367SemasteBreakpoint::RemoveInvalidLocations (const ArchSpec &arch) 124263367Semaste{ 125263367Semaste m_locations.RemoveInvalidLocations(arch); 126263367Semaste} 127263367Semaste 128254721Semaste// For each of the overall options we need to decide how they propagate to 129254721Semaste// the location options. This will determine the precedence of options on 130254721Semaste// the breakpoint vs. its locations. 131254721Semaste 132254721Semaste// Disable at the breakpoint level should override the location settings. 133254721Semaste// That way you can conveniently turn off a whole breakpoint without messing 134254721Semaste// up the individual settings. 135254721Semaste 136254721Semastevoid 137254721SemasteBreakpoint::SetEnabled (bool enable) 138254721Semaste{ 139254721Semaste if (enable == m_options.IsEnabled()) 140254721Semaste return; 141254721Semaste 142254721Semaste m_options.SetEnabled(enable); 143254721Semaste if (enable) 144254721Semaste m_locations.ResolveAllBreakpointSites(); 145254721Semaste else 146254721Semaste m_locations.ClearAllBreakpointSites(); 147254721Semaste 148254721Semaste SendBreakpointChangedEvent (enable ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled); 149254721Semaste 150254721Semaste} 151254721Semaste 152254721Semastebool 153254721SemasteBreakpoint::IsEnabled () 154254721Semaste{ 155254721Semaste return m_options.IsEnabled(); 156254721Semaste} 157254721Semaste 158254721Semastevoid 159254721SemasteBreakpoint::SetIgnoreCount (uint32_t n) 160254721Semaste{ 161254721Semaste if (m_options.GetIgnoreCount() == n) 162254721Semaste return; 163254721Semaste 164254721Semaste m_options.SetIgnoreCount(n); 165254721Semaste SendBreakpointChangedEvent (eBreakpointEventTypeIgnoreChanged); 166254721Semaste} 167254721Semaste 168254721Semastevoid 169254721SemasteBreakpoint::DecrementIgnoreCount () 170254721Semaste{ 171254721Semaste uint32_t ignore = m_options.GetIgnoreCount(); 172254721Semaste if (ignore != 0) 173254721Semaste m_options.SetIgnoreCount(ignore - 1); 174254721Semaste} 175254721Semaste 176254721Semasteuint32_t 177254721SemasteBreakpoint::GetIgnoreCount () const 178254721Semaste{ 179254721Semaste return m_options.GetIgnoreCount(); 180254721Semaste} 181254721Semaste 182254721Semastebool 183254721SemasteBreakpoint::IgnoreCountShouldStop () 184254721Semaste{ 185254721Semaste uint32_t ignore = GetIgnoreCount(); 186254721Semaste if (ignore != 0) 187254721Semaste { 188254721Semaste // When we get here we know the location that caused the stop doesn't have an ignore count, 189254721Semaste // since by contract we call it first... So we don't have to find & decrement it, we only have 190254721Semaste // to decrement our own ignore count. 191254721Semaste DecrementIgnoreCount(); 192254721Semaste return false; 193254721Semaste } 194254721Semaste else 195254721Semaste return true; 196254721Semaste} 197254721Semaste 198254721Semasteuint32_t 199254721SemasteBreakpoint::GetHitCount () const 200254721Semaste{ 201254721Semaste return m_locations.GetHitCount(); 202254721Semaste} 203254721Semaste 204254721Semastebool 205254721SemasteBreakpoint::IsOneShot () const 206254721Semaste{ 207254721Semaste return m_options.IsOneShot(); 208254721Semaste} 209254721Semaste 210254721Semastevoid 211254721SemasteBreakpoint::SetOneShot (bool one_shot) 212254721Semaste{ 213254721Semaste m_options.SetOneShot (one_shot); 214254721Semaste} 215254721Semaste 216254721Semastevoid 217254721SemasteBreakpoint::SetThreadID (lldb::tid_t thread_id) 218254721Semaste{ 219254721Semaste if (m_options.GetThreadSpec()->GetTID() == thread_id) 220254721Semaste return; 221254721Semaste 222254721Semaste m_options.GetThreadSpec()->SetTID(thread_id); 223254721Semaste SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged); 224254721Semaste} 225254721Semaste 226254721Semastelldb::tid_t 227254721SemasteBreakpoint::GetThreadID () const 228254721Semaste{ 229254721Semaste if (m_options.GetThreadSpecNoCreate() == NULL) 230254721Semaste return LLDB_INVALID_THREAD_ID; 231254721Semaste else 232254721Semaste return m_options.GetThreadSpecNoCreate()->GetTID(); 233254721Semaste} 234254721Semaste 235254721Semastevoid 236254721SemasteBreakpoint::SetThreadIndex (uint32_t index) 237254721Semaste{ 238254721Semaste if (m_options.GetThreadSpec()->GetIndex() == index) 239254721Semaste return; 240254721Semaste 241254721Semaste m_options.GetThreadSpec()->SetIndex(index); 242254721Semaste SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged); 243254721Semaste} 244254721Semaste 245254721Semasteuint32_t 246254721SemasteBreakpoint::GetThreadIndex() const 247254721Semaste{ 248254721Semaste if (m_options.GetThreadSpecNoCreate() == NULL) 249254721Semaste return 0; 250254721Semaste else 251254721Semaste return m_options.GetThreadSpecNoCreate()->GetIndex(); 252254721Semaste} 253254721Semaste 254254721Semastevoid 255254721SemasteBreakpoint::SetThreadName (const char *thread_name) 256254721Semaste{ 257254721Semaste if (m_options.GetThreadSpec()->GetName() != NULL 258254721Semaste && ::strcmp (m_options.GetThreadSpec()->GetName(), thread_name) == 0) 259254721Semaste return; 260254721Semaste 261254721Semaste m_options.GetThreadSpec()->SetName (thread_name); 262254721Semaste SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged); 263254721Semaste} 264254721Semaste 265254721Semasteconst char * 266254721SemasteBreakpoint::GetThreadName () const 267254721Semaste{ 268254721Semaste if (m_options.GetThreadSpecNoCreate() == NULL) 269254721Semaste return NULL; 270254721Semaste else 271254721Semaste return m_options.GetThreadSpecNoCreate()->GetName(); 272254721Semaste} 273254721Semaste 274254721Semastevoid 275254721SemasteBreakpoint::SetQueueName (const char *queue_name) 276254721Semaste{ 277254721Semaste if (m_options.GetThreadSpec()->GetQueueName() != NULL 278254721Semaste && ::strcmp (m_options.GetThreadSpec()->GetQueueName(), queue_name) == 0) 279254721Semaste return; 280254721Semaste 281254721Semaste m_options.GetThreadSpec()->SetQueueName (queue_name); 282254721Semaste SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged); 283254721Semaste} 284254721Semaste 285254721Semasteconst char * 286254721SemasteBreakpoint::GetQueueName () const 287254721Semaste{ 288254721Semaste if (m_options.GetThreadSpecNoCreate() == NULL) 289254721Semaste return NULL; 290254721Semaste else 291254721Semaste return m_options.GetThreadSpecNoCreate()->GetQueueName(); 292254721Semaste} 293254721Semaste 294254721Semastevoid 295254721SemasteBreakpoint::SetCondition (const char *condition) 296254721Semaste{ 297254721Semaste m_options.SetCondition (condition); 298254721Semaste SendBreakpointChangedEvent (eBreakpointEventTypeConditionChanged); 299254721Semaste} 300254721Semaste 301254721Semasteconst char * 302254721SemasteBreakpoint::GetConditionText () const 303254721Semaste{ 304254721Semaste return m_options.GetConditionText(); 305254721Semaste} 306254721Semaste 307254721Semaste// This function is used when "baton" doesn't need to be freed 308254721Semastevoid 309254721SemasteBreakpoint::SetCallback (BreakpointHitCallback callback, void *baton, bool is_synchronous) 310254721Semaste{ 311254721Semaste // The default "Baton" class will keep a copy of "baton" and won't free 312254721Semaste // or delete it when it goes goes out of scope. 313254721Semaste m_options.SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous); 314254721Semaste 315254721Semaste SendBreakpointChangedEvent (eBreakpointEventTypeCommandChanged); 316254721Semaste} 317254721Semaste 318254721Semaste// This function is used when a baton needs to be freed and therefore is 319254721Semaste// contained in a "Baton" subclass. 320254721Semastevoid 321254721SemasteBreakpoint::SetCallback (BreakpointHitCallback callback, const BatonSP &callback_baton_sp, bool is_synchronous) 322254721Semaste{ 323254721Semaste m_options.SetCallback(callback, callback_baton_sp, is_synchronous); 324254721Semaste} 325254721Semaste 326254721Semastevoid 327254721SemasteBreakpoint::ClearCallback () 328254721Semaste{ 329254721Semaste m_options.ClearCallback (); 330254721Semaste} 331254721Semaste 332254721Semastebool 333254721SemasteBreakpoint::InvokeCallback (StoppointCallbackContext *context, break_id_t bp_loc_id) 334254721Semaste{ 335254721Semaste return m_options.InvokeCallback (context, GetID(), bp_loc_id); 336254721Semaste} 337254721Semaste 338254721SemasteBreakpointOptions * 339254721SemasteBreakpoint::GetOptions () 340254721Semaste{ 341254721Semaste return &m_options; 342254721Semaste} 343254721Semaste 344254721Semastevoid 345254721SemasteBreakpoint::ResolveBreakpoint () 346254721Semaste{ 347254721Semaste if (m_resolver_sp) 348254721Semaste m_resolver_sp->ResolveBreakpoint(*m_filter_sp); 349254721Semaste} 350254721Semaste 351254721Semastevoid 352254721SemasteBreakpoint::ResolveBreakpointInModules (ModuleList &module_list) 353254721Semaste{ 354254721Semaste if (m_resolver_sp) 355254721Semaste m_resolver_sp->ResolveBreakpointInModules(*m_filter_sp, module_list); 356254721Semaste} 357254721Semaste 358254721Semastevoid 359254721SemasteBreakpoint::ClearAllBreakpointSites () 360254721Semaste{ 361254721Semaste m_locations.ClearAllBreakpointSites(); 362254721Semaste} 363254721Semaste 364254721Semaste//---------------------------------------------------------------------- 365254721Semaste// ModulesChanged: Pass in a list of new modules, and 366254721Semaste//---------------------------------------------------------------------- 367254721Semaste 368254721Semastevoid 369254721SemasteBreakpoint::ModulesChanged (ModuleList &module_list, bool load, bool delete_locations) 370254721Semaste{ 371254721Semaste Mutex::Locker modules_mutex(module_list.GetMutex()); 372254721Semaste if (load) 373254721Semaste { 374254721Semaste // The logic for handling new modules is: 375254721Semaste // 1) If the filter rejects this module, then skip it. 376254721Semaste // 2) Run through the current location list and if there are any locations 377254721Semaste // for that module, we mark the module as "seen" and we don't try to re-resolve 378254721Semaste // breakpoint locations for that module. 379254721Semaste // However, we do add breakpoint sites to these locations if needed. 380254721Semaste // 3) If we don't see this module in our breakpoint location list, call ResolveInModules. 381254721Semaste 382254721Semaste ModuleList new_modules; // We'll stuff the "unseen" modules in this list, and then resolve 383254721Semaste // them after the locations pass. Have to do it this way because 384254721Semaste // resolving breakpoints will add new locations potentially. 385254721Semaste 386254721Semaste const size_t num_locs = m_locations.GetSize(); 387254721Semaste size_t num_modules = module_list.GetSize(); 388254721Semaste for (size_t i = 0; i < num_modules; i++) 389254721Semaste { 390254721Semaste bool seen = false; 391254721Semaste ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (i)); 392254721Semaste if (!m_filter_sp->ModulePasses (module_sp)) 393254721Semaste continue; 394254721Semaste 395254721Semaste for (size_t loc_idx = 0; loc_idx < num_locs; loc_idx++) 396254721Semaste { 397254721Semaste BreakpointLocationSP break_loc = m_locations.GetByIndex(loc_idx); 398254721Semaste if (!break_loc->IsEnabled()) 399254721Semaste continue; 400254721Semaste SectionSP section_sp (break_loc->GetAddress().GetSection()); 401254721Semaste if (!section_sp || section_sp->GetModule() == module_sp) 402254721Semaste { 403254721Semaste if (!seen) 404254721Semaste seen = true; 405254721Semaste 406254721Semaste if (!break_loc->ResolveBreakpointSite()) 407254721Semaste { 408254721Semaste Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); 409254721Semaste if (log) 410254721Semaste log->Printf ("Warning: could not set breakpoint site for breakpoint location %d of breakpoint %d.\n", 411254721Semaste break_loc->GetID(), GetID()); 412254721Semaste } 413254721Semaste } 414254721Semaste } 415254721Semaste 416254721Semaste if (!seen) 417254721Semaste new_modules.AppendIfNeeded (module_sp); 418254721Semaste 419254721Semaste } 420254721Semaste 421254721Semaste if (new_modules.GetSize() > 0) 422254721Semaste { 423254721Semaste // If this is not an internal breakpoint, set up to record the new locations, then dispatch 424254721Semaste // an event with the new locations. 425254721Semaste if (!IsInternal()) 426254721Semaste { 427254721Semaste BreakpointEventData *new_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsAdded, 428254721Semaste shared_from_this()); 429254721Semaste 430254721Semaste m_locations.StartRecordingNewLocations(new_locations_event->GetBreakpointLocationCollection()); 431254721Semaste 432254721Semaste ResolveBreakpointInModules(new_modules); 433254721Semaste 434254721Semaste m_locations.StopRecordingNewLocations(); 435254721Semaste if (new_locations_event->GetBreakpointLocationCollection().GetSize() != 0) 436254721Semaste { 437254721Semaste SendBreakpointChangedEvent (new_locations_event); 438254721Semaste } 439254721Semaste else 440254721Semaste delete new_locations_event; 441254721Semaste } 442254721Semaste else 443254721Semaste ResolveBreakpointInModules(new_modules); 444254721Semaste 445254721Semaste } 446254721Semaste } 447254721Semaste else 448254721Semaste { 449254721Semaste // Go through the currently set locations and if any have breakpoints in 450254721Semaste // the module list, then remove their breakpoint sites, and their locations if asked to. 451254721Semaste 452254721Semaste BreakpointEventData *removed_locations_event; 453254721Semaste if (!IsInternal()) 454254721Semaste removed_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsRemoved, 455254721Semaste shared_from_this()); 456254721Semaste else 457254721Semaste removed_locations_event = NULL; 458254721Semaste 459254721Semaste size_t num_modules = module_list.GetSize(); 460254721Semaste for (size_t i = 0; i < num_modules; i++) 461254721Semaste { 462254721Semaste ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (i)); 463254721Semaste if (m_filter_sp->ModulePasses (module_sp)) 464254721Semaste { 465254721Semaste size_t loc_idx = 0; 466254721Semaste size_t num_locations = m_locations.GetSize(); 467254721Semaste BreakpointLocationCollection locations_to_remove; 468254721Semaste for (loc_idx = 0; loc_idx < num_locations; loc_idx++) 469254721Semaste { 470254721Semaste BreakpointLocationSP break_loc_sp (m_locations.GetByIndex(loc_idx)); 471254721Semaste SectionSP section_sp (break_loc_sp->GetAddress().GetSection()); 472254721Semaste if (section_sp && section_sp->GetModule() == module_sp) 473254721Semaste { 474254721Semaste // Remove this breakpoint since the shared library is 475254721Semaste // unloaded, but keep the breakpoint location around 476254721Semaste // so we always get complete hit count and breakpoint 477254721Semaste // lifetime info 478254721Semaste break_loc_sp->ClearBreakpointSite(); 479254721Semaste if (removed_locations_event) 480254721Semaste { 481254721Semaste removed_locations_event->GetBreakpointLocationCollection().Add(break_loc_sp); 482254721Semaste } 483254721Semaste if (delete_locations) 484254721Semaste locations_to_remove.Add (break_loc_sp); 485254721Semaste 486254721Semaste } 487254721Semaste } 488254721Semaste 489254721Semaste if (delete_locations) 490254721Semaste { 491254721Semaste size_t num_locations_to_remove = locations_to_remove.GetSize(); 492254721Semaste for (loc_idx = 0; loc_idx < num_locations_to_remove; loc_idx++) 493254721Semaste m_locations.RemoveLocation (locations_to_remove.GetByIndex(loc_idx)); 494254721Semaste } 495254721Semaste } 496254721Semaste } 497254721Semaste SendBreakpointChangedEvent (removed_locations_event); 498254721Semaste } 499254721Semaste} 500254721Semaste 501254721Semastevoid 502254721SemasteBreakpoint::ModuleReplaced (ModuleSP old_module_sp, ModuleSP new_module_sp) 503254721Semaste{ 504254721Semaste ModuleList temp_list; 505254721Semaste temp_list.Append (new_module_sp); 506254721Semaste ModulesChanged (temp_list, true); 507254721Semaste 508254721Semaste // TO DO: For now I'm just adding locations for the new module and removing the 509254721Semaste // breakpoint locations that were in the old module. 510254721Semaste // We should really go find the ones that are in the new module & if we can determine that they are "equivalent" 511254721Semaste // carry over the options from the old location to the new. 512254721Semaste 513254721Semaste temp_list.Clear(); 514254721Semaste temp_list.Append (old_module_sp); 515254721Semaste ModulesChanged (temp_list, false, true); 516254721Semaste} 517254721Semaste 518254721Semastevoid 519254721SemasteBreakpoint::Dump (Stream *) 520254721Semaste{ 521254721Semaste} 522254721Semaste 523254721Semastesize_t 524254721SemasteBreakpoint::GetNumResolvedLocations() const 525254721Semaste{ 526254721Semaste // Return the number of breakpoints that are actually resolved and set 527254721Semaste // down in the inferior process. 528254721Semaste return m_locations.GetNumResolvedLocations(); 529254721Semaste} 530254721Semaste 531254721Semastesize_t 532254721SemasteBreakpoint::GetNumLocations() const 533254721Semaste{ 534254721Semaste return m_locations.GetSize(); 535254721Semaste} 536254721Semaste 537254721Semastevoid 538254721SemasteBreakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_locations) 539254721Semaste{ 540254721Semaste assert (s != NULL); 541254721Semaste 542254721Semaste if (!m_kind_description.empty()) 543254721Semaste { 544254721Semaste if (eDescriptionLevelBrief) 545254721Semaste { 546254721Semaste s->PutCString (GetBreakpointKind()); 547254721Semaste return; 548254721Semaste } 549254721Semaste else 550254721Semaste s->Printf("Kind: %s\n", GetBreakpointKind ()); 551254721Semaste } 552254721Semaste 553254721Semaste const size_t num_locations = GetNumLocations (); 554254721Semaste const size_t num_resolved_locations = GetNumResolvedLocations (); 555254721Semaste 556254721Semaste // They just made the breakpoint, they don't need to be told HOW they made it... 557254721Semaste // Also, we'll print the breakpoint number differently depending on whether there is 1 or more locations. 558254721Semaste if (level != eDescriptionLevelInitial) 559254721Semaste { 560254721Semaste s->Printf("%i: ", GetID()); 561254721Semaste GetResolverDescription (s); 562254721Semaste GetFilterDescription (s); 563254721Semaste } 564254721Semaste 565254721Semaste switch (level) 566254721Semaste { 567254721Semaste case lldb::eDescriptionLevelBrief: 568254721Semaste case lldb::eDescriptionLevelFull: 569254721Semaste if (num_locations > 0) 570254721Semaste { 571254721Semaste s->Printf(", locations = %" PRIu64, (uint64_t)num_locations); 572254721Semaste if (num_resolved_locations > 0) 573263363Semaste s->Printf(", resolved = %" PRIu64 ", hit count = %d", (uint64_t)num_resolved_locations, GetHitCount()); 574254721Semaste } 575254721Semaste else 576254721Semaste { 577254721Semaste // Don't print the pending notification for exception resolvers since we don't generally 578254721Semaste // know how to set them until the target is run. 579254721Semaste if (m_resolver_sp->getResolverID() != BreakpointResolver::ExceptionResolver) 580254721Semaste s->Printf(", locations = 0 (pending)"); 581254721Semaste } 582254721Semaste 583254721Semaste GetOptions()->GetDescription(s, level); 584254721Semaste 585254721Semaste if (level == lldb::eDescriptionLevelFull) 586254721Semaste { 587254721Semaste s->IndentLess(); 588254721Semaste s->EOL(); 589254721Semaste } 590254721Semaste break; 591254721Semaste 592254721Semaste case lldb::eDescriptionLevelInitial: 593254721Semaste s->Printf ("Breakpoint %i: ", GetID()); 594254721Semaste if (num_locations == 0) 595254721Semaste { 596254721Semaste s->Printf ("no locations (pending)."); 597254721Semaste } 598254721Semaste else if (num_locations == 1) 599254721Semaste { 600254721Semaste // If there is one location only, we'll just print that location information. But don't do this if 601254721Semaste // show locations is true, then that will be handled below. 602254721Semaste if (show_locations == false) 603254721Semaste { 604254721Semaste GetLocationAtIndex(0)->GetDescription(s, level); 605254721Semaste } 606254721Semaste else 607254721Semaste { 608254721Semaste s->Printf ("%zd locations.", num_locations); 609254721Semaste } 610254721Semaste } 611254721Semaste else 612254721Semaste { 613254721Semaste s->Printf ("%zd locations.", num_locations); 614254721Semaste } 615254721Semaste s->EOL(); 616254721Semaste break; 617254721Semaste case lldb::eDescriptionLevelVerbose: 618254721Semaste // Verbose mode does a debug dump of the breakpoint 619254721Semaste Dump (s); 620254721Semaste s->EOL (); 621254721Semaste //s->Indent(); 622254721Semaste GetOptions()->GetDescription(s, level); 623254721Semaste break; 624254721Semaste 625254721Semaste default: 626254721Semaste break; 627254721Semaste } 628254721Semaste 629254721Semaste // The brief description is just the location name (1.2 or whatever). That's pointless to 630254721Semaste // show in the breakpoint's description, so suppress it. 631254721Semaste if (show_locations && level != lldb::eDescriptionLevelBrief) 632254721Semaste { 633254721Semaste s->IndentMore(); 634254721Semaste for (size_t i = 0; i < num_locations; ++i) 635254721Semaste { 636254721Semaste BreakpointLocation *loc = GetLocationAtIndex(i).get(); 637254721Semaste loc->GetDescription(s, level); 638254721Semaste s->EOL(); 639254721Semaste } 640254721Semaste s->IndentLess(); 641254721Semaste } 642254721Semaste} 643254721Semaste 644254721Semastevoid 645254721SemasteBreakpoint::GetResolverDescription (Stream *s) 646254721Semaste{ 647254721Semaste if (m_resolver_sp) 648254721Semaste m_resolver_sp->GetDescription (s); 649254721Semaste} 650254721Semaste 651254721Semaste 652254721Semastebool 653254721SemasteBreakpoint::GetMatchingFileLine (const ConstString &filename, uint32_t line_number, BreakpointLocationCollection &loc_coll) 654254721Semaste{ 655254721Semaste // TODO: To be correct, this method needs to fill the breakpoint location collection 656254721Semaste // with the location IDs which match the filename and line_number. 657254721Semaste // 658254721Semaste 659254721Semaste if (m_resolver_sp) 660254721Semaste { 661254721Semaste BreakpointResolverFileLine *resolverFileLine = dyn_cast<BreakpointResolverFileLine>(m_resolver_sp.get()); 662254721Semaste if (resolverFileLine && 663254721Semaste resolverFileLine->m_file_spec.GetFilename() == filename && 664254721Semaste resolverFileLine->m_line_number == line_number) 665254721Semaste { 666254721Semaste return true; 667254721Semaste } 668254721Semaste } 669254721Semaste return false; 670254721Semaste} 671254721Semaste 672254721Semastevoid 673254721SemasteBreakpoint::GetFilterDescription (Stream *s) 674254721Semaste{ 675254721Semaste m_filter_sp->GetDescription (s); 676254721Semaste} 677254721Semaste 678254721Semastevoid 679254721SemasteBreakpoint::SendBreakpointChangedEvent (lldb::BreakpointEventType eventKind) 680254721Semaste{ 681254721Semaste if (!m_being_created 682254721Semaste && !IsInternal() 683254721Semaste && GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged)) 684254721Semaste { 685254721Semaste BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind, shared_from_this()); 686254721Semaste 687254721Semaste GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data); 688254721Semaste } 689254721Semaste} 690254721Semaste 691254721Semastevoid 692254721SemasteBreakpoint::SendBreakpointChangedEvent (BreakpointEventData *data) 693254721Semaste{ 694254721Semaste 695254721Semaste if (data == NULL) 696254721Semaste return; 697254721Semaste 698254721Semaste if (!m_being_created 699254721Semaste && !IsInternal() 700254721Semaste && GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged)) 701254721Semaste GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data); 702254721Semaste else 703254721Semaste delete data; 704254721Semaste} 705254721Semaste 706254721SemasteBreakpoint::BreakpointEventData::BreakpointEventData (BreakpointEventType sub_type, 707254721Semaste const BreakpointSP &new_breakpoint_sp) : 708254721Semaste EventData (), 709254721Semaste m_breakpoint_event (sub_type), 710254721Semaste m_new_breakpoint_sp (new_breakpoint_sp) 711254721Semaste{ 712254721Semaste} 713254721Semaste 714254721SemasteBreakpoint::BreakpointEventData::~BreakpointEventData () 715254721Semaste{ 716254721Semaste} 717254721Semaste 718254721Semasteconst ConstString & 719254721SemasteBreakpoint::BreakpointEventData::GetFlavorString () 720254721Semaste{ 721254721Semaste static ConstString g_flavor ("Breakpoint::BreakpointEventData"); 722254721Semaste return g_flavor; 723254721Semaste} 724254721Semaste 725254721Semasteconst ConstString & 726254721SemasteBreakpoint::BreakpointEventData::GetFlavor () const 727254721Semaste{ 728254721Semaste return BreakpointEventData::GetFlavorString (); 729254721Semaste} 730254721Semaste 731254721Semaste 732254721SemasteBreakpointSP & 733254721SemasteBreakpoint::BreakpointEventData::GetBreakpoint () 734254721Semaste{ 735254721Semaste return m_new_breakpoint_sp; 736254721Semaste} 737254721Semaste 738254721SemasteBreakpointEventType 739254721SemasteBreakpoint::BreakpointEventData::GetBreakpointEventType () const 740254721Semaste{ 741254721Semaste return m_breakpoint_event; 742254721Semaste} 743254721Semaste 744254721Semastevoid 745254721SemasteBreakpoint::BreakpointEventData::Dump (Stream *s) const 746254721Semaste{ 747254721Semaste} 748254721Semaste 749254721Semasteconst Breakpoint::BreakpointEventData * 750254721SemasteBreakpoint::BreakpointEventData::GetEventDataFromEvent (const Event *event) 751254721Semaste{ 752254721Semaste if (event) 753254721Semaste { 754254721Semaste const EventData *event_data = event->GetData(); 755254721Semaste if (event_data && event_data->GetFlavor() == BreakpointEventData::GetFlavorString()) 756254721Semaste return static_cast <const BreakpointEventData *> (event->GetData()); 757254721Semaste } 758254721Semaste return NULL; 759254721Semaste} 760254721Semaste 761254721SemasteBreakpointEventType 762254721SemasteBreakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (const EventSP &event_sp) 763254721Semaste{ 764254721Semaste const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get()); 765254721Semaste 766254721Semaste if (data == NULL) 767254721Semaste return eBreakpointEventTypeInvalidType; 768254721Semaste else 769254721Semaste return data->GetBreakpointEventType(); 770254721Semaste} 771254721Semaste 772254721SemasteBreakpointSP 773254721SemasteBreakpoint::BreakpointEventData::GetBreakpointFromEvent (const EventSP &event_sp) 774254721Semaste{ 775254721Semaste BreakpointSP bp_sp; 776254721Semaste 777254721Semaste const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get()); 778254721Semaste if (data) 779254721Semaste bp_sp = data->m_new_breakpoint_sp; 780254721Semaste 781254721Semaste return bp_sp; 782254721Semaste} 783254721Semaste 784254721Semastesize_t 785254721SemasteBreakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent (const EventSP &event_sp) 786254721Semaste{ 787254721Semaste const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get()); 788254721Semaste if (data) 789254721Semaste return data->m_locations.GetSize(); 790254721Semaste 791254721Semaste return 0; 792254721Semaste} 793254721Semaste 794254721Semastelldb::BreakpointLocationSP 795254721SemasteBreakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (const lldb::EventSP &event_sp, uint32_t bp_loc_idx) 796254721Semaste{ 797254721Semaste lldb::BreakpointLocationSP bp_loc_sp; 798254721Semaste 799254721Semaste const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get()); 800254721Semaste if (data) 801254721Semaste { 802254721Semaste bp_loc_sp = data->m_locations.GetByIndex(bp_loc_idx); 803254721Semaste } 804254721Semaste 805254721Semaste return bp_loc_sp; 806254721Semaste} 807