130fdc8d8SChris Lattner //===-- ThreadPlanStepOut.cpp -----------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1030fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOut.h"
1130fdc8d8SChris Lattner 
1230fdc8d8SChris Lattner // C Includes
1330fdc8d8SChris Lattner // C++ Includes
1430fdc8d8SChris Lattner // Other libraries and framework includes
1530fdc8d8SChris Lattner // Project includes
1630fdc8d8SChris Lattner #include "lldb/Breakpoint/Breakpoint.h"
1730fdc8d8SChris Lattner #include "lldb/lldb-private-log.h"
1830fdc8d8SChris Lattner #include "lldb/Core/Log.h"
1930fdc8d8SChris Lattner #include "lldb/Target/Process.h"
2030fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h"
21f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h"
2230fdc8d8SChris Lattner #include "lldb/Target/Target.h"
23*a5ce6c88SJim Ingham #include "lldb/Target/ThreadPlanStepOverRange.h"
2430fdc8d8SChris Lattner 
2530fdc8d8SChris Lattner using namespace lldb;
2630fdc8d8SChris Lattner using namespace lldb_private;
2730fdc8d8SChris Lattner 
2830fdc8d8SChris Lattner //----------------------------------------------------------------------
2930fdc8d8SChris Lattner // ThreadPlanStepOut: Step out of the current frame
3030fdc8d8SChris Lattner //----------------------------------------------------------------------
3130fdc8d8SChris Lattner 
3230fdc8d8SChris Lattner ThreadPlanStepOut::ThreadPlanStepOut
3330fdc8d8SChris Lattner (
3430fdc8d8SChris Lattner     Thread &thread,
3530fdc8d8SChris Lattner     SymbolContext *context,
3630fdc8d8SChris Lattner     bool first_insn,
3730fdc8d8SChris Lattner     bool stop_others,
3830fdc8d8SChris Lattner     Vote stop_vote,
39481cef25SGreg Clayton     Vote run_vote,
40481cef25SGreg Clayton     uint32_t frame_idx
4130fdc8d8SChris Lattner ) :
42b01e742aSJim Ingham     ThreadPlan (ThreadPlan::eKindStepOut, "Step out", thread, stop_vote, run_vote),
4330fdc8d8SChris Lattner     m_step_from_context (context),
4430fdc8d8SChris Lattner     m_step_from_insn (LLDB_INVALID_ADDRESS),
451ee0d4f7SBenjamin Kramer     m_return_bp_id (LLDB_INVALID_BREAK_ID),
4630fdc8d8SChris Lattner     m_return_addr (LLDB_INVALID_ADDRESS),
4730fdc8d8SChris Lattner     m_first_insn (first_insn),
48*a5ce6c88SJim Ingham     m_stop_others (stop_others),
49*a5ce6c88SJim Ingham     m_step_through_inline_plan_sp(),
50*a5ce6c88SJim Ingham     m_step_out_plan_sp ()
51*a5ce6c88SJim Ingham 
5230fdc8d8SChris Lattner {
5330fdc8d8SChris Lattner     m_step_from_insn = m_thread.GetRegisterContext()->GetPC(0);
5430fdc8d8SChris Lattner 
55*a5ce6c88SJim Ingham     StackFrameSP return_frame_sp (m_thread.GetStackFrameAtIndex(frame_idx + 1));
56*a5ce6c88SJim Ingham     StackFrameSP immediate_return_from_sp (m_thread.GetStackFrameAtIndex (frame_idx));
57*a5ce6c88SJim Ingham 
58*a5ce6c88SJim Ingham     m_stack_depth = m_thread.GetStackFrameCount() - frame_idx;
59*a5ce6c88SJim Ingham 
60*a5ce6c88SJim Ingham     // If the frame directly below the one we are returning to is inlined, we have to be
61*a5ce6c88SJim Ingham     // a little more careful.  It is non-trivial to determine the real "return code address" for
62*a5ce6c88SJim Ingham     // an inlined frame, so we have to work our way to that frame and then step out.
63*a5ce6c88SJim Ingham     if (immediate_return_from_sp && immediate_return_from_sp->IsInlined())
64*a5ce6c88SJim Ingham     {
65*a5ce6c88SJim Ingham         if (frame_idx > 0)
66*a5ce6c88SJim Ingham         {
67*a5ce6c88SJim Ingham             // First queue a plan that gets us to this inlined frame, and when we get there we'll queue a second
68*a5ce6c88SJim Ingham             // plan that walks us out of this frame.
69*a5ce6c88SJim Ingham             m_step_out_plan_sp.reset (new ThreadPlanStepOut(m_thread, NULL, false, stop_others, eVoteNoOpinion, eVoteNoOpinion, frame_idx - 1));
70*a5ce6c88SJim Ingham             m_step_out_plan_sp->SetOkayToDiscard(true);
71*a5ce6c88SJim Ingham         }
72*a5ce6c88SJim Ingham         else
73*a5ce6c88SJim Ingham         {
74*a5ce6c88SJim Ingham             // If we're already at the inlined frame we're stepping through, then just do that now.
75*a5ce6c88SJim Ingham             QueueInlinedStepPlan(false);
76*a5ce6c88SJim Ingham         }
77*a5ce6c88SJim Ingham 
78*a5ce6c88SJim Ingham     }
79*a5ce6c88SJim Ingham     else if (return_frame_sp)
80*a5ce6c88SJim Ingham     {
8130fdc8d8SChris Lattner         // Find the return address and set a breakpoint there:
8230fdc8d8SChris Lattner         // FIXME - can we do this more securely if we know first_insn?
8330fdc8d8SChris Lattner 
84*a5ce6c88SJim Ingham         m_return_addr = return_frame_sp->GetFrameCodeAddress().GetLoadAddress(&m_thread.GetProcess().GetTarget());
8530fdc8d8SChris Lattner         Breakpoint *return_bp = m_thread.GetProcess().GetTarget().CreateBreakpoint (m_return_addr, true).get();
8630fdc8d8SChris Lattner         if (return_bp != NULL)
8730fdc8d8SChris Lattner         {
8830fdc8d8SChris Lattner             return_bp->SetThreadID(m_thread.GetID());
8930fdc8d8SChris Lattner             m_return_bp_id = return_bp->GetID();
9030fdc8d8SChris Lattner         }
9130fdc8d8SChris Lattner     }
9230fdc8d8SChris Lattner 
93*a5ce6c88SJim Ingham }
94*a5ce6c88SJim Ingham 
95*a5ce6c88SJim Ingham void
96*a5ce6c88SJim Ingham ThreadPlanStepOut::DidPush()
97*a5ce6c88SJim Ingham {
98*a5ce6c88SJim Ingham     if (m_step_out_plan_sp)
99*a5ce6c88SJim Ingham         m_thread.QueueThreadPlan(m_step_out_plan_sp, false);
100*a5ce6c88SJim Ingham     else if (m_step_through_inline_plan_sp)
101*a5ce6c88SJim Ingham         m_thread.QueueThreadPlan(m_step_through_inline_plan_sp, false);
10230fdc8d8SChris Lattner }
10330fdc8d8SChris Lattner 
10430fdc8d8SChris Lattner ThreadPlanStepOut::~ThreadPlanStepOut ()
10530fdc8d8SChris Lattner {
10630fdc8d8SChris Lattner     if (m_return_bp_id != LLDB_INVALID_BREAK_ID)
10730fdc8d8SChris Lattner         m_thread.GetProcess().GetTarget().RemoveBreakpointByID(m_return_bp_id);
10830fdc8d8SChris Lattner }
10930fdc8d8SChris Lattner 
11030fdc8d8SChris Lattner void
11130fdc8d8SChris Lattner ThreadPlanStepOut::GetDescription (Stream *s, lldb::DescriptionLevel level)
11230fdc8d8SChris Lattner {
11330fdc8d8SChris Lattner     if (level == lldb::eDescriptionLevelBrief)
11430fdc8d8SChris Lattner         s->Printf ("step out");
11530fdc8d8SChris Lattner     else
11630fdc8d8SChris Lattner     {
117*a5ce6c88SJim Ingham         if (m_step_out_plan_sp)
118*a5ce6c88SJim Ingham             s->Printf ("Stepping out to inlined frame at depth: %d so we can walk through it.", m_stack_depth);
119*a5ce6c88SJim Ingham         else if (m_step_through_inline_plan_sp)
120*a5ce6c88SJim Ingham             s->Printf ("Stepping out by stepping through inlined function.");
121*a5ce6c88SJim Ingham         else
122*a5ce6c88SJim Ingham             s->Printf ("Stepping out from address 0x%llx to return address 0x%llx at depth: %d using breakpoint site %d",
12330fdc8d8SChris Lattner                        (uint64_t)m_step_from_insn,
12430fdc8d8SChris Lattner                        (uint64_t)m_return_addr,
125*a5ce6c88SJim Ingham                        m_stack_depth,
12630fdc8d8SChris Lattner                        m_return_bp_id);
12730fdc8d8SChris Lattner     }
12830fdc8d8SChris Lattner }
12930fdc8d8SChris Lattner 
13030fdc8d8SChris Lattner bool
13130fdc8d8SChris Lattner ThreadPlanStepOut::ValidatePlan (Stream *error)
13230fdc8d8SChris Lattner {
133*a5ce6c88SJim Ingham     if (m_step_out_plan_sp)
134*a5ce6c88SJim Ingham         return m_step_out_plan_sp->ValidatePlan (error);
135*a5ce6c88SJim Ingham     else if (m_step_through_inline_plan_sp)
136*a5ce6c88SJim Ingham         return m_step_through_inline_plan_sp->ValidatePlan (error);
137*a5ce6c88SJim Ingham     else if (m_return_bp_id == LLDB_INVALID_BREAK_ID)
138*a5ce6c88SJim Ingham     {
139*a5ce6c88SJim Ingham         error->PutCString("Could not create return address breakpoint.");
14030fdc8d8SChris Lattner         return false;
141*a5ce6c88SJim Ingham     }
14230fdc8d8SChris Lattner     else
14330fdc8d8SChris Lattner         return true;
14430fdc8d8SChris Lattner }
14530fdc8d8SChris Lattner 
14630fdc8d8SChris Lattner bool
14730fdc8d8SChris Lattner ThreadPlanStepOut::PlanExplainsStop ()
14830fdc8d8SChris Lattner {
149*a5ce6c88SJim Ingham     // If one of our child plans just finished, then we do explain the stop.
150*a5ce6c88SJim Ingham     if (m_step_out_plan_sp)
151*a5ce6c88SJim Ingham     {
152*a5ce6c88SJim Ingham         if (m_step_out_plan_sp->MischiefManaged())
153*a5ce6c88SJim Ingham         {
154*a5ce6c88SJim Ingham             // If this one is done, then we are all done.
155*a5ce6c88SJim Ingham             SetPlanComplete();
156*a5ce6c88SJim Ingham             return true;
157*a5ce6c88SJim Ingham         }
158*a5ce6c88SJim Ingham         else
159*a5ce6c88SJim Ingham             return false;
160*a5ce6c88SJim Ingham     }
161*a5ce6c88SJim Ingham     else if (m_step_through_inline_plan_sp)
162*a5ce6c88SJim Ingham     {
163*a5ce6c88SJim Ingham         if (m_step_through_inline_plan_sp->MischiefManaged())
164*a5ce6c88SJim Ingham             return true;
165*a5ce6c88SJim Ingham         else
166*a5ce6c88SJim Ingham             return false;
167*a5ce6c88SJim Ingham     }
168*a5ce6c88SJim Ingham 
16930fdc8d8SChris Lattner     // We don't explain signals or breakpoints (breakpoints that handle stepping in or
17030fdc8d8SChris Lattner     // out will be handled by a child plan.
171*a5ce6c88SJim Ingham 
172b15bfc75SJim Ingham     StopInfoSP stop_info_sp = GetPrivateStopReason();
173b15bfc75SJim Ingham     if (stop_info_sp)
17430fdc8d8SChris Lattner     {
175b15bfc75SJim Ingham         StopReason reason = stop_info_sp->GetStopReason();
17630fdc8d8SChris Lattner         switch (reason)
17730fdc8d8SChris Lattner         {
17830fdc8d8SChris Lattner         case eStopReasonBreakpoint:
17930fdc8d8SChris Lattner         {
18030fdc8d8SChris Lattner             // If this is OUR breakpoint, we're fine, otherwise we don't know why this happened...
181b15bfc75SJim Ingham             BreakpointSiteSP site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (stop_info_sp->GetValue()));
182f4b47e15SGreg Clayton             if (site_sp && site_sp->IsBreakpointAtThisSite (m_return_bp_id))
18330fdc8d8SChris Lattner             {
184481cef25SGreg Clayton                 const uint32_t num_frames = m_thread.GetStackFrameCount();
185b0616a6fSJohnny Chen                 if (m_stack_depth > num_frames)
186481cef25SGreg Clayton                     SetPlanComplete();
187481cef25SGreg Clayton 
18830fdc8d8SChris Lattner                 // If there was only one owner, then we're done.  But if we also hit some
18930fdc8d8SChris Lattner                 // user breakpoint on our way out, we should mark ourselves as done, but
19030fdc8d8SChris Lattner                 // also not claim to explain the stop, since it is more important to report
19130fdc8d8SChris Lattner                 // the user breakpoint than the step out completion.
19230fdc8d8SChris Lattner 
193f4b47e15SGreg Clayton                 if (site_sp->GetNumberOfOwners() == 1)
19430fdc8d8SChris Lattner                     return true;
195f4b47e15SGreg Clayton 
19630fdc8d8SChris Lattner             }
19730fdc8d8SChris Lattner             return false;
19830fdc8d8SChris Lattner         }
19930fdc8d8SChris Lattner         case eStopReasonWatchpoint:
20030fdc8d8SChris Lattner         case eStopReasonSignal:
20130fdc8d8SChris Lattner         case eStopReasonException:
20230fdc8d8SChris Lattner             return false;
203f4b47e15SGreg Clayton 
20430fdc8d8SChris Lattner         default:
20530fdc8d8SChris Lattner             return true;
20630fdc8d8SChris Lattner         }
20730fdc8d8SChris Lattner     }
20830fdc8d8SChris Lattner     return true;
20930fdc8d8SChris Lattner }
21030fdc8d8SChris Lattner 
21130fdc8d8SChris Lattner bool
21230fdc8d8SChris Lattner ThreadPlanStepOut::ShouldStop (Event *event_ptr)
21330fdc8d8SChris Lattner {
214*a5ce6c88SJim Ingham         if (IsPlanComplete())
215*a5ce6c88SJim Ingham         {
216*a5ce6c88SJim Ingham             return true;
217*a5ce6c88SJim Ingham         }
218*a5ce6c88SJim Ingham         else if (m_stack_depth > m_thread.GetStackFrameCount())
21930fdc8d8SChris Lattner         {
22030fdc8d8SChris Lattner             SetPlanComplete();
22130fdc8d8SChris Lattner             return true;
22230fdc8d8SChris Lattner         }
22330fdc8d8SChris Lattner         else
224*a5ce6c88SJim Ingham         {
225*a5ce6c88SJim Ingham             if (m_step_out_plan_sp)
226*a5ce6c88SJim Ingham             {
227*a5ce6c88SJim Ingham                 if (m_step_out_plan_sp->MischiefManaged())
228*a5ce6c88SJim Ingham                 {
229*a5ce6c88SJim Ingham                     // Now step through the inlined stack we are in:
230*a5ce6c88SJim Ingham                     if (QueueInlinedStepPlan(true))
231*a5ce6c88SJim Ingham                     {
23230fdc8d8SChris Lattner                         return false;
23330fdc8d8SChris Lattner                     }
234*a5ce6c88SJim Ingham                     else
235*a5ce6c88SJim Ingham                     {
236*a5ce6c88SJim Ingham                         SetPlanComplete ();
237*a5ce6c88SJim Ingham                         return true;
238*a5ce6c88SJim Ingham                     }
239*a5ce6c88SJim Ingham                 }
240*a5ce6c88SJim Ingham                 else
241*a5ce6c88SJim Ingham                     return m_step_out_plan_sp->ShouldStop(event_ptr);
242*a5ce6c88SJim Ingham             }
243*a5ce6c88SJim Ingham             else if (m_step_through_inline_plan_sp)
244*a5ce6c88SJim Ingham             {
245*a5ce6c88SJim Ingham                 if (m_step_through_inline_plan_sp->MischiefManaged())
246*a5ce6c88SJim Ingham                 {
247*a5ce6c88SJim Ingham                     SetPlanComplete();
248*a5ce6c88SJim Ingham                     return true;
249*a5ce6c88SJim Ingham                 }
250*a5ce6c88SJim Ingham                 else
251*a5ce6c88SJim Ingham                     return m_step_through_inline_plan_sp->ShouldStop(event_ptr);
252*a5ce6c88SJim Ingham             }
253*a5ce6c88SJim Ingham             else
254*a5ce6c88SJim Ingham                 return false;
255*a5ce6c88SJim Ingham         }
256*a5ce6c88SJim Ingham }
25730fdc8d8SChris Lattner 
25830fdc8d8SChris Lattner bool
25930fdc8d8SChris Lattner ThreadPlanStepOut::StopOthers ()
26030fdc8d8SChris Lattner {
26130fdc8d8SChris Lattner     return m_stop_others;
26230fdc8d8SChris Lattner }
26330fdc8d8SChris Lattner 
26430fdc8d8SChris Lattner StateType
26506e827ccSJim Ingham ThreadPlanStepOut::GetPlanRunState ()
26630fdc8d8SChris Lattner {
26730fdc8d8SChris Lattner     return eStateRunning;
26830fdc8d8SChris Lattner }
26930fdc8d8SChris Lattner 
27030fdc8d8SChris Lattner bool
27130fdc8d8SChris Lattner ThreadPlanStepOut::WillResume (StateType resume_state, bool current_plan)
27230fdc8d8SChris Lattner {
27330fdc8d8SChris Lattner     ThreadPlan::WillResume (resume_state, current_plan);
274*a5ce6c88SJim Ingham     if (m_step_out_plan_sp || m_step_through_inline_plan_sp)
275*a5ce6c88SJim Ingham         return true;
276*a5ce6c88SJim Ingham 
27730fdc8d8SChris Lattner     if (m_return_bp_id == LLDB_INVALID_BREAK_ID)
27830fdc8d8SChris Lattner         return false;
27930fdc8d8SChris Lattner 
28030fdc8d8SChris Lattner     if (current_plan)
28130fdc8d8SChris Lattner     {
28230fdc8d8SChris Lattner         Breakpoint *return_bp = m_thread.GetProcess().GetTarget().GetBreakpointByID(m_return_bp_id).get();
28330fdc8d8SChris Lattner         if (return_bp != NULL)
28430fdc8d8SChris Lattner             return_bp->SetEnabled (true);
28530fdc8d8SChris Lattner     }
28630fdc8d8SChris Lattner     return true;
28730fdc8d8SChris Lattner }
28830fdc8d8SChris Lattner 
28930fdc8d8SChris Lattner bool
29030fdc8d8SChris Lattner ThreadPlanStepOut::WillStop ()
29130fdc8d8SChris Lattner {
292*a5ce6c88SJim Ingham     if (m_return_bp_id != LLDB_INVALID_BREAK_ID)
293*a5ce6c88SJim Ingham     {
29430fdc8d8SChris Lattner         Breakpoint *return_bp = m_thread.GetProcess().GetTarget().GetBreakpointByID(m_return_bp_id).get();
29530fdc8d8SChris Lattner         if (return_bp != NULL)
29630fdc8d8SChris Lattner             return_bp->SetEnabled (false);
297*a5ce6c88SJim Ingham     }
298*a5ce6c88SJim Ingham 
29930fdc8d8SChris Lattner     return true;
30030fdc8d8SChris Lattner }
30130fdc8d8SChris Lattner 
30230fdc8d8SChris Lattner bool
30330fdc8d8SChris Lattner ThreadPlanStepOut::MischiefManaged ()
30430fdc8d8SChris Lattner {
305*a5ce6c88SJim Ingham     if (IsPlanComplete())
30630fdc8d8SChris Lattner     {
30730fdc8d8SChris Lattner         // Did I reach my breakpoint?  If so I'm done.
30830fdc8d8SChris Lattner         //
30930fdc8d8SChris Lattner         // I also check the stack depth, since if we've blown past the breakpoint for some
31030fdc8d8SChris Lattner         // reason and we're now stopping for some other reason altogether, then we're done
31130fdc8d8SChris Lattner         // with this step out operation.
31230fdc8d8SChris Lattner 
3132d4edfbcSGreg Clayton         LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
31430fdc8d8SChris Lattner         if (log)
31530fdc8d8SChris Lattner             log->Printf("Completed step out plan.");
316*a5ce6c88SJim Ingham         if (m_return_bp_id != LLDB_INVALID_BREAK_ID)
317*a5ce6c88SJim Ingham         {
31830fdc8d8SChris Lattner             m_thread.GetProcess().GetTarget().RemoveBreakpointByID (m_return_bp_id);
31930fdc8d8SChris Lattner             m_return_bp_id = LLDB_INVALID_BREAK_ID;
320*a5ce6c88SJim Ingham         }
321*a5ce6c88SJim Ingham 
32230fdc8d8SChris Lattner         ThreadPlan::MischiefManaged ();
32330fdc8d8SChris Lattner         return true;
32430fdc8d8SChris Lattner     }
32530fdc8d8SChris Lattner     else
32630fdc8d8SChris Lattner     {
32730fdc8d8SChris Lattner         return false;
32830fdc8d8SChris Lattner     }
32930fdc8d8SChris Lattner }
33030fdc8d8SChris Lattner 
331*a5ce6c88SJim Ingham bool
332*a5ce6c88SJim Ingham ThreadPlanStepOut::QueueInlinedStepPlan (bool queue_now)
333*a5ce6c88SJim Ingham {
334*a5ce6c88SJim Ingham     // Now figure out the range of this inlined block, and set up a "step through range"
335*a5ce6c88SJim Ingham     // plan for that.  If we've been provided with a context, then use the block in that
336*a5ce6c88SJim Ingham     // context.
337*a5ce6c88SJim Ingham     StackFrameSP immediate_return_from_sp (m_thread.GetStackFrameAtIndex (0));
338*a5ce6c88SJim Ingham     if (!immediate_return_from_sp)
339*a5ce6c88SJim Ingham         return false;
340*a5ce6c88SJim Ingham 
341*a5ce6c88SJim Ingham     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
342*a5ce6c88SJim Ingham     if (log)
343*a5ce6c88SJim Ingham     {
344*a5ce6c88SJim Ingham         StreamString s;
345*a5ce6c88SJim Ingham         immediate_return_from_sp->Dump(&s, true, false);
346*a5ce6c88SJim Ingham         log->Printf("Queuing inlined frame to step past: %s.", s.GetData());
347*a5ce6c88SJim Ingham     }
348*a5ce6c88SJim Ingham 
349*a5ce6c88SJim Ingham     Block *from_block = immediate_return_from_sp->GetFrameBlock();
350*a5ce6c88SJim Ingham     if (from_block)
351*a5ce6c88SJim Ingham     {
352*a5ce6c88SJim Ingham         Block *inlined_block = from_block->GetContainingInlinedBlock();
353*a5ce6c88SJim Ingham         if (inlined_block)
354*a5ce6c88SJim Ingham         {
355*a5ce6c88SJim Ingham             size_t num_ranges = inlined_block->GetNumRanges();
356*a5ce6c88SJim Ingham             AddressRange inline_range;
357*a5ce6c88SJim Ingham             if (inlined_block->GetRangeAtIndex(0, inline_range))
358*a5ce6c88SJim Ingham             {
359*a5ce6c88SJim Ingham                 SymbolContext inlined_sc;
360*a5ce6c88SJim Ingham                 inlined_block->CalculateSymbolContext(&inlined_sc);
361*a5ce6c88SJim Ingham                 RunMode run_mode = m_stop_others ? lldb::eOnlyThisThread : lldb::eAllThreads;
362*a5ce6c88SJim Ingham                 ThreadPlanStepOverRange *step_through_inline_plan_ptr = new ThreadPlanStepOverRange(m_thread,
363*a5ce6c88SJim Ingham                                                                                                     inline_range,
364*a5ce6c88SJim Ingham                                                                                                     inlined_sc,
365*a5ce6c88SJim Ingham                                                                                                     run_mode);
366*a5ce6c88SJim Ingham                 step_through_inline_plan_ptr->SetOkayToDiscard(true);
367*a5ce6c88SJim Ingham                 StreamString errors;
368*a5ce6c88SJim Ingham                 if (!step_through_inline_plan_ptr->ValidatePlan(&errors))
369*a5ce6c88SJim Ingham                 {
370*a5ce6c88SJim Ingham                     //FIXME: Log this failure.
371*a5ce6c88SJim Ingham                     delete step_through_inline_plan_ptr;
372*a5ce6c88SJim Ingham                     return false;
373*a5ce6c88SJim Ingham                 }
374*a5ce6c88SJim Ingham 
375*a5ce6c88SJim Ingham                 for (size_t i = 1; i < num_ranges; i++)
376*a5ce6c88SJim Ingham                 {
377*a5ce6c88SJim Ingham                     if (inlined_block->GetRangeAtIndex (i, inline_range))
378*a5ce6c88SJim Ingham                         step_through_inline_plan_ptr->AddRange (inline_range);
379*a5ce6c88SJim Ingham                 }
380*a5ce6c88SJim Ingham                 m_step_through_inline_plan_sp.reset (step_through_inline_plan_ptr);
381*a5ce6c88SJim Ingham                 if (queue_now)
382*a5ce6c88SJim Ingham                     m_thread.QueueThreadPlan (m_step_through_inline_plan_sp, false);
383*a5ce6c88SJim Ingham                 return true;
384*a5ce6c88SJim Ingham             }
385*a5ce6c88SJim Ingham         }
386*a5ce6c88SJim Ingham     }
387*a5ce6c88SJim Ingham 
388*a5ce6c88SJim Ingham     return false;
389*a5ce6c88SJim Ingham }
390