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