diff options
Diffstat (limited to 'source/Target/ThreadPlanShouldStopHere.cpp')
| -rw-r--r-- | source/Target/ThreadPlanShouldStopHere.cpp | 142 | 
1 files changed, 118 insertions, 24 deletions
diff --git a/source/Target/ThreadPlanShouldStopHere.cpp b/source/Target/ThreadPlanShouldStopHere.cpp index 87662345a06d..e89f5d2bde1b 100644 --- a/source/Target/ThreadPlanShouldStopHere.cpp +++ b/source/Target/ThreadPlanShouldStopHere.cpp @@ -23,12 +23,23 @@ using namespace lldb_private;  //----------------------------------------------------------------------  // ThreadPlanShouldStopHere constructor  //---------------------------------------------------------------------- -ThreadPlanShouldStopHere::ThreadPlanShouldStopHere(ThreadPlan *owner, ThreadPlanShouldStopHereCallback callback, void *baton) : -    m_callback (callback), -    m_baton (baton), +ThreadPlanShouldStopHere::ThreadPlanShouldStopHere(ThreadPlan *owner) : +    m_callbacks (), +    m_baton (NULL),      m_owner (owner),      m_flags (ThreadPlanShouldStopHere::eNone)  { +    m_callbacks.should_stop_here_callback = ThreadPlanShouldStopHere::DefaultShouldStopHereCallback; +    m_callbacks.step_from_here_callback = ThreadPlanShouldStopHere::DefaultStepFromHereCallback; +} + +ThreadPlanShouldStopHere::ThreadPlanShouldStopHere(ThreadPlan *owner, const ThreadPlanShouldStopHereCallbacks *callbacks, void *baton) : +    m_callbacks (), +    m_baton (), +    m_owner (owner), +    m_flags (ThreadPlanShouldStopHere::eNone) +{ +    SetShouldStopHereCallbacks(callbacks, baton);  }  //---------------------------------------------------------------------- @@ -38,37 +49,120 @@ ThreadPlanShouldStopHere::~ThreadPlanShouldStopHere()  {  } -void -ThreadPlanShouldStopHere::SetShouldStopHereCallback (ThreadPlanShouldStopHereCallback callback, void *baton) +bool +ThreadPlanShouldStopHere::InvokeShouldStopHereCallback (FrameComparison operation)  { -    m_callback = callback; -    m_baton = baton; -} - -ThreadPlanSP -ThreadPlanShouldStopHere::InvokeShouldStopHereCallback () -{ -    if (m_callback) +    bool should_stop_here = true; +    if (m_callbacks.should_stop_here_callback)      { -        ThreadPlanSP return_plan_sp(m_callback (m_owner, m_flags, m_baton)); +        should_stop_here = m_callbacks.should_stop_here_callback (m_owner, m_flags, operation, m_baton);          Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));          if (log)          {              lldb::addr_t current_addr = m_owner->GetThread().GetRegisterContext()->GetPC(0); -            if (return_plan_sp) -            { -                StreamString s; -                return_plan_sp->GetDescription (&s, lldb::eDescriptionLevelFull); -                log->Printf ("ShouldStopHere callback found a step out plan from 0x%" PRIx64 ": %s.", current_addr, s.GetData()); -            } -            else -            { -                log->Printf ("ShouldStopHere callback didn't find a step out plan from: 0x%" PRIx64 ".", current_addr); -            } +            log->Printf ("ShouldStopHere callback returned %u from 0x%" PRIx64 ".", should_stop_here, current_addr);          } +    } +     +    return should_stop_here; +} + +bool +ThreadPlanShouldStopHere::DefaultShouldStopHereCallback (ThreadPlan *current_plan, +                                                         Flags &flags, +                                                         FrameComparison operation, +                                                         void *baton) +{ +    bool should_stop_here = true; +    StackFrame *frame = current_plan->GetThread().GetStackFrameAtIndex(0).get(); +    if (!frame) +        return true; +     +    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); + +    if ((operation == eFrameCompareOlder && flags.Test(eStepOutAvoidNoDebug)) +        || (operation == eFrameCompareYounger && flags.Test(eStepInAvoidNoDebug)) +        || (operation == eFrameCompareSameParent && flags.Test(eStepInAvoidNoDebug))) +    { +        if (!frame->HasDebugInformation()) +        { +            if (log) +                log->Printf ("Stepping out of frame with no debug info"); + +            should_stop_here = false; +        } +    } +     +    // Always avoid code with line number 0. +    // FIXME: At present the ShouldStop and the StepFromHere calculate this independently.  If this ever +    // becomes expensive (this one isn't) we can try to have this set a state that the StepFromHere can use. +    if (frame) +    { +        SymbolContext sc; +        sc = frame->GetSymbolContext (eSymbolContextLineEntry); +        if (sc.line_entry.line == 0) +            should_stop_here = false; +    } +     +    return should_stop_here; +} + +ThreadPlanSP +ThreadPlanShouldStopHere::DefaultStepFromHereCallback (ThreadPlan *current_plan, +                                                         Flags &flags, +                                                         FrameComparison operation, +                                                         void *baton) +{ +    const bool stop_others = false; +    const size_t frame_index = 0; +    ThreadPlanSP return_plan_sp; +    // If we are stepping through code at line number 0, then we need to step over this range.  Otherwise +    // we will step out. +    StackFrame *frame = current_plan->GetThread().GetStackFrameAtIndex(0).get(); +    if (!frame)          return return_plan_sp; +    SymbolContext sc; +    sc = frame->GetSymbolContext (eSymbolContextLineEntry); +    if (sc.line_entry.line == 0) +    { +        AddressRange range = sc.line_entry.range; +        return_plan_sp = current_plan->GetThread().QueueThreadPlanForStepOverRange(false, +                                                                                   range, +                                                                                   sc, +                                                                                   eOnlyDuringStepping, +                                                                                   eLazyBoolNo); +    } +     +    if (!return_plan_sp) +        return_plan_sp = current_plan->GetThread().QueueThreadPlanForStepOutNoShouldStop (false, +                                                                                          NULL, +                                                                                          true, +                                                                                          stop_others, +                                                                                          eVoteNo, +                                                                                          eVoteNoOpinion, +                                                                                          frame_index); +    return return_plan_sp; +} + +ThreadPlanSP +ThreadPlanShouldStopHere::QueueStepOutFromHerePlan(lldb_private::Flags &flags, lldb::FrameComparison operation) +{ +    ThreadPlanSP return_plan_sp; +    if (m_callbacks.step_from_here_callback) +    { +         return_plan_sp = m_callbacks.step_from_here_callback (m_owner, flags, operation, m_baton);      } +    return return_plan_sp; + +} + +lldb::ThreadPlanSP +ThreadPlanShouldStopHere::CheckShouldStopHereAndQueueStepOut (lldb::FrameComparison operation) +{ +    if (!InvokeShouldStopHereCallback(operation)) +        return QueueStepOutFromHerePlan(m_flags, operation);      else          return ThreadPlanSP();  } +  | 
