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 ("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 { 46 m_instruction_addr = m_thread.GetRegisterContext()->GetPC(0); 47 m_stack_depth = m_thread.GetStackFrameCount(); 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 Thread::StopInfo info; 87 if (m_thread.GetStopInfo (&info)) 88 { 89 StopReason reason = info.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 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP); 104 if (m_thread.GetStackFrameCount() <= m_stack_depth) 105 { 106 if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr) 107 { 108 SetPlanComplete(); 109 return true; 110 } 111 else 112 return false; 113 } 114 else 115 { 116 // We've stepped in, step back out again: 117 StackFrame *return_frame = m_thread.GetStackFrameAtIndex(1).get(); 118 if (return_frame) 119 { 120 if (log) 121 { 122 StreamString s; 123 s.PutCString ("Stepped in to: "); 124 addr_t stop_addr = m_thread.GetStackFrameAtIndex(0)->GetPC().GetLoadAddress(&m_thread.GetProcess()); 125 s.Address (stop_addr, m_thread.GetProcess().GetAddressByteSize()); 126 s.PutCString (" stepping out to: "); 127 addr_t return_addr = return_frame->GetPC().GetLoadAddress(&m_thread.GetProcess()); 128 s.Address (return_addr, m_thread.GetProcess().GetAddressByteSize()); 129 log->Printf("%s.", s.GetData()); 130 } 131 m_thread.QueueThreadPlanForStepOut(false, NULL, true, m_stop_other_threads, eVoteNo, eVoteNoOpinion); 132 return false; 133 } 134 else 135 { 136 if (log) 137 log->Printf("Could not find previous frame, stopping."); 138 SetPlanComplete(); 139 return true; 140 } 141 142 } 143 144 } 145 else 146 { 147 if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr) 148 { 149 SetPlanComplete(); 150 return true; 151 } 152 else 153 return false; 154 } 155 } 156 157 bool 158 ThreadPlanStepInstruction::StopOthers () 159 { 160 return m_stop_other_threads; 161 } 162 163 StateType 164 ThreadPlanStepInstruction::RunState () 165 { 166 return eStateStepping; 167 } 168 169 bool 170 ThreadPlanStepInstruction::WillStop () 171 { 172 return true; 173 } 174 175 bool 176 ThreadPlanStepInstruction::MischiefManaged () 177 { 178 if (IsPlanComplete()) 179 { 180 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP); 181 if (log) 182 log->Printf("Completed single instruction step plan."); 183 ThreadPlan::MischiefManaged (); 184 return true; 185 } 186 else 187 { 188 return false; 189 } 190 } 191 192