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