]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/llvm/tools/lldb/source/Breakpoint/BreakpointLocation.cpp
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / llvm / tools / lldb / source / Breakpoint / BreakpointLocation.cpp
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     m_condition_mutex ()
51 {
52     SetThreadID (tid);
53     m_being_created = false;
54 }
55
56 BreakpointLocation::~BreakpointLocation()
57 {
58     ClearBreakpointSite();
59 }
60
61 lldb::addr_t
62 BreakpointLocation::GetLoadAddress () const
63 {
64     return m_address.GetOpcodeLoadAddress (&m_owner.GetTarget());
65 }
66
67 Address &
68 BreakpointLocation::GetAddress ()
69 {
70     return m_address;
71 }
72
73 Breakpoint &
74 BreakpointLocation::GetBreakpoint ()
75 {
76     return m_owner;
77 }
78
79 bool
80 BreakpointLocation::IsEnabled () const
81 {
82     if (!m_owner.IsEnabled())
83         return false;
84     else if (m_options_ap.get() != NULL)
85         return m_options_ap->IsEnabled();
86     else
87         return true;
88 }
89
90 void
91 BreakpointLocation::SetEnabled (bool enabled)
92 {
93     GetLocationOptions()->SetEnabled(enabled);
94     if (enabled)
95     {
96         ResolveBreakpointSite();
97     }
98     else
99     {
100         ClearBreakpointSite();
101     }
102     SendBreakpointLocationChangedEvent (enabled ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled);
103 }
104
105 void
106 BreakpointLocation::SetThreadID (lldb::tid_t thread_id)
107 {
108     if (thread_id != LLDB_INVALID_THREAD_ID)
109         GetLocationOptions()->SetThreadID(thread_id);
110     else
111     {
112         // If we're resetting this to an invalid thread id, then
113         // don't make an options pointer just to do that.
114         if (m_options_ap.get() != NULL)
115             m_options_ap->SetThreadID (thread_id);
116     }
117     SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
118 }
119
120 lldb::tid_t
121 BreakpointLocation::GetThreadID ()
122 {
123     if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
124         return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID();
125     else
126         return LLDB_INVALID_THREAD_ID;
127 }
128
129 void
130 BreakpointLocation::SetThreadIndex (uint32_t index)
131 {
132     if (index != 0)
133         GetLocationOptions()->GetThreadSpec()->SetIndex(index);
134     else
135     {
136         // If we're resetting this to an invalid thread id, then
137         // don't make an options pointer just to do that.
138         if (m_options_ap.get() != NULL)
139             m_options_ap->GetThreadSpec()->SetIndex(index);
140     }
141     SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
142                         
143 }
144
145 uint32_t
146 BreakpointLocation::GetThreadIndex() const
147 {
148     if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
149         return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetIndex();
150     else
151         return 0;
152 }
153
154 void
155 BreakpointLocation::SetThreadName (const char *thread_name)
156 {
157     if (thread_name != NULL)
158         GetLocationOptions()->GetThreadSpec()->SetName(thread_name);
159     else
160     {
161         // If we're resetting this to an invalid thread id, then
162         // don't make an options pointer just to do that.
163         if (m_options_ap.get() != NULL)
164             m_options_ap->GetThreadSpec()->SetName(thread_name);
165     }
166     SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
167 }
168
169 const char *
170 BreakpointLocation::GetThreadName () const
171 {
172     if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
173         return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetName();
174     else
175         return NULL;
176 }
177
178 void 
179 BreakpointLocation::SetQueueName (const char *queue_name)
180 {
181     if (queue_name != NULL)
182         GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name);
183     else
184     {
185         // If we're resetting this to an invalid thread id, then
186         // don't make an options pointer just to do that.
187         if (m_options_ap.get() != NULL)
188             m_options_ap->GetThreadSpec()->SetQueueName(queue_name);
189     }
190     SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
191 }
192
193 const char *
194 BreakpointLocation::GetQueueName () const
195 {
196     if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
197         return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetQueueName();
198     else
199         return NULL;
200 }
201
202 bool
203 BreakpointLocation::InvokeCallback (StoppointCallbackContext *context)
204 {
205     if (m_options_ap.get() != NULL && m_options_ap->HasCallback())
206         return m_options_ap->InvokeCallback (context, m_owner.GetID(), GetID());
207     else    
208         return m_owner.InvokeCallback (context, GetID());
209 }
210
211 void
212 BreakpointLocation::SetCallback (BreakpointHitCallback callback, void *baton,
213                  bool is_synchronous)
214 {
215     // The default "Baton" class will keep a copy of "baton" and won't free
216     // or delete it when it goes goes out of scope.
217     GetLocationOptions()->SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous);
218     SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged);
219 }
220
221 void
222 BreakpointLocation::SetCallback (BreakpointHitCallback callback, const BatonSP &baton_sp,
223                  bool is_synchronous)
224 {
225     GetLocationOptions()->SetCallback (callback, baton_sp, is_synchronous);
226     SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged);
227 }
228
229
230 void
231 BreakpointLocation::ClearCallback ()
232 {
233     GetLocationOptions()->ClearCallback();
234 }
235
236 void 
237 BreakpointLocation::SetCondition (const char *condition)
238 {
239     GetLocationOptions()->SetCondition (condition);
240     SendBreakpointLocationChangedEvent (eBreakpointEventTypeConditionChanged);
241 }
242
243 const char *
244 BreakpointLocation::GetConditionText (size_t *hash) const
245 {
246     return GetOptionsNoCreate()->GetConditionText(hash);
247 }
248
249 bool
250 BreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error)
251 {
252     Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
253  
254     Mutex::Locker evaluation_locker(m_condition_mutex);
255     
256     size_t condition_hash;
257     const char *condition_text = GetConditionText(&condition_hash);
258     
259     if (!condition_text)
260     {
261         m_user_expression_sp.reset();
262         return false;
263     }
264     
265     if (condition_hash != m_condition_hash ||
266         !m_user_expression_sp ||
267         !m_user_expression_sp->MatchesContext(exe_ctx))
268     {
269         m_user_expression_sp.reset(new ClangUserExpression(condition_text,
270                                                            NULL,
271                                                            lldb::eLanguageTypeUnknown,
272                                                            ClangUserExpression::eResultTypeAny));
273         
274         StreamString errors;
275         
276         if (!m_user_expression_sp->Parse(errors,
277                                          exe_ctx,
278                                          eExecutionPolicyOnlyWhenNeeded,
279                                          true))
280         {
281             error.SetErrorStringWithFormat("Couldn't parse conditional expression:\n%s",
282                                            errors.GetData());
283             m_user_expression_sp.reset();
284             return false;
285         }
286         
287         m_condition_hash = condition_hash;
288     }
289
290     // We need to make sure the user sees any parse errors in their condition, so we'll hook the
291     // constructor errors up to the debugger's Async I/O.
292         
293     ValueObjectSP result_value_sp;
294     const bool unwind_on_error = true;
295     const bool ignore_breakpoints = true;
296     const bool try_all_threads = true;
297     
298     Error expr_error;
299     
300     StreamString execution_errors;
301     
302     ClangExpressionVariableSP result_variable_sp;
303     
304     ExecutionResults result_code =
305     m_user_expression_sp->Execute(execution_errors,
306                                   exe_ctx,
307                                   unwind_on_error,
308                                   ignore_breakpoints,
309                                   m_user_expression_sp,
310                                   result_variable_sp,
311                                   try_all_threads,
312                                   ClangUserExpression::kDefaultTimeout);
313     
314     bool ret;
315     
316     if (result_code == eExecutionCompleted)
317     {
318         if (!result_variable_sp)
319         {
320             ret = false;
321             error.SetErrorString("Expression did not return a result");
322             return false;
323         }
324         
325         result_value_sp = result_variable_sp->GetValueObject();
326
327         if (result_value_sp)
328         {
329             Scalar scalar_value;
330             if (result_value_sp->ResolveValue (scalar_value))
331             {
332                 if (scalar_value.ULongLong(1) == 0)
333                     ret = false;
334                 else
335                     ret = true;
336                 if (log)
337                     log->Printf("Condition successfully evaluated, result is %s.\n",
338                                 ret ? "true" : "false");
339             }
340             else
341             {
342                 ret = false;
343                 error.SetErrorString("Failed to get an integer result from the expression");
344             }
345         }
346         else
347         {
348             ret = false;
349             error.SetErrorString("Failed to get any result from the expression");
350         }
351     }
352     else
353     {
354         ret = false;
355         error.SetErrorStringWithFormat("Couldn't execute expression:\n%s", execution_errors.GetData());
356     }
357     
358     return ret;
359 }
360
361 uint32_t
362 BreakpointLocation::GetIgnoreCount ()
363 {
364     return GetOptionsNoCreate()->GetIgnoreCount();
365 }
366
367 void
368 BreakpointLocation::SetIgnoreCount (uint32_t n)
369 {
370     GetLocationOptions()->SetIgnoreCount(n);
371     SendBreakpointLocationChangedEvent (eBreakpointEventTypeIgnoreChanged);
372 }
373
374 void
375 BreakpointLocation::DecrementIgnoreCount()
376 {
377     if (m_options_ap.get() != NULL)
378     {
379         uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
380         if (loc_ignore != 0)
381             m_options_ap->SetIgnoreCount(loc_ignore - 1);
382     }
383 }
384
385 bool
386 BreakpointLocation::IgnoreCountShouldStop()
387 {
388     if (m_options_ap.get() != NULL)
389     {
390         uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
391         if (loc_ignore != 0)
392         {
393             m_owner.DecrementIgnoreCount();
394             DecrementIgnoreCount();          // Have to decrement our owners' ignore count, since it won't get a
395                                              // chance to.
396             return false;
397         }
398     }
399     return true;
400 }
401
402 const BreakpointOptions *
403 BreakpointLocation::GetOptionsNoCreate () const
404 {
405     if (m_options_ap.get() != NULL)
406         return m_options_ap.get();
407     else
408         return m_owner.GetOptions ();
409 }
410
411 BreakpointOptions *
412 BreakpointLocation::GetLocationOptions ()
413 {
414     // If we make the copy we don't copy the callbacks because that is potentially 
415     // expensive and we don't want to do that for the simple case where someone is
416     // just disabling the location.
417     if (m_options_ap.get() == NULL)
418         m_options_ap.reset(BreakpointOptions::CopyOptionsNoCallback(*m_owner.GetOptions ()));
419     
420     return m_options_ap.get();
421 }
422
423 bool
424 BreakpointLocation::ValidForThisThread (Thread *thread)
425 {
426     return thread->MatchesSpec(GetOptionsNoCreate()->GetThreadSpecNoCreate());
427 }
428
429 // RETURNS - true if we should stop at this breakpoint, false if we
430 // should continue.  Note, we don't check the thread spec for the breakpoint
431 // here, since if the breakpoint is not for this thread, then the event won't
432 // even get reported, so the check is redundant.
433
434 bool
435 BreakpointLocation::ShouldStop (StoppointCallbackContext *context)
436 {
437     bool should_stop = true;
438     Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
439
440     IncrementHitCount();
441
442     if (!IsEnabled())
443         return false;
444
445     if (!IgnoreCountShouldStop())
446         return false;
447     
448     if (!m_owner.IgnoreCountShouldStop())
449         return false;
450
451     // We only run synchronous callbacks in ShouldStop:
452     context->is_synchronous = true;
453     should_stop = InvokeCallback (context);
454     
455     if (log)
456     {
457         StreamString s;
458         GetDescription (&s, lldb::eDescriptionLevelVerbose);
459         log->Printf ("Hit breakpoint location: %s, %s.\n", s.GetData(), should_stop ? "stopping" : "continuing");
460     }
461     
462     return should_stop;
463 }
464
465 bool
466 BreakpointLocation::IsResolved () const
467 {
468     return m_bp_site_sp.get() != NULL;
469 }
470
471 lldb::BreakpointSiteSP
472 BreakpointLocation::GetBreakpointSite() const
473 {
474     return m_bp_site_sp;
475 }
476
477 bool
478 BreakpointLocation::ResolveBreakpointSite ()
479 {
480     if (m_bp_site_sp)
481         return true;
482
483     Process *process = m_owner.GetTarget().GetProcessSP().get();
484     if (process == NULL)
485         return false;
486
487     lldb::break_id_t new_id = process->CreateBreakpointSite (shared_from_this(), false);
488
489     if (new_id == LLDB_INVALID_BREAK_ID)
490     {
491         Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
492         if (log)
493             log->Warning ("Tried to add breakpoint site at 0x%" PRIx64 " but it was already present.\n",
494                           m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()));
495         return false;
496     }
497
498     return true;
499 }
500
501 bool
502 BreakpointLocation::SetBreakpointSite (BreakpointSiteSP& bp_site_sp)
503 {
504     m_bp_site_sp = bp_site_sp;
505     return true;
506 }
507
508 bool
509 BreakpointLocation::ClearBreakpointSite ()
510 {
511     if (m_bp_site_sp.get())
512     {
513         m_owner.GetTarget().GetProcessSP()->RemoveOwnerFromBreakpointSite (GetBreakpoint().GetID(), 
514                                                                            GetID(), m_bp_site_sp);
515         m_bp_site_sp.reset();
516         return true;
517     }
518     return false;
519 }
520
521 void
522 BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level)
523 {
524     SymbolContext sc;
525     
526     // If the description level is "initial" then the breakpoint is printing out our initial state,
527     // and we should let it decide how it wants to print our label.
528     if (level != eDescriptionLevelInitial)
529     {
530         s->Indent();
531         BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID());
532     }
533     
534     if (level == lldb::eDescriptionLevelBrief)
535         return;
536
537     if (level != eDescriptionLevelInitial)
538         s->PutCString(": ");
539
540     if (level == lldb::eDescriptionLevelVerbose)
541         s->IndentMore();
542
543     if (m_address.IsSectionOffset())
544     {
545         m_address.CalculateSymbolContext(&sc);
546
547         if (level == lldb::eDescriptionLevelFull || level == eDescriptionLevelInitial)
548         {
549             s->PutCString("where = ");
550             sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false);
551         }
552         else
553         {
554             if (sc.module_sp)
555             {
556                 s->EOL();
557                 s->Indent("module = ");
558                 sc.module_sp->GetFileSpec().Dump (s);
559             }
560
561             if (sc.comp_unit != NULL)
562             {
563                 s->EOL();
564                 s->Indent("compile unit = ");
565                 static_cast<FileSpec*>(sc.comp_unit)->GetFilename().Dump (s);
566
567                 if (sc.function != NULL)
568                 {
569                     s->EOL();
570                     s->Indent("function = ");
571                     s->PutCString (sc.function->GetMangled().GetName().AsCString("<unknown>"));
572                 }
573
574                 if (sc.line_entry.line > 0)
575                 {
576                     s->EOL();
577                     s->Indent("location = ");
578                     sc.line_entry.DumpStopContext (s, true);
579                 }
580
581             }
582             else
583             {
584                 // If we don't have a comp unit, see if we have a symbol we can print.
585                 if (sc.symbol)
586                 {
587                     s->EOL();
588                     s->Indent("symbol = ");
589                     s->PutCString(sc.symbol->GetMangled().GetName().AsCString("<unknown>"));
590                 }
591             }
592         }
593     }
594
595     if (level == lldb::eDescriptionLevelVerbose)
596     {
597         s->EOL();
598         s->Indent();
599     }
600     
601     if (m_address.IsSectionOffset() && (level == eDescriptionLevelFull || level == eDescriptionLevelInitial))
602         s->Printf (", ");
603     s->Printf ("address = ");
604     
605     ExecutionContextScope *exe_scope = NULL;
606     Target *target = &m_owner.GetTarget();
607     if (target)
608         exe_scope = target->GetProcessSP().get();
609     if (exe_scope == NULL)
610         exe_scope = target;
611
612     if (eDescriptionLevelInitial)
613         m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
614     else
615         m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
616
617     if (level == lldb::eDescriptionLevelVerbose)
618     {
619         s->EOL();
620         s->Indent();
621         s->Printf("resolved = %s\n", IsResolved() ? "true" : "false");
622
623         s->Indent();
624         s->Printf ("hit count = %-4u\n", GetHitCount());
625
626         if (m_options_ap.get())
627         {
628             s->Indent();
629             m_options_ap->GetDescription (s, level);
630             s->EOL();
631         }
632         s->IndentLess();
633     }
634     else if (level != eDescriptionLevelInitial)
635     {
636         s->Printf(", %sresolved, hit count = %u ",
637                   (IsResolved() ? "" : "un"),
638                   GetHitCount());
639         if (m_options_ap.get())
640         {
641             m_options_ap->GetDescription (s, level);
642         }
643     }
644 }
645
646 void
647 BreakpointLocation::Dump(Stream *s) const
648 {
649     if (s == NULL)
650         return;
651
652     s->Printf("BreakpointLocation %u: tid = %4.4" PRIx64 "  load addr = 0x%8.8" PRIx64 "  state = %s  type = %s breakpoint  "
653               "hw_index = %i  hit_count = %-4u  ignore_count = %-4u",
654               GetID(),
655               GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(),
656               (uint64_t) m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()),
657               (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled()) ? "enabled " : "disabled",
658               IsHardware() ? "hardware" : "software",
659               GetHardwareIndex(),
660               GetHitCount(),
661               GetOptionsNoCreate()->GetIgnoreCount());
662 }
663
664 void
665 BreakpointLocation::SendBreakpointLocationChangedEvent (lldb::BreakpointEventType eventKind)
666 {
667     if (!m_being_created
668         && !m_owner.IsInternal() 
669         && m_owner.GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
670     {
671         Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind, 
672                                                                                      m_owner.shared_from_this());
673         data->GetBreakpointLocationCollection().Add (shared_from_this());
674         m_owner.GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
675     }
676 }
677