130fdc8d8SChris Lattner //===-- ThreadPlanStepInstruction.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 1130fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h" 1230fdc8d8SChris Lattner 1330fdc8d8SChris Lattner // C Includes 1430fdc8d8SChris Lattner // C++ Includes 1530fdc8d8SChris Lattner // Other libraries and framework includes 1630fdc8d8SChris Lattner // Project includes 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" 21f4b47e15SGreg Clayton #include "lldb/Target/RegisterContext.h" 22f4b47e15SGreg Clayton #include "lldb/Target/RegisterContext.h" 23f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h" 24f4b47e15SGreg Clayton #include "lldb/Target/Target.h" 2530fdc8d8SChris Lattner 2630fdc8d8SChris Lattner using namespace lldb; 2730fdc8d8SChris Lattner using namespace lldb_private; 2830fdc8d8SChris Lattner 2930fdc8d8SChris Lattner //---------------------------------------------------------------------- 3030fdc8d8SChris Lattner // ThreadPlanStepInstruction: Step over the current instruction 3130fdc8d8SChris Lattner //---------------------------------------------------------------------- 3230fdc8d8SChris Lattner 3330fdc8d8SChris Lattner ThreadPlanStepInstruction::ThreadPlanStepInstruction 3430fdc8d8SChris Lattner ( 3530fdc8d8SChris Lattner Thread &thread, 3630fdc8d8SChris Lattner bool step_over, 3730fdc8d8SChris Lattner bool stop_other_threads, 3830fdc8d8SChris Lattner Vote stop_vote, 3930fdc8d8SChris Lattner Vote run_vote 4030fdc8d8SChris Lattner ) : 41b01e742aSJim Ingham ThreadPlan (ThreadPlan::eKindStepInstruction, "Step over single instruction", thread, stop_vote, run_vote), 4230fdc8d8SChris Lattner m_instruction_addr (0), 431ee0d4f7SBenjamin Kramer m_stop_other_threads (stop_other_threads), 446b35c86fSJim Ingham m_step_over (step_over) 451ee0d4f7SBenjamin Kramer { 4630fdc8d8SChris Lattner m_instruction_addr = m_thread.GetRegisterContext()->GetPC(0); 47*b57e4a1bSJason Molenda StackFrameSP m_start_frame_sp(m_thread.GetStackFrameAtIndex(0)); 48a7d4822cSJim Ingham m_stack_id = m_start_frame_sp->GetStackID(); 49a7d4822cSJim Ingham 50a7d4822cSJim Ingham m_start_has_symbol = m_start_frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol != NULL; 51a7d4822cSJim Ingham 52*b57e4a1bSJason Molenda StackFrameSP parent_frame_sp = m_thread.GetStackFrameAtIndex(1); 53886a3e2cSJim Ingham if (parent_frame_sp) 54886a3e2cSJim Ingham m_parent_frame_id = parent_frame_sp->GetStackID(); 5530fdc8d8SChris Lattner } 5630fdc8d8SChris Lattner 5730fdc8d8SChris Lattner ThreadPlanStepInstruction::~ThreadPlanStepInstruction () 5830fdc8d8SChris Lattner { 5930fdc8d8SChris Lattner } 6030fdc8d8SChris Lattner 6130fdc8d8SChris Lattner void 6230fdc8d8SChris Lattner ThreadPlanStepInstruction::GetDescription (Stream *s, lldb::DescriptionLevel level) 6330fdc8d8SChris Lattner { 6430fdc8d8SChris Lattner if (level == lldb::eDescriptionLevelBrief) 6530fdc8d8SChris Lattner { 6630fdc8d8SChris Lattner if (m_step_over) 6730fdc8d8SChris Lattner s->Printf ("instruction step over"); 6830fdc8d8SChris Lattner else 6930fdc8d8SChris Lattner s->Printf ("instruction step into"); 7030fdc8d8SChris Lattner } 7130fdc8d8SChris Lattner else 7230fdc8d8SChris Lattner { 7330fdc8d8SChris Lattner s->Printf ("Stepping one instruction past "); 7430fdc8d8SChris Lattner s->Address(m_instruction_addr, sizeof (addr_t)); 75a7d4822cSJim Ingham if (!m_start_has_symbol) 76a7d4822cSJim Ingham s->Printf(" which has no symbol"); 77a7d4822cSJim Ingham 7830fdc8d8SChris Lattner if (m_step_over) 7930fdc8d8SChris Lattner s->Printf(" stepping over calls"); 8030fdc8d8SChris Lattner else 8130fdc8d8SChris Lattner s->Printf(" stepping into calls"); 8230fdc8d8SChris Lattner } 8330fdc8d8SChris Lattner } 8430fdc8d8SChris Lattner 8530fdc8d8SChris Lattner bool 8630fdc8d8SChris Lattner ThreadPlanStepInstruction::ValidatePlan (Stream *error) 8730fdc8d8SChris Lattner { 8830fdc8d8SChris Lattner // Since we read the instruction we're stepping over from the thread, 8930fdc8d8SChris Lattner // this plan will always work. 9030fdc8d8SChris Lattner return true; 9130fdc8d8SChris Lattner } 9230fdc8d8SChris Lattner 9330fdc8d8SChris Lattner bool 94221d51cfSJim Ingham ThreadPlanStepInstruction::DoPlanExplainsStop (Event *event_ptr) 9530fdc8d8SChris Lattner { 9660c4118cSJim Ingham StopInfoSP stop_info_sp = GetPrivateStopInfo (); 97b15bfc75SJim Ingham if (stop_info_sp) 9830fdc8d8SChris Lattner { 99b15bfc75SJim Ingham StopReason reason = stop_info_sp->GetStopReason(); 10030fdc8d8SChris Lattner if (reason == eStopReasonTrace || reason == eStopReasonNone) 10130fdc8d8SChris Lattner return true; 10230fdc8d8SChris Lattner else 10330fdc8d8SChris Lattner return false; 10430fdc8d8SChris Lattner } 10530fdc8d8SChris Lattner return false; 10630fdc8d8SChris Lattner } 10730fdc8d8SChris Lattner 10830fdc8d8SChris Lattner bool 10930fdc8d8SChris Lattner ThreadPlanStepInstruction::ShouldStop (Event *event_ptr) 11030fdc8d8SChris Lattner { 11130fdc8d8SChris Lattner if (m_step_over) 11230fdc8d8SChris Lattner { 1135160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 1146b35c86fSJim Ingham 1156b35c86fSJim Ingham StackID cur_frame_zero_id = m_thread.GetStackFrameAtIndex(0)->GetStackID(); 1166b35c86fSJim Ingham 1176b35c86fSJim Ingham if (cur_frame_zero_id == m_stack_id || m_stack_id < cur_frame_zero_id) 11830fdc8d8SChris Lattner { 11930fdc8d8SChris Lattner if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr) 12030fdc8d8SChris Lattner { 12130fdc8d8SChris Lattner SetPlanComplete(); 12230fdc8d8SChris Lattner return true; 12330fdc8d8SChris Lattner } 12430fdc8d8SChris Lattner else 12530fdc8d8SChris Lattner return false; 12630fdc8d8SChris Lattner } 12730fdc8d8SChris Lattner else 12830fdc8d8SChris Lattner { 12930fdc8d8SChris Lattner // We've stepped in, step back out again: 130*b57e4a1bSJason Molenda StackFrame *return_frame = m_thread.GetStackFrameAtIndex(1).get(); 13130fdc8d8SChris Lattner if (return_frame) 13230fdc8d8SChris Lattner { 133a7d4822cSJim Ingham if (return_frame->GetStackID() != m_parent_frame_id || m_start_has_symbol) 134886a3e2cSJim Ingham { 13530fdc8d8SChris Lattner if (log) 13630fdc8d8SChris Lattner { 13730fdc8d8SChris Lattner StreamString s; 13830fdc8d8SChris Lattner s.PutCString ("Stepped in to: "); 1399da7bd07SGreg Clayton addr_t stop_addr = m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC(); 1401ac04c30SGreg Clayton s.Address (stop_addr, m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize()); 14130fdc8d8SChris Lattner s.PutCString (" stepping out to: "); 1429da7bd07SGreg Clayton addr_t return_addr = return_frame->GetRegisterContext()->GetPC(); 1431ac04c30SGreg Clayton s.Address (return_addr, m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize()); 14430fdc8d8SChris Lattner log->Printf("%s.", s.GetData()); 14530fdc8d8SChris Lattner } 1464a58e968SJim Ingham 1474a58e968SJim Ingham // StepInstruction should probably have the tri-state RunMode, but for now it is safer to 1484a58e968SJim Ingham // run others. 1494a58e968SJim Ingham const bool stop_others = false; 15064e7ead1SJim Ingham m_thread.QueueThreadPlanForStepOut(false, 15164e7ead1SJim Ingham NULL, 15264e7ead1SJim Ingham true, 1534a58e968SJim Ingham stop_others, 15464e7ead1SJim Ingham eVoteNo, 15564e7ead1SJim Ingham eVoteNoOpinion, 15664e7ead1SJim Ingham 0); 15730fdc8d8SChris Lattner return false; 15830fdc8d8SChris Lattner } 15930fdc8d8SChris Lattner else 16030fdc8d8SChris Lattner { 16130fdc8d8SChris Lattner if (log) 162886a3e2cSJim Ingham { 163a7d4822cSJim Ingham log->PutCString("The stack id we are stepping in changed, but our parent frame did not when stepping from code with no symbols. " 164886a3e2cSJim Ingham "We are probably just confused about where we are, stopping."); 165886a3e2cSJim Ingham } 166886a3e2cSJim Ingham SetPlanComplete(); 167886a3e2cSJim Ingham return true; 168886a3e2cSJim Ingham } 169886a3e2cSJim Ingham } 170886a3e2cSJim Ingham else 171886a3e2cSJim Ingham { 172886a3e2cSJim Ingham if (log) 17330fdc8d8SChris Lattner log->Printf("Could not find previous frame, stopping."); 17430fdc8d8SChris Lattner SetPlanComplete(); 17530fdc8d8SChris Lattner return true; 17630fdc8d8SChris Lattner } 17730fdc8d8SChris Lattner 17830fdc8d8SChris Lattner } 17930fdc8d8SChris Lattner 18030fdc8d8SChris Lattner } 18130fdc8d8SChris Lattner else 18230fdc8d8SChris Lattner { 18330fdc8d8SChris Lattner if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr) 18430fdc8d8SChris Lattner { 18530fdc8d8SChris Lattner SetPlanComplete(); 18630fdc8d8SChris Lattner return true; 18730fdc8d8SChris Lattner } 18830fdc8d8SChris Lattner else 18930fdc8d8SChris Lattner return false; 19030fdc8d8SChris Lattner } 19130fdc8d8SChris Lattner } 19230fdc8d8SChris Lattner 19330fdc8d8SChris Lattner bool 19430fdc8d8SChris Lattner ThreadPlanStepInstruction::StopOthers () 19530fdc8d8SChris Lattner { 19630fdc8d8SChris Lattner return m_stop_other_threads; 19730fdc8d8SChris Lattner } 19830fdc8d8SChris Lattner 19930fdc8d8SChris Lattner StateType 20006e827ccSJim Ingham ThreadPlanStepInstruction::GetPlanRunState () 20130fdc8d8SChris Lattner { 20230fdc8d8SChris Lattner return eStateStepping; 20330fdc8d8SChris Lattner } 20430fdc8d8SChris Lattner 20530fdc8d8SChris Lattner bool 20630fdc8d8SChris Lattner ThreadPlanStepInstruction::WillStop () 20730fdc8d8SChris Lattner { 20830fdc8d8SChris Lattner return true; 20930fdc8d8SChris Lattner } 21030fdc8d8SChris Lattner 21130fdc8d8SChris Lattner bool 21230fdc8d8SChris Lattner ThreadPlanStepInstruction::MischiefManaged () 21330fdc8d8SChris Lattner { 21430fdc8d8SChris Lattner if (IsPlanComplete()) 21530fdc8d8SChris Lattner { 2165160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 21730fdc8d8SChris Lattner if (log) 21830fdc8d8SChris Lattner log->Printf("Completed single instruction step plan."); 21930fdc8d8SChris Lattner ThreadPlan::MischiefManaged (); 22030fdc8d8SChris Lattner return true; 22130fdc8d8SChris Lattner } 22230fdc8d8SChris Lattner else 22330fdc8d8SChris Lattner { 22430fdc8d8SChris Lattner return false; 22530fdc8d8SChris Lattner } 22630fdc8d8SChris Lattner } 22730fdc8d8SChris Lattner 228