blob: 0b88625fe9e596933f6780d4f6b1808550c7e44c [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"
Greg Clayton49ce8962012-08-29 21:13:06 +000025#include "lldb/Core/Section.h"
Chris Lattner24943d22010-06-08 16:52:24 +000026#include "lldb/Core/Stream.h"
27#include "lldb/Core/StreamString.h"
28#include "lldb/Symbol/SymbolContext.h"
29#include "lldb/Target/Target.h"
Jim Ingham3c7b5b92010-06-16 02:00:15 +000030#include "lldb/Target/ThreadSpec.h"
Chris Lattner24943d22010-06-08 16:52:24 +000031#include "lldb/lldb-private-log.h"
Johnny Chena62ad7c2010-10-28 17:27:46 +000032#include "llvm/Support/Casting.h"
Chris Lattner24943d22010-06-08 16:52:24 +000033
34using namespace lldb;
35using namespace lldb_private;
Johnny Chena62ad7c2010-10-28 17:27:46 +000036using namespace llvm;
Chris Lattner24943d22010-06-08 16:52:24 +000037
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) :
Jim Ingham28e23862012-02-08 05:23:15 +000049 m_being_created(true),
Chris Lattner24943d22010-06-08 16:52:24 +000050 m_target (target),
51 m_filter_sp (filter_sp),
52 m_resolver_sp (resolver_sp),
53 m_options (),
Jim Ingham28e23862012-02-08 05:23:15 +000054 m_locations (*this)
Chris Lattner24943d22010-06-08 16:52:24 +000055{
Jim Ingham28e23862012-02-08 05:23:15 +000056 m_being_created = false;
Chris Lattner24943d22010-06-08 16:52:24 +000057}
58
59//----------------------------------------------------------------------
60// Destructor
61//----------------------------------------------------------------------
62Breakpoint::~Breakpoint()
63{
64}
65
66bool
67Breakpoint::IsInternal () const
68{
69 return LLDB_BREAK_ID_IS_INTERNAL(m_bid);
70}
71
72
73
74Target&
75Breakpoint::GetTarget ()
76{
77 return m_target;
78}
79
80const Target&
81Breakpoint::GetTarget () const
82{
83 return m_target;
84}
85
86BreakpointLocationSP
Greg Clayton19a1ab82011-02-05 00:38:04 +000087Breakpoint::AddLocation (const Address &addr, bool *new_location)
Chris Lattner24943d22010-06-08 16:52:24 +000088{
Jim Ingham28e23862012-02-08 05:23:15 +000089 return m_locations.AddLocation (addr, new_location);
Chris Lattner24943d22010-06-08 16:52:24 +000090}
91
92BreakpointLocationSP
Greg Clayton19a1ab82011-02-05 00:38:04 +000093Breakpoint::FindLocationByAddress (const Address &addr)
Chris Lattner24943d22010-06-08 16:52:24 +000094{
95 return m_locations.FindByAddress(addr);
96}
97
98break_id_t
Greg Clayton19a1ab82011-02-05 00:38:04 +000099Breakpoint::FindLocationIDByAddress (const Address &addr)
Chris Lattner24943d22010-06-08 16:52:24 +0000100{
101 return m_locations.FindIDByAddress(addr);
102}
103
104BreakpointLocationSP
105Breakpoint::FindLocationByID (break_id_t bp_loc_id)
106{
107 return m_locations.FindByID(bp_loc_id);
108}
109
110BreakpointLocationSP
111Breakpoint::GetLocationAtIndex (uint32_t index)
112{
113 return m_locations.GetByIndex(index);
114}
115
Chris Lattner24943d22010-06-08 16:52:24 +0000116// For each of the overall options we need to decide how they propagate to
117// the location options. This will determine the precedence of options on
Johnny Chen736f0d62012-01-25 23:08:23 +0000118// the breakpoint vs. its locations.
Chris Lattner24943d22010-06-08 16:52:24 +0000119
120// Disable at the breakpoint level should override the location settings.
121// That way you can conveniently turn off a whole breakpoint without messing
122// up the individual settings.
123
124void
125Breakpoint::SetEnabled (bool enable)
126{
Jim Ingham28e23862012-02-08 05:23:15 +0000127 if (enable == m_options.IsEnabled())
128 return;
129
Chris Lattner24943d22010-06-08 16:52:24 +0000130 m_options.SetEnabled(enable);
131 if (enable)
132 m_locations.ResolveAllBreakpointSites();
133 else
134 m_locations.ClearAllBreakpointSites();
Jim Ingham28e23862012-02-08 05:23:15 +0000135
136 SendBreakpointChangedEvent (enable ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled);
137
Chris Lattner24943d22010-06-08 16:52:24 +0000138}
139
140bool
141Breakpoint::IsEnabled ()
142{
143 return m_options.IsEnabled();
144}
145
146void
Greg Clayton54e7afa2010-07-09 20:39:50 +0000147Breakpoint::SetIgnoreCount (uint32_t n)
Chris Lattner24943d22010-06-08 16:52:24 +0000148{
Jim Ingham28e23862012-02-08 05:23:15 +0000149 if (m_options.GetIgnoreCount() == n)
150 return;
151
Chris Lattner24943d22010-06-08 16:52:24 +0000152 m_options.SetIgnoreCount(n);
Jim Ingham28e23862012-02-08 05:23:15 +0000153 SendBreakpointChangedEvent (eBreakpointEventTypeIgnoreChanged);
Chris Lattner24943d22010-06-08 16:52:24 +0000154}
155
Jim Inghamfdbd10a2012-06-26 22:27:55 +0000156void
157Breakpoint::DecrementIgnoreCount ()
158{
159 uint32_t ignore = m_options.GetIgnoreCount();
160 if (ignore != 0)
161 m_options.SetIgnoreCount(ignore - 1);
162}
163
Greg Clayton54e7afa2010-07-09 20:39:50 +0000164uint32_t
Chris Lattner24943d22010-06-08 16:52:24 +0000165Breakpoint::GetIgnoreCount () const
166{
167 return m_options.GetIgnoreCount();
168}
169
Jim Inghamfdbd10a2012-06-26 22:27:55 +0000170bool
171Breakpoint::IgnoreCountShouldStop ()
172{
173 uint32_t ignore = GetIgnoreCount();
174 if (ignore != 0)
175 {
176 // When we get here we know the location that caused the stop doesn't have an ignore count,
177 // since by contract we call it first... So we don't have to find & decrement it, we only have
178 // to decrement our own ignore count.
179 DecrementIgnoreCount();
180 return false;
181 }
182 else
183 return true;
184}
185
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000186uint32_t
187Breakpoint::GetHitCount () const
188{
189 return m_locations.GetHitCount();
190}
191
Jim Ingham2753a022012-10-05 19:16:31 +0000192bool
193Breakpoint::IsOneShot () const
194{
195 return m_options.IsOneShot();
196}
197
198void
199Breakpoint::SetOneShot (bool one_shot)
200{
201 m_options.SetOneShot (one_shot);
202}
203
Chris Lattner24943d22010-06-08 16:52:24 +0000204void
205Breakpoint::SetThreadID (lldb::tid_t thread_id)
206{
Jim Ingham28e23862012-02-08 05:23:15 +0000207 if (m_options.GetThreadSpec()->GetTID() == thread_id)
208 return;
209
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000210 m_options.GetThreadSpec()->SetTID(thread_id);
Jim Ingham28e23862012-02-08 05:23:15 +0000211 SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged);
Chris Lattner24943d22010-06-08 16:52:24 +0000212}
213
214lldb::tid_t
Jim Ingham28e23862012-02-08 05:23:15 +0000215Breakpoint::GetThreadID () const
Chris Lattner24943d22010-06-08 16:52:24 +0000216{
Jim Ingham28e23862012-02-08 05:23:15 +0000217 if (m_options.GetThreadSpecNoCreate() == NULL)
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000218 return LLDB_INVALID_THREAD_ID;
219 else
Jim Ingham28e23862012-02-08 05:23:15 +0000220 return m_options.GetThreadSpecNoCreate()->GetTID();
221}
222
223void
224Breakpoint::SetThreadIndex (uint32_t index)
225{
226 if (m_options.GetThreadSpec()->GetIndex() == index)
227 return;
228
229 m_options.GetThreadSpec()->SetIndex(index);
230 SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged);
231}
232
233uint32_t
234Breakpoint::GetThreadIndex() const
235{
236 if (m_options.GetThreadSpecNoCreate() == NULL)
237 return 0;
238 else
239 return m_options.GetThreadSpecNoCreate()->GetIndex();
240}
241
242void
243Breakpoint::SetThreadName (const char *thread_name)
244{
245 if (::strcmp (m_options.GetThreadSpec()->GetName(), thread_name) == 0)
246 return;
247
248 m_options.GetThreadSpec()->SetName (thread_name);
249 SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged);
250}
251
252const char *
253Breakpoint::GetThreadName () const
254{
255 if (m_options.GetThreadSpecNoCreate() == NULL)
256 return NULL;
257 else
258 return m_options.GetThreadSpecNoCreate()->GetName();
259}
260
261void
262Breakpoint::SetQueueName (const char *queue_name)
263{
264 if (::strcmp (m_options.GetThreadSpec()->GetQueueName(), queue_name) == 0)
265 return;
266
267 m_options.GetThreadSpec()->SetQueueName (queue_name);
268 SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged);
269}
270
271const char *
272Breakpoint::GetQueueName () const
273{
274 if (m_options.GetThreadSpecNoCreate() == NULL)
275 return NULL;
276 else
277 return m_options.GetThreadSpecNoCreate()->GetQueueName();
Chris Lattner24943d22010-06-08 16:52:24 +0000278}
279
Jim Inghamd1686902010-10-14 23:45:03 +0000280void
281Breakpoint::SetCondition (const char *condition)
282{
283 m_options.SetCondition (condition);
Jim Ingham28e23862012-02-08 05:23:15 +0000284 SendBreakpointChangedEvent (eBreakpointEventTypeConditionChanged);
Jim Inghamd1686902010-10-14 23:45:03 +0000285}
286
Jim Inghamd1686902010-10-14 23:45:03 +0000287const char *
Jim Inghamac354422011-06-15 21:16:00 +0000288Breakpoint::GetConditionText () const
Jim Inghamd1686902010-10-14 23:45:03 +0000289{
290 return m_options.GetConditionText();
291}
292
Chris Lattner24943d22010-06-08 16:52:24 +0000293// This function is used when "baton" doesn't need to be freed
294void
295Breakpoint::SetCallback (BreakpointHitCallback callback, void *baton, bool is_synchronous)
296{
297 // The default "Baton" class will keep a copy of "baton" and won't free
298 // or delete it when it goes goes out of scope.
299 m_options.SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous);
Jim Ingham28e23862012-02-08 05:23:15 +0000300
301 SendBreakpointChangedEvent (eBreakpointEventTypeCommandChanged);
Chris Lattner24943d22010-06-08 16:52:24 +0000302}
303
304// This function is used when a baton needs to be freed and therefore is
305// contained in a "Baton" subclass.
306void
307Breakpoint::SetCallback (BreakpointHitCallback callback, const BatonSP &callback_baton_sp, bool is_synchronous)
308{
309 m_options.SetCallback(callback, callback_baton_sp, is_synchronous);
310}
311
312void
313Breakpoint::ClearCallback ()
314{
315 m_options.ClearCallback ();
316}
317
318bool
319Breakpoint::InvokeCallback (StoppointCallbackContext *context, break_id_t bp_loc_id)
320{
321 return m_options.InvokeCallback (context, GetID(), bp_loc_id);
322}
323
324BreakpointOptions *
325Breakpoint::GetOptions ()
326{
327 return &m_options;
328}
329
330void
331Breakpoint::ResolveBreakpoint ()
332{
333 if (m_resolver_sp)
334 m_resolver_sp->ResolveBreakpoint(*m_filter_sp);
335}
336
337void
338Breakpoint::ResolveBreakpointInModules (ModuleList &module_list)
339{
340 if (m_resolver_sp)
341 m_resolver_sp->ResolveBreakpointInModules(*m_filter_sp, module_list);
342}
343
344void
345Breakpoint::ClearAllBreakpointSites ()
346{
347 m_locations.ClearAllBreakpointSites();
348}
349
350//----------------------------------------------------------------------
351// ModulesChanged: Pass in a list of new modules, and
352//----------------------------------------------------------------------
353
354void
Jim Ingham03e5e512012-05-17 18:38:42 +0000355Breakpoint::ModulesChanged (ModuleList &module_list, bool load, bool delete_locations)
Chris Lattner24943d22010-06-08 16:52:24 +0000356{
Jim Ingham93367902012-05-30 02:19:25 +0000357 Mutex::Locker modules_mutex(module_list.GetMutex());
Chris Lattner24943d22010-06-08 16:52:24 +0000358 if (load)
359 {
360 // The logic for handling new modules is:
361 // 1) If the filter rejects this module, then skip it.
362 // 2) Run through the current location list and if there are any locations
363 // for that module, we mark the module as "seen" and we don't try to re-resolve
364 // breakpoint locations for that module.
365 // However, we do add breakpoint sites to these locations if needed.
366 // 3) If we don't see this module in our breakpoint location list, call ResolveInModules.
367
368 ModuleList new_modules; // We'll stuff the "unseen" modules in this list, and then resolve
Greg Clayton19a1ab82011-02-05 00:38:04 +0000369 // them after the locations pass. Have to do it this way because
370 // resolving breakpoints will add new locations potentially.
371
372 const size_t num_locs = m_locations.GetSize();
Jim Ingham93367902012-05-30 02:19:25 +0000373 size_t num_modules = module_list.GetSize();
374 for (size_t i = 0; i < num_modules; i++)
Chris Lattner24943d22010-06-08 16:52:24 +0000375 {
376 bool seen = false;
Jim Ingham93367902012-05-30 02:19:25 +0000377 ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (i));
Chris Lattner24943d22010-06-08 16:52:24 +0000378 if (!m_filter_sp->ModulePasses (module_sp))
379 continue;
380
Greg Clayton19a1ab82011-02-05 00:38:04 +0000381 for (size_t loc_idx = 0; loc_idx < num_locs; loc_idx++)
Chris Lattner24943d22010-06-08 16:52:24 +0000382 {
Greg Clayton7b9fcc02010-12-06 23:51:26 +0000383 BreakpointLocationSP break_loc = m_locations.GetByIndex(loc_idx);
Jim Ingham1de036b2010-10-20 03:36:33 +0000384 if (!break_loc->IsEnabled())
385 continue;
Greg Clayton3508c382012-02-24 01:59:29 +0000386 SectionSP section_sp (break_loc->GetAddress().GetSection());
387 if (!section_sp || section_sp->GetModule() == module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000388 {
389 if (!seen)
390 seen = true;
391
392 if (!break_loc->ResolveBreakpointSite())
393 {
Greg Claytone005f2c2010-11-06 01:53:30 +0000394 LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
Chris Lattner24943d22010-06-08 16:52:24 +0000395 if (log)
396 log->Printf ("Warning: could not set breakpoint site for breakpoint location %d of breakpoint %d.\n",
397 break_loc->GetID(), GetID());
398 }
399 }
400 }
401
402 if (!seen)
Greg Claytonab429022010-12-12 21:03:32 +0000403 new_modules.AppendIfNeeded (module_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000404
405 }
Jim Ingham28e23862012-02-08 05:23:15 +0000406
Chris Lattner24943d22010-06-08 16:52:24 +0000407 if (new_modules.GetSize() > 0)
408 {
Jim Ingham28e23862012-02-08 05:23:15 +0000409 // If this is not an internal breakpoint, set up to record the new locations, then dispatch
410 // an event with the new locations.
411 if (!IsInternal())
412 {
413 BreakpointEventData *new_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsAdded,
414 shared_from_this());
415
416 m_locations.StartRecordingNewLocations(new_locations_event->GetBreakpointLocationCollection());
417
418 ResolveBreakpointInModules(new_modules);
419
420 m_locations.StopRecordingNewLocations();
421 if (new_locations_event->GetBreakpointLocationCollection().GetSize() != 0)
422 {
423 SendBreakpointChangedEvent (new_locations_event);
424 }
425 else
426 delete new_locations_event;
427 }
428 else
429 ResolveBreakpointInModules(new_modules);
430
Chris Lattner24943d22010-06-08 16:52:24 +0000431 }
432 }
433 else
434 {
435 // Go through the currently set locations and if any have breakpoints in
Jim Ingham03e5e512012-05-17 18:38:42 +0000436 // the module list, then remove their breakpoint sites, and their locations if asked to.
Chris Lattner24943d22010-06-08 16:52:24 +0000437
Jim Ingham28e23862012-02-08 05:23:15 +0000438 BreakpointEventData *removed_locations_event;
439 if (!IsInternal())
440 removed_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsRemoved,
441 shared_from_this());
442 else
443 removed_locations_event = NULL;
Jim Ingham93367902012-05-30 02:19:25 +0000444
445 size_t num_modules = module_list.GetSize();
446 for (size_t i = 0; i < num_modules; i++)
Chris Lattner24943d22010-06-08 16:52:24 +0000447 {
Jim Ingham93367902012-05-30 02:19:25 +0000448 ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (i));
Greg Clayton7b9fcc02010-12-06 23:51:26 +0000449 if (m_filter_sp->ModulePasses (module_sp))
Chris Lattner24943d22010-06-08 16:52:24 +0000450 {
Greg Clayton3508c382012-02-24 01:59:29 +0000451 size_t loc_idx = 0;
Jim Ingham03e5e512012-05-17 18:38:42 +0000452 size_t num_locations = m_locations.GetSize();
453 BreakpointLocationCollection locations_to_remove;
454 for (loc_idx = 0; loc_idx < num_locations; loc_idx++)
Chris Lattner24943d22010-06-08 16:52:24 +0000455 {
Greg Clayton3508c382012-02-24 01:59:29 +0000456 BreakpointLocationSP break_loc_sp (m_locations.GetByIndex(loc_idx));
457 SectionSP section_sp (break_loc_sp->GetAddress().GetSection());
458 if (section_sp && section_sp->GetModule() == module_sp)
Greg Clayton7b9fcc02010-12-06 23:51:26 +0000459 {
460 // Remove this breakpoint since the shared library is
461 // unloaded, but keep the breakpoint location around
462 // so we always get complete hit count and breakpoint
463 // lifetime info
Greg Clayton3508c382012-02-24 01:59:29 +0000464 break_loc_sp->ClearBreakpointSite();
Jim Ingham28e23862012-02-08 05:23:15 +0000465 if (removed_locations_event)
466 {
Greg Clayton3508c382012-02-24 01:59:29 +0000467 removed_locations_event->GetBreakpointLocationCollection().Add(break_loc_sp);
Jim Ingham28e23862012-02-08 05:23:15 +0000468 }
Jim Ingham03e5e512012-05-17 18:38:42 +0000469 if (delete_locations)
470 locations_to_remove.Add (break_loc_sp);
471
Greg Clayton7b9fcc02010-12-06 23:51:26 +0000472 }
Jim Ingham03e5e512012-05-17 18:38:42 +0000473 }
474
475 if (delete_locations)
476 {
477 size_t num_locations_to_remove = locations_to_remove.GetSize();
478 for (loc_idx = 0; loc_idx < num_locations_to_remove; loc_idx++)
479 m_locations.RemoveLocation (locations_to_remove.GetByIndex(loc_idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000480 }
Chris Lattner24943d22010-06-08 16:52:24 +0000481 }
482 }
Jim Ingham28e23862012-02-08 05:23:15 +0000483 SendBreakpointChangedEvent (removed_locations_event);
Chris Lattner24943d22010-06-08 16:52:24 +0000484 }
485}
486
487void
Jim Ingham03e5e512012-05-17 18:38:42 +0000488Breakpoint::ModuleReplaced (ModuleSP old_module_sp, ModuleSP new_module_sp)
489{
490 ModuleList temp_list;
491 temp_list.Append (new_module_sp);
492 ModulesChanged (temp_list, true);
493
494 // TO DO: For now I'm just adding locations for the new module and removing the
495 // breakpoint locations that were in the old module.
496 // We should really go find the ones that are in the new module & if we can determine that they are "equivalent"
497 // carry over the options from the old location to the new.
498
499 temp_list.Clear();
500 temp_list.Append (old_module_sp);
501 ModulesChanged (temp_list, false, true);
502}
503
504void
Chris Lattner24943d22010-06-08 16:52:24 +0000505Breakpoint::Dump (Stream *)
506{
507}
508
509size_t
510Breakpoint::GetNumResolvedLocations() const
511{
512 // Return the number of breakpoints that are actually resolved and set
513 // down in the inferior process.
514 return m_locations.GetNumResolvedLocations();
515}
516
517size_t
518Breakpoint::GetNumLocations() const
519{
520 return m_locations.GetSize();
521}
522
523void
524Breakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_locations)
525{
Greg Clayton54e7afa2010-07-09 20:39:50 +0000526 const size_t num_locations = GetNumLocations ();
527 const size_t num_resolved_locations = GetNumResolvedLocations ();
Chris Lattner24943d22010-06-08 16:52:24 +0000528
Jim Ingham4f61ba92012-09-22 00:04:04 +0000529 assert (s != NULL);
530
531
532
533 // They just made the breakpoint, they don't need to be told HOW they made it...
534 // Also, we'll print the breakpoint number differently depending on whether there is 1 or more locations.
535 if (level != eDescriptionLevelInitial)
536 {
537 s->Printf("%i: ", GetID());
538 GetResolverDescription (s);
539 GetFilterDescription (s);
540 }
541
Chris Lattner24943d22010-06-08 16:52:24 +0000542 switch (level)
543 {
544 case lldb::eDescriptionLevelBrief:
545 case lldb::eDescriptionLevelFull:
546 if (num_locations > 0)
547 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000548 s->Printf(", locations = %" PRIu64, (uint64_t)num_locations);
Chris Lattner24943d22010-06-08 16:52:24 +0000549 if (num_resolved_locations > 0)
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000550 s->Printf(", resolved = %" PRIu64, (uint64_t)num_resolved_locations);
Chris Lattner24943d22010-06-08 16:52:24 +0000551 }
552 else
553 {
Jim Ingham4722b102012-03-06 00:37:27 +0000554 // Don't print the pending notification for exception resolvers since we don't generally
555 // know how to set them until the target is run.
556 if (m_resolver_sp->getResolverID() != BreakpointResolver::ExceptionResolver)
557 s->Printf(", locations = 0 (pending)");
Chris Lattner24943d22010-06-08 16:52:24 +0000558 }
559
Jim Ingham649492b2010-06-18 01:00:58 +0000560 GetOptions()->GetDescription(s, level);
561
Chris Lattner24943d22010-06-08 16:52:24 +0000562 if (level == lldb::eDescriptionLevelFull)
563 {
Jim Ingham649492b2010-06-18 01:00:58 +0000564 s->IndentLess();
565 s->EOL();
Chris Lattner24943d22010-06-08 16:52:24 +0000566 }
567 break;
Jim Ingham4f61ba92012-09-22 00:04:04 +0000568
569 case lldb::eDescriptionLevelInitial:
570 s->Printf ("Breakpoint %i: ", GetID());
571 if (num_locations == 0)
572 {
573 s->Printf ("no locations (pending).");
574 }
575 else if (num_locations == 1)
576 {
577 // If there is one location only, we'll just print that location information. But don't do this if
578 // show locations is true, then that will be handled below.
579 if (show_locations == false)
580 {
581 GetLocationAtIndex(0)->GetDescription(s, level);
582 }
583 else
584 {
585 s->Printf ("%zd locations.", num_locations);
586 }
587 }
588 else
589 {
590 s->Printf ("%zd locations.", num_locations);
591 }
592 s->EOL();
593 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000594 case lldb::eDescriptionLevelVerbose:
595 // Verbose mode does a debug dump of the breakpoint
596 Dump (s);
Jim Ingham649492b2010-06-18 01:00:58 +0000597 s->EOL ();
Greg Claytonb1888f22011-03-19 01:12:21 +0000598 //s->Indent();
Jim Ingham649492b2010-06-18 01:00:58 +0000599 GetOptions()->GetDescription(s, level);
Chris Lattner24943d22010-06-08 16:52:24 +0000600 break;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000601
602 default:
603 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000604 }
605
Jim Ingham1cd466f2011-05-14 01:11:02 +0000606 // The brief description is just the location name (1.2 or whatever). That's pointless to
607 // show in the breakpoint's description, so suppress it.
608 if (show_locations && level != lldb::eDescriptionLevelBrief)
Chris Lattner24943d22010-06-08 16:52:24 +0000609 {
Chris Lattner24943d22010-06-08 16:52:24 +0000610 s->IndentMore();
Greg Clayton54e7afa2010-07-09 20:39:50 +0000611 for (size_t i = 0; i < num_locations; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +0000612 {
613 BreakpointLocation *loc = GetLocationAtIndex(i).get();
614 loc->GetDescription(s, level);
615 s->EOL();
616 }
617 s->IndentLess();
Chris Lattner24943d22010-06-08 16:52:24 +0000618 }
619}
620
Jim Ingham5f4f3272012-02-09 01:49:26 +0000621void
622Breakpoint::GetResolverDescription (Stream *s)
623{
624 if (m_resolver_sp)
625 m_resolver_sp->GetDescription (s);
626}
627
628
629bool
630Breakpoint::GetMatchingFileLine (const ConstString &filename, uint32_t line_number, BreakpointLocationCollection &loc_coll)
631{
632 // TODO: To be correct, this method needs to fill the breakpoint location collection
633 // with the location IDs which match the filename and line_number.
634 //
635
636 if (m_resolver_sp)
637 {
638 BreakpointResolverFileLine *resolverFileLine = dyn_cast<BreakpointResolverFileLine>(m_resolver_sp.get());
639 if (resolverFileLine &&
640 resolverFileLine->m_file_spec.GetFilename() == filename &&
641 resolverFileLine->m_line_number == line_number)
642 {
643 return true;
644 }
645 }
646 return false;
647}
648
649void
650Breakpoint::GetFilterDescription (Stream *s)
651{
652 m_filter_sp->GetDescription (s);
653}
654
655void
656Breakpoint::SendBreakpointChangedEvent (lldb::BreakpointEventType eventKind)
657{
658 if (!m_being_created
659 && !IsInternal()
660 && GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
661 {
662 BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind, shared_from_this());
663
664 GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
665 }
666}
667
668void
669Breakpoint::SendBreakpointChangedEvent (BreakpointEventData *data)
670{
671
672 if (data == NULL)
673 return;
674
675 if (!m_being_created
676 && !IsInternal()
677 && GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
678 GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
679 else
680 delete data;
681}
682
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000683Breakpoint::BreakpointEventData::BreakpointEventData (BreakpointEventType sub_type,
Jim Ingham28e23862012-02-08 05:23:15 +0000684 const BreakpointSP &new_breakpoint_sp) :
Chris Lattner24943d22010-06-08 16:52:24 +0000685 EventData (),
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000686 m_breakpoint_event (sub_type),
Chris Lattner24943d22010-06-08 16:52:24 +0000687 m_new_breakpoint_sp (new_breakpoint_sp)
688{
689}
690
691Breakpoint::BreakpointEventData::~BreakpointEventData ()
692{
693}
694
695const ConstString &
696Breakpoint::BreakpointEventData::GetFlavorString ()
697{
698 static ConstString g_flavor ("Breakpoint::BreakpointEventData");
699 return g_flavor;
700}
701
702const ConstString &
703Breakpoint::BreakpointEventData::GetFlavor () const
704{
705 return BreakpointEventData::GetFlavorString ();
706}
707
708
709BreakpointSP &
710Breakpoint::BreakpointEventData::GetBreakpoint ()
711{
712 return m_new_breakpoint_sp;
713}
714
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000715BreakpointEventType
716Breakpoint::BreakpointEventData::GetBreakpointEventType () const
Chris Lattner24943d22010-06-08 16:52:24 +0000717{
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000718 return m_breakpoint_event;
Chris Lattner24943d22010-06-08 16:52:24 +0000719}
720
721void
722Breakpoint::BreakpointEventData::Dump (Stream *s) const
723{
724}
725
Jim Ingham28e23862012-02-08 05:23:15 +0000726const Breakpoint::BreakpointEventData *
727Breakpoint::BreakpointEventData::GetEventDataFromEvent (const Event *event)
Chris Lattner24943d22010-06-08 16:52:24 +0000728{
Jim Ingham28e23862012-02-08 05:23:15 +0000729 if (event)
Chris Lattner24943d22010-06-08 16:52:24 +0000730 {
Jim Ingham28e23862012-02-08 05:23:15 +0000731 const EventData *event_data = event->GetData();
Chris Lattner24943d22010-06-08 16:52:24 +0000732 if (event_data && event_data->GetFlavor() == BreakpointEventData::GetFlavorString())
Jim Ingham28e23862012-02-08 05:23:15 +0000733 return static_cast <const BreakpointEventData *> (event->GetData());
Chris Lattner24943d22010-06-08 16:52:24 +0000734 }
735 return NULL;
736}
737
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000738BreakpointEventType
739Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (const EventSP &event_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000740{
Jim Ingham28e23862012-02-08 05:23:15 +0000741 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
Chris Lattner24943d22010-06-08 16:52:24 +0000742
743 if (data == NULL)
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000744 return eBreakpointEventTypeInvalidType;
Chris Lattner24943d22010-06-08 16:52:24 +0000745 else
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000746 return data->GetBreakpointEventType();
Chris Lattner24943d22010-06-08 16:52:24 +0000747}
748
749BreakpointSP
750Breakpoint::BreakpointEventData::GetBreakpointFromEvent (const EventSP &event_sp)
751{
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000752 BreakpointSP bp_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000753
Jim Ingham28e23862012-02-08 05:23:15 +0000754 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000755 if (data)
Jim Ingham28e23862012-02-08 05:23:15 +0000756 bp_sp = data->m_new_breakpoint_sp;
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000757
758 return bp_sp;
759}
760
Jim Ingham28e23862012-02-08 05:23:15 +0000761uint32_t
762Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent (const EventSP &event_sp)
763{
764 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
765 if (data)
766 return data->m_locations.GetSize();
767
768 return 0;
769}
770
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000771lldb::BreakpointLocationSP
772Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (const lldb::EventSP &event_sp, uint32_t bp_loc_idx)
773{
774 lldb::BreakpointLocationSP bp_loc_sp;
775
Jim Ingham28e23862012-02-08 05:23:15 +0000776 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000777 if (data)
Chris Lattner24943d22010-06-08 16:52:24 +0000778 {
Jim Ingham28e23862012-02-08 05:23:15 +0000779 bp_loc_sp = data->m_locations.GetByIndex(bp_loc_idx);
Chris Lattner24943d22010-06-08 16:52:24 +0000780 }
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000781
782 return bp_loc_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000783}