130fdc8d8SChris Lattner //===-- ThreadPlanStepOverRange.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/ThreadPlanStepOverRange.h" 1130fdc8d8SChris Lattner 1230fdc8d8SChris Lattner // C Includes 1330fdc8d8SChris Lattner // C++ Includes 1430fdc8d8SChris Lattner // Other libraries and framework includes 1530fdc8d8SChris Lattner // Project includes 1630fdc8d8SChris Lattner 1730fdc8d8SChris Lattner #include "lldb/lldb-private-log.h" 1830fdc8d8SChris Lattner #include "lldb/Core/Log.h" 1930fdc8d8SChris Lattner #include "lldb/Core/Stream.h" 2030fdc8d8SChris Lattner #include "lldb/Target/Process.h" 2130fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h" 2230fdc8d8SChris Lattner #include "lldb/Target/Thread.h" 2330fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOut.h" 2430fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepThrough.h" 2530fdc8d8SChris Lattner 2630fdc8d8SChris Lattner using namespace lldb_private; 272d4edfbcSGreg Clayton using namespace lldb; 2830fdc8d8SChris Lattner 2930fdc8d8SChris Lattner 3030fdc8d8SChris Lattner //---------------------------------------------------------------------- 3130fdc8d8SChris Lattner // ThreadPlanStepOverRange: Step through a stack range, either stepping over or into 3230fdc8d8SChris Lattner // based on the value of \a type. 3330fdc8d8SChris Lattner //---------------------------------------------------------------------- 3430fdc8d8SChris Lattner 3530fdc8d8SChris Lattner ThreadPlanStepOverRange::ThreadPlanStepOverRange 3630fdc8d8SChris Lattner ( 3730fdc8d8SChris Lattner Thread &thread, 3830fdc8d8SChris Lattner const AddressRange &range, 3930fdc8d8SChris Lattner const SymbolContext &addr_context, 4030fdc8d8SChris Lattner lldb::RunMode stop_others, 4130fdc8d8SChris Lattner bool okay_to_discard 4230fdc8d8SChris Lattner ) : 43b01e742aSJim Ingham ThreadPlanStepRange (ThreadPlan::eKindStepOverRange, "Step range stepping over", thread, range, addr_context, stop_others) 4430fdc8d8SChris Lattner { 4530fdc8d8SChris Lattner SetOkayToDiscard (okay_to_discard); 4630fdc8d8SChris Lattner } 4730fdc8d8SChris Lattner 4830fdc8d8SChris Lattner ThreadPlanStepOverRange::~ThreadPlanStepOverRange () 4930fdc8d8SChris Lattner { 5030fdc8d8SChris Lattner } 5130fdc8d8SChris Lattner 5230fdc8d8SChris Lattner void 5330fdc8d8SChris Lattner ThreadPlanStepOverRange::GetDescription (Stream *s, lldb::DescriptionLevel level) 5430fdc8d8SChris Lattner { 5530fdc8d8SChris Lattner if (level == lldb::eDescriptionLevelBrief) 5630fdc8d8SChris Lattner s->Printf("step over"); 5730fdc8d8SChris Lattner else 5830fdc8d8SChris Lattner { 5930fdc8d8SChris Lattner s->Printf ("stepping through range (stepping over functions): "); 60f5e56de0SGreg Clayton m_address_range.Dump (s, &m_thread.GetProcess().GetTarget(), Address::DumpStyleLoadAddress); 6130fdc8d8SChris Lattner } 6230fdc8d8SChris Lattner } 6330fdc8d8SChris Lattner 6430fdc8d8SChris Lattner bool 6530fdc8d8SChris Lattner ThreadPlanStepOverRange::ShouldStop (Event *event_ptr) 6630fdc8d8SChris Lattner { 672d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 6830fdc8d8SChris Lattner 6930fdc8d8SChris Lattner if (log) 7030fdc8d8SChris Lattner { 7130fdc8d8SChris Lattner StreamString s; 7230fdc8d8SChris Lattner s.Address (m_thread.GetRegisterContext()->GetPC(), m_thread.GetProcess().GetAddressByteSize()); 7330fdc8d8SChris Lattner log->Printf("ThreadPlanStepOverRange reached %s.", s.GetData()); 7430fdc8d8SChris Lattner } 7530fdc8d8SChris Lattner 7630fdc8d8SChris Lattner // If we're still in the range, keep going. 7730fdc8d8SChris Lattner if (InRange()) 7830fdc8d8SChris Lattner return false; 7930fdc8d8SChris Lattner 8030fdc8d8SChris Lattner // If we're out of the range but in the same frame or in our caller's frame 8130fdc8d8SChris Lattner // then we should stop. 8230fdc8d8SChris Lattner // When stepping out we only step if we are forcing running one thread. 8330fdc8d8SChris Lattner bool stop_others; 8430fdc8d8SChris Lattner if (m_stop_others == lldb::eOnlyThisThread) 8530fdc8d8SChris Lattner stop_others = true; 8630fdc8d8SChris Lattner else 8730fdc8d8SChris Lattner stop_others = false; 8830fdc8d8SChris Lattner 8930fdc8d8SChris Lattner ThreadPlan* new_plan = NULL; 9030fdc8d8SChris Lattner 9130fdc8d8SChris Lattner if (FrameIsOlder()) 925822173bSJim Ingham { 935822173bSJim Ingham // If we're in an older frame then we should stop. 945822173bSJim Ingham // 955822173bSJim Ingham // A caveat to this is if we think the frame is older but we're actually in a trampoline. 965822173bSJim Ingham // I'm going to make the assumption that you wouldn't RETURN to a trampoline. So if we are 975822173bSJim Ingham // in a trampoline we think the frame is older because the trampoline confused the backtracer. 985822173bSJim Ingham // As below, we step through first, and then try to figure out how to get back out again. 995822173bSJim Ingham 1005822173bSJim Ingham new_plan = m_thread.QueueThreadPlanForStepThrough (false, stop_others); 1015822173bSJim Ingham 1025822173bSJim Ingham if (new_plan != NULL && log) 1035822173bSJim Ingham log->Printf("Thought I stepped out, but in fact arrived at a trampoline."); 1045822173bSJim Ingham } 10530fdc8d8SChris Lattner else if (FrameIsYounger()) 10630fdc8d8SChris Lattner { 107*481cef25SGreg Clayton new_plan = m_thread.QueueThreadPlanForStepOut (false, 108*481cef25SGreg Clayton NULL, 109*481cef25SGreg Clayton true, 110*481cef25SGreg Clayton stop_others, 111*481cef25SGreg Clayton lldb::eVoteNo, 112*481cef25SGreg Clayton lldb::eVoteNoOpinion, 113*481cef25SGreg Clayton 0); 11430fdc8d8SChris Lattner } 11530fdc8d8SChris Lattner else if (!InSymbol()) 11630fdc8d8SChris Lattner { 11730fdc8d8SChris Lattner // This one is a little tricky. Sometimes we may be in a stub or something similar, 11830fdc8d8SChris Lattner // in which case we need to get out of there. But if we are in a stub then it's 11930fdc8d8SChris Lattner // likely going to be hard to get out from here. It is probably easiest to step into the 12030fdc8d8SChris Lattner // stub, and then it will be straight-forward to step out. 12130fdc8d8SChris Lattner new_plan = m_thread.QueueThreadPlanForStepThrough (false, stop_others); 12230fdc8d8SChris Lattner } 12330fdc8d8SChris Lattner 12430fdc8d8SChris Lattner if (new_plan == NULL) 12530fdc8d8SChris Lattner m_no_more_plans = true; 12630fdc8d8SChris Lattner else 12730fdc8d8SChris Lattner m_no_more_plans = false; 12830fdc8d8SChris Lattner 12930fdc8d8SChris Lattner if (new_plan == NULL) 13030fdc8d8SChris Lattner { 13130fdc8d8SChris Lattner // For efficiencies sake, we know we're done here so we don't have to do this 13230fdc8d8SChris Lattner // calculation again in MischiefManaged. 13330fdc8d8SChris Lattner SetPlanComplete(); 13430fdc8d8SChris Lattner return true; 13530fdc8d8SChris Lattner } 13630fdc8d8SChris Lattner else 13730fdc8d8SChris Lattner return false; 13830fdc8d8SChris Lattner } 139