ThreadPlanStepInstruction.cpp revision 1ebdcc7789aac1ef30ad6dcd485dff86c63136ad
1//===-- ThreadPlanStepInstruction.cpp ---------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10 11#include "lldb/Target/ThreadPlanStepInstruction.h" 12 13// C Includes 14// C++ Includes 15// Other libraries and framework includes 16// Project includes 17#include "lldb/lldb-private-log.h" 18#include "lldb/Core/Log.h" 19#include "lldb/Core/Stream.h" 20#include "lldb/Target/Process.h" 21#include "lldb/Target/RegisterContext.h" 22#include "lldb/Target/RegisterContext.h" 23#include "lldb/Target/StopInfo.h" 24#include "lldb/Target/Target.h" 25 26using namespace lldb; 27using namespace lldb_private; 28 29//---------------------------------------------------------------------- 30// ThreadPlanStepInstruction: Step over the current instruction 31//---------------------------------------------------------------------- 32 33ThreadPlanStepInstruction::ThreadPlanStepInstruction 34( 35 Thread &thread, 36 bool step_over, 37 bool stop_other_threads, 38 Vote stop_vote, 39 Vote run_vote 40) : 41 ThreadPlan (ThreadPlan::eKindStepInstruction, "Step over single instruction", thread, stop_vote, run_vote), 42 m_instruction_addr (0), 43 m_stop_other_threads (stop_other_threads), 44 m_step_over (step_over), 45 m_stack_depth (0) 46{ 47 m_instruction_addr = m_thread.GetRegisterContext()->GetPC(0); 48 m_stack_depth = m_thread.GetStackFrameCount(); 49} 50 51ThreadPlanStepInstruction::~ThreadPlanStepInstruction () 52{ 53} 54 55void 56ThreadPlanStepInstruction::GetDescription (Stream *s, lldb::DescriptionLevel level) 57{ 58 if (level == lldb::eDescriptionLevelBrief) 59 { 60 if (m_step_over) 61 s->Printf ("instruction step over"); 62 else 63 s->Printf ("instruction step into"); 64 } 65 else 66 { 67 s->Printf ("Stepping one instruction past "); 68 s->Address(m_instruction_addr, sizeof (addr_t)); 69 if (m_step_over) 70 s->Printf(" stepping over calls"); 71 else 72 s->Printf(" stepping into calls"); 73 } 74} 75 76bool 77ThreadPlanStepInstruction::ValidatePlan (Stream *error) 78{ 79 // Since we read the instruction we're stepping over from the thread, 80 // this plan will always work. 81 return true; 82} 83 84bool 85ThreadPlanStepInstruction::PlanExplainsStop () 86{ 87 StopInfoSP stop_info_sp = GetPrivateStopReason(); 88 if (stop_info_sp) 89 { 90 StopReason reason = stop_info_sp->GetStopReason(); 91 if (reason == eStopReasonTrace || reason == eStopReasonNone) 92 return true; 93 else 94 return false; 95 } 96 return false; 97} 98 99bool 100ThreadPlanStepInstruction::ShouldStop (Event *event_ptr) 101{ 102 if (m_step_over) 103 { 104 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 105 if (m_thread.GetStackFrameCount() <= m_stack_depth) 106 { 107 if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr) 108 { 109 SetPlanComplete(); 110 return true; 111 } 112 else 113 return false; 114 } 115 else 116 { 117 // We've stepped in, step back out again: 118 StackFrame *return_frame = m_thread.GetStackFrameAtIndex(1).get(); 119 if (return_frame) 120 { 121 if (log) 122 { 123 StreamString s; 124 s.PutCString ("Stepped in to: "); 125 addr_t stop_addr = m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC(); 126 s.Address (stop_addr, m_thread.GetProcess().GetAddressByteSize()); 127 s.PutCString (" stepping out to: "); 128 addr_t return_addr = return_frame->GetRegisterContext()->GetPC(); 129 s.Address (return_addr, m_thread.GetProcess().GetAddressByteSize()); 130 log->Printf("%s.", s.GetData()); 131 } 132 m_thread.QueueThreadPlanForStepOut(false, NULL, true, m_stop_other_threads, eVoteNo, eVoteNoOpinion, 0); 133 return false; 134 } 135 else 136 { 137 if (log) 138 log->Printf("Could not find previous frame, stopping."); 139 SetPlanComplete(); 140 return true; 141 } 142 143 } 144 145 } 146 else 147 { 148 if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr) 149 { 150 SetPlanComplete(); 151 return true; 152 } 153 else 154 return false; 155 } 156} 157 158bool 159ThreadPlanStepInstruction::StopOthers () 160{ 161 return m_stop_other_threads; 162} 163 164StateType 165ThreadPlanStepInstruction::GetPlanRunState () 166{ 167 return eStateStepping; 168} 169 170bool 171ThreadPlanStepInstruction::WillStop () 172{ 173 return true; 174} 175 176bool 177ThreadPlanStepInstruction::MischiefManaged () 178{ 179 if (IsPlanComplete()) 180 { 181 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 182 if (log) 183 log->Printf("Completed single instruction step plan."); 184 ThreadPlan::MischiefManaged (); 185 return true; 186 } 187 else 188 { 189 return false; 190 } 191} 192 193