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_instruction_addr = m_thread.GetRegisterContext()->GetPC(0); 47 m_stack_id = m_thread.GetStackFrameAtIndex(0)->GetStackID(); 48 } 49 50 ThreadPlanStepInstruction::~ThreadPlanStepInstruction () 51 { 52 } 53 54 void 55 ThreadPlanStepInstruction::GetDescription (Stream *s, lldb::DescriptionLevel level) 56 { 57 if (level == lldb::eDescriptionLevelBrief) 58 { 59 if (m_step_over) 60 s->Printf ("instruction step over"); 61 else 62 s->Printf ("instruction step into"); 63 } 64 else 65 { 66 s->Printf ("Stepping one instruction past "); 67 s->Address(m_instruction_addr, sizeof (addr_t)); 68 if (m_step_over) 69 s->Printf(" stepping over calls"); 70 else 71 s->Printf(" stepping into calls"); 72 } 73 } 74 75 bool 76 ThreadPlanStepInstruction::ValidatePlan (Stream *error) 77 { 78 // Since we read the instruction we're stepping over from the thread, 79 // this plan will always work. 80 return true; 81 } 82 83 bool 84 ThreadPlanStepInstruction::PlanExplainsStop () 85 { 86 StopInfoSP stop_info_sp = GetPrivateStopReason(); 87 if (stop_info_sp) 88 { 89 StopReason reason = stop_info_sp->GetStopReason(); 90 if (reason == eStopReasonTrace || reason == eStopReasonNone) 91 return true; 92 else 93 return false; 94 } 95 return false; 96 } 97 98 bool 99 ThreadPlanStepInstruction::ShouldStop (Event *event_ptr) 100 { 101 if (m_step_over) 102 { 103 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 104 105 StackID cur_frame_zero_id = m_thread.GetStackFrameAtIndex(0)->GetStackID(); 106 107 if (cur_frame_zero_id == m_stack_id || m_stack_id < cur_frame_zero_id) 108 { 109 if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr) 110 { 111 SetPlanComplete(); 112 return true; 113 } 114 else 115 return false; 116 } 117 else 118 { 119 // We've stepped in, step back out again: 120 StackFrame *return_frame = m_thread.GetStackFrameAtIndex(1).get(); 121 if (return_frame) 122 { 123 if (log) 124 { 125 StreamString s; 126 s.PutCString ("Stepped in to: "); 127 addr_t stop_addr = m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC(); 128 s.Address (stop_addr, m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize()); 129 s.PutCString (" stepping out to: "); 130 addr_t return_addr = return_frame->GetRegisterContext()->GetPC(); 131 s.Address (return_addr, m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize()); 132 log->Printf("%s.", s.GetData()); 133 } 134 m_thread.QueueThreadPlanForStepOut(false, NULL, true, m_stop_other_threads, eVoteNo, eVoteNoOpinion, 0); 135 return false; 136 } 137 else 138 { 139 if (log) 140 log->Printf("Could not find previous frame, stopping."); 141 SetPlanComplete(); 142 return true; 143 } 144 145 } 146 147 } 148 else 149 { 150 if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr) 151 { 152 SetPlanComplete(); 153 return true; 154 } 155 else 156 return false; 157 } 158 } 159 160 bool 161 ThreadPlanStepInstruction::StopOthers () 162 { 163 return m_stop_other_threads; 164 } 165 166 StateType 167 ThreadPlanStepInstruction::GetPlanRunState () 168 { 169 return eStateStepping; 170 } 171 172 bool 173 ThreadPlanStepInstruction::WillStop () 174 { 175 return true; 176 } 177 178 bool 179 ThreadPlanStepInstruction::MischiefManaged () 180 { 181 if (IsPlanComplete()) 182 { 183 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 184 if (log) 185 log->Printf("Completed single instruction step plan."); 186 ThreadPlan::MischiefManaged (); 187 return true; 188 } 189 else 190 { 191 return false; 192 } 193 } 194 195