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