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