blob: 5acfa9d39aa92cf378b43d5809b7825453bd32a4 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- 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"
Johnny Chena62ad7c2010-10-28 17:27:46 +000019#include "lldb/Breakpoint/BreakpointLocationCollection.h"
Chris Lattner24943d22010-06-08 16:52:24 +000020#include "lldb/Breakpoint/BreakpointResolver.h"
Johnny Chena62ad7c2010-10-28 17:27:46 +000021#include "lldb/Breakpoint/BreakpointResolverFileLine.h"
Chris Lattner24943d22010-06-08 16:52:24 +000022#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"
Jim Ingham3c7b5b92010-06-16 02:00:15 +000029#include "lldb/Target/ThreadSpec.h"
Chris Lattner24943d22010-06-08 16:52:24 +000030#include "lldb/lldb-private-log.h"
Johnny Chena62ad7c2010-10-28 17:27:46 +000031#include "llvm/Support/Casting.h"
Chris Lattner24943d22010-06-08 16:52:24 +000032
33using namespace lldb;
34using namespace lldb_private;
Johnny Chena62ad7c2010-10-28 17:27:46 +000035using namespace llvm;
Chris Lattner24943d22010-06-08 16:52:24 +000036
37const ConstString &
38Breakpoint::GetEventIdentifier ()
39{
40 static ConstString g_identifier("event-identifier.breakpoint.changed");
41 return g_identifier;
42}
43
44//----------------------------------------------------------------------
45// Breakpoint constructor
46//----------------------------------------------------------------------
47Breakpoint::Breakpoint(Target &target, SearchFilterSP &filter_sp, BreakpointResolverSP &resolver_sp) :
Jim Ingham28e23862012-02-08 05:23:15 +000048 m_being_created(true),
Chris Lattner24943d22010-06-08 16:52:24 +000049 m_target (target),
50 m_filter_sp (filter_sp),
51 m_resolver_sp (resolver_sp),
52 m_options (),
Jim Ingham28e23862012-02-08 05:23:15 +000053 m_locations (*this)
Chris Lattner24943d22010-06-08 16:52:24 +000054{
Jim Ingham28e23862012-02-08 05:23:15 +000055 m_being_created = false;
Chris Lattner24943d22010-06-08 16:52:24 +000056}
57
58//----------------------------------------------------------------------
59// Destructor
60//----------------------------------------------------------------------
61Breakpoint::~Breakpoint()
62{
63}
64
65bool
66Breakpoint::IsInternal () const
67{
68 return LLDB_BREAK_ID_IS_INTERNAL(m_bid);
69}
70
71
72
73Target&
74Breakpoint::GetTarget ()
75{
76 return m_target;
77}
78
79const Target&
80Breakpoint::GetTarget () const
81{
82 return m_target;
83}
84
85BreakpointLocationSP
Greg Clayton19a1ab82011-02-05 00:38:04 +000086Breakpoint::AddLocation (const Address &addr, bool *new_location)
Chris Lattner24943d22010-06-08 16:52:24 +000087{
Jim Ingham28e23862012-02-08 05:23:15 +000088 return m_locations.AddLocation (addr, new_location);
Chris Lattner24943d22010-06-08 16:52:24 +000089}
90
91BreakpointLocationSP
Greg Clayton19a1ab82011-02-05 00:38:04 +000092Breakpoint::FindLocationByAddress (const Address &addr)
Chris Lattner24943d22010-06-08 16:52:24 +000093{
94 return m_locations.FindByAddress(addr);
95}
96
97break_id_t
Greg Clayton19a1ab82011-02-05 00:38:04 +000098Breakpoint::FindLocationIDByAddress (const Address &addr)
Chris Lattner24943d22010-06-08 16:52:24 +000099{
100 return m_locations.FindIDByAddress(addr);
101}
102
103BreakpointLocationSP
104Breakpoint::FindLocationByID (break_id_t bp_loc_id)
105{
106 return m_locations.FindByID(bp_loc_id);
107}
108
109BreakpointLocationSP
110Breakpoint::GetLocationAtIndex (uint32_t index)
111{
112 return m_locations.GetByIndex(index);
113}
114
Chris Lattner24943d22010-06-08 16:52:24 +0000115// 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
Johnny Chen736f0d62012-01-25 23:08:23 +0000117// the breakpoint vs. its locations.
Chris Lattner24943d22010-06-08 16:52:24 +0000118
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
123void
124Breakpoint::SetEnabled (bool enable)
125{
Jim Ingham28e23862012-02-08 05:23:15 +0000126 if (enable == m_options.IsEnabled())
127 return;
128
Chris Lattner24943d22010-06-08 16:52:24 +0000129 m_options.SetEnabled(enable);
130 if (enable)
131 m_locations.ResolveAllBreakpointSites();
132 else
133 m_locations.ClearAllBreakpointSites();
Jim Ingham28e23862012-02-08 05:23:15 +0000134
135 SendBreakpointChangedEvent (enable ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled);
136
Chris Lattner24943d22010-06-08 16:52:24 +0000137}
138
139bool
140Breakpoint::IsEnabled ()
141{
142 return m_options.IsEnabled();
143}
144
145void
Greg Clayton54e7afa2010-07-09 20:39:50 +0000146Breakpoint::SetIgnoreCount (uint32_t n)
Chris Lattner24943d22010-06-08 16:52:24 +0000147{
Jim Ingham28e23862012-02-08 05:23:15 +0000148 if (m_options.GetIgnoreCount() == n)
149 return;
150
Chris Lattner24943d22010-06-08 16:52:24 +0000151 m_options.SetIgnoreCount(n);
Jim Ingham28e23862012-02-08 05:23:15 +0000152 SendBreakpointChangedEvent (eBreakpointEventTypeIgnoreChanged);
Chris Lattner24943d22010-06-08 16:52:24 +0000153}
154
Jim Inghamfdbd10a2012-06-26 22:27:55 +0000155void
156Breakpoint::DecrementIgnoreCount ()
157{
158 uint32_t ignore = m_options.GetIgnoreCount();
159 if (ignore != 0)
160 m_options.SetIgnoreCount(ignore - 1);
161}
162
Greg Clayton54e7afa2010-07-09 20:39:50 +0000163uint32_t
Chris Lattner24943d22010-06-08 16:52:24 +0000164Breakpoint::GetIgnoreCount () const
165{
166 return m_options.GetIgnoreCount();
167}
168
Jim Inghamfdbd10a2012-06-26 22:27:55 +0000169bool
170Breakpoint::IgnoreCountShouldStop ()
171{
172 uint32_t ignore = GetIgnoreCount();
173 if (ignore != 0)
174 {
175 // When we get here we know the location that caused the stop doesn't have an ignore count,
176 // since by contract we call it first... So we don't have to find & decrement it, we only have
177 // to decrement our own ignore count.
178 DecrementIgnoreCount();
179 return false;
180 }
181 else
182 return true;
183}
184
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000185uint32_t
186Breakpoint::GetHitCount () const
187{
188 return m_locations.GetHitCount();
189}
190
Chris Lattner24943d22010-06-08 16:52:24 +0000191void
192Breakpoint::SetThreadID (lldb::tid_t thread_id)
193{
Jim Ingham28e23862012-02-08 05:23:15 +0000194 if (m_options.GetThreadSpec()->GetTID() == thread_id)
195 return;
196
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000197 m_options.GetThreadSpec()->SetTID(thread_id);
Jim Ingham28e23862012-02-08 05:23:15 +0000198 SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged);
Chris Lattner24943d22010-06-08 16:52:24 +0000199}
200
201lldb::tid_t
Jim Ingham28e23862012-02-08 05:23:15 +0000202Breakpoint::GetThreadID () const
Chris Lattner24943d22010-06-08 16:52:24 +0000203{
Jim Ingham28e23862012-02-08 05:23:15 +0000204 if (m_options.GetThreadSpecNoCreate() == NULL)
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000205 return LLDB_INVALID_THREAD_ID;
206 else
Jim Ingham28e23862012-02-08 05:23:15 +0000207 return m_options.GetThreadSpecNoCreate()->GetTID();
208}
209
210void
211Breakpoint::SetThreadIndex (uint32_t index)
212{
213 if (m_options.GetThreadSpec()->GetIndex() == index)
214 return;
215
216 m_options.GetThreadSpec()->SetIndex(index);
217 SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged);
218}
219
220uint32_t
221Breakpoint::GetThreadIndex() const
222{
223 if (m_options.GetThreadSpecNoCreate() == NULL)
224 return 0;
225 else
226 return m_options.GetThreadSpecNoCreate()->GetIndex();
227}
228
229void
230Breakpoint::SetThreadName (const char *thread_name)
231{
232 if (::strcmp (m_options.GetThreadSpec()->GetName(), thread_name) == 0)
233 return;
234
235 m_options.GetThreadSpec()->SetName (thread_name);
236 SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged);
237}
238
239const char *
240Breakpoint::GetThreadName () const
241{
242 if (m_options.GetThreadSpecNoCreate() == NULL)
243 return NULL;
244 else
245 return m_options.GetThreadSpecNoCreate()->GetName();
246}
247
248void
249Breakpoint::SetQueueName (const char *queue_name)
250{
251 if (::strcmp (m_options.GetThreadSpec()->GetQueueName(), queue_name) == 0)
252 return;
253
254 m_options.GetThreadSpec()->SetQueueName (queue_name);
255 SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged);
256}
257
258const char *
259Breakpoint::GetQueueName () const
260{
261 if (m_options.GetThreadSpecNoCreate() == NULL)
262 return NULL;
263 else
264 return m_options.GetThreadSpecNoCreate()->GetQueueName();
Chris Lattner24943d22010-06-08 16:52:24 +0000265}
266
Jim Inghamd1686902010-10-14 23:45:03 +0000267void
268Breakpoint::SetCondition (const char *condition)
269{
270 m_options.SetCondition (condition);
Jim Ingham28e23862012-02-08 05:23:15 +0000271 SendBreakpointChangedEvent (eBreakpointEventTypeConditionChanged);
Jim Inghamd1686902010-10-14 23:45:03 +0000272}
273
Jim Inghamd1686902010-10-14 23:45:03 +0000274const char *
Jim Inghamac354422011-06-15 21:16:00 +0000275Breakpoint::GetConditionText () const
Jim Inghamd1686902010-10-14 23:45:03 +0000276{
277 return m_options.GetConditionText();
278}
279
Chris Lattner24943d22010-06-08 16:52:24 +0000280// This function is used when "baton" doesn't need to be freed
281void
282Breakpoint::SetCallback (BreakpointHitCallback callback, void *baton, bool is_synchronous)
283{
284 // The default "Baton" class will keep a copy of "baton" and won't free
285 // or delete it when it goes goes out of scope.
286 m_options.SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous);
Jim Ingham28e23862012-02-08 05:23:15 +0000287
288 SendBreakpointChangedEvent (eBreakpointEventTypeCommandChanged);
Chris Lattner24943d22010-06-08 16:52:24 +0000289}
290
291// This function is used when a baton needs to be freed and therefore is
292// contained in a "Baton" subclass.
293void
294Breakpoint::SetCallback (BreakpointHitCallback callback, const BatonSP &callback_baton_sp, bool is_synchronous)
295{
296 m_options.SetCallback(callback, callback_baton_sp, is_synchronous);
297}
298
299void
300Breakpoint::ClearCallback ()
301{
302 m_options.ClearCallback ();
303}
304
305bool
306Breakpoint::InvokeCallback (StoppointCallbackContext *context, break_id_t bp_loc_id)
307{
308 return m_options.InvokeCallback (context, GetID(), bp_loc_id);
309}
310
311BreakpointOptions *
312Breakpoint::GetOptions ()
313{
314 return &m_options;
315}
316
317void
318Breakpoint::ResolveBreakpoint ()
319{
320 if (m_resolver_sp)
321 m_resolver_sp->ResolveBreakpoint(*m_filter_sp);
322}
323
324void
325Breakpoint::ResolveBreakpointInModules (ModuleList &module_list)
326{
327 if (m_resolver_sp)
328 m_resolver_sp->ResolveBreakpointInModules(*m_filter_sp, module_list);
329}
330
331void
332Breakpoint::ClearAllBreakpointSites ()
333{
334 m_locations.ClearAllBreakpointSites();
335}
336
337//----------------------------------------------------------------------
338// ModulesChanged: Pass in a list of new modules, and
339//----------------------------------------------------------------------
340
341void
Jim Ingham03e5e512012-05-17 18:38:42 +0000342Breakpoint::ModulesChanged (ModuleList &module_list, bool load, bool delete_locations)
Chris Lattner24943d22010-06-08 16:52:24 +0000343{
Jim Ingham93367902012-05-30 02:19:25 +0000344 Mutex::Locker modules_mutex(module_list.GetMutex());
Chris Lattner24943d22010-06-08 16:52:24 +0000345 if (load)
346 {
347 // The logic for handling new modules is:
348 // 1) If the filter rejects this module, then skip it.
349 // 2) Run through the current location list and if there are any locations
350 // for that module, we mark the module as "seen" and we don't try to re-resolve
351 // breakpoint locations for that module.
352 // However, we do add breakpoint sites to these locations if needed.
353 // 3) If we don't see this module in our breakpoint location list, call ResolveInModules.
354
355 ModuleList new_modules; // We'll stuff the "unseen" modules in this list, and then resolve
Greg Clayton19a1ab82011-02-05 00:38:04 +0000356 // them after the locations pass. Have to do it this way because
357 // resolving breakpoints will add new locations potentially.
358
359 const size_t num_locs = m_locations.GetSize();
Jim Ingham93367902012-05-30 02:19:25 +0000360 size_t num_modules = module_list.GetSize();
361 for (size_t i = 0; i < num_modules; i++)
Chris Lattner24943d22010-06-08 16:52:24 +0000362 {
363 bool seen = false;
Jim Ingham93367902012-05-30 02:19:25 +0000364 ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (i));
Chris Lattner24943d22010-06-08 16:52:24 +0000365 if (!m_filter_sp->ModulePasses (module_sp))
366 continue;
367
Greg Clayton19a1ab82011-02-05 00:38:04 +0000368 for (size_t loc_idx = 0; loc_idx < num_locs; loc_idx++)
Chris Lattner24943d22010-06-08 16:52:24 +0000369 {
Greg Clayton7b9fcc02010-12-06 23:51:26 +0000370 BreakpointLocationSP break_loc = m_locations.GetByIndex(loc_idx);
Jim Ingham1de036b2010-10-20 03:36:33 +0000371 if (!break_loc->IsEnabled())
372 continue;
Greg Clayton3508c382012-02-24 01:59:29 +0000373 SectionSP section_sp (break_loc->GetAddress().GetSection());
374 if (!section_sp || section_sp->GetModule() == module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000375 {
376 if (!seen)
377 seen = true;
378
379 if (!break_loc->ResolveBreakpointSite())
380 {
Greg Claytone005f2c2010-11-06 01:53:30 +0000381 LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
Chris Lattner24943d22010-06-08 16:52:24 +0000382 if (log)
383 log->Printf ("Warning: could not set breakpoint site for breakpoint location %d of breakpoint %d.\n",
384 break_loc->GetID(), GetID());
385 }
386 }
387 }
388
389 if (!seen)
Greg Claytonab429022010-12-12 21:03:32 +0000390 new_modules.AppendIfNeeded (module_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000391
392 }
Jim Ingham28e23862012-02-08 05:23:15 +0000393
Chris Lattner24943d22010-06-08 16:52:24 +0000394 if (new_modules.GetSize() > 0)
395 {
Jim Ingham28e23862012-02-08 05:23:15 +0000396 // If this is not an internal breakpoint, set up to record the new locations, then dispatch
397 // an event with the new locations.
398 if (!IsInternal())
399 {
400 BreakpointEventData *new_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsAdded,
401 shared_from_this());
402
403 m_locations.StartRecordingNewLocations(new_locations_event->GetBreakpointLocationCollection());
404
405 ResolveBreakpointInModules(new_modules);
406
407 m_locations.StopRecordingNewLocations();
408 if (new_locations_event->GetBreakpointLocationCollection().GetSize() != 0)
409 {
410 SendBreakpointChangedEvent (new_locations_event);
411 }
412 else
413 delete new_locations_event;
414 }
415 else
416 ResolveBreakpointInModules(new_modules);
417
Chris Lattner24943d22010-06-08 16:52:24 +0000418 }
419 }
420 else
421 {
422 // Go through the currently set locations and if any have breakpoints in
Jim Ingham03e5e512012-05-17 18:38:42 +0000423 // the module list, then remove their breakpoint sites, and their locations if asked to.
Chris Lattner24943d22010-06-08 16:52:24 +0000424
Jim Ingham28e23862012-02-08 05:23:15 +0000425 BreakpointEventData *removed_locations_event;
426 if (!IsInternal())
427 removed_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsRemoved,
428 shared_from_this());
429 else
430 removed_locations_event = NULL;
Jim Ingham93367902012-05-30 02:19:25 +0000431
432 size_t num_modules = module_list.GetSize();
433 for (size_t i = 0; i < num_modules; i++)
Chris Lattner24943d22010-06-08 16:52:24 +0000434 {
Jim Ingham93367902012-05-30 02:19:25 +0000435 ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (i));
Greg Clayton7b9fcc02010-12-06 23:51:26 +0000436 if (m_filter_sp->ModulePasses (module_sp))
Chris Lattner24943d22010-06-08 16:52:24 +0000437 {
Greg Clayton3508c382012-02-24 01:59:29 +0000438 size_t loc_idx = 0;
Jim Ingham03e5e512012-05-17 18:38:42 +0000439 size_t num_locations = m_locations.GetSize();
440 BreakpointLocationCollection locations_to_remove;
441 for (loc_idx = 0; loc_idx < num_locations; loc_idx++)
Chris Lattner24943d22010-06-08 16:52:24 +0000442 {
Greg Clayton3508c382012-02-24 01:59:29 +0000443 BreakpointLocationSP break_loc_sp (m_locations.GetByIndex(loc_idx));
444 SectionSP section_sp (break_loc_sp->GetAddress().GetSection());
445 if (section_sp && section_sp->GetModule() == module_sp)
Greg Clayton7b9fcc02010-12-06 23:51:26 +0000446 {
447 // Remove this breakpoint since the shared library is
448 // unloaded, but keep the breakpoint location around
449 // so we always get complete hit count and breakpoint
450 // lifetime info
Greg Clayton3508c382012-02-24 01:59:29 +0000451 break_loc_sp->ClearBreakpointSite();
Jim Ingham28e23862012-02-08 05:23:15 +0000452 if (removed_locations_event)
453 {
Greg Clayton3508c382012-02-24 01:59:29 +0000454 removed_locations_event->GetBreakpointLocationCollection().Add(break_loc_sp);
Jim Ingham28e23862012-02-08 05:23:15 +0000455 }
Jim Ingham03e5e512012-05-17 18:38:42 +0000456 if (delete_locations)
457 locations_to_remove.Add (break_loc_sp);
458
Greg Clayton7b9fcc02010-12-06 23:51:26 +0000459 }
Jim Ingham03e5e512012-05-17 18:38:42 +0000460 }
461
462 if (delete_locations)
463 {
464 size_t num_locations_to_remove = locations_to_remove.GetSize();
465 for (loc_idx = 0; loc_idx < num_locations_to_remove; loc_idx++)
466 m_locations.RemoveLocation (locations_to_remove.GetByIndex(loc_idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000467 }
Chris Lattner24943d22010-06-08 16:52:24 +0000468 }
469 }
Jim Ingham28e23862012-02-08 05:23:15 +0000470 SendBreakpointChangedEvent (removed_locations_event);
Chris Lattner24943d22010-06-08 16:52:24 +0000471 }
472}
473
474void
Jim Ingham03e5e512012-05-17 18:38:42 +0000475Breakpoint::ModuleReplaced (ModuleSP old_module_sp, ModuleSP new_module_sp)
476{
477 ModuleList temp_list;
478 temp_list.Append (new_module_sp);
479 ModulesChanged (temp_list, true);
480
481 // TO DO: For now I'm just adding locations for the new module and removing the
482 // breakpoint locations that were in the old module.
483 // We should really go find the ones that are in the new module & if we can determine that they are "equivalent"
484 // carry over the options from the old location to the new.
485
486 temp_list.Clear();
487 temp_list.Append (old_module_sp);
488 ModulesChanged (temp_list, false, true);
489}
490
491void
Chris Lattner24943d22010-06-08 16:52:24 +0000492Breakpoint::Dump (Stream *)
493{
494}
495
496size_t
497Breakpoint::GetNumResolvedLocations() const
498{
499 // Return the number of breakpoints that are actually resolved and set
500 // down in the inferior process.
501 return m_locations.GetNumResolvedLocations();
502}
503
504size_t
505Breakpoint::GetNumLocations() const
506{
507 return m_locations.GetSize();
508}
509
510void
511Breakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_locations)
512{
513 assert (s != NULL);
Greg Clayton12bec712010-06-28 21:30:43 +0000514 s->Printf("%i: ", GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000515 GetResolverDescription (s);
Greg Clayton12bec712010-06-28 21:30:43 +0000516 GetFilterDescription (s);
Chris Lattner24943d22010-06-08 16:52:24 +0000517
Greg Clayton54e7afa2010-07-09 20:39:50 +0000518 const size_t num_locations = GetNumLocations ();
519 const size_t num_resolved_locations = GetNumResolvedLocations ();
Chris Lattner24943d22010-06-08 16:52:24 +0000520
521 switch (level)
522 {
523 case lldb::eDescriptionLevelBrief:
524 case lldb::eDescriptionLevelFull:
525 if (num_locations > 0)
526 {
Greg Clayton54e7afa2010-07-09 20:39:50 +0000527 s->Printf(", locations = %zu", num_locations);
Chris Lattner24943d22010-06-08 16:52:24 +0000528 if (num_resolved_locations > 0)
Greg Clayton54e7afa2010-07-09 20:39:50 +0000529 s->Printf(", resolved = %zu", num_resolved_locations);
Chris Lattner24943d22010-06-08 16:52:24 +0000530 }
531 else
532 {
Jim Ingham4722b102012-03-06 00:37:27 +0000533 // Don't print the pending notification for exception resolvers since we don't generally
534 // know how to set them until the target is run.
535 if (m_resolver_sp->getResolverID() != BreakpointResolver::ExceptionResolver)
536 s->Printf(", locations = 0 (pending)");
Chris Lattner24943d22010-06-08 16:52:24 +0000537 }
538
Jim Ingham649492b2010-06-18 01:00:58 +0000539 GetOptions()->GetDescription(s, level);
540
Chris Lattner24943d22010-06-08 16:52:24 +0000541 if (level == lldb::eDescriptionLevelFull)
542 {
Jim Ingham649492b2010-06-18 01:00:58 +0000543 s->IndentLess();
544 s->EOL();
Chris Lattner24943d22010-06-08 16:52:24 +0000545 }
546 break;
547
548 case lldb::eDescriptionLevelVerbose:
549 // Verbose mode does a debug dump of the breakpoint
550 Dump (s);
Jim Ingham649492b2010-06-18 01:00:58 +0000551 s->EOL ();
Greg Claytonb1888f22011-03-19 01:12:21 +0000552 //s->Indent();
Jim Ingham649492b2010-06-18 01:00:58 +0000553 GetOptions()->GetDescription(s, level);
Chris Lattner24943d22010-06-08 16:52:24 +0000554 break;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000555
556 default:
557 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000558 }
559
Jim Ingham1cd466f2011-05-14 01:11:02 +0000560 // The brief description is just the location name (1.2 or whatever). That's pointless to
561 // show in the breakpoint's description, so suppress it.
562 if (show_locations && level != lldb::eDescriptionLevelBrief)
Chris Lattner24943d22010-06-08 16:52:24 +0000563 {
Chris Lattner24943d22010-06-08 16:52:24 +0000564 s->IndentMore();
Greg Clayton54e7afa2010-07-09 20:39:50 +0000565 for (size_t i = 0; i < num_locations; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +0000566 {
567 BreakpointLocation *loc = GetLocationAtIndex(i).get();
568 loc->GetDescription(s, level);
569 s->EOL();
570 }
571 s->IndentLess();
Chris Lattner24943d22010-06-08 16:52:24 +0000572 }
573}
574
Jim Ingham5f4f3272012-02-09 01:49:26 +0000575void
576Breakpoint::GetResolverDescription (Stream *s)
577{
578 if (m_resolver_sp)
579 m_resolver_sp->GetDescription (s);
580}
581
582
583bool
584Breakpoint::GetMatchingFileLine (const ConstString &filename, uint32_t line_number, BreakpointLocationCollection &loc_coll)
585{
586 // TODO: To be correct, this method needs to fill the breakpoint location collection
587 // with the location IDs which match the filename and line_number.
588 //
589
590 if (m_resolver_sp)
591 {
592 BreakpointResolverFileLine *resolverFileLine = dyn_cast<BreakpointResolverFileLine>(m_resolver_sp.get());
593 if (resolverFileLine &&
594 resolverFileLine->m_file_spec.GetFilename() == filename &&
595 resolverFileLine->m_line_number == line_number)
596 {
597 return true;
598 }
599 }
600 return false;
601}
602
603void
604Breakpoint::GetFilterDescription (Stream *s)
605{
606 m_filter_sp->GetDescription (s);
607}
608
609void
610Breakpoint::SendBreakpointChangedEvent (lldb::BreakpointEventType eventKind)
611{
612 if (!m_being_created
613 && !IsInternal()
614 && GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
615 {
616 BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind, shared_from_this());
617
618 GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
619 }
620}
621
622void
623Breakpoint::SendBreakpointChangedEvent (BreakpointEventData *data)
624{
625
626 if (data == NULL)
627 return;
628
629 if (!m_being_created
630 && !IsInternal()
631 && GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
632 GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
633 else
634 delete data;
635}
636
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000637Breakpoint::BreakpointEventData::BreakpointEventData (BreakpointEventType sub_type,
Jim Ingham28e23862012-02-08 05:23:15 +0000638 const BreakpointSP &new_breakpoint_sp) :
Chris Lattner24943d22010-06-08 16:52:24 +0000639 EventData (),
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000640 m_breakpoint_event (sub_type),
Chris Lattner24943d22010-06-08 16:52:24 +0000641 m_new_breakpoint_sp (new_breakpoint_sp)
642{
643}
644
645Breakpoint::BreakpointEventData::~BreakpointEventData ()
646{
647}
648
649const ConstString &
650Breakpoint::BreakpointEventData::GetFlavorString ()
651{
652 static ConstString g_flavor ("Breakpoint::BreakpointEventData");
653 return g_flavor;
654}
655
656const ConstString &
657Breakpoint::BreakpointEventData::GetFlavor () const
658{
659 return BreakpointEventData::GetFlavorString ();
660}
661
662
663BreakpointSP &
664Breakpoint::BreakpointEventData::GetBreakpoint ()
665{
666 return m_new_breakpoint_sp;
667}
668
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000669BreakpointEventType
670Breakpoint::BreakpointEventData::GetBreakpointEventType () const
Chris Lattner24943d22010-06-08 16:52:24 +0000671{
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000672 return m_breakpoint_event;
Chris Lattner24943d22010-06-08 16:52:24 +0000673}
674
675void
676Breakpoint::BreakpointEventData::Dump (Stream *s) const
677{
678}
679
Jim Ingham28e23862012-02-08 05:23:15 +0000680const Breakpoint::BreakpointEventData *
681Breakpoint::BreakpointEventData::GetEventDataFromEvent (const Event *event)
Chris Lattner24943d22010-06-08 16:52:24 +0000682{
Jim Ingham28e23862012-02-08 05:23:15 +0000683 if (event)
Chris Lattner24943d22010-06-08 16:52:24 +0000684 {
Jim Ingham28e23862012-02-08 05:23:15 +0000685 const EventData *event_data = event->GetData();
Chris Lattner24943d22010-06-08 16:52:24 +0000686 if (event_data && event_data->GetFlavor() == BreakpointEventData::GetFlavorString())
Jim Ingham28e23862012-02-08 05:23:15 +0000687 return static_cast <const BreakpointEventData *> (event->GetData());
Chris Lattner24943d22010-06-08 16:52:24 +0000688 }
689 return NULL;
690}
691
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000692BreakpointEventType
693Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (const EventSP &event_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000694{
Jim Ingham28e23862012-02-08 05:23:15 +0000695 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
Chris Lattner24943d22010-06-08 16:52:24 +0000696
697 if (data == NULL)
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000698 return eBreakpointEventTypeInvalidType;
Chris Lattner24943d22010-06-08 16:52:24 +0000699 else
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000700 return data->GetBreakpointEventType();
Chris Lattner24943d22010-06-08 16:52:24 +0000701}
702
703BreakpointSP
704Breakpoint::BreakpointEventData::GetBreakpointFromEvent (const EventSP &event_sp)
705{
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000706 BreakpointSP bp_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000707
Jim Ingham28e23862012-02-08 05:23:15 +0000708 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000709 if (data)
Jim Ingham28e23862012-02-08 05:23:15 +0000710 bp_sp = data->m_new_breakpoint_sp;
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000711
712 return bp_sp;
713}
714
Jim Ingham28e23862012-02-08 05:23:15 +0000715uint32_t
716Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent (const EventSP &event_sp)
717{
718 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
719 if (data)
720 return data->m_locations.GetSize();
721
722 return 0;
723}
724
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000725lldb::BreakpointLocationSP
726Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (const lldb::EventSP &event_sp, uint32_t bp_loc_idx)
727{
728 lldb::BreakpointLocationSP bp_loc_sp;
729
Jim Ingham28e23862012-02-08 05:23:15 +0000730 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000731 if (data)
Chris Lattner24943d22010-06-08 16:52:24 +0000732 {
Jim Ingham28e23862012-02-08 05:23:15 +0000733 bp_loc_sp = data->m_locations.GetByIndex(bp_loc_idx);
Chris Lattner24943d22010-06-08 16:52:24 +0000734 }
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000735
736 return bp_loc_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000737}