1 //===-- BreakpointLocation.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 #include "lldb/lldb-python.h"
11 
12 // C Includes
13 // C++ Includes
14 #include <string>
15 
16 // Other libraries and framework includes
17 // Project includes
18 #include "lldb/lldb-private-log.h"
19 #include "lldb/Breakpoint/BreakpointLocation.h"
20 #include "lldb/Breakpoint/BreakpointID.h"
21 #include "lldb/Breakpoint/StoppointCallbackContext.h"
22 #include "lldb/Core/Debugger.h"
23 #include "lldb/Core/Log.h"
24 #include "lldb/Core/Module.h"
25 #include "lldb/Core/StreamString.h"
26 #include "lldb/Symbol/CompileUnit.h"
27 #include "lldb/Symbol/Symbol.h"
28 #include "lldb/Target/Target.h"
29 #include "lldb/Target/Process.h"
30 #include "lldb/Target/Thread.h"
31 #include "lldb/Target/ThreadSpec.h"
32 
33 using namespace lldb;
34 using namespace lldb_private;
35 
36 BreakpointLocation::BreakpointLocation
37 (
38     break_id_t loc_id,
39     Breakpoint &owner,
40     const Address &addr,
41     lldb::tid_t tid,
42     bool hardware
43 ) :
44     StoppointLocation (loc_id, addr.GetOpcodeLoadAddress(&owner.GetTarget()), hardware),
45     m_being_created(true),
46     m_address (addr),
47     m_owner (owner),
48     m_options_ap (),
49     m_bp_site_sp ()
50 {
51     SetThreadID (tid);
52     m_being_created = false;
53 }
54 
55 BreakpointLocation::~BreakpointLocation()
56 {
57     ClearBreakpointSite();
58 }
59 
60 lldb::addr_t
61 BreakpointLocation::GetLoadAddress () const
62 {
63     return m_address.GetOpcodeLoadAddress (&m_owner.GetTarget());
64 }
65 
66 Address &
67 BreakpointLocation::GetAddress ()
68 {
69     return m_address;
70 }
71 
72 Breakpoint &
73 BreakpointLocation::GetBreakpoint ()
74 {
75     return m_owner;
76 }
77 
78 bool
79 BreakpointLocation::IsEnabled () const
80 {
81     if (!m_owner.IsEnabled())
82         return false;
83     else if (m_options_ap.get() != NULL)
84         return m_options_ap->IsEnabled();
85     else
86         return true;
87 }
88 
89 void
90 BreakpointLocation::SetEnabled (bool enabled)
91 {
92     GetLocationOptions()->SetEnabled(enabled);
93     if (enabled)
94     {
95         ResolveBreakpointSite();
96     }
97     else
98     {
99         ClearBreakpointSite();
100     }
101     SendBreakpointLocationChangedEvent (enabled ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled);
102 }
103 
104 void
105 BreakpointLocation::SetThreadID (lldb::tid_t thread_id)
106 {
107     if (thread_id != LLDB_INVALID_THREAD_ID)
108         GetLocationOptions()->SetThreadID(thread_id);
109     else
110     {
111         // If we're resetting this to an invalid thread id, then
112         // don't make an options pointer just to do that.
113         if (m_options_ap.get() != NULL)
114             m_options_ap->SetThreadID (thread_id);
115     }
116     SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
117 }
118 
119 lldb::tid_t
120 BreakpointLocation::GetThreadID ()
121 {
122     if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
123         return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID();
124     else
125         return LLDB_INVALID_THREAD_ID;
126 }
127 
128 void
129 BreakpointLocation::SetThreadIndex (uint32_t index)
130 {
131     if (index != 0)
132         GetLocationOptions()->GetThreadSpec()->SetIndex(index);
133     else
134     {
135         // If we're resetting this to an invalid thread id, then
136         // don't make an options pointer just to do that.
137         if (m_options_ap.get() != NULL)
138             m_options_ap->GetThreadSpec()->SetIndex(index);
139     }
140     SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
141 
142 }
143 
144 uint32_t
145 BreakpointLocation::GetThreadIndex() const
146 {
147     if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
148         return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetIndex();
149     else
150         return 0;
151 }
152 
153 void
154 BreakpointLocation::SetThreadName (const char *thread_name)
155 {
156     if (thread_name != NULL)
157         GetLocationOptions()->GetThreadSpec()->SetName(thread_name);
158     else
159     {
160         // If we're resetting this to an invalid thread id, then
161         // don't make an options pointer just to do that.
162         if (m_options_ap.get() != NULL)
163             m_options_ap->GetThreadSpec()->SetName(thread_name);
164     }
165     SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
166 }
167 
168 const char *
169 BreakpointLocation::GetThreadName () const
170 {
171     if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
172         return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetName();
173     else
174         return NULL;
175 }
176 
177 void
178 BreakpointLocation::SetQueueName (const char *queue_name)
179 {
180     if (queue_name != NULL)
181         GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name);
182     else
183     {
184         // If we're resetting this to an invalid thread id, then
185         // don't make an options pointer just to do that.
186         if (m_options_ap.get() != NULL)
187             m_options_ap->GetThreadSpec()->SetQueueName(queue_name);
188     }
189     SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
190 }
191 
192 const char *
193 BreakpointLocation::GetQueueName () const
194 {
195     if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
196         return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetQueueName();
197     else
198         return NULL;
199 }
200 
201 bool
202 BreakpointLocation::InvokeCallback (StoppointCallbackContext *context)
203 {
204     if (m_options_ap.get() != NULL && m_options_ap->HasCallback())
205         return m_options_ap->InvokeCallback (context, m_owner.GetID(), GetID());
206     else
207         return m_owner.InvokeCallback (context, GetID());
208 }
209 
210 void
211 BreakpointLocation::SetCallback (BreakpointHitCallback callback, void *baton,
212                  bool is_synchronous)
213 {
214     // The default "Baton" class will keep a copy of "baton" and won't free
215     // or delete it when it goes goes out of scope.
216     GetLocationOptions()->SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous);
217     SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged);
218 }
219 
220 void
221 BreakpointLocation::SetCallback (BreakpointHitCallback callback, const BatonSP &baton_sp,
222                  bool is_synchronous)
223 {
224     GetLocationOptions()->SetCallback (callback, baton_sp, is_synchronous);
225     SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged);
226 }
227 
228 
229 void
230 BreakpointLocation::ClearCallback ()
231 {
232     GetLocationOptions()->ClearCallback();
233 }
234 
235 void
236 BreakpointLocation::SetCondition (const char *condition)
237 {
238     GetLocationOptions()->SetCondition (condition);
239     SendBreakpointLocationChangedEvent (eBreakpointEventTypeConditionChanged);
240 }
241 
242 const char *
243 BreakpointLocation::GetConditionText () const
244 {
245     return GetOptionsNoCreate()->GetConditionText();
246 }
247 
248 uint32_t
249 BreakpointLocation::GetIgnoreCount ()
250 {
251     return GetOptionsNoCreate()->GetIgnoreCount();
252 }
253 
254 void
255 BreakpointLocation::SetIgnoreCount (uint32_t n)
256 {
257     GetLocationOptions()->SetIgnoreCount(n);
258     SendBreakpointLocationChangedEvent (eBreakpointEventTypeIgnoreChanged);
259 }
260 
261 void
262 BreakpointLocation::DecrementIgnoreCount()
263 {
264     if (m_options_ap.get() != NULL)
265     {
266         uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
267         if (loc_ignore != 0)
268             m_options_ap->SetIgnoreCount(loc_ignore - 1);
269     }
270 }
271 
272 bool
273 BreakpointLocation::IgnoreCountShouldStop()
274 {
275     if (m_options_ap.get() != NULL)
276     {
277         uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
278         if (loc_ignore != 0)
279         {
280             m_owner.DecrementIgnoreCount();
281             DecrementIgnoreCount();          // Have to decrement our owners' ignore count, since it won't get a
282                                              // chance to.
283             return false;
284         }
285     }
286     return true;
287 }
288 
289 const BreakpointOptions *
290 BreakpointLocation::GetOptionsNoCreate () const
291 {
292     if (m_options_ap.get() != NULL)
293         return m_options_ap.get();
294     else
295         return m_owner.GetOptions ();
296 }
297 
298 BreakpointOptions *
299 BreakpointLocation::GetLocationOptions ()
300 {
301     // If we make the copy we don't copy the callbacks because that is potentially
302     // expensive and we don't want to do that for the simple case where someone is
303     // just disabling the location.
304     if (m_options_ap.get() == NULL)
305         m_options_ap.reset(BreakpointOptions::CopyOptionsNoCallback(*m_owner.GetOptions ()));
306 
307     return m_options_ap.get();
308 }
309 
310 bool
311 BreakpointLocation::ValidForThisThread (Thread *thread)
312 {
313     return thread->MatchesSpec(GetOptionsNoCreate()->GetThreadSpecNoCreate());
314 }
315 
316 // RETURNS - true if we should stop at this breakpoint, false if we
317 // should continue.  Note, we don't check the thread spec for the breakpoint
318 // here, since if the breakpoint is not for this thread, then the event won't
319 // even get reported, so the check is redundant.
320 
321 bool
322 BreakpointLocation::ShouldStop (StoppointCallbackContext *context)
323 {
324     bool should_stop = true;
325     LogSP log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
326 
327     IncrementHitCount();
328 
329     if (!IsEnabled())
330         return false;
331 
332     if (!IgnoreCountShouldStop())
333         return false;
334 
335     if (!m_owner.IgnoreCountShouldStop())
336         return false;
337 
338     // We only run synchronous callbacks in ShouldStop:
339     context->is_synchronous = true;
340     should_stop = InvokeCallback (context);
341 
342     if (log)
343     {
344         StreamString s;
345         GetDescription (&s, lldb::eDescriptionLevelVerbose);
346         log->Printf ("Hit breakpoint location: %s, %s.\n", s.GetData(), should_stop ? "stopping" : "continuing");
347     }
348 
349     return should_stop;
350 }
351 
352 bool
353 BreakpointLocation::IsResolved () const
354 {
355     return m_bp_site_sp.get() != NULL;
356 }
357 
358 lldb::BreakpointSiteSP
359 BreakpointLocation::GetBreakpointSite() const
360 {
361     return m_bp_site_sp;
362 }
363 
364 bool
365 BreakpointLocation::ResolveBreakpointSite ()
366 {
367     if (m_bp_site_sp)
368         return true;
369 
370     Process *process = m_owner.GetTarget().GetProcessSP().get();
371     if (process == NULL)
372         return false;
373 
374     if (m_owner.GetTarget().GetSectionLoadList().IsEmpty())
375         return false;
376 
377     lldb::break_id_t new_id = process->CreateBreakpointSite (shared_from_this(), false);
378 
379     if (new_id == LLDB_INVALID_BREAK_ID)
380     {
381         LogSP log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
382         if (log)
383             log->Warning ("Tried to add breakpoint site at 0x%" PRIx64 " but it was already present.\n",
384                           m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()));
385         return false;
386     }
387 
388     return true;
389 }
390 
391 bool
392 BreakpointLocation::SetBreakpointSite (BreakpointSiteSP& bp_site_sp)
393 {
394     m_bp_site_sp = bp_site_sp;
395     return true;
396 }
397 
398 bool
399 BreakpointLocation::ClearBreakpointSite ()
400 {
401     if (m_bp_site_sp.get())
402     {
403         m_owner.GetTarget().GetProcessSP()->RemoveOwnerFromBreakpointSite (GetBreakpoint().GetID(),
404                                                                            GetID(), m_bp_site_sp);
405         m_bp_site_sp.reset();
406         return true;
407     }
408     return false;
409 }
410 
411 void
412 BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level)
413 {
414     SymbolContext sc;
415 
416     // If the description level is "initial" then the breakpoint is printing out our initial state,
417     // and we should let it decide how it wants to print our label.
418     if (level != eDescriptionLevelInitial)
419     {
420         s->Indent();
421         BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID());
422     }
423 
424     if (level == lldb::eDescriptionLevelBrief)
425         return;
426 
427     if (level != eDescriptionLevelInitial)
428         s->PutCString(": ");
429 
430     if (level == lldb::eDescriptionLevelVerbose)
431         s->IndentMore();
432 
433     if (m_address.IsSectionOffset())
434     {
435         m_address.CalculateSymbolContext(&sc);
436 
437         if (level == lldb::eDescriptionLevelFull || level == eDescriptionLevelInitial)
438         {
439             s->PutCString("where = ");
440             sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false);
441         }
442         else
443         {
444             if (sc.module_sp)
445             {
446                 s->EOL();
447                 s->Indent("module = ");
448                 sc.module_sp->GetFileSpec().Dump (s);
449             }
450 
451             if (sc.comp_unit != NULL)
452             {
453                 s->EOL();
454                 s->Indent("compile unit = ");
455                 static_cast<FileSpec*>(sc.comp_unit)->GetFilename().Dump (s);
456 
457                 if (sc.function != NULL)
458                 {
459                     s->EOL();
460                     s->Indent("function = ");
461                     s->PutCString (sc.function->GetMangled().GetName().AsCString("<unknown>"));
462                 }
463 
464                 if (sc.line_entry.line > 0)
465                 {
466                     s->EOL();
467                     s->Indent("location = ");
468                     sc.line_entry.DumpStopContext (s, true);
469                 }
470 
471             }
472             else
473             {
474                 // If we don't have a comp unit, see if we have a symbol we can print.
475                 if (sc.symbol)
476                 {
477                     s->EOL();
478                     s->Indent("symbol = ");
479                     s->PutCString(sc.symbol->GetMangled().GetName().AsCString("<unknown>"));
480                 }
481             }
482         }
483     }
484 
485     if (level == lldb::eDescriptionLevelVerbose)
486     {
487         s->EOL();
488         s->Indent();
489     }
490 
491     if (m_address.IsSectionOffset() && (level == eDescriptionLevelFull || level == eDescriptionLevelInitial))
492         s->Printf (", ");
493     s->Printf ("address = ");
494 
495     ExecutionContextScope *exe_scope = NULL;
496     Target *target = &m_owner.GetTarget();
497     if (target)
498         exe_scope = target->GetProcessSP().get();
499     if (exe_scope == NULL)
500         exe_scope = target;
501 
502     if (eDescriptionLevelInitial)
503         m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
504     else
505         m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
506 
507     if (level == lldb::eDescriptionLevelVerbose)
508     {
509         s->EOL();
510         s->Indent();
511         s->Printf("resolved = %s\n", IsResolved() ? "true" : "false");
512 
513         s->Indent();
514         s->Printf ("hit count = %-4u\n", GetHitCount());
515 
516         if (m_options_ap.get())
517         {
518             s->Indent();
519             m_options_ap->GetDescription (s, level);
520             s->EOL();
521         }
522         s->IndentLess();
523     }
524     else if (level != eDescriptionLevelInitial)
525     {
526         s->Printf(", %sresolved, hit count = %u ",
527                   (IsResolved() ? "" : "un"),
528                   GetHitCount());
529         if (m_options_ap.get())
530         {
531             m_options_ap->GetDescription (s, level);
532         }
533     }
534 }
535 
536 void
537 BreakpointLocation::Dump(Stream *s) const
538 {
539     if (s == NULL)
540         return;
541 
542     s->Printf("BreakpointLocation %u: tid = %4.4" PRIx64 "  load addr = 0x%8.8" PRIx64 "  state = %s  type = %s breakpoint  "
543               "hw_index = %i  hit_count = %-4u  ignore_count = %-4u",
544               GetID(),
545               GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(),
546               (uint64_t) m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()),
547               (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled()) ? "enabled " : "disabled",
548               IsHardware() ? "hardware" : "software",
549               GetHardwareIndex(),
550               GetHitCount(),
551               GetOptionsNoCreate()->GetIgnoreCount());
552 }
553 
554 void
555 BreakpointLocation::SendBreakpointLocationChangedEvent (lldb::BreakpointEventType eventKind)
556 {
557     if (!m_being_created
558         && !m_owner.IsInternal()
559         && m_owner.GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
560     {
561         Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind,
562                                                                                      m_owner.shared_from_this());
563         data->GetBreakpointLocationCollection().Add (shared_from_this());
564         m_owner.GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
565     }
566 }
567 
568