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 const char *
251 Breakpoint::GetConditionText () const
252 {
253     return m_options.GetConditionText();
254 }
255 
256 // This function is used when "baton" doesn't need to be freed
257 void
258 Breakpoint::SetCallback (BreakpointHitCallback callback, void *baton, bool is_synchronous)
259 {
260     // The default "Baton" class will keep a copy of "baton" and won't free
261     // or delete it when it goes goes out of scope.
262     m_options.SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous);
263 
264     SendBreakpointChangedEvent (eBreakpointEventTypeCommandChanged);
265 }
266 
267 // This function is used when a baton needs to be freed and therefore is
268 // contained in a "Baton" subclass.
269 void
270 Breakpoint::SetCallback (BreakpointHitCallback callback, const BatonSP &callback_baton_sp, bool is_synchronous)
271 {
272     m_options.SetCallback(callback, callback_baton_sp, is_synchronous);
273 }
274 
275 void
276 Breakpoint::ClearCallback ()
277 {
278     m_options.ClearCallback ();
279 }
280 
281 bool
282 Breakpoint::InvokeCallback (StoppointCallbackContext *context, break_id_t bp_loc_id)
283 {
284     return m_options.InvokeCallback (context, GetID(), bp_loc_id);
285 }
286 
287 BreakpointOptions *
288 Breakpoint::GetOptions ()
289 {
290     return &m_options;
291 }
292 
293 void
294 Breakpoint::ResolveBreakpoint ()
295 {
296     if (m_resolver_sp)
297         m_resolver_sp->ResolveBreakpoint(*m_filter_sp);
298 }
299 
300 void
301 Breakpoint::ResolveBreakpointInModules (ModuleList &module_list)
302 {
303     if (m_resolver_sp)
304         m_resolver_sp->ResolveBreakpointInModules(*m_filter_sp, module_list);
305 }
306 
307 void
308 Breakpoint::ClearAllBreakpointSites ()
309 {
310     m_locations.ClearAllBreakpointSites();
311 }
312 
313 //----------------------------------------------------------------------
314 // ModulesChanged: Pass in a list of new modules, and
315 //----------------------------------------------------------------------
316 
317 void
318 Breakpoint::ModulesChanged (ModuleList &module_list, bool load, bool delete_locations)
319 {
320     if (load)
321     {
322         // The logic for handling new modules is:
323         // 1) If the filter rejects this module, then skip it.
324         // 2) Run through the current location list and if there are any locations
325         //    for that module, we mark the module as "seen" and we don't try to re-resolve
326         //    breakpoint locations for that module.
327         //    However, we do add breakpoint sites to these locations if needed.
328         // 3) If we don't see this module in our breakpoint location list, call ResolveInModules.
329 
330         ModuleList new_modules;  // We'll stuff the "unseen" modules in this list, and then resolve
331                                  // them after the locations pass.  Have to do it this way because
332                                  // resolving breakpoints will add new locations potentially.
333 
334         const size_t num_locs = m_locations.GetSize();
335 
336         for (size_t i = 0; i < module_list.GetSize(); i++)
337         {
338             bool seen = false;
339             ModuleSP module_sp (module_list.GetModuleAtIndex (i));
340             if (!m_filter_sp->ModulePasses (module_sp))
341                 continue;
342 
343             for (size_t loc_idx = 0; loc_idx < num_locs; loc_idx++)
344             {
345                 BreakpointLocationSP break_loc = m_locations.GetByIndex(loc_idx);
346                 if (!break_loc->IsEnabled())
347                     continue;
348                 SectionSP section_sp (break_loc->GetAddress().GetSection());
349                 if (!section_sp || section_sp->GetModule() == module_sp)
350                 {
351                     if (!seen)
352                         seen = true;
353 
354                     if (!break_loc->ResolveBreakpointSite())
355                     {
356                         LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
357                         if (log)
358                             log->Printf ("Warning: could not set breakpoint site for breakpoint location %d of breakpoint %d.\n",
359                                          break_loc->GetID(), GetID());
360                     }
361                 }
362             }
363 
364             if (!seen)
365                 new_modules.AppendIfNeeded (module_sp);
366 
367         }
368 
369         if (new_modules.GetSize() > 0)
370         {
371             // If this is not an internal breakpoint, set up to record the new locations, then dispatch
372             // an event with the new locations.
373             if (!IsInternal())
374             {
375                 BreakpointEventData *new_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsAdded,
376                                                                                     shared_from_this());
377 
378                 m_locations.StartRecordingNewLocations(new_locations_event->GetBreakpointLocationCollection());
379 
380                 ResolveBreakpointInModules(new_modules);
381 
382                 m_locations.StopRecordingNewLocations();
383                 if (new_locations_event->GetBreakpointLocationCollection().GetSize() != 0)
384                 {
385                     SendBreakpointChangedEvent (new_locations_event);
386                 }
387                 else
388                     delete new_locations_event;
389             }
390             else
391                 ResolveBreakpointInModules(new_modules);
392 
393         }
394     }
395     else
396     {
397         // Go through the currently set locations and if any have breakpoints in
398         // the module list, then remove their breakpoint sites, and their locations if asked to.
399 
400         BreakpointEventData *removed_locations_event;
401         if (!IsInternal())
402             removed_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsRemoved,
403                                                                shared_from_this());
404         else
405             removed_locations_event = NULL;
406 
407         for (size_t i = 0; i < module_list.GetSize(); i++)
408         {
409             ModuleSP module_sp (module_list.GetModuleAtIndex (i));
410             if (m_filter_sp->ModulePasses (module_sp))
411             {
412                 size_t loc_idx = 0;
413                 size_t num_locations = m_locations.GetSize();
414                 BreakpointLocationCollection locations_to_remove;
415                 for (loc_idx = 0; loc_idx < num_locations; loc_idx++)
416                 {
417                     BreakpointLocationSP break_loc_sp (m_locations.GetByIndex(loc_idx));
418                     SectionSP section_sp (break_loc_sp->GetAddress().GetSection());
419                     if (section_sp && section_sp->GetModule() == module_sp)
420                     {
421                         // Remove this breakpoint since the shared library is
422                         // unloaded, but keep the breakpoint location around
423                         // so we always get complete hit count and breakpoint
424                         // lifetime info
425                         break_loc_sp->ClearBreakpointSite();
426                         if (removed_locations_event)
427                         {
428                             removed_locations_event->GetBreakpointLocationCollection().Add(break_loc_sp);
429                         }
430                         if (delete_locations)
431                             locations_to_remove.Add (break_loc_sp);
432 
433                     }
434                 }
435 
436                 if (delete_locations)
437                 {
438                     size_t num_locations_to_remove = locations_to_remove.GetSize();
439                     for (loc_idx = 0; loc_idx < num_locations_to_remove; loc_idx++)
440                         m_locations.RemoveLocation  (locations_to_remove.GetByIndex(loc_idx));
441                 }
442             }
443         }
444         SendBreakpointChangedEvent (removed_locations_event);
445     }
446 }
447 
448 void
449 Breakpoint::ModuleReplaced (ModuleSP old_module_sp, ModuleSP new_module_sp)
450 {
451     ModuleList temp_list;
452     temp_list.Append (new_module_sp);
453     ModulesChanged (temp_list, true);
454 
455     // TO DO: For now I'm just adding locations for the new module and removing the
456     // breakpoint locations that were in the old module.
457     // We should really go find the ones that are in the new module & if we can determine that they are "equivalent"
458     // carry over the options from the old location to the new.
459 
460     temp_list.Clear();
461     temp_list.Append (old_module_sp);
462     ModulesChanged (temp_list, false, true);
463 }
464 
465 void
466 Breakpoint::Dump (Stream *)
467 {
468 }
469 
470 size_t
471 Breakpoint::GetNumResolvedLocations() const
472 {
473     // Return the number of breakpoints that are actually resolved and set
474     // down in the inferior process.
475     return m_locations.GetNumResolvedLocations();
476 }
477 
478 size_t
479 Breakpoint::GetNumLocations() const
480 {
481     return m_locations.GetSize();
482 }
483 
484 void
485 Breakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_locations)
486 {
487     assert (s != NULL);
488     s->Printf("%i: ", GetID());
489     GetResolverDescription (s);
490     GetFilterDescription (s);
491 
492     const size_t num_locations = GetNumLocations ();
493     const size_t num_resolved_locations = GetNumResolvedLocations ();
494 
495     switch (level)
496     {
497     case lldb::eDescriptionLevelBrief:
498     case lldb::eDescriptionLevelFull:
499         if (num_locations > 0)
500         {
501             s->Printf(", locations = %zu", num_locations);
502             if (num_resolved_locations > 0)
503                 s->Printf(", resolved = %zu", num_resolved_locations);
504         }
505         else
506         {
507             // Don't print the pending notification for exception resolvers since we don't generally
508             // know how to set them until the target is run.
509             if (m_resolver_sp->getResolverID() != BreakpointResolver::ExceptionResolver)
510                 s->Printf(", locations = 0 (pending)");
511         }
512 
513         GetOptions()->GetDescription(s, level);
514 
515         if (level == lldb::eDescriptionLevelFull)
516         {
517             s->IndentLess();
518             s->EOL();
519         }
520         break;
521 
522     case lldb::eDescriptionLevelVerbose:
523         // Verbose mode does a debug dump of the breakpoint
524         Dump (s);
525         s->EOL ();
526             //s->Indent();
527         GetOptions()->GetDescription(s, level);
528         break;
529 
530     default:
531         break;
532     }
533 
534     // The brief description is just the location name (1.2 or whatever).  That's pointless to
535     // show in the breakpoint's description, so suppress it.
536     if (show_locations && level != lldb::eDescriptionLevelBrief)
537     {
538         s->IndentMore();
539         for (size_t i = 0; i < num_locations; ++i)
540         {
541             BreakpointLocation *loc = GetLocationAtIndex(i).get();
542             loc->GetDescription(s, level);
543             s->EOL();
544         }
545         s->IndentLess();
546     }
547 }
548 
549 void
550 Breakpoint::GetResolverDescription (Stream *s)
551 {
552     if (m_resolver_sp)
553         m_resolver_sp->GetDescription (s);
554 }
555 
556 
557 bool
558 Breakpoint::GetMatchingFileLine (const ConstString &filename, uint32_t line_number, BreakpointLocationCollection &loc_coll)
559 {
560     // TODO: To be correct, this method needs to fill the breakpoint location collection
561     //       with the location IDs which match the filename and line_number.
562     //
563 
564     if (m_resolver_sp)
565     {
566         BreakpointResolverFileLine *resolverFileLine = dyn_cast<BreakpointResolverFileLine>(m_resolver_sp.get());
567         if (resolverFileLine &&
568             resolverFileLine->m_file_spec.GetFilename() == filename &&
569             resolverFileLine->m_line_number == line_number)
570         {
571             return true;
572         }
573     }
574     return false;
575 }
576 
577 void
578 Breakpoint::GetFilterDescription (Stream *s)
579 {
580     m_filter_sp->GetDescription (s);
581 }
582 
583 void
584 Breakpoint::SendBreakpointChangedEvent (lldb::BreakpointEventType eventKind)
585 {
586     if (!m_being_created
587         && !IsInternal()
588         && GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
589     {
590         BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind, shared_from_this());
591 
592         GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
593     }
594 }
595 
596 void
597 Breakpoint::SendBreakpointChangedEvent (BreakpointEventData *data)
598 {
599 
600     if (data == NULL)
601         return;
602 
603     if (!m_being_created
604         && !IsInternal()
605         && GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
606         GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
607     else
608         delete data;
609 }
610 
611 Breakpoint::BreakpointEventData::BreakpointEventData (BreakpointEventType sub_type,
612                                                       const BreakpointSP &new_breakpoint_sp) :
613     EventData (),
614     m_breakpoint_event (sub_type),
615     m_new_breakpoint_sp (new_breakpoint_sp)
616 {
617 }
618 
619 Breakpoint::BreakpointEventData::~BreakpointEventData ()
620 {
621 }
622 
623 const ConstString &
624 Breakpoint::BreakpointEventData::GetFlavorString ()
625 {
626     static ConstString g_flavor ("Breakpoint::BreakpointEventData");
627     return g_flavor;
628 }
629 
630 const ConstString &
631 Breakpoint::BreakpointEventData::GetFlavor () const
632 {
633     return BreakpointEventData::GetFlavorString ();
634 }
635 
636 
637 BreakpointSP &
638 Breakpoint::BreakpointEventData::GetBreakpoint ()
639 {
640     return m_new_breakpoint_sp;
641 }
642 
643 BreakpointEventType
644 Breakpoint::BreakpointEventData::GetBreakpointEventType () const
645 {
646     return m_breakpoint_event;
647 }
648 
649 void
650 Breakpoint::BreakpointEventData::Dump (Stream *s) const
651 {
652 }
653 
654 const Breakpoint::BreakpointEventData *
655 Breakpoint::BreakpointEventData::GetEventDataFromEvent (const Event *event)
656 {
657     if (event)
658     {
659         const EventData *event_data = event->GetData();
660         if (event_data && event_data->GetFlavor() == BreakpointEventData::GetFlavorString())
661             return static_cast <const BreakpointEventData *> (event->GetData());
662     }
663     return NULL;
664 }
665 
666 BreakpointEventType
667 Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (const EventSP &event_sp)
668 {
669     const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
670 
671     if (data == NULL)
672         return eBreakpointEventTypeInvalidType;
673     else
674         return data->GetBreakpointEventType();
675 }
676 
677 BreakpointSP
678 Breakpoint::BreakpointEventData::GetBreakpointFromEvent (const EventSP &event_sp)
679 {
680     BreakpointSP bp_sp;
681 
682     const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
683     if (data)
684         bp_sp = data->m_new_breakpoint_sp;
685 
686     return bp_sp;
687 }
688 
689 uint32_t
690 Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent (const EventSP &event_sp)
691 {
692     const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
693     if (data)
694         return data->m_locations.GetSize();
695 
696     return 0;
697 }
698 
699 lldb::BreakpointLocationSP
700 Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (const lldb::EventSP &event_sp, uint32_t bp_loc_idx)
701 {
702     lldb::BreakpointLocationSP bp_loc_sp;
703 
704     const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
705     if (data)
706     {
707         bp_loc_sp = data->m_locations.GetByIndex(bp_loc_idx);
708     }
709 
710     return bp_loc_sp;
711 }
712