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