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    m_condition_mutex ()
51{
52    SetThreadID (tid);
53    m_being_created = false;
54}
55
56BreakpointLocation::~BreakpointLocation()
57{
58    ClearBreakpointSite();
59}
60
61lldb::addr_t
62BreakpointLocation::GetLoadAddress () const
63{
64    return m_address.GetOpcodeLoadAddress (&m_owner.GetTarget());
65}
66
67Address &
68BreakpointLocation::GetAddress ()
69{
70    return m_address;
71}
72
73Breakpoint &
74BreakpointLocation::GetBreakpoint ()
75{
76    return m_owner;
77}
78
79bool
80BreakpointLocation::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
90void
91BreakpointLocation::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
105void
106BreakpointLocation::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
120lldb::tid_t
121BreakpointLocation::GetThreadID ()
122{
123    if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
124        return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID();
125    else
126        return LLDB_INVALID_THREAD_ID;
127}
128
129void
130BreakpointLocation::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
145uint32_t
146BreakpointLocation::GetThreadIndex() const
147{
148    if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
149        return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetIndex();
150    else
151        return 0;
152}
153
154void
155BreakpointLocation::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
169const char *
170BreakpointLocation::GetThreadName () const
171{
172    if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
173        return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetName();
174    else
175        return NULL;
176}
177
178void
179BreakpointLocation::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
193const char *
194BreakpointLocation::GetQueueName () const
195{
196    if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
197        return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetQueueName();
198    else
199        return NULL;
200}
201
202bool
203BreakpointLocation::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
211void
212BreakpointLocation::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
221void
222BreakpointLocation::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
230void
231BreakpointLocation::ClearCallback ()
232{
233    GetLocationOptions()->ClearCallback();
234}
235
236void
237BreakpointLocation::SetCondition (const char *condition)
238{
239    GetLocationOptions()->SetCondition (condition);
240    SendBreakpointLocationChangedEvent (eBreakpointEventTypeConditionChanged);
241}
242
243const char *
244BreakpointLocation::GetConditionText (size_t *hash) const
245{
246    return GetOptionsNoCreate()->GetConditionText(hash);
247}
248
249bool
250BreakpointLocation::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
361uint32_t
362BreakpointLocation::GetIgnoreCount ()
363{
364    return GetOptionsNoCreate()->GetIgnoreCount();
365}
366
367void
368BreakpointLocation::SetIgnoreCount (uint32_t n)
369{
370    GetLocationOptions()->SetIgnoreCount(n);
371    SendBreakpointLocationChangedEvent (eBreakpointEventTypeIgnoreChanged);
372}
373
374void
375BreakpointLocation::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
385bool
386BreakpointLocation::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
402const BreakpointOptions *
403BreakpointLocation::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
411BreakpointOptions *
412BreakpointLocation::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
423bool
424BreakpointLocation::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
434bool
435BreakpointLocation::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
465bool
466BreakpointLocation::IsResolved () const
467{
468    return m_bp_site_sp.get() != NULL;
469}
470
471lldb::BreakpointSiteSP
472BreakpointLocation::GetBreakpointSite() const
473{
474    return m_bp_site_sp;
475}
476
477bool
478BreakpointLocation::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
501bool
502BreakpointLocation::SetBreakpointSite (BreakpointSiteSP& bp_site_sp)
503{
504    m_bp_site_sp = bp_site_sp;
505    return true;
506}
507
508bool
509BreakpointLocation::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
521void
522BreakpointLocation::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
646void
647BreakpointLocation::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
664void
665BreakpointLocation::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
678