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