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/BreakpointResolver.h"
20 #include "lldb/Core/Log.h"
21 #include "lldb/Core/ModuleList.h"
22 #include "lldb/Core/SearchFilter.h"
23 #include "lldb/Core/Stream.h"
24 #include "lldb/Core/StreamString.h"
25 #include "lldb/Symbol/SymbolContext.h"
26 #include "lldb/Target/Target.h"
27 #include "lldb/Target/ThreadSpec.h"
28 #include "lldb/lldb-private-log.h"
29 
30 using namespace lldb;
31 using namespace lldb_private;
32 
33 const ConstString &
34 Breakpoint::GetEventIdentifier ()
35 {
36     static ConstString g_identifier("event-identifier.breakpoint.changed");
37     return g_identifier;
38 }
39 
40 //----------------------------------------------------------------------
41 // Breakpoint constructor
42 //----------------------------------------------------------------------
43 Breakpoint::Breakpoint(Target &target, SearchFilterSP &filter_sp, BreakpointResolverSP &resolver_sp) :
44     m_target (target),
45     m_filter_sp (filter_sp),
46     m_resolver_sp (resolver_sp),
47     m_options (),
48     m_locations ()
49 {
50 }
51 
52 //----------------------------------------------------------------------
53 // Destructor
54 //----------------------------------------------------------------------
55 Breakpoint::~Breakpoint()
56 {
57 }
58 
59 bool
60 Breakpoint::IsInternal () const
61 {
62     return LLDB_BREAK_ID_IS_INTERNAL(m_bid);
63 }
64 
65 
66 
67 Target&
68 Breakpoint::GetTarget ()
69 {
70     return m_target;
71 }
72 
73 const Target&
74 Breakpoint::GetTarget () const
75 {
76     return m_target;
77 }
78 
79 BreakpointLocationSP
80 Breakpoint::AddLocation (Address &addr, bool *new_location)
81 {
82     BreakpointLocationSP bp_loc_sp (m_locations.FindByAddress(addr));
83     if (bp_loc_sp)
84     {
85         if (new_location)
86             *new_location = false;
87         return bp_loc_sp;
88     }
89 
90     bp_loc_sp.reset (new BreakpointLocation (m_locations.GetNextID(), *this, addr));
91     m_locations.Add (bp_loc_sp);
92     bp_loc_sp->ResolveBreakpointSite();
93 
94     if (new_location)
95         *new_location = true;
96     return bp_loc_sp;
97 }
98 
99 BreakpointLocationSP
100 Breakpoint::FindLocationByAddress (Address &addr)
101 {
102     return m_locations.FindByAddress(addr);
103 }
104 
105 break_id_t
106 Breakpoint::FindLocationIDByAddress (Address &addr)
107 {
108     return m_locations.FindIDByAddress(addr);
109 }
110 
111 BreakpointLocationSP
112 Breakpoint::FindLocationByID (break_id_t bp_loc_id)
113 {
114     return m_locations.FindByID(bp_loc_id);
115 }
116 
117 BreakpointLocationSP
118 Breakpoint::GetLocationAtIndex (uint32_t index)
119 {
120     return m_locations.GetByIndex(index);
121 }
122 
123 BreakpointLocationSP
124 Breakpoint::GetLocationSP (BreakpointLocation *bp_loc_ptr)
125 {
126     assert (bp_loc_ptr->GetBreakpoint().GetID() == GetID());
127     return m_locations.FindByID(bp_loc_ptr->GetID());
128 }
129 
130 
131 // For each of the overall options we need to decide how they propagate to
132 // the location options.  This will determine the precedence of options on
133 // the breakpoint vrs. its locations.
134 
135 // Disable at the breakpoint level should override the location settings.
136 // That way you can conveniently turn off a whole breakpoint without messing
137 // up the individual settings.
138 
139 void
140 Breakpoint::SetEnabled (bool enable)
141 {
142     m_options.SetEnabled(enable);
143     if (enable)
144         m_locations.ResolveAllBreakpointSites();
145     else
146         m_locations.ClearAllBreakpointSites();
147 }
148 
149 bool
150 Breakpoint::IsEnabled ()
151 {
152     return m_options.IsEnabled();
153 }
154 
155 void
156 Breakpoint::SetIgnoreCount (uint32_t n)
157 {
158     m_options.SetIgnoreCount(n);
159 }
160 
161 uint32_t
162 Breakpoint::GetIgnoreCount () const
163 {
164     return m_options.GetIgnoreCount();
165 }
166 
167 uint32_t
168 Breakpoint::GetHitCount () const
169 {
170     return m_locations.GetHitCount();
171 }
172 
173 void
174 Breakpoint::SetThreadID (lldb::tid_t thread_id)
175 {
176     m_options.GetThreadSpec()->SetTID(thread_id);
177 }
178 
179 lldb::tid_t
180 Breakpoint::GetThreadID ()
181 {
182     if (m_options.GetThreadSpec() == NULL)
183         return LLDB_INVALID_THREAD_ID;
184     else
185         return m_options.GetThreadSpec()->GetTID();
186 }
187 
188 void
189 Breakpoint::SetCondition (const char *condition)
190 {
191     m_options.SetCondition (condition);
192 }
193 
194 ThreadPlan *
195 Breakpoint::GetThreadPlanToTestCondition (ExecutionContext &exe_ctx, lldb::BreakpointLocationSP loc_sp, Stream &error)
196 {
197     return m_options.GetThreadPlanToTestCondition (exe_ctx, loc_sp, error);
198 }
199 
200 const char *
201 Breakpoint::GetConditionText ()
202 {
203     return m_options.GetConditionText();
204 }
205 
206 // This function is used when "baton" doesn't need to be freed
207 void
208 Breakpoint::SetCallback (BreakpointHitCallback callback, void *baton, bool is_synchronous)
209 {
210     // The default "Baton" class will keep a copy of "baton" and won't free
211     // or delete it when it goes goes out of scope.
212     m_options.SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous);
213 }
214 
215 // This function is used when a baton needs to be freed and therefore is
216 // contained in a "Baton" subclass.
217 void
218 Breakpoint::SetCallback (BreakpointHitCallback callback, const BatonSP &callback_baton_sp, bool is_synchronous)
219 {
220     m_options.SetCallback(callback, callback_baton_sp, is_synchronous);
221 }
222 
223 void
224 Breakpoint::ClearCallback ()
225 {
226     m_options.ClearCallback ();
227 }
228 
229 bool
230 Breakpoint::InvokeCallback (StoppointCallbackContext *context, break_id_t bp_loc_id)
231 {
232     return m_options.InvokeCallback (context, GetID(), bp_loc_id);
233 }
234 
235 BreakpointOptions *
236 Breakpoint::GetOptions ()
237 {
238     return &m_options;
239 }
240 
241 void
242 Breakpoint::ResolveBreakpoint ()
243 {
244     if (m_resolver_sp)
245         m_resolver_sp->ResolveBreakpoint(*m_filter_sp);
246 }
247 
248 void
249 Breakpoint::ResolveBreakpointInModules (ModuleList &module_list)
250 {
251     if (m_resolver_sp)
252         m_resolver_sp->ResolveBreakpointInModules(*m_filter_sp, module_list);
253 }
254 
255 void
256 Breakpoint::ClearAllBreakpointSites ()
257 {
258     m_locations.ClearAllBreakpointSites();
259 }
260 
261 //----------------------------------------------------------------------
262 // ModulesChanged: Pass in a list of new modules, and
263 //----------------------------------------------------------------------
264 
265 void
266 Breakpoint::ModulesChanged (ModuleList &module_list, bool load)
267 {
268     if (load)
269     {
270         // The logic for handling new modules is:
271         // 1) If the filter rejects this module, then skip it.
272         // 2) Run through the current location list and if there are any locations
273         //    for that module, we mark the module as "seen" and we don't try to re-resolve
274         //    breakpoint locations for that module.
275         //    However, we do add breakpoint sites to these locations if needed.
276         // 3) If we don't see this module in our breakpoint location list, call ResolveInModules.
277 
278         ModuleList new_modules;  // We'll stuff the "unseen" modules in this list, and then resolve
279                                    // them after the locations pass.  Have to do it this way because
280                                    // resolving breakpoints will add new locations potentially.
281 
282         for (size_t i = 0; i < module_list.GetSize(); i++)
283         {
284             bool seen = false;
285             ModuleSP module_sp (module_list.GetModuleAtIndex (i));
286             Module *module = module_sp.get();
287             if (!m_filter_sp->ModulePasses (module_sp))
288                 continue;
289 
290             for (size_t j = 0; j < m_locations.GetSize(); j++)
291             {
292                 BreakpointLocationSP break_loc = m_locations.GetByIndex(j);
293                 if (!break_loc->IsEnabled())
294                     continue;
295                 const Section *section = break_loc->GetAddress().GetSection();
296                 if (section == NULL || section->GetModule() == module)
297                 {
298                     if (!seen)
299                         seen = true;
300 
301                     if (!break_loc->ResolveBreakpointSite())
302                     {
303                         Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
304                         if (log)
305                             log->Printf ("Warning: could not set breakpoint site for breakpoint location %d of breakpoint %d.\n",
306                                          break_loc->GetID(), GetID());
307                     }
308                 }
309             }
310 
311             if (!seen)
312                 new_modules.AppendInNeeded (module_sp);
313 
314         }
315         if (new_modules.GetSize() > 0)
316         {
317             ResolveBreakpointInModules(new_modules);
318         }
319     }
320     else
321     {
322         // Go through the currently set locations and if any have breakpoints in
323         // the module list, then remove their breakpoint sites.
324         // FIXME: Think about this...  Maybe it's better to delete the locations?
325         // Are we sure that on load-unload-reload the module pointer will remain
326         // the same?  Or do we need to do an equality on modules that is an
327         // "equivalence"???
328 
329         for (size_t i = 0; i < module_list.GetSize(); i++)
330         {
331             ModuleSP module_sp (module_list.GetModuleAtIndex (i));
332             if (!m_filter_sp->ModulePasses (module_sp))
333                 continue;
334 
335             for (size_t j = 0; j < m_locations.GetSize(); j++)
336             {
337                 BreakpointLocationSP break_loc = m_locations.GetByIndex(j);
338                 const Section *section = break_loc->GetAddress().GetSection();
339                 if (section)
340                 {
341                     if (section->GetModule() == module_sp.get())
342                         break_loc->ClearBreakpointSite();
343                 }
344 //                else
345 //                {
346 //                    Address temp_addr;
347 //                    if (module->ResolveLoadAddress(break_loc->GetLoadAddress(), m_target->GetProcess(), temp_addr))
348 //                        break_loc->ClearBreakpointSite();
349 //                }
350             }
351         }
352     }
353 }
354 
355 void
356 Breakpoint::Dump (Stream *)
357 {
358 }
359 
360 size_t
361 Breakpoint::GetNumResolvedLocations() const
362 {
363     // Return the number of breakpoints that are actually resolved and set
364     // down in the inferior process.
365     return m_locations.GetNumResolvedLocations();
366 }
367 
368 size_t
369 Breakpoint::GetNumLocations() const
370 {
371     return m_locations.GetSize();
372 }
373 
374 void
375 Breakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_locations)
376 {
377     assert (s != NULL);
378     s->Printf("%i: ", GetID());
379     GetResolverDescription (s);
380     GetFilterDescription (s);
381 
382     const size_t num_locations = GetNumLocations ();
383     const size_t num_resolved_locations = GetNumResolvedLocations ();
384 
385     switch (level)
386     {
387     case lldb::eDescriptionLevelBrief:
388     case lldb::eDescriptionLevelFull:
389         if (num_locations > 0)
390         {
391             s->Printf(", locations = %zu", num_locations);
392             if (num_resolved_locations > 0)
393                 s->Printf(", resolved = %zu", num_resolved_locations);
394         }
395         else
396         {
397             s->Printf(", locations = 0 (pending)");
398         }
399 
400         GetOptions()->GetDescription(s, level);
401 
402         if (level == lldb::eDescriptionLevelFull)
403         {
404             s->IndentLess();
405             s->EOL();
406         }
407         break;
408 
409     case lldb::eDescriptionLevelVerbose:
410         // Verbose mode does a debug dump of the breakpoint
411         Dump (s);
412         s->EOL ();
413         s->Indent();
414         GetOptions()->GetDescription(s, level);
415         break;
416 
417     default:
418         break;
419     }
420 
421     if (show_locations)
422     {
423         s->IndentMore();
424         for (size_t i = 0; i < num_locations; ++i)
425         {
426             BreakpointLocation *loc = GetLocationAtIndex(i).get();
427             loc->GetDescription(s, level);
428             s->EOL();
429         }
430         s->IndentLess();
431     }
432 }
433 
434 Breakpoint::BreakpointEventData::BreakpointEventData (BreakpointEventType sub_type,
435                                                       BreakpointSP &new_breakpoint_sp) :
436     EventData (),
437     m_breakpoint_event (sub_type),
438     m_new_breakpoint_sp (new_breakpoint_sp)
439 {
440 }
441 
442 Breakpoint::BreakpointEventData::~BreakpointEventData ()
443 {
444 }
445 
446 const ConstString &
447 Breakpoint::BreakpointEventData::GetFlavorString ()
448 {
449     static ConstString g_flavor ("Breakpoint::BreakpointEventData");
450     return g_flavor;
451 }
452 
453 const ConstString &
454 Breakpoint::BreakpointEventData::GetFlavor () const
455 {
456     return BreakpointEventData::GetFlavorString ();
457 }
458 
459 
460 BreakpointSP &
461 Breakpoint::BreakpointEventData::GetBreakpoint ()
462 {
463     return m_new_breakpoint_sp;
464 }
465 
466 BreakpointEventType
467 Breakpoint::BreakpointEventData::GetBreakpointEventType () const
468 {
469     return m_breakpoint_event;
470 }
471 
472 void
473 Breakpoint::BreakpointEventData::Dump (Stream *s) const
474 {
475 }
476 
477 Breakpoint::BreakpointEventData *
478 Breakpoint::BreakpointEventData::GetEventDataFromEvent (const EventSP &event_sp)
479 {
480     if (event_sp)
481     {
482         EventData *event_data = event_sp->GetData();
483         if (event_data && event_data->GetFlavor() == BreakpointEventData::GetFlavorString())
484             return static_cast <BreakpointEventData *> (event_sp->GetData());
485     }
486     return NULL;
487 }
488 
489 BreakpointEventType
490 Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (const EventSP &event_sp)
491 {
492     BreakpointEventData *data = GetEventDataFromEvent (event_sp);
493 
494     if (data == NULL)
495         return eBreakpointEventTypeInvalidType;
496     else
497         return data->GetBreakpointEventType();
498 }
499 
500 BreakpointSP
501 Breakpoint::BreakpointEventData::GetBreakpointFromEvent (const EventSP &event_sp)
502 {
503     BreakpointSP bp_sp;
504 
505     BreakpointEventData *data = GetEventDataFromEvent (event_sp);
506     if (data)
507         bp_sp = data->GetBreakpoint();
508 
509     return bp_sp;
510 }
511 
512 lldb::BreakpointLocationSP
513 Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (const lldb::EventSP &event_sp, uint32_t bp_loc_idx)
514 {
515     lldb::BreakpointLocationSP bp_loc_sp;
516 
517     BreakpointEventData *data = GetEventDataFromEvent (event_sp);
518     if (data)
519     {
520         Breakpoint *bp = data->GetBreakpoint().get();
521         if (bp)
522             bp_loc_sp = bp->GetLocationAtIndex(bp_loc_idx);
523     }
524 
525     return bp_loc_sp;
526 }
527 
528 
529 void
530 Breakpoint::GetResolverDescription (Stream *s)
531 {
532     if (m_resolver_sp)
533         m_resolver_sp->GetDescription (s);
534 }
535 
536 void
537 Breakpoint::GetFilterDescription (Stream *s)
538 {
539     m_filter_sp->GetDescription (s);
540 }
541 
542 const BreakpointSP
543 Breakpoint::GetSP ()
544 {
545     return m_target.GetBreakpointList().FindBreakpointByID (GetID());
546 }
547