blob: e90a827fdba998c4003fc2bcd3ca8416f5fb0bbd [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
Chris Lattner24943d22010-06-08 16:52:24 +0000192void
193Breakpoint::SetThreadID (lldb::tid_t thread_id)
194{
Jim Ingham28e23862012-02-08 05:23:15 +0000195 if (m_options.GetThreadSpec()->GetTID() == thread_id)
196 return;
197
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000198 m_options.GetThreadSpec()->SetTID(thread_id);
Jim Ingham28e23862012-02-08 05:23:15 +0000199 SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged);
Chris Lattner24943d22010-06-08 16:52:24 +0000200}
201
202lldb::tid_t
Jim Ingham28e23862012-02-08 05:23:15 +0000203Breakpoint::GetThreadID () const
Chris Lattner24943d22010-06-08 16:52:24 +0000204{
Jim Ingham28e23862012-02-08 05:23:15 +0000205 if (m_options.GetThreadSpecNoCreate() == NULL)
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000206 return LLDB_INVALID_THREAD_ID;
207 else
Jim Ingham28e23862012-02-08 05:23:15 +0000208 return m_options.GetThreadSpecNoCreate()->GetTID();
209}
210
211void
212Breakpoint::SetThreadIndex (uint32_t index)
213{
214 if (m_options.GetThreadSpec()->GetIndex() == index)
215 return;
216
217 m_options.GetThreadSpec()->SetIndex(index);
218 SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged);
219}
220
221uint32_t
222Breakpoint::GetThreadIndex() const
223{
224 if (m_options.GetThreadSpecNoCreate() == NULL)
225 return 0;
226 else
227 return m_options.GetThreadSpecNoCreate()->GetIndex();
228}
229
230void
231Breakpoint::SetThreadName (const char *thread_name)
232{
233 if (::strcmp (m_options.GetThreadSpec()->GetName(), thread_name) == 0)
234 return;
235
236 m_options.GetThreadSpec()->SetName (thread_name);
237 SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged);
238}
239
240const char *
241Breakpoint::GetThreadName () const
242{
243 if (m_options.GetThreadSpecNoCreate() == NULL)
244 return NULL;
245 else
246 return m_options.GetThreadSpecNoCreate()->GetName();
247}
248
249void
250Breakpoint::SetQueueName (const char *queue_name)
251{
252 if (::strcmp (m_options.GetThreadSpec()->GetQueueName(), queue_name) == 0)
253 return;
254
255 m_options.GetThreadSpec()->SetQueueName (queue_name);
256 SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged);
257}
258
259const char *
260Breakpoint::GetQueueName () const
261{
262 if (m_options.GetThreadSpecNoCreate() == NULL)
263 return NULL;
264 else
265 return m_options.GetThreadSpecNoCreate()->GetQueueName();
Chris Lattner24943d22010-06-08 16:52:24 +0000266}
267
Jim Inghamd1686902010-10-14 23:45:03 +0000268void
269Breakpoint::SetCondition (const char *condition)
270{
271 m_options.SetCondition (condition);
Jim Ingham28e23862012-02-08 05:23:15 +0000272 SendBreakpointChangedEvent (eBreakpointEventTypeConditionChanged);
Jim Inghamd1686902010-10-14 23:45:03 +0000273}
274
Jim Inghamd1686902010-10-14 23:45:03 +0000275const char *
Jim Inghamac354422011-06-15 21:16:00 +0000276Breakpoint::GetConditionText () const
Jim Inghamd1686902010-10-14 23:45:03 +0000277{
278 return m_options.GetConditionText();
279}
280
Chris Lattner24943d22010-06-08 16:52:24 +0000281// This function is used when "baton" doesn't need to be freed
282void
283Breakpoint::SetCallback (BreakpointHitCallback callback, void *baton, bool is_synchronous)
284{
285 // The default "Baton" class will keep a copy of "baton" and won't free
286 // or delete it when it goes goes out of scope.
287 m_options.SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous);
Jim Ingham28e23862012-02-08 05:23:15 +0000288
289 SendBreakpointChangedEvent (eBreakpointEventTypeCommandChanged);
Chris Lattner24943d22010-06-08 16:52:24 +0000290}
291
292// This function is used when a baton needs to be freed and therefore is
293// contained in a "Baton" subclass.
294void
295Breakpoint::SetCallback (BreakpointHitCallback callback, const BatonSP &callback_baton_sp, bool is_synchronous)
296{
297 m_options.SetCallback(callback, callback_baton_sp, is_synchronous);
298}
299
300void
301Breakpoint::ClearCallback ()
302{
303 m_options.ClearCallback ();
304}
305
306bool
307Breakpoint::InvokeCallback (StoppointCallbackContext *context, break_id_t bp_loc_id)
308{
309 return m_options.InvokeCallback (context, GetID(), bp_loc_id);
310}
311
312BreakpointOptions *
313Breakpoint::GetOptions ()
314{
315 return &m_options;
316}
317
318void
319Breakpoint::ResolveBreakpoint ()
320{
321 if (m_resolver_sp)
322 m_resolver_sp->ResolveBreakpoint(*m_filter_sp);
323}
324
325void
326Breakpoint::ResolveBreakpointInModules (ModuleList &module_list)
327{
328 if (m_resolver_sp)
329 m_resolver_sp->ResolveBreakpointInModules(*m_filter_sp, module_list);
330}
331
332void
333Breakpoint::ClearAllBreakpointSites ()
334{
335 m_locations.ClearAllBreakpointSites();
336}
337
338//----------------------------------------------------------------------
339// ModulesChanged: Pass in a list of new modules, and
340//----------------------------------------------------------------------
341
342void
Jim Ingham03e5e512012-05-17 18:38:42 +0000343Breakpoint::ModulesChanged (ModuleList &module_list, bool load, bool delete_locations)
Chris Lattner24943d22010-06-08 16:52:24 +0000344{
Jim Ingham93367902012-05-30 02:19:25 +0000345 Mutex::Locker modules_mutex(module_list.GetMutex());
Chris Lattner24943d22010-06-08 16:52:24 +0000346 if (load)
347 {
348 // The logic for handling new modules is:
349 // 1) If the filter rejects this module, then skip it.
350 // 2) Run through the current location list and if there are any locations
351 // for that module, we mark the module as "seen" and we don't try to re-resolve
352 // breakpoint locations for that module.
353 // However, we do add breakpoint sites to these locations if needed.
354 // 3) If we don't see this module in our breakpoint location list, call ResolveInModules.
355
356 ModuleList new_modules; // We'll stuff the "unseen" modules in this list, and then resolve
Greg Clayton19a1ab82011-02-05 00:38:04 +0000357 // them after the locations pass. Have to do it this way because
358 // resolving breakpoints will add new locations potentially.
359
360 const size_t num_locs = m_locations.GetSize();
Jim Ingham93367902012-05-30 02:19:25 +0000361 size_t num_modules = module_list.GetSize();
362 for (size_t i = 0; i < num_modules; i++)
Chris Lattner24943d22010-06-08 16:52:24 +0000363 {
364 bool seen = false;
Jim Ingham93367902012-05-30 02:19:25 +0000365 ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (i));
Chris Lattner24943d22010-06-08 16:52:24 +0000366 if (!m_filter_sp->ModulePasses (module_sp))
367 continue;
368
Greg Clayton19a1ab82011-02-05 00:38:04 +0000369 for (size_t loc_idx = 0; loc_idx < num_locs; loc_idx++)
Chris Lattner24943d22010-06-08 16:52:24 +0000370 {
Greg Clayton7b9fcc02010-12-06 23:51:26 +0000371 BreakpointLocationSP break_loc = m_locations.GetByIndex(loc_idx);
Jim Ingham1de036b2010-10-20 03:36:33 +0000372 if (!break_loc->IsEnabled())
373 continue;
Greg Clayton3508c382012-02-24 01:59:29 +0000374 SectionSP section_sp (break_loc->GetAddress().GetSection());
375 if (!section_sp || section_sp->GetModule() == module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000376 {
377 if (!seen)
378 seen = true;
379
380 if (!break_loc->ResolveBreakpointSite())
381 {
Greg Claytone005f2c2010-11-06 01:53:30 +0000382 LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
Chris Lattner24943d22010-06-08 16:52:24 +0000383 if (log)
384 log->Printf ("Warning: could not set breakpoint site for breakpoint location %d of breakpoint %d.\n",
385 break_loc->GetID(), GetID());
386 }
387 }
388 }
389
390 if (!seen)
Greg Claytonab429022010-12-12 21:03:32 +0000391 new_modules.AppendIfNeeded (module_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000392
393 }
Jim Ingham28e23862012-02-08 05:23:15 +0000394
Chris Lattner24943d22010-06-08 16:52:24 +0000395 if (new_modules.GetSize() > 0)
396 {
Jim Ingham28e23862012-02-08 05:23:15 +0000397 // If this is not an internal breakpoint, set up to record the new locations, then dispatch
398 // an event with the new locations.
399 if (!IsInternal())
400 {
401 BreakpointEventData *new_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsAdded,
402 shared_from_this());
403
404 m_locations.StartRecordingNewLocations(new_locations_event->GetBreakpointLocationCollection());
405
406 ResolveBreakpointInModules(new_modules);
407
408 m_locations.StopRecordingNewLocations();
409 if (new_locations_event->GetBreakpointLocationCollection().GetSize() != 0)
410 {
411 SendBreakpointChangedEvent (new_locations_event);
412 }
413 else
414 delete new_locations_event;
415 }
416 else
417 ResolveBreakpointInModules(new_modules);
418
Chris Lattner24943d22010-06-08 16:52:24 +0000419 }
420 }
421 else
422 {
423 // Go through the currently set locations and if any have breakpoints in
Jim Ingham03e5e512012-05-17 18:38:42 +0000424 // the module list, then remove their breakpoint sites, and their locations if asked to.
Chris Lattner24943d22010-06-08 16:52:24 +0000425
Jim Ingham28e23862012-02-08 05:23:15 +0000426 BreakpointEventData *removed_locations_event;
427 if (!IsInternal())
428 removed_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsRemoved,
429 shared_from_this());
430 else
431 removed_locations_event = NULL;
Jim Ingham93367902012-05-30 02:19:25 +0000432
433 size_t num_modules = module_list.GetSize();
434 for (size_t i = 0; i < num_modules; i++)
Chris Lattner24943d22010-06-08 16:52:24 +0000435 {
Jim Ingham93367902012-05-30 02:19:25 +0000436 ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (i));
Greg Clayton7b9fcc02010-12-06 23:51:26 +0000437 if (m_filter_sp->ModulePasses (module_sp))
Chris Lattner24943d22010-06-08 16:52:24 +0000438 {
Greg Clayton3508c382012-02-24 01:59:29 +0000439 size_t loc_idx = 0;
Jim Ingham03e5e512012-05-17 18:38:42 +0000440 size_t num_locations = m_locations.GetSize();
441 BreakpointLocationCollection locations_to_remove;
442 for (loc_idx = 0; loc_idx < num_locations; loc_idx++)
Chris Lattner24943d22010-06-08 16:52:24 +0000443 {
Greg Clayton3508c382012-02-24 01:59:29 +0000444 BreakpointLocationSP break_loc_sp (m_locations.GetByIndex(loc_idx));
445 SectionSP section_sp (break_loc_sp->GetAddress().GetSection());
446 if (section_sp && section_sp->GetModule() == module_sp)
Greg Clayton7b9fcc02010-12-06 23:51:26 +0000447 {
448 // Remove this breakpoint since the shared library is
449 // unloaded, but keep the breakpoint location around
450 // so we always get complete hit count and breakpoint
451 // lifetime info
Greg Clayton3508c382012-02-24 01:59:29 +0000452 break_loc_sp->ClearBreakpointSite();
Jim Ingham28e23862012-02-08 05:23:15 +0000453 if (removed_locations_event)
454 {
Greg Clayton3508c382012-02-24 01:59:29 +0000455 removed_locations_event->GetBreakpointLocationCollection().Add(break_loc_sp);
Jim Ingham28e23862012-02-08 05:23:15 +0000456 }
Jim Ingham03e5e512012-05-17 18:38:42 +0000457 if (delete_locations)
458 locations_to_remove.Add (break_loc_sp);
459
Greg Clayton7b9fcc02010-12-06 23:51:26 +0000460 }
Jim Ingham03e5e512012-05-17 18:38:42 +0000461 }
462
463 if (delete_locations)
464 {
465 size_t num_locations_to_remove = locations_to_remove.GetSize();
466 for (loc_idx = 0; loc_idx < num_locations_to_remove; loc_idx++)
467 m_locations.RemoveLocation (locations_to_remove.GetByIndex(loc_idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000468 }
Chris Lattner24943d22010-06-08 16:52:24 +0000469 }
470 }
Jim Ingham28e23862012-02-08 05:23:15 +0000471 SendBreakpointChangedEvent (removed_locations_event);
Chris Lattner24943d22010-06-08 16:52:24 +0000472 }
473}
474
475void
Jim Ingham03e5e512012-05-17 18:38:42 +0000476Breakpoint::ModuleReplaced (ModuleSP old_module_sp, ModuleSP new_module_sp)
477{
478 ModuleList temp_list;
479 temp_list.Append (new_module_sp);
480 ModulesChanged (temp_list, true);
481
482 // TO DO: For now I'm just adding locations for the new module and removing the
483 // breakpoint locations that were in the old module.
484 // We should really go find the ones that are in the new module & if we can determine that they are "equivalent"
485 // carry over the options from the old location to the new.
486
487 temp_list.Clear();
488 temp_list.Append (old_module_sp);
489 ModulesChanged (temp_list, false, true);
490}
491
492void
Chris Lattner24943d22010-06-08 16:52:24 +0000493Breakpoint::Dump (Stream *)
494{
495}
496
497size_t
498Breakpoint::GetNumResolvedLocations() const
499{
500 // Return the number of breakpoints that are actually resolved and set
501 // down in the inferior process.
502 return m_locations.GetNumResolvedLocations();
503}
504
505size_t
506Breakpoint::GetNumLocations() const
507{
508 return m_locations.GetSize();
509}
510
511void
512Breakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_locations)
513{
Greg Clayton54e7afa2010-07-09 20:39:50 +0000514 const size_t num_locations = GetNumLocations ();
515 const size_t num_resolved_locations = GetNumResolvedLocations ();
Chris Lattner24943d22010-06-08 16:52:24 +0000516
Jim Ingham4f61ba92012-09-22 00:04:04 +0000517 assert (s != NULL);
518
519
520
521 // They just made the breakpoint, they don't need to be told HOW they made it...
522 // Also, we'll print the breakpoint number differently depending on whether there is 1 or more locations.
523 if (level != eDescriptionLevelInitial)
524 {
525 s->Printf("%i: ", GetID());
526 GetResolverDescription (s);
527 GetFilterDescription (s);
528 }
529
Chris Lattner24943d22010-06-08 16:52:24 +0000530 switch (level)
531 {
532 case lldb::eDescriptionLevelBrief:
533 case lldb::eDescriptionLevelFull:
534 if (num_locations > 0)
535 {
Greg Clayton851e30e2012-09-18 18:04:04 +0000536 s->Printf(", locations = %llu", (uint64_t)num_locations);
Chris Lattner24943d22010-06-08 16:52:24 +0000537 if (num_resolved_locations > 0)
Greg Clayton851e30e2012-09-18 18:04:04 +0000538 s->Printf(", resolved = %llu", (uint64_t)num_resolved_locations);
Chris Lattner24943d22010-06-08 16:52:24 +0000539 }
540 else
541 {
Jim Ingham4722b102012-03-06 00:37:27 +0000542 // Don't print the pending notification for exception resolvers since we don't generally
543 // know how to set them until the target is run.
544 if (m_resolver_sp->getResolverID() != BreakpointResolver::ExceptionResolver)
545 s->Printf(", locations = 0 (pending)");
Chris Lattner24943d22010-06-08 16:52:24 +0000546 }
547
Jim Ingham649492b2010-06-18 01:00:58 +0000548 GetOptions()->GetDescription(s, level);
549
Chris Lattner24943d22010-06-08 16:52:24 +0000550 if (level == lldb::eDescriptionLevelFull)
551 {
Jim Ingham649492b2010-06-18 01:00:58 +0000552 s->IndentLess();
553 s->EOL();
Chris Lattner24943d22010-06-08 16:52:24 +0000554 }
555 break;
Jim Ingham4f61ba92012-09-22 00:04:04 +0000556
557 case lldb::eDescriptionLevelInitial:
558 s->Printf ("Breakpoint %i: ", GetID());
559 if (num_locations == 0)
560 {
561 s->Printf ("no locations (pending).");
562 }
563 else if (num_locations == 1)
564 {
565 // If there is one location only, we'll just print that location information. But don't do this if
566 // show locations is true, then that will be handled below.
567 if (show_locations == false)
568 {
569 GetLocationAtIndex(0)->GetDescription(s, level);
570 }
571 else
572 {
573 s->Printf ("%zd locations.", num_locations);
574 }
575 }
576 else
577 {
578 s->Printf ("%zd locations.", num_locations);
579 }
580 s->EOL();
581 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000582 case lldb::eDescriptionLevelVerbose:
583 // Verbose mode does a debug dump of the breakpoint
584 Dump (s);
Jim Ingham649492b2010-06-18 01:00:58 +0000585 s->EOL ();
Greg Claytonb1888f22011-03-19 01:12:21 +0000586 //s->Indent();
Jim Ingham649492b2010-06-18 01:00:58 +0000587 GetOptions()->GetDescription(s, level);
Chris Lattner24943d22010-06-08 16:52:24 +0000588 break;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000589
590 default:
591 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000592 }
593
Jim Ingham1cd466f2011-05-14 01:11:02 +0000594 // The brief description is just the location name (1.2 or whatever). That's pointless to
595 // show in the breakpoint's description, so suppress it.
596 if (show_locations && level != lldb::eDescriptionLevelBrief)
Chris Lattner24943d22010-06-08 16:52:24 +0000597 {
Chris Lattner24943d22010-06-08 16:52:24 +0000598 s->IndentMore();
Greg Clayton54e7afa2010-07-09 20:39:50 +0000599 for (size_t i = 0; i < num_locations; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +0000600 {
601 BreakpointLocation *loc = GetLocationAtIndex(i).get();
602 loc->GetDescription(s, level);
603 s->EOL();
604 }
605 s->IndentLess();
Chris Lattner24943d22010-06-08 16:52:24 +0000606 }
607}
608
Jim Ingham5f4f3272012-02-09 01:49:26 +0000609void
610Breakpoint::GetResolverDescription (Stream *s)
611{
612 if (m_resolver_sp)
613 m_resolver_sp->GetDescription (s);
614}
615
616
617bool
618Breakpoint::GetMatchingFileLine (const ConstString &filename, uint32_t line_number, BreakpointLocationCollection &loc_coll)
619{
620 // TODO: To be correct, this method needs to fill the breakpoint location collection
621 // with the location IDs which match the filename and line_number.
622 //
623
624 if (m_resolver_sp)
625 {
626 BreakpointResolverFileLine *resolverFileLine = dyn_cast<BreakpointResolverFileLine>(m_resolver_sp.get());
627 if (resolverFileLine &&
628 resolverFileLine->m_file_spec.GetFilename() == filename &&
629 resolverFileLine->m_line_number == line_number)
630 {
631 return true;
632 }
633 }
634 return false;
635}
636
637void
638Breakpoint::GetFilterDescription (Stream *s)
639{
640 m_filter_sp->GetDescription (s);
641}
642
643void
644Breakpoint::SendBreakpointChangedEvent (lldb::BreakpointEventType eventKind)
645{
646 if (!m_being_created
647 && !IsInternal()
648 && GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
649 {
650 BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind, shared_from_this());
651
652 GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
653 }
654}
655
656void
657Breakpoint::SendBreakpointChangedEvent (BreakpointEventData *data)
658{
659
660 if (data == NULL)
661 return;
662
663 if (!m_being_created
664 && !IsInternal()
665 && GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
666 GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
667 else
668 delete data;
669}
670
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000671Breakpoint::BreakpointEventData::BreakpointEventData (BreakpointEventType sub_type,
Jim Ingham28e23862012-02-08 05:23:15 +0000672 const BreakpointSP &new_breakpoint_sp) :
Chris Lattner24943d22010-06-08 16:52:24 +0000673 EventData (),
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000674 m_breakpoint_event (sub_type),
Chris Lattner24943d22010-06-08 16:52:24 +0000675 m_new_breakpoint_sp (new_breakpoint_sp)
676{
677}
678
679Breakpoint::BreakpointEventData::~BreakpointEventData ()
680{
681}
682
683const ConstString &
684Breakpoint::BreakpointEventData::GetFlavorString ()
685{
686 static ConstString g_flavor ("Breakpoint::BreakpointEventData");
687 return g_flavor;
688}
689
690const ConstString &
691Breakpoint::BreakpointEventData::GetFlavor () const
692{
693 return BreakpointEventData::GetFlavorString ();
694}
695
696
697BreakpointSP &
698Breakpoint::BreakpointEventData::GetBreakpoint ()
699{
700 return m_new_breakpoint_sp;
701}
702
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000703BreakpointEventType
704Breakpoint::BreakpointEventData::GetBreakpointEventType () const
Chris Lattner24943d22010-06-08 16:52:24 +0000705{
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000706 return m_breakpoint_event;
Chris Lattner24943d22010-06-08 16:52:24 +0000707}
708
709void
710Breakpoint::BreakpointEventData::Dump (Stream *s) const
711{
712}
713
Jim Ingham28e23862012-02-08 05:23:15 +0000714const Breakpoint::BreakpointEventData *
715Breakpoint::BreakpointEventData::GetEventDataFromEvent (const Event *event)
Chris Lattner24943d22010-06-08 16:52:24 +0000716{
Jim Ingham28e23862012-02-08 05:23:15 +0000717 if (event)
Chris Lattner24943d22010-06-08 16:52:24 +0000718 {
Jim Ingham28e23862012-02-08 05:23:15 +0000719 const EventData *event_data = event->GetData();
Chris Lattner24943d22010-06-08 16:52:24 +0000720 if (event_data && event_data->GetFlavor() == BreakpointEventData::GetFlavorString())
Jim Ingham28e23862012-02-08 05:23:15 +0000721 return static_cast <const BreakpointEventData *> (event->GetData());
Chris Lattner24943d22010-06-08 16:52:24 +0000722 }
723 return NULL;
724}
725
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000726BreakpointEventType
727Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (const EventSP &event_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000728{
Jim Ingham28e23862012-02-08 05:23:15 +0000729 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
Chris Lattner24943d22010-06-08 16:52:24 +0000730
731 if (data == NULL)
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000732 return eBreakpointEventTypeInvalidType;
Chris Lattner24943d22010-06-08 16:52:24 +0000733 else
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000734 return data->GetBreakpointEventType();
Chris Lattner24943d22010-06-08 16:52:24 +0000735}
736
737BreakpointSP
738Breakpoint::BreakpointEventData::GetBreakpointFromEvent (const EventSP &event_sp)
739{
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000740 BreakpointSP bp_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000741
Jim Ingham28e23862012-02-08 05:23:15 +0000742 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000743 if (data)
Jim Ingham28e23862012-02-08 05:23:15 +0000744 bp_sp = data->m_new_breakpoint_sp;
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000745
746 return bp_sp;
747}
748
Jim Ingham28e23862012-02-08 05:23:15 +0000749uint32_t
750Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent (const EventSP &event_sp)
751{
752 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
753 if (data)
754 return data->m_locations.GetSize();
755
756 return 0;
757}
758
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000759lldb::BreakpointLocationSP
760Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (const lldb::EventSP &event_sp, uint32_t bp_loc_idx)
761{
762 lldb::BreakpointLocationSP bp_loc_sp;
763
Jim Ingham28e23862012-02-08 05:23:15 +0000764 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000765 if (data)
Chris Lattner24943d22010-06-08 16:52:24 +0000766 {
Jim Ingham28e23862012-02-08 05:23:15 +0000767 bp_loc_sp = data->m_locations.GetByIndex(bp_loc_idx);
Chris Lattner24943d22010-06-08 16:52:24 +0000768 }
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000769
770 return bp_loc_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000771}