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