124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- ThreadPlanStepInRange.cpp -------------------------------*- C++ -*-===//
224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//                     The LLVM Compiler Infrastructure
424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source
624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details.
724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===//
924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/ThreadPlanStepInRange.h"
1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C Includes
1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C++ Includes
1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Other libraries and framework includes
1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Project includes
1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/lldb-private-log.h"
1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Log.h"
1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Stream.h"
20809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham#include "lldb/Symbol/Symbol.h"
210e81b6475a71b32d1edf30a26487c003cc308bf3Jim Ingham#include "lldb/Symbol/Function.h"
2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/Process.h"
2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/RegisterContext.h"
24395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton#include "lldb/Target/Target.h"
2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/Thread.h"
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/ThreadPlanStepOut.h"
2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/ThreadPlanStepThrough.h"
28809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham#include "lldb/Core/RegularExpression.h"
2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb;
3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private;
3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t ThreadPlanStepInRange::s_default_flag_values = ThreadPlanShouldStopHere::eAvoidNoDebug;
3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// ThreadPlanStepInRange: Step through a stack range, either stepping over or into
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// based on the value of \a type.
3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanStepInRange::ThreadPlanStepInRange
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner(
4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Thread &thread,
4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const AddressRange &range,
4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const SymbolContext &addr_context,
4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    lldb::RunMode stop_others
4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner) :
475a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham    ThreadPlanStepRange (ThreadPlan::eKindStepInRange, "Step Range stepping in", thread, range, addr_context, stop_others),
480e81b6475a71b32d1edf30a26487c003cc308bf3Jim Ingham    ThreadPlanShouldStopHere (this, ThreadPlanStepInRange::DefaultShouldStopHereCallback, NULL),
4945bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham    m_step_past_prologue (true),
5045bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham    m_virtual_step (false)
5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    SetFlagsToDefault ();
5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
55f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim InghamThreadPlanStepInRange::ThreadPlanStepInRange
56f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham(
57f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham    Thread &thread,
58f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham    const AddressRange &range,
59f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham    const SymbolContext &addr_context,
60f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham    const char *step_into_target,
61f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham    lldb::RunMode stop_others
62f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham) :
63f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham    ThreadPlanStepRange (ThreadPlan::eKindStepInRange, "Step Range stepping in", thread, range, addr_context, stop_others),
64f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham    ThreadPlanShouldStopHere (this, ThreadPlanStepInRange::DefaultShouldStopHereCallback, NULL),
65f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham    m_step_past_prologue (true),
66f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham    m_virtual_step (false),
67f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham    m_step_into_target (step_into_target)
68f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham{
69f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham    SetFlagsToDefault ();
70f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham}
71f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham
7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanStepInRange::~ThreadPlanStepInRange ()
7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanStepInRange::GetDescription (Stream *s, lldb::DescriptionLevel level)
7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (level == lldb::eDescriptionLevelBrief)
8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        s->Printf("step in");
8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        s->Printf ("Stepping through range (stepping into functions): ");
8476e55f722acc41f6eaf35a7f988090f97b2c82e0Jim Ingham        DumpRanges(s);
85008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham        const char *step_into_target = m_step_into_target.AsCString();
86008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham        if (step_into_target && step_into_target[0] != '\0')
87008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham            s->Printf (" targeting %s.", m_step_into_target.AsCString());
88008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham        else
89008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham            s->PutChar('.');
9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanStepInRange::ShouldStop (Event *event_ptr)
9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
96952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (log)
9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        StreamString s;
101395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton        s.Address (m_thread.GetRegisterContext()->GetPC(),
102f4124deeb9532044a38c0774ced872f2709347daGreg Clayton                   m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize());
10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        log->Printf("ThreadPlanStepInRange reached %s.", s.GetData());
10424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
106ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    if (IsPlanComplete())
107ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        return true;
108ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham
109008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham    m_no_more_plans = false;
110008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham    if (m_sub_plan_sp && m_sub_plan_sp->IsPlanComplete())
111008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham    {
112008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham        if (!m_sub_plan_sp->PlanSucceeded())
113008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham        {
114008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham            SetPlanComplete();
115008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham            m_no_more_plans = true;
116008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham            return true;
117008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham        }
118008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham        else
119008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham            m_sub_plan_sp.reset();
120008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham    }
121008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham
12245bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham    if (m_virtual_step)
1234f385f181467701d2c5225f2c954ed5771e0763fJim Ingham    {
12445bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham        // If we've just completed a virtual step, all we need to do is check for a ShouldStopHere plan, and otherwise
12545bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham        // we're done.
126008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham        m_sub_plan_sp = InvokeShouldStopHereCallback();
1274f385f181467701d2c5225f2c954ed5771e0763fJim Ingham    }
12845bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham    else
1294f385f181467701d2c5225f2c954ed5771e0763fJim Ingham    {
13023f2194bd1bb5efdc7a5aa8d8f3304d54d48deaaJim Ingham        // Stepping through should be done running other threads in general, since we're setting a breakpoint and
13123f2194bd1bb5efdc7a5aa8d8f3304d54d48deaaJim Ingham        // continuing.  So only stop others if we are explicitly told to do so.
132b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham
13345bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham        bool stop_others;
13423f2194bd1bb5efdc7a5aa8d8f3304d54d48deaaJim Ingham        if (m_stop_others == lldb::eOnlyThisThread)
13545bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham            stop_others = false;
13623f2194bd1bb5efdc7a5aa8d8f3304d54d48deaaJim Ingham        else
13723f2194bd1bb5efdc7a5aa8d8f3304d54d48deaaJim Ingham            stop_others = true;
1380e81b6475a71b32d1edf30a26487c003cc308bf3Jim Ingham
13945bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham        FrameComparison frame_order = CompareCurrentFrameToStartFrame();
14045bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham
14145bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham        if (frame_order == eFrameCompareOlder)
14245bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham        {
14345bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham            // If we're in an older frame then we should stop.
14445bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham            //
14545bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham            // A caveat to this is if we think the frame is older but we're actually in a trampoline.
14645bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham            // I'm going to make the assumption that you wouldn't RETURN to a trampoline.  So if we are
14745bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham            // in a trampoline we think the frame is older because the trampoline confused the backtracer.
148008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham            m_sub_plan_sp = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
149008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham            if (!m_sub_plan_sp)
15045bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham                return true;
15145bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham            else if (log)
1520e81b6475a71b32d1edf30a26487c003cc308bf3Jim Ingham            {
15345bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham                log->Printf("Thought I stepped out, but in fact arrived at a trampoline.");
1540e81b6475a71b32d1edf30a26487c003cc308bf3Jim Ingham            }
15545bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham
15645bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham        }
15745bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham        else if (frame_order == eFrameCompareEqual && InSymbol())
15845bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham        {
15945bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham            // If we are not in a place we should step through, we're done.
16045bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham            // One tricky bit here is that some stubs don't push a frame, so we have to check
16145bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham            // both the case of a frame that is younger, or the same as this frame.
16245bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham            // However, if the frame is the same, and we are still in the symbol we started
16345bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham            // in, the we don't need to do this.  This first check isn't strictly necessary,
16445bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham            // but it is more efficient.
16545bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham
16645bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham            // If we're still in the range, keep going, either by running to the next branch breakpoint, or by
16745bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham            // stepping.
16845bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham            if (InRange())
1690e81b6475a71b32d1edf30a26487c003cc308bf3Jim Ingham            {
17045bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham                SetNextBranchBreakpoint();
17145bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham                return false;
1720e81b6475a71b32d1edf30a26487c003cc308bf3Jim Ingham            }
17345bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham
17445bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham            SetPlanComplete();
175f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham            m_no_more_plans = true;
17645bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham            return true;
17745bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham        }
17845bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham
17945bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham        // If we get to this point, we're not going to use a previously set "next branch" breakpoint, so delete it:
18045bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham        ClearNextBranchBreakpoint();
18145bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham
18245bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham        // We may have set the plan up above in the FrameIsOlder section:
18345bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham
184008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham        if (!m_sub_plan_sp)
185008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham            m_sub_plan_sp = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
18645bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham
18745bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham        if (log)
18845bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham        {
189008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham            if (m_sub_plan_sp)
190008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham                log->Printf ("Found a step through plan: %s", m_sub_plan_sp->GetName());
19145bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham            else
19245bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham                log->Printf ("No step through plan found.");
19345bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham        }
19445bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham
19545bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham        // If not, give the "should_stop" callback a chance to push a plan to get us out of here.
19645bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham        // But only do that if we actually have stepped in.
197008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham        if (!m_sub_plan_sp && frame_order == eFrameCompareYounger)
198008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham            m_sub_plan_sp = InvokeShouldStopHereCallback();
19945bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham
20045bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham        // If we've stepped in and we are going to stop here, check to see if we were asked to
20145bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham        // run past the prologue, and if so do that.
20245bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham
203008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham        if (!m_sub_plan_sp && frame_order == eFrameCompareYounger && m_step_past_prologue)
20445bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham        {
20545bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham            lldb::StackFrameSP curr_frame = m_thread.GetStackFrameAtIndex(0);
20645bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham            if (curr_frame)
2070e81b6475a71b32d1edf30a26487c003cc308bf3Jim Ingham            {
20845bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham                size_t bytes_to_skip = 0;
20945bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham                lldb::addr_t curr_addr = m_thread.GetRegisterContext()->GetPC();
21045bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham                Address func_start_address;
21145bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham
21245bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham                SymbolContext sc = curr_frame->GetSymbolContext (eSymbolContextFunction | eSymbolContextSymbol);
21345bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham
21445bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham                if (sc.function)
21545bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham                {
21645bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham                    func_start_address = sc.function->GetAddressRange().GetBaseAddress();
21745bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham                    if (curr_addr == func_start_address.GetLoadAddress(m_thread.CalculateTarget().get()))
21845bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham                        bytes_to_skip = sc.function->GetPrologueByteSize();
21945bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham                }
22045bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham                else if (sc.symbol)
22145bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham                {
22245bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham                    func_start_address = sc.symbol->GetAddress();
22345bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham                    if (curr_addr == func_start_address.GetLoadAddress(m_thread.CalculateTarget().get()))
22445bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham                        bytes_to_skip = sc.symbol->GetPrologueByteSize();
22545bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham                }
22645bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham
22745bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham                if (bytes_to_skip != 0)
22845bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham                {
22945bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham                    func_start_address.Slide (bytes_to_skip);
23045bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham                    log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
23145bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham                    if (log)
23245bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham                        log->Printf ("Pushing past prologue ");
23345bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham
234008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham                    m_sub_plan_sp = m_thread.QueueThreadPlanForRunToAddress(false, func_start_address,true);
23545bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham                }
2360e81b6475a71b32d1edf30a26487c003cc308bf3Jim Ingham            }
2370e81b6475a71b32d1edf30a26487c003cc308bf3Jim Ingham        }
23845bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham     }
2390e81b6475a71b32d1edf30a26487c003cc308bf3Jim Ingham
240008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham     if (!m_sub_plan_sp)
2410e81b6475a71b32d1edf30a26487c003cc308bf3Jim Ingham     {
24224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_no_more_plans = true;
24324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        SetPlanComplete();
24424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return true;
24524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
24624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
24724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
24824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_no_more_plans = false;
24924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
25024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
25124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
25224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
25324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
25424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanStepInRange::SetFlagsToDefault ()
25524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
25624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    GetFlags().Set(ThreadPlanStepInRange::s_default_flag_values);
25724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
25824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
259809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Inghamvoid
260809ab9bcd5eb7aa87fb662a89a327384f892b923Jim InghamThreadPlanStepInRange::SetAvoidRegexp(const char *name)
261809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham{
262809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham    if (m_avoid_regexp_ap.get() == NULL)
263809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham        m_avoid_regexp_ap.reset (new RegularExpression(name));
264809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham
265809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham    m_avoid_regexp_ap->Compile (name);
266809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham}
267809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham
26824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
26924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanStepInRange::SetDefaultFlagValue (uint32_t new_value)
27024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
27124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // TODO: Should we test this for sanity?
27224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ThreadPlanStepInRange::s_default_flag_values = new_value;
27324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
27424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
275809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Inghambool
276809ab9bcd5eb7aa87fb662a89a327384f892b923Jim InghamThreadPlanStepInRange::FrameMatchesAvoidRegexp ()
277809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham{
278809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham    StackFrame *frame = GetThread().GetStackFrameAtIndex(0).get();
279809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham
28073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    const RegularExpression *avoid_regexp_to_use = m_avoid_regexp_ap.get();
28120594b1b003f63ed34ebafeec37634ee44552339Jim Ingham    if (avoid_regexp_to_use == NULL)
28220594b1b003f63ed34ebafeec37634ee44552339Jim Ingham        avoid_regexp_to_use = GetThread().GetSymbolsToAvoidRegexp();
28320594b1b003f63ed34ebafeec37634ee44552339Jim Ingham
28420594b1b003f63ed34ebafeec37634ee44552339Jim Ingham    if (avoid_regexp_to_use != NULL)
285809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham    {
286002b3cff25840b4fb568f43f7d5c074ff8ba21f7Greg Clayton        SymbolContext sc = frame->GetSymbolContext(eSymbolContextFunction|eSymbolContextBlock|eSymbolContextSymbol);
287809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham        if (sc.symbol != NULL)
288809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham        {
289002b3cff25840b4fb568f43f7d5c074ff8ba21f7Greg Clayton            const char *frame_function_name = sc.GetFunctionName().GetCString();
290002b3cff25840b4fb568f43f7d5c074ff8ba21f7Greg Clayton            if (frame_function_name)
2915c38c31ecf3c53bad937d95d6701f804d56abac2Jim Ingham            {
29234a96b8d7def97af250fdeff1a1bb5e18cc9b71aJim Ingham                size_t num_matches = 0;
293952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton                Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
29434a96b8d7def97af250fdeff1a1bb5e18cc9b71aJim Ingham                if (log)
29534a96b8d7def97af250fdeff1a1bb5e18cc9b71aJim Ingham                    num_matches = 1;
29600af72e395d138f459192b7f5450fa4c7854f135Greg Clayton
29700af72e395d138f459192b7f5450fa4c7854f135Greg Clayton                RegularExpression::Match regex_match(num_matches);
29800af72e395d138f459192b7f5450fa4c7854f135Greg Clayton
29900af72e395d138f459192b7f5450fa4c7854f135Greg Clayton                bool return_value = avoid_regexp_to_use->Execute(frame_function_name, &regex_match);
3005c38c31ecf3c53bad937d95d6701f804d56abac2Jim Ingham                if (return_value)
3015c38c31ecf3c53bad937d95d6701f804d56abac2Jim Ingham                {
3025c38c31ecf3c53bad937d95d6701f804d56abac2Jim Ingham                    if (log)
30334a96b8d7def97af250fdeff1a1bb5e18cc9b71aJim Ingham                    {
30434a96b8d7def97af250fdeff1a1bb5e18cc9b71aJim Ingham                        std::string match;
30500af72e395d138f459192b7f5450fa4c7854f135Greg Clayton                        regex_match.GetMatchAtIndex(frame_function_name,0, match);
30634a96b8d7def97af250fdeff1a1bb5e18cc9b71aJim Ingham                        log->Printf ("Stepping out of function \"%s\" because it matches the avoid regexp \"%s\" - match substring: \"%s\".",
3075c38c31ecf3c53bad937d95d6701f804d56abac2Jim Ingham                                     frame_function_name,
30834a96b8d7def97af250fdeff1a1bb5e18cc9b71aJim Ingham                                     avoid_regexp_to_use->GetText(),
30934a96b8d7def97af250fdeff1a1bb5e18cc9b71aJim Ingham                                     match.c_str());
31034a96b8d7def97af250fdeff1a1bb5e18cc9b71aJim Ingham                    }
3115c38c31ecf3c53bad937d95d6701f804d56abac2Jim Ingham
3125c38c31ecf3c53bad937d95d6701f804d56abac2Jim Ingham                }
3135c38c31ecf3c53bad937d95d6701f804d56abac2Jim Ingham                return return_value;
3145c38c31ecf3c53bad937d95d6701f804d56abac2Jim Ingham            }
315809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham        }
316809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham    }
317809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham    return false;
318809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham}
319809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham
320008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim InghamThreadPlanSP
32124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanStepInRange::DefaultShouldStopHereCallback (ThreadPlan *current_plan, Flags &flags, void *baton)
32224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
323809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham    bool should_step_out = false;
324809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham    StackFrame *frame = current_plan->GetThread().GetStackFrameAtIndex(0).get();
325952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
326809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham
327f3d0b0c8081691128626eb496fdfcbf8ae54c1deGreg Clayton    if (flags.Test(eAvoidNoDebug))
32824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
32924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (!frame->HasDebugInformation())
330e4b8aeb376c2035fe45997d8ff7d44ad1a83b917Jim Ingham        {
331e4b8aeb376c2035fe45997d8ff7d44ad1a83b917Jim Ingham            if (log)
332e4b8aeb376c2035fe45997d8ff7d44ad1a83b917Jim Ingham                log->Printf ("Stepping out of frame with no debug info");
333e4b8aeb376c2035fe45997d8ff7d44ad1a83b917Jim Ingham
334809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham            should_step_out = true;
335e4b8aeb376c2035fe45997d8ff7d44ad1a83b917Jim Ingham        }
336809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham    }
337809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham
338f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham    if (current_plan->GetKind() == eKindStepInRange)
339809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham    {
340f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham        ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (current_plan);
341f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham        if (step_in_range_plan->m_step_into_target)
342f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham        {
343f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham            SymbolContext sc = frame->GetSymbolContext(eSymbolContextFunction|eSymbolContextBlock|eSymbolContextSymbol);
344f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham            if (sc.symbol != NULL)
345f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham            {
346f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham                // First try an exact match, since that's cheap with ConstStrings.  Then do a strstr compare.
347f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham                if (step_in_range_plan->m_step_into_target == sc.GetFunctionName())
348f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham                {
349f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham                    should_step_out = false;
350f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham                }
351f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham                else
352f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham                {
353f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham                    const char *target_name = step_in_range_plan->m_step_into_target.AsCString();
354f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham                    const char *function_name = sc.GetFunctionName().AsCString();
355f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham
356f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham                    if (function_name == NULL)
357f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham                        should_step_out = true;
358f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham                    else if (strstr (function_name, target_name) == NULL)
359f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham                        should_step_out = true;
360f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham                }
3615c38c31ecf3c53bad937d95d6701f804d56abac2Jim Ingham                if (log && should_step_out)
3625c38c31ecf3c53bad937d95d6701f804d56abac2Jim Ingham                    log->Printf("Stepping out of frame %s which did not match step into target %s.",
3635c38c31ecf3c53bad937d95d6701f804d56abac2Jim Ingham                                sc.GetFunctionName().AsCString(),
3645c38c31ecf3c53bad937d95d6701f804d56abac2Jim Ingham                                step_in_range_plan->m_step_into_target.AsCString());
365f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham            }
366f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham        }
367f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham
368f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham        if (!should_step_out)
36924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
3705c38c31ecf3c53bad937d95d6701f804d56abac2Jim Ingham            ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (current_plan);
3715c38c31ecf3c53bad937d95d6701f804d56abac2Jim Ingham            // Don't log the should_step_out here, it's easier to do it in FrameMatchesAvoidRegexp.
3725c38c31ecf3c53bad937d95d6701f804d56abac2Jim Ingham            should_step_out = step_in_range_plan->FrameMatchesAvoidRegexp ();
37324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
37424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
375809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham
376f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham
377809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham    if (should_step_out)
378809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham    {
379809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham        // FIXME: Make sure the ThreadPlanForStepOut does the right thing with inlined functions.
38023f2194bd1bb5efdc7a5aa8d8f3304d54d48deaaJim Ingham        // We really should have all plans take the tri-state for "stop others" so we can do the right
38123f2194bd1bb5efdc7a5aa8d8f3304d54d48deaaJim Ingham        // thing.  For now let's be safe and always run others when we are likely to run arbitrary code.
38223f2194bd1bb5efdc7a5aa8d8f3304d54d48deaaJim Ingham        const bool stop_others = false;
3831ebdcc7789aac1ef30ad6dcd485dff86c63136adGreg Clayton        return current_plan->GetThread().QueueThreadPlanForStepOut (false,
3841ebdcc7789aac1ef30ad6dcd485dff86c63136adGreg Clayton                                                                    NULL,
3851ebdcc7789aac1ef30ad6dcd485dff86c63136adGreg Clayton                                                                    true,
38623f2194bd1bb5efdc7a5aa8d8f3304d54d48deaaJim Ingham                                                                    stop_others,
3871ebdcc7789aac1ef30ad6dcd485dff86c63136adGreg Clayton                                                                    eVoteNo,
3881ebdcc7789aac1ef30ad6dcd485dff86c63136adGreg Clayton                                                                    eVoteNoOpinion,
3891ebdcc7789aac1ef30ad6dcd485dff86c63136adGreg Clayton                                                                    0); // Frame index
390809ab9bcd5eb7aa87fb662a89a327384f892b923Jim Ingham    }
39124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
392008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham    return ThreadPlanSP();
39324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
394707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham
395707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Inghambool
3967c79a27b955432dfd3ad9439640f0af2eccf37b8Jim InghamThreadPlanStepInRange::DoPlanExplainsStop (Event *event_ptr)
397707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham{
398707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham    // We always explain a stop.  Either we've just done a single step, in which
399707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham    // case we'll do our ordinary processing, or we stopped for some
400707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham    // reason that isn't handled by our sub-plans, in which case we want to just stop right
401707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham    // away.
402f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham    // In general, we don't want to mark the plan as complete for unexplained stops.
403f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham    // For instance, if you step in to some code with no debug info, so you step out
404f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham    // and in the course of that hit a breakpoint, then you want to stop & show the user
405f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham    // the breakpoint, but not unship the step in plan, since you still may want to complete that
406f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham    // plan when you continue.  This is particularly true when doing "step in to target function."
407f2ca573e8dc034ecc5050a874d8f01ace0703e18Jim Ingham    // stepping.
408707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham    //
409707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham    // The only variation is that if we are doing "step by running to next branch" in which case
410707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham    // if we hit our branch breakpoint we don't set the plan to complete.
4117c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham
4127c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham    bool return_value;
413707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham
41445bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham    if (m_virtual_step)
415707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham    {
4167c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham        return_value = true;
4177c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham    }
4187c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham    else
4197c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham    {
42004cc48eb5cff32268a822b57f87590c9dc2643f8Jim Ingham        StopInfoSP stop_info_sp = GetPrivateStopInfo ();
4217c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham        if (stop_info_sp)
422707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham        {
4237c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham            StopReason reason = stop_info_sp->GetStopReason();
4247c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham
4257c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham            switch (reason)
4260c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham            {
4277c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham            case eStopReasonBreakpoint:
4287c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham                if (NextRangeBreakpointExplainsStop(stop_info_sp))
4297c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham                {
4307c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham                    return_value = true;
4317c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham                    break;
4327c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham                }
4337c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham            case eStopReasonWatchpoint:
4347c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham            case eStopReasonSignal:
4357c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham            case eStopReasonException:
4367c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham            case eStopReasonExec:
4377c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham            case eStopReasonThreadExiting:
4387c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham                {
4397c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham                    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
4407c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham                    if (log)
4417c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham                        log->PutCString ("ThreadPlanStepInRange got asked if it explains the stop for some reason other than step.");
4427c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham                }
4437c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham                return_value = false;
4447c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham                break;
4457c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham            default:
4467c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham                return_value = true;
4477c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham                break;
4480c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham            }
449707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham        }
4507c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham        else
4517c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham            return_value = true;
452707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham    }
4537c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham
4547c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham    return return_value;
455707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham}
4560c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham
4570c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Inghambool
4587c79a27b955432dfd3ad9439640f0af2eccf37b8Jim InghamThreadPlanStepInRange::DoWillResume (lldb::StateType resume_state, bool current_plan)
4590c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham{
4600c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham    if (resume_state == eStateStepping && current_plan)
4610c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham    {
4620c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        // See if we are about to step over a virtual inlined call.
4630c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        bool step_without_resume = m_thread.DecrementCurrentInlinedDepth();
4640c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        if (step_without_resume)
4650c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        {
466952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
4670c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham            if (log)
4687c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham                log->Printf ("ThreadPlanStepInRange::DoWillResume: returning false, inline_depth: %d",
4690c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham                             m_thread.GetCurrentInlinedDepth());
4700c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham            SetStopInfo(StopInfo::CreateStopReasonToTrace(m_thread));
47145bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham
47245bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham            // FIXME: Maybe it would be better to create a InlineStep stop reason, but then
47345bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham            // the whole rest of the world would have to handle that stop reason.
47445bc4a2bce24f397445ced0e8327fc0ad9a5b801Jim Ingham            m_virtual_step = true;
4750c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        }
4760c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham        return !step_without_resume;
4770c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham    }
4787c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham    return true;
4790c8fa2d7dd18ae1816c82846234c45f79142e3dfJim Ingham}
480375ba883a11c84b7eb27f6f04751aea878e3e9b0Daniel Malea
481375ba883a11c84b7eb27f6f04751aea878e3e9b0Daniel Maleabool
482375ba883a11c84b7eb27f6f04751aea878e3e9b0Daniel MaleaThreadPlanStepInRange::IsVirtualStep()
483375ba883a11c84b7eb27f6f04751aea878e3e9b0Daniel Malea{
484375ba883a11c84b7eb27f6f04751aea878e3e9b0Daniel Malea  return m_virtual_step;
485375ba883a11c84b7eb27f6f04751aea878e3e9b0Daniel Malea}
486