1*30fdc8d8SChris Lattner //===-- ThreadPlanStepOverRange.cpp -----------------------------*- C++ -*-===// 2*30fdc8d8SChris Lattner // 3*30fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 4*30fdc8d8SChris Lattner // 5*30fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 6*30fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 7*30fdc8d8SChris Lattner // 8*30fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 9*30fdc8d8SChris Lattner 10*30fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOverRange.h" 11*30fdc8d8SChris Lattner 12*30fdc8d8SChris Lattner // C Includes 13*30fdc8d8SChris Lattner // C++ Includes 14*30fdc8d8SChris Lattner // Other libraries and framework includes 15*30fdc8d8SChris Lattner // Project includes 16*30fdc8d8SChris Lattner 17*30fdc8d8SChris Lattner #include "lldb/lldb-private-log.h" 18*30fdc8d8SChris Lattner #include "lldb/Core/Log.h" 19*30fdc8d8SChris Lattner #include "lldb/Core/Stream.h" 20*30fdc8d8SChris Lattner #include "lldb/Target/Process.h" 21*30fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h" 22*30fdc8d8SChris Lattner #include "lldb/Target/Thread.h" 23*30fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOut.h" 24*30fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepThrough.h" 25*30fdc8d8SChris Lattner 26*30fdc8d8SChris Lattner using namespace lldb_private; 27*30fdc8d8SChris Lattner 28*30fdc8d8SChris Lattner 29*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 30*30fdc8d8SChris Lattner // ThreadPlanStepOverRange: Step through a stack range, either stepping over or into 31*30fdc8d8SChris Lattner // based on the value of \a type. 32*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 33*30fdc8d8SChris Lattner 34*30fdc8d8SChris Lattner ThreadPlanStepOverRange::ThreadPlanStepOverRange 35*30fdc8d8SChris Lattner ( 36*30fdc8d8SChris Lattner Thread &thread, 37*30fdc8d8SChris Lattner const AddressRange &range, 38*30fdc8d8SChris Lattner const SymbolContext &addr_context, 39*30fdc8d8SChris Lattner lldb::RunMode stop_others, 40*30fdc8d8SChris Lattner bool okay_to_discard 41*30fdc8d8SChris Lattner ) : 42*30fdc8d8SChris Lattner ThreadPlanStepRange ("Step range stepping over", thread, range, addr_context, stop_others) 43*30fdc8d8SChris Lattner { 44*30fdc8d8SChris Lattner SetOkayToDiscard (okay_to_discard); 45*30fdc8d8SChris Lattner } 46*30fdc8d8SChris Lattner 47*30fdc8d8SChris Lattner ThreadPlanStepOverRange::~ThreadPlanStepOverRange () 48*30fdc8d8SChris Lattner { 49*30fdc8d8SChris Lattner } 50*30fdc8d8SChris Lattner 51*30fdc8d8SChris Lattner void 52*30fdc8d8SChris Lattner ThreadPlanStepOverRange::GetDescription (Stream *s, lldb::DescriptionLevel level) 53*30fdc8d8SChris Lattner { 54*30fdc8d8SChris Lattner if (level == lldb::eDescriptionLevelBrief) 55*30fdc8d8SChris Lattner s->Printf("step over"); 56*30fdc8d8SChris Lattner else 57*30fdc8d8SChris Lattner { 58*30fdc8d8SChris Lattner s->Printf ("stepping through range (stepping over functions): "); 59*30fdc8d8SChris Lattner m_address_range.Dump (s, &m_thread.GetProcess(), Address::DumpStyleLoadAddress); 60*30fdc8d8SChris Lattner } 61*30fdc8d8SChris Lattner } 62*30fdc8d8SChris Lattner 63*30fdc8d8SChris Lattner bool 64*30fdc8d8SChris Lattner ThreadPlanStepOverRange::ShouldStop (Event *event_ptr) 65*30fdc8d8SChris Lattner { 66*30fdc8d8SChris Lattner Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP); 67*30fdc8d8SChris Lattner 68*30fdc8d8SChris Lattner if (log) 69*30fdc8d8SChris Lattner { 70*30fdc8d8SChris Lattner StreamString s; 71*30fdc8d8SChris Lattner s.Address (m_thread.GetRegisterContext()->GetPC(), m_thread.GetProcess().GetAddressByteSize()); 72*30fdc8d8SChris Lattner log->Printf("ThreadPlanStepOverRange reached %s.", s.GetData()); 73*30fdc8d8SChris Lattner } 74*30fdc8d8SChris Lattner 75*30fdc8d8SChris Lattner // If we're still in the range, keep going. 76*30fdc8d8SChris Lattner if (InRange()) 77*30fdc8d8SChris Lattner return false; 78*30fdc8d8SChris Lattner 79*30fdc8d8SChris Lattner // If we're out of the range but in the same frame or in our caller's frame 80*30fdc8d8SChris Lattner // then we should stop. 81*30fdc8d8SChris Lattner // When stepping out we only step if we are forcing running one thread. 82*30fdc8d8SChris Lattner bool stop_others; 83*30fdc8d8SChris Lattner if (m_stop_others == lldb::eOnlyThisThread) 84*30fdc8d8SChris Lattner stop_others = true; 85*30fdc8d8SChris Lattner else 86*30fdc8d8SChris Lattner stop_others = false; 87*30fdc8d8SChris Lattner 88*30fdc8d8SChris Lattner ThreadPlan* new_plan = NULL; 89*30fdc8d8SChris Lattner 90*30fdc8d8SChris Lattner if (FrameIsOlder()) 91*30fdc8d8SChris Lattner return true; 92*30fdc8d8SChris Lattner else if (FrameIsYounger()) 93*30fdc8d8SChris Lattner { 94*30fdc8d8SChris Lattner new_plan = m_thread.QueueThreadPlanForStepOut (false, NULL, true, stop_others, lldb::eVoteNo, lldb::eVoteNoOpinion); 95*30fdc8d8SChris Lattner } 96*30fdc8d8SChris Lattner else if (!InSymbol()) 97*30fdc8d8SChris Lattner { 98*30fdc8d8SChris Lattner // This one is a little tricky. Sometimes we may be in a stub or something similar, 99*30fdc8d8SChris Lattner // in which case we need to get out of there. But if we are in a stub then it's 100*30fdc8d8SChris Lattner // likely going to be hard to get out from here. It is probably easiest to step into the 101*30fdc8d8SChris Lattner // stub, and then it will be straight-forward to step out. 102*30fdc8d8SChris Lattner new_plan = m_thread.QueueThreadPlanForStepThrough (false, stop_others); 103*30fdc8d8SChris Lattner } 104*30fdc8d8SChris Lattner 105*30fdc8d8SChris Lattner if (new_plan == NULL) 106*30fdc8d8SChris Lattner m_no_more_plans = true; 107*30fdc8d8SChris Lattner else 108*30fdc8d8SChris Lattner m_no_more_plans = false; 109*30fdc8d8SChris Lattner 110*30fdc8d8SChris Lattner if (new_plan == NULL) 111*30fdc8d8SChris Lattner { 112*30fdc8d8SChris Lattner // For efficiencies sake, we know we're done here so we don't have to do this 113*30fdc8d8SChris Lattner // calculation again in MischiefManaged. 114*30fdc8d8SChris Lattner SetPlanComplete(); 115*30fdc8d8SChris Lattner return true; 116*30fdc8d8SChris Lattner } 117*30fdc8d8SChris Lattner else 118*30fdc8d8SChris Lattner return false; 119*30fdc8d8SChris Lattner } 120