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 26 using namespace lldb; 27 using namespace lldb_private; 28 29 //---------------------------------------------------------------------- 30 // ThreadPlanStepInstruction: Step over the current instruction 31 //---------------------------------------------------------------------- 32 33 ThreadPlanStepInstruction::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 { 46 m_takes_iteration_count = true; 47 SetUpState(); 48 } 49 50 ThreadPlanStepInstruction::~ThreadPlanStepInstruction () 51 { 52 } 53 54 void 55 ThreadPlanStepInstruction::SetUpState() 56 { 57 m_instruction_addr = m_thread.GetRegisterContext()->GetPC(0); 58 StackFrameSP start_frame_sp(m_thread.GetStackFrameAtIndex(0)); 59 m_stack_id = start_frame_sp->GetStackID(); 60 61 m_start_has_symbol = start_frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol != NULL; 62 63 StackFrameSP parent_frame_sp = m_thread.GetStackFrameAtIndex(1); 64 if (parent_frame_sp) 65 m_parent_frame_id = parent_frame_sp->GetStackID(); 66 } 67 68 void 69 ThreadPlanStepInstruction::GetDescription (Stream *s, lldb::DescriptionLevel level) 70 { 71 if (level == lldb::eDescriptionLevelBrief) 72 { 73 if (m_step_over) 74 s->Printf ("instruction step over"); 75 else 76 s->Printf ("instruction step into"); 77 } 78 else 79 { 80 s->Printf ("Stepping one instruction past "); 81 s->Address(m_instruction_addr, sizeof (addr_t)); 82 if (!m_start_has_symbol) 83 s->Printf(" which has no symbol"); 84 85 if (m_step_over) 86 s->Printf(" stepping over calls"); 87 else 88 s->Printf(" stepping into calls"); 89 } 90 } 91 92 bool 93 ThreadPlanStepInstruction::ValidatePlan (Stream *error) 94 { 95 // Since we read the instruction we're stepping over from the thread, 96 // this plan will always work. 97 return true; 98 } 99 100 bool 101 ThreadPlanStepInstruction::DoPlanExplainsStop (Event *event_ptr) 102 { 103 StopInfoSP stop_info_sp = GetPrivateStopInfo (); 104 if (stop_info_sp) 105 { 106 StopReason reason = stop_info_sp->GetStopReason(); 107 if (reason == eStopReasonTrace || reason == eStopReasonNone) 108 return true; 109 else 110 return false; 111 } 112 return false; 113 } 114 115 bool 116 ThreadPlanStepInstruction::IsPlanStale () 117 { 118 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 119 StackID cur_frame_id = m_thread.GetStackFrameAtIndex(0)->GetStackID(); 120 if (cur_frame_id == m_stack_id) 121 { 122 if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr) 123 return true; 124 else 125 return false; 126 } 127 else if (cur_frame_id < m_stack_id) 128 { 129 // If the current frame is younger than the start frame and we are stepping over, then we need to continue, 130 // but if we are doing just one step, we're done. 131 if (m_step_over) 132 return false; 133 else 134 return true; 135 } 136 else 137 { 138 if (log) 139 { 140 log->Printf ("ThreadPlanStepInstruction::IsPlanStale - Current frame is older than start frame, plan is stale."); 141 } 142 return true; 143 } 144 } 145 146 bool 147 ThreadPlanStepInstruction::ShouldStop (Event *event_ptr) 148 { 149 if (m_step_over) 150 { 151 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 152 153 StackFrameSP cur_frame_sp = m_thread.GetStackFrameAtIndex(0); 154 if (!cur_frame_sp) 155 { 156 if (log) 157 log->Printf ("ThreadPlanStepInstruction couldn't get the 0th frame, stopping."); 158 SetPlanComplete(); 159 return true; 160 } 161 162 StackID cur_frame_zero_id = cur_frame_sp->GetStackID(); 163 164 if (cur_frame_zero_id == m_stack_id || m_stack_id < cur_frame_zero_id) 165 { 166 if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr) 167 { 168 if (--m_iteration_count <= 0) 169 { 170 SetPlanComplete(); 171 return true; 172 } 173 else 174 { 175 // We are still stepping, reset the start pc, and in case we've stepped out, 176 // reset the current stack id. 177 SetUpState(); 178 return false; 179 } 180 } 181 else 182 return false; 183 } 184 else 185 { 186 // We've stepped in, step back out again: 187 StackFrame *return_frame = m_thread.GetStackFrameAtIndex(1).get(); 188 if (return_frame) 189 { 190 if (return_frame->GetStackID() != m_parent_frame_id || m_start_has_symbol) 191 { 192 // next-instruction shouldn't step out of inlined functions. But we may have stepped into a 193 // real function that starts with an inlined function, and we do want to step out of that... 194 195 if (cur_frame_sp->IsInlined()) 196 { 197 StackFrameSP parent_frame_sp = m_thread.GetFrameWithStackID(m_stack_id); 198 199 if(parent_frame_sp && parent_frame_sp->GetConcreteFrameIndex() == cur_frame_sp->GetConcreteFrameIndex()) 200 { 201 SetPlanComplete(); 202 if (log) 203 { 204 log->Printf("Frame we stepped into is inlined into the frame we were stepping from, stopping."); 205 } 206 return true; 207 } 208 } 209 210 if (log) 211 { 212 StreamString s; 213 s.PutCString ("Stepped in to: "); 214 addr_t stop_addr = m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC(); 215 s.Address (stop_addr, m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize()); 216 s.PutCString (" stepping out to: "); 217 addr_t return_addr = return_frame->GetRegisterContext()->GetPC(); 218 s.Address (return_addr, m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize()); 219 log->Printf("%s.", s.GetData()); 220 } 221 222 // StepInstruction should probably have the tri-state RunMode, but for now it is safer to 223 // run others. 224 const bool stop_others = false; 225 m_thread.QueueThreadPlanForStepOutNoShouldStop(false, 226 NULL, 227 true, 228 stop_others, 229 eVoteNo, 230 eVoteNoOpinion, 231 0); 232 return false; 233 } 234 else 235 { 236 if (log) 237 { 238 log->PutCString("The stack id we are stepping in changed, but our parent frame did not when stepping from code with no symbols. " 239 "We are probably just confused about where we are, stopping."); 240 } 241 SetPlanComplete(); 242 return true; 243 } 244 } 245 else 246 { 247 if (log) 248 log->Printf("Could not find previous frame, stopping."); 249 SetPlanComplete(); 250 return true; 251 } 252 253 } 254 255 } 256 else 257 { 258 if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr) 259 { 260 if (--m_iteration_count <= 0) 261 { 262 SetPlanComplete(); 263 return true; 264 } 265 else 266 { 267 // We are still stepping, reset the start pc, and in case we've stepped in or out, 268 // reset the current stack id. 269 SetUpState(); 270 return false; 271 } 272 } 273 else 274 return false; 275 } 276 } 277 278 bool 279 ThreadPlanStepInstruction::StopOthers () 280 { 281 return m_stop_other_threads; 282 } 283 284 StateType 285 ThreadPlanStepInstruction::GetPlanRunState () 286 { 287 return eStateStepping; 288 } 289 290 bool 291 ThreadPlanStepInstruction::WillStop () 292 { 293 return true; 294 } 295 296 bool 297 ThreadPlanStepInstruction::MischiefManaged () 298 { 299 if (IsPlanComplete()) 300 { 301 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 302 if (log) 303 log->Printf("Completed single instruction step plan."); 304 ThreadPlan::MischiefManaged (); 305 return true; 306 } 307 else 308 { 309 return false; 310 } 311 } 312 313