124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- ThreadPlanStepThrough.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/ThreadPlanStepThrough.h"
1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C Includes
1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C++ Includes
1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Other libraries and framework includes
1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Project includes
1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/lldb-private-log.h"
1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Log.h"
1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Stream.h"
1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/DynamicLoader.h"
20b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham#include "lldb/Target/ObjCLanguageRuntime.h"
2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/Process.h"
2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/RegisterContext.h"
23ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham#include "lldb/Target/Target.h"
24ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham#include "lldb/Breakpoint/Breakpoint.h"
2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb;
2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private;
2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// ThreadPlanStepThrough: If the current instruction is a trampoline, step through it
3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// If it is the beginning of the prologue of a function, step through that as well.
3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// FIXME: At present only handles DYLD trampolines.
3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
35038fa8e30621e0e55faed3479387d811986f28b7Jim InghamThreadPlanStepThrough::ThreadPlanStepThrough (Thread &thread, StackID &m_stack_id, bool stop_others) :
365a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham    ThreadPlan (ThreadPlan::eKindStepThrough, "Step through trampolines and prologues", thread, eVoteNoOpinion, eVoteNoOpinion),
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_start_address (0),
38ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    m_backstop_bkpt_id (LLDB_INVALID_BREAK_ID),
39ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    m_backstop_addr(LLDB_INVALID_ADDRESS),
40038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham    m_return_stack_id (m_stack_id),
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_stop_others (stop_others)
4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
43ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham
44ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    LookForPlanToStepThroughFromCurrentPC();
45ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham
46ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    // If we don't get a valid step through plan, don't bother to set up a backstop.
47ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    if (m_sub_plan_sp)
48ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    {
49ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        m_start_address = GetThread().GetRegisterContext()->GetPC(0);
5041ce4f1706ddd3a092c331ff15917e7f600f2e94Jim Ingham
51ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        // We are going to return back to the concrete frame 1, we might pass by some inlined code that we're in
52ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        // the middle of by doing this, but it's easier than trying to figure out where the inlined code might return to.
53ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham
54038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham        StackFrameSP return_frame_sp = m_thread.GetFrameWithStackID (m_stack_id);
55ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham
56ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        if (return_frame_sp)
57ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        {
58f4124deeb9532044a38c0774ced872f2709347daGreg Clayton            m_backstop_addr = return_frame_sp->GetFrameCodeAddress().GetLoadAddress(m_thread.CalculateTarget().get());
59f4124deeb9532044a38c0774ced872f2709347daGreg Clayton            Breakpoint *return_bp = m_thread.GetProcess()->GetTarget().CreateBreakpoint (m_backstop_addr, true).get();
60ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham            if (return_bp != NULL)
61ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham            {
62ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham                return_bp->SetThreadID(m_thread.GetID());
63ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham                m_backstop_bkpt_id = return_bp->GetID();
64090f83176695d86197b0e86b67dee4160ec5003dJim Ingham                return_bp->SetBreakpointKind("step-through-backstop");
65ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham            }
66952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
67ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham            if (log)
68ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham            {
695f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea                log->Printf ("Setting backstop breakpoint %d at address: 0x%" PRIx64, m_backstop_bkpt_id, m_backstop_addr);
70ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham            }
71ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        }
72ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    }
7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanStepThrough::~ThreadPlanStepThrough ()
7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
77038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham    ClearBackstopBreakpoint ();
78ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham}
79ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham
80ad382c523709e86f01bfea27f1991df9afeef2ddJim Inghamvoid
81ad382c523709e86f01bfea27f1991df9afeef2ddJim InghamThreadPlanStepThrough::DidPush ()
82ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham{
83ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    if (m_sub_plan_sp)
84ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        PushPlan(m_sub_plan_sp);
85ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham}
86ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham
87ad382c523709e86f01bfea27f1991df9afeef2ddJim Inghamvoid
88ad382c523709e86f01bfea27f1991df9afeef2ddJim InghamThreadPlanStepThrough::LookForPlanToStepThroughFromCurrentPC()
89ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham{
90f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    m_sub_plan_sp = m_thread.GetProcess()->GetDynamicLoader()->GetStepThroughTrampolinePlan (m_thread, m_stop_others);
91ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    // If that didn't come up with anything, try the ObjC runtime plugin:
92ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    if (!m_sub_plan_sp.get())
93ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    {
94f4124deeb9532044a38c0774ced872f2709347daGreg Clayton        ObjCLanguageRuntime *objc_runtime = m_thread.GetProcess()->GetObjCLanguageRuntime();
95ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        if (objc_runtime)
96ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham            m_sub_plan_sp = objc_runtime->GetStepThroughTrampolinePlan (m_thread, m_stop_others);
97ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    }
98ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham
99952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
100ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    if (log)
101ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    {
102ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        lldb::addr_t current_address = GetThread().GetRegisterContext()->GetPC(0);
103ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        if (m_sub_plan_sp)
104ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        {
105ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham            StreamString s;
106ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham            m_sub_plan_sp->GetDescription(&s, lldb::eDescriptionLevelFull);
1075f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea            log->Printf ("Found step through plan from 0x%" PRIx64 ": %s", current_address, s.GetData());
108ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        }
109ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        else
110ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        {
1115f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea            log->Printf ("Couldn't find step through plan from address 0x%" PRIx64 ".", current_address);
112ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        }
113ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    }
11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanStepThrough::GetDescription (Stream *s, lldb::DescriptionLevel level)
11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (level == lldb::eDescriptionLevelBrief)
12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        s->Printf ("Step through");
12124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
123ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        s->PutCString ("Stepping through trampoline code from: ");
12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        s->Address(m_start_address, sizeof (addr_t));
125ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        if (m_backstop_bkpt_id != LLDB_INVALID_BREAK_ID)
126ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        {
127ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham            s->Printf (" with backstop breakpoint id: %d at address: ", m_backstop_bkpt_id);
128ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham            s->Address (m_backstop_addr, sizeof (addr_t));
129ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        }
130ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        else
131ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham            s->PutCString (" unable to set a backstop breakpoint.");
13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanStepThrough::ValidatePlan (Stream *error)
13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
138ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    return m_sub_plan_sp.get() != NULL;
13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
1427c79a27b955432dfd3ad9439640f0af2eccf37b8Jim InghamThreadPlanStepThrough::DoPlanExplainsStop (Event *event_ptr)
14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
144ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    // If we have a sub-plan, it will have been asked first if we explain the stop, and
145ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    // we won't get asked.  The only time we would be the one directly asked this question
146ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    // is if we hit our backstop breakpoint.
147ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham
148ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    if (HitOurBackstopBreakpoint())
149ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        return true;
150ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    else
151ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        return false;
15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanStepThrough::ShouldStop (Event *event_ptr)
15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
157ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    // If we've already marked ourselves done, then we're done...
158ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    if (IsPlanComplete())
159ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        return true;
160ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham
161038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham    // First, did we hit the backstop breakpoint?
162038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham    if (HitOurBackstopBreakpoint())
163038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham    {
164038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham        SetPlanComplete(false);
165038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham        return true;
166038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham    }
167038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham
168ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    // If we don't have a sub-plan, then we're also done (can't see how we would ever get here
169ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    // without a plan, but just in case.
170ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham
171ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    if (!m_sub_plan_sp)
172ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    {
173ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        SetPlanComplete();
174ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        return true;
175ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    }
176ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham
177ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    // If the current sub plan is not done, we don't want to stop.  Actually, we probably won't
178ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    // ever get here in this state, since we generally won't get asked any questions if out
179ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    // current sub-plan is not done...
180ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    if (!m_sub_plan_sp->IsPlanComplete())
181038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham        return false;
182038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham
183038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham    // If our current sub plan failed, then let's just run to our backstop.  If we can't do that then just stop.
184038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham    if (!m_sub_plan_sp->PlanSucceeded())
185038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham    {
186038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham        if (m_backstop_bkpt_id != LLDB_INVALID_BREAK_ID)
187038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham        {
188038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham            m_sub_plan_sp.reset();
189ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham            return false;
190038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham        }
191038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham        else
192038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham        {
193038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham            SetPlanComplete(false);
194038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham            return true;
195038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham        }
196038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham    }
197038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham
198ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    // Next see if there is a specific step through plan at our current pc (these might
199ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    // chain, for instance stepping through a dylib trampoline to the objc dispatch function...)
200ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    LookForPlanToStepThroughFromCurrentPC();
201ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    if (m_sub_plan_sp)
202ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    {
203ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        PushPlan (m_sub_plan_sp);
204ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        return false;
205ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    }
206ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    else
207ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    {
208ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        SetPlanComplete();
209ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        return true;
210ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    }
21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
21224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
21324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
21424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanStepThrough::StopOthers ()
21524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
21624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return m_stop_others;
21724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
21824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerStateType
220745ac7a5826fe7c392007941a4046bfb1a8dff81Jim InghamThreadPlanStepThrough::GetPlanRunState ()
22124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
222038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham    return eStateRunning;
22324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
22424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
22524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
2267c79a27b955432dfd3ad9439640f0af2eccf37b8Jim InghamThreadPlanStepThrough::DoWillResume (StateType resume_state, bool current_plan)
22724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
22824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return true;
22924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
23024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
23124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
23224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanStepThrough::WillStop ()
23324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
23424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return true;
23524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
23624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
237038fa8e30621e0e55faed3479387d811986f28b7Jim Inghamvoid
238038fa8e30621e0e55faed3479387d811986f28b7Jim InghamThreadPlanStepThrough::ClearBackstopBreakpoint ()
239038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham{
240038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham    if (m_backstop_bkpt_id != LLDB_INVALID_BREAK_ID)
241038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham    {
242038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham        m_thread.GetProcess()->GetTarget().RemoveBreakpointByID (m_backstop_bkpt_id);
243038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham        m_backstop_bkpt_id = LLDB_INVALID_BREAK_ID;
244038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham    }
245038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham}
246038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham
24724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
24824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanStepThrough::MischiefManaged ()
24924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
250952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
25124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
252ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    if (!IsPlanComplete())
25324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
25424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
25524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
25624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
25724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
25824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (log)
25924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            log->Printf("Completed step through step plan.");
260038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham
261038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham        ClearBackstopBreakpoint ();
26224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ThreadPlan::MischiefManaged ();
26324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return true;
26424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
26524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
26624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
26724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
268ad382c523709e86f01bfea27f1991df9afeef2ddJim InghamThreadPlanStepThrough::HitOurBackstopBreakpoint()
26924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
270ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    StopInfoSP stop_info_sp(m_thread.GetStopInfo());
271ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint)
272ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    {
273ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        break_id_t stop_value = (break_id_t) stop_info_sp->GetValue();
274f4124deeb9532044a38c0774ced872f2709347daGreg Clayton        BreakpointSiteSP cur_site_sp = m_thread.GetProcess()->GetBreakpointSiteList().FindByID(stop_value);
275ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        if (cur_site_sp && cur_site_sp->IsBreakpointAtThisSite(m_backstop_bkpt_id))
276ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        {
27741ce4f1706ddd3a092c331ff15917e7f600f2e94Jim Ingham            StackID cur_frame_zero_id = m_thread.GetStackFrameAtIndex(0)->GetStackID();
27841ce4f1706ddd3a092c331ff15917e7f600f2e94Jim Ingham
279038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham            if (cur_frame_zero_id == m_return_stack_id)
280ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham            {
281952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton                Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
282ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham                if (log)
283ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham                    log->PutCString ("ThreadPlanStepThrough hit backstop breakpoint.");
284ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham                return true;
285ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham            }
286ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham        }
287ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    }
288ad382c523709e86f01bfea27f1991df9afeef2ddJim Ingham    return false;
28924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
29024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
291