130fdc8d8SChris Lattner //===-- ThreadPlanStepRange.cpp ---------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 1030fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepRange.h" 1130fdc8d8SChris Lattner 1230fdc8d8SChris Lattner // C Includes 1330fdc8d8SChris Lattner // C++ Includes 1430fdc8d8SChris Lattner // Other libraries and framework includes 1530fdc8d8SChris Lattner // Project includes 1630fdc8d8SChris Lattner 1730fdc8d8SChris Lattner #include "lldb/lldb-private-log.h" 18*564d8bc2SJim Ingham #include "lldb/Core/Disassembler.h" 1930fdc8d8SChris Lattner #include "lldb/Core/Log.h" 2030fdc8d8SChris Lattner #include "lldb/Core/Stream.h" 2130fdc8d8SChris Lattner #include "lldb/Symbol/Function.h" 2230fdc8d8SChris Lattner #include "lldb/Symbol/Symbol.h" 23*564d8bc2SJim Ingham #include "lldb/Target/ExecutionContext.h" 24f4b47e15SGreg Clayton #include "lldb/Target/Process.h" 25f4b47e15SGreg Clayton #include "lldb/Target/RegisterContext.h" 26f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h" 27*564d8bc2SJim Ingham #include "lldb/Target/Target.h" 28f4b47e15SGreg Clayton #include "lldb/Target/Thread.h" 29*564d8bc2SJim Ingham #include "lldb/Target/ThreadPlanRunToAddress.h" 3030fdc8d8SChris Lattner 3130fdc8d8SChris Lattner using namespace lldb; 3230fdc8d8SChris Lattner using namespace lldb_private; 3330fdc8d8SChris Lattner 3430fdc8d8SChris Lattner 3530fdc8d8SChris Lattner //---------------------------------------------------------------------- 3630fdc8d8SChris Lattner // ThreadPlanStepRange: Step through a stack range, either stepping over or into 3730fdc8d8SChris Lattner // based on the value of \a type. 3830fdc8d8SChris Lattner //---------------------------------------------------------------------- 3930fdc8d8SChris Lattner 40242e0ad7SJim Ingham ThreadPlanStepRange::ThreadPlanStepRange (ThreadPlanKind kind, 41242e0ad7SJim Ingham const char *name, 42242e0ad7SJim Ingham Thread &thread, 43242e0ad7SJim Ingham const AddressRange &range, 44242e0ad7SJim Ingham const SymbolContext &addr_context, 45242e0ad7SJim Ingham lldb::RunMode stop_others) : 4635b21fefSJim Ingham ThreadPlan (kind, name, thread, eVoteNoOpinion, eVoteNoOpinion), 4730fdc8d8SChris Lattner m_addr_context (addr_context), 48c4c9fedcSJim Ingham m_address_ranges (), 4930fdc8d8SChris Lattner m_stop_others (stop_others), 5030fdc8d8SChris Lattner m_stack_id (), 51c982c768SGreg Clayton m_no_more_plans (false), 5230fdc8d8SChris Lattner m_first_run_event (true) 5330fdc8d8SChris Lattner { 54c4c9fedcSJim Ingham AddRange(range); 5530fdc8d8SChris Lattner m_stack_id = m_thread.GetStackFrameAtIndex(0)->GetStackID(); 5630fdc8d8SChris Lattner } 5730fdc8d8SChris Lattner 5830fdc8d8SChris Lattner ThreadPlanStepRange::~ThreadPlanStepRange () 5930fdc8d8SChris Lattner { 60*564d8bc2SJim Ingham ClearNextBranchBreakpoint(); 61*564d8bc2SJim Ingham } 62*564d8bc2SJim Ingham 63*564d8bc2SJim Ingham void 64*564d8bc2SJim Ingham ThreadPlanStepRange::DidPush () 65*564d8bc2SJim Ingham { 66*564d8bc2SJim Ingham // See if we can find a "next range" breakpoint: 67*564d8bc2SJim Ingham SetNextBranchBreakpoint(); 6830fdc8d8SChris Lattner } 6930fdc8d8SChris Lattner 7030fdc8d8SChris Lattner bool 7130fdc8d8SChris Lattner ThreadPlanStepRange::ValidatePlan (Stream *error) 7230fdc8d8SChris Lattner { 7330fdc8d8SChris Lattner return true; 7430fdc8d8SChris Lattner } 7530fdc8d8SChris Lattner 7630fdc8d8SChris Lattner Vote 7730fdc8d8SChris Lattner ThreadPlanStepRange::ShouldReportStop (Event *event_ptr) 7830fdc8d8SChris Lattner { 792d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 802cad65a5SGreg Clayton 812cad65a5SGreg Clayton const Vote vote = IsPlanComplete() ? eVoteYes : eVoteNo; 822cad65a5SGreg Clayton if (log) 83411c0ce8SGreg Clayton log->Printf ("ThreadPlanStepRange::ShouldReportStop() returning vote %i\n", vote); 842cad65a5SGreg Clayton return vote; 8530fdc8d8SChris Lattner } 8630fdc8d8SChris Lattner 87c4c9fedcSJim Ingham void 88c4c9fedcSJim Ingham ThreadPlanStepRange::AddRange(const AddressRange &new_range) 89c4c9fedcSJim Ingham { 90c4c9fedcSJim Ingham // For now I'm just adding the ranges. At some point we may want to 91c4c9fedcSJim Ingham // condense the ranges if they overlap, though I don't think it is likely 92c4c9fedcSJim Ingham // to be very important. 93c4c9fedcSJim Ingham m_address_ranges.push_back (new_range); 94*564d8bc2SJim Ingham m_instruction_ranges.push_back (DisassemblerSP()); 95c4c9fedcSJim Ingham } 96c4c9fedcSJim Ingham 97c4c9fedcSJim Ingham void 98c4c9fedcSJim Ingham ThreadPlanStepRange::DumpRanges(Stream *s) 99c4c9fedcSJim Ingham { 100c4c9fedcSJim Ingham size_t num_ranges = m_address_ranges.size(); 101c4c9fedcSJim Ingham if (num_ranges == 1) 102c4c9fedcSJim Ingham { 1031ac04c30SGreg Clayton m_address_ranges[0].Dump (s, m_thread.CalculateTarget().get(), Address::DumpStyleLoadAddress); 104c4c9fedcSJim Ingham } 105c4c9fedcSJim Ingham else 106c4c9fedcSJim Ingham { 107c4c9fedcSJim Ingham for (size_t i = 0; i < num_ranges; i++) 108c4c9fedcSJim Ingham { 109c4c9fedcSJim Ingham s->PutCString("%d: "); 1101ac04c30SGreg Clayton m_address_ranges[i].Dump (s, m_thread.CalculateTarget().get(), Address::DumpStyleLoadAddress); 111c4c9fedcSJim Ingham } 112c4c9fedcSJim Ingham } 113c4c9fedcSJim Ingham } 114c4c9fedcSJim Ingham 11530fdc8d8SChris Lattner bool 11630fdc8d8SChris Lattner ThreadPlanStepRange::InRange () 11730fdc8d8SChris Lattner { 1182d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 11930fdc8d8SChris Lattner bool ret_value = false; 12030fdc8d8SChris Lattner 12130fdc8d8SChris Lattner lldb::addr_t pc_load_addr = m_thread.GetRegisterContext()->GetPC(); 12230fdc8d8SChris Lattner 123c4c9fedcSJim Ingham size_t num_ranges = m_address_ranges.size(); 124c4c9fedcSJim Ingham for (size_t i = 0; i < num_ranges; i++) 125c4c9fedcSJim Ingham { 1261ac04c30SGreg Clayton ret_value = m_address_ranges[i].ContainsLoadAddress(pc_load_addr, m_thread.CalculateTarget().get()); 127c4c9fedcSJim Ingham if (ret_value) 128c4c9fedcSJim Ingham break; 129c4c9fedcSJim Ingham } 13030fdc8d8SChris Lattner 13130fdc8d8SChris Lattner if (!ret_value) 13230fdc8d8SChris Lattner { 13330fdc8d8SChris Lattner // See if we've just stepped to another part of the same line number... 13430fdc8d8SChris Lattner StackFrame *frame = m_thread.GetStackFrameAtIndex(0).get(); 13530fdc8d8SChris Lattner 13630fdc8d8SChris Lattner SymbolContext new_context(frame->GetSymbolContext(eSymbolContextEverything)); 13730fdc8d8SChris Lattner if (m_addr_context.line_entry.IsValid() && new_context.line_entry.IsValid()) 13830fdc8d8SChris Lattner { 139843bfb2cSJim Ingham if (m_addr_context.line_entry.file == new_context.line_entry.file) 140843bfb2cSJim Ingham { 141843bfb2cSJim Ingham if (m_addr_context.line_entry.line == new_context.line_entry.line) 14230fdc8d8SChris Lattner { 14330fdc8d8SChris Lattner m_addr_context = new_context; 144c4c9fedcSJim Ingham AddRange(m_addr_context.line_entry.range); 14530fdc8d8SChris Lattner ret_value = true; 14630fdc8d8SChris Lattner if (log) 14730fdc8d8SChris Lattner { 14830fdc8d8SChris Lattner StreamString s; 149c4c9fedcSJim Ingham m_addr_context.line_entry.range.Dump (&s, 1501ac04c30SGreg Clayton m_thread.CalculateTarget().get(), 151c4c9fedcSJim Ingham Address::DumpStyleLoadAddress); 15230fdc8d8SChris Lattner 15330fdc8d8SChris Lattner log->Printf ("Step range plan stepped to another range of same line: %s", s.GetData()); 15430fdc8d8SChris Lattner } 15530fdc8d8SChris Lattner } 1561ac04c30SGreg Clayton else if (new_context.line_entry.range.GetBaseAddress().GetLoadAddress(m_thread.CalculateTarget().get()) 157843bfb2cSJim Ingham != pc_load_addr) 158843bfb2cSJim Ingham { 159843bfb2cSJim Ingham // Another thing that sometimes happens here is that we step out of one line into the MIDDLE of another 160843bfb2cSJim Ingham // line. So far I mostly see this due to bugs in the debug information. 161843bfb2cSJim Ingham // But we probably don't want to be in the middle of a line range, so in that case reset the stepping 162843bfb2cSJim Ingham // range to the line we've stepped into the middle of and continue. 163843bfb2cSJim Ingham m_addr_context = new_context; 164c4c9fedcSJim Ingham m_address_ranges.clear(); 165c4c9fedcSJim Ingham AddRange(m_addr_context.line_entry.range); 166843bfb2cSJim Ingham ret_value = true; 167843bfb2cSJim Ingham if (log) 168843bfb2cSJim Ingham { 169843bfb2cSJim Ingham StreamString s; 170c4c9fedcSJim Ingham m_addr_context.line_entry.range.Dump (&s, 1711ac04c30SGreg Clayton m_thread.CalculateTarget().get(), 172c4c9fedcSJim Ingham Address::DumpStyleLoadAddress); 173843bfb2cSJim Ingham 174843bfb2cSJim Ingham log->Printf ("Step range plan stepped to the middle of new line(%d): %s, continuing to clear this line.", 175843bfb2cSJim Ingham new_context.line_entry.line, 176843bfb2cSJim Ingham s.GetData()); 177843bfb2cSJim Ingham } 178843bfb2cSJim Ingham 179843bfb2cSJim Ingham } 180843bfb2cSJim Ingham } 181843bfb2cSJim Ingham 18230fdc8d8SChris Lattner } 18330fdc8d8SChris Lattner 18430fdc8d8SChris Lattner } 18530fdc8d8SChris Lattner 18630fdc8d8SChris Lattner if (!ret_value && log) 18730fdc8d8SChris Lattner log->Printf ("Step range plan out of range to 0x%llx", pc_load_addr); 18830fdc8d8SChris Lattner 18930fdc8d8SChris Lattner return ret_value; 19030fdc8d8SChris Lattner } 19130fdc8d8SChris Lattner 19230fdc8d8SChris Lattner bool 19330fdc8d8SChris Lattner ThreadPlanStepRange::InSymbol() 19430fdc8d8SChris Lattner { 19530fdc8d8SChris Lattner lldb::addr_t cur_pc = m_thread.GetRegisterContext()->GetPC(); 19630fdc8d8SChris Lattner if (m_addr_context.function != NULL) 19730fdc8d8SChris Lattner { 1981ac04c30SGreg Clayton return m_addr_context.function->GetAddressRange().ContainsLoadAddress (cur_pc, m_thread.CalculateTarget().get()); 19930fdc8d8SChris Lattner } 200e7612134SGreg Clayton else if (m_addr_context.symbol) 20130fdc8d8SChris Lattner { 202e7612134SGreg Clayton AddressRange range(m_addr_context.symbol->GetAddress(), m_addr_context.symbol->GetByteSize()); 203e7612134SGreg Clayton return range.ContainsLoadAddress (cur_pc, m_thread.CalculateTarget().get()); 20430fdc8d8SChris Lattner } 20530fdc8d8SChris Lattner return false; 20630fdc8d8SChris Lattner } 20730fdc8d8SChris Lattner 20830fdc8d8SChris Lattner // FIXME: This should also handle inlining if we aren't going to do inlining in the 20930fdc8d8SChris Lattner // main stack. 21030fdc8d8SChris Lattner // 21130fdc8d8SChris Lattner // Ideally we should remember the whole stack frame list, and then compare that 21230fdc8d8SChris Lattner // to the current list. 21330fdc8d8SChris Lattner 214b5c0d1ccSJim Ingham lldb::FrameComparison 215b5c0d1ccSJim Ingham ThreadPlanStepRange::CompareCurrentFrameToStartFrame() 21630fdc8d8SChris Lattner { 217b5c0d1ccSJim Ingham FrameComparison frame_order; 2187ce490c6SJim Ingham 219b5c0d1ccSJim Ingham StackID cur_frame_id = m_thread.GetStackFrameAtIndex(0)->GetStackID(); 2207ce490c6SJim Ingham 221b5c0d1ccSJim Ingham if (cur_frame_id == m_stack_id) 22230fdc8d8SChris Lattner { 223b5c0d1ccSJim Ingham frame_order = eFrameCompareEqual; 22430fdc8d8SChris Lattner } 225b5c0d1ccSJim Ingham else if (cur_frame_id < m_stack_id) 22630fdc8d8SChris Lattner { 227b5c0d1ccSJim Ingham frame_order = eFrameCompareYounger; 22830fdc8d8SChris Lattner } 22930fdc8d8SChris Lattner else 23030fdc8d8SChris Lattner { 231b5c0d1ccSJim Ingham frame_order = eFrameCompareOlder; 23230fdc8d8SChris Lattner } 233b5c0d1ccSJim Ingham return frame_order; 23430fdc8d8SChris Lattner } 23530fdc8d8SChris Lattner 23630fdc8d8SChris Lattner bool 23730fdc8d8SChris Lattner ThreadPlanStepRange::StopOthers () 23830fdc8d8SChris Lattner { 23930fdc8d8SChris Lattner if (m_stop_others == lldb::eOnlyThisThread 24030fdc8d8SChris Lattner || m_stop_others == lldb::eOnlyDuringStepping) 24130fdc8d8SChris Lattner return true; 24230fdc8d8SChris Lattner else 24330fdc8d8SChris Lattner return false; 24430fdc8d8SChris Lattner } 24530fdc8d8SChris Lattner 246*564d8bc2SJim Ingham InstructionList * 247*564d8bc2SJim Ingham ThreadPlanStepRange::GetInstructionsForAddress(lldb::addr_t addr, size_t &range_index, size_t &insn_offset) 248*564d8bc2SJim Ingham { 249*564d8bc2SJim Ingham size_t num_ranges = m_address_ranges.size(); 250*564d8bc2SJim Ingham for (size_t i = 0; i < num_ranges; i++) 251*564d8bc2SJim Ingham { 252*564d8bc2SJim Ingham if (m_address_ranges[i].ContainsLoadAddress(addr, &GetTarget())) 253*564d8bc2SJim Ingham { 254*564d8bc2SJim Ingham // Some joker added a zero size range to the stepping range... 255*564d8bc2SJim Ingham if (m_address_ranges[i].GetByteSize() == 0) 256*564d8bc2SJim Ingham return NULL; 257*564d8bc2SJim Ingham 258*564d8bc2SJim Ingham if (!m_instruction_ranges[i]) 259*564d8bc2SJim Ingham { 260*564d8bc2SJim Ingham //Disassemble the address range given: 261*564d8bc2SJim Ingham ExecutionContext exe_ctx (m_thread.GetProcess()); 262*564d8bc2SJim Ingham m_instruction_ranges[i] = Disassembler::DisassembleRange(GetTarget().GetArchitecture(), 263*564d8bc2SJim Ingham NULL, 264*564d8bc2SJim Ingham exe_ctx, 265*564d8bc2SJim Ingham m_address_ranges[i]); 266*564d8bc2SJim Ingham 267*564d8bc2SJim Ingham } 268*564d8bc2SJim Ingham if (!m_instruction_ranges[i]) 269*564d8bc2SJim Ingham return NULL; 270*564d8bc2SJim Ingham else 271*564d8bc2SJim Ingham { 272*564d8bc2SJim Ingham // Find where we are in the instruction list as well. If we aren't at an instruction, 273*564d8bc2SJim Ingham // return NULL. In this case, we're probably lost, and shouldn't try to do anything fancy. 274*564d8bc2SJim Ingham 275*564d8bc2SJim Ingham insn_offset = m_instruction_ranges[i]->GetInstructionList().GetIndexOfInstructionAtLoadAddress(addr, GetTarget()); 276*564d8bc2SJim Ingham if (insn_offset == UINT32_MAX) 277*564d8bc2SJim Ingham return NULL; 278*564d8bc2SJim Ingham else 279*564d8bc2SJim Ingham { 280*564d8bc2SJim Ingham range_index = i; 281*564d8bc2SJim Ingham return &m_instruction_ranges[i]->GetInstructionList(); 282*564d8bc2SJim Ingham } 283*564d8bc2SJim Ingham } 284*564d8bc2SJim Ingham } 285*564d8bc2SJim Ingham } 286*564d8bc2SJim Ingham return NULL; 287*564d8bc2SJim Ingham } 288*564d8bc2SJim Ingham 289*564d8bc2SJim Ingham void 290*564d8bc2SJim Ingham ThreadPlanStepRange::ClearNextBranchBreakpoint() 291*564d8bc2SJim Ingham { 292*564d8bc2SJim Ingham if (m_next_branch_bp_sp) 293*564d8bc2SJim Ingham { 294*564d8bc2SJim Ingham GetTarget().RemoveBreakpointByID (m_next_branch_bp_sp->GetID()); 295*564d8bc2SJim Ingham m_next_branch_bp_sp.reset(); 296*564d8bc2SJim Ingham } 297*564d8bc2SJim Ingham } 298*564d8bc2SJim Ingham 299*564d8bc2SJim Ingham bool 300*564d8bc2SJim Ingham ThreadPlanStepRange::SetNextBranchBreakpoint () 301*564d8bc2SJim Ingham { 302*564d8bc2SJim Ingham // Stepping through ranges using breakpoints doesn't work yet, but with this off we fall back to instruction 303*564d8bc2SJim Ingham // single stepping. 304*564d8bc2SJim Ingham return false; 305*564d8bc2SJim Ingham // Always clear the next branch breakpoint, we don't want to leave one of these stranded. 306*564d8bc2SJim Ingham ClearNextBranchBreakpoint(); 307*564d8bc2SJim Ingham lldb::addr_t cur_addr = GetThread().GetRegisterContext()->GetPC(); 308*564d8bc2SJim Ingham // Find the current address in our address ranges, and fetch the disassembly if we haven't already: 309*564d8bc2SJim Ingham size_t pc_index; 310*564d8bc2SJim Ingham size_t range_index; 311*564d8bc2SJim Ingham InstructionList *instructions = GetInstructionsForAddress (cur_addr, range_index, pc_index); 312*564d8bc2SJim Ingham if (instructions == NULL) 313*564d8bc2SJim Ingham return false; 314*564d8bc2SJim Ingham else 315*564d8bc2SJim Ingham { 316*564d8bc2SJim Ingham uint32_t branch_index; 317*564d8bc2SJim Ingham branch_index = instructions->GetIndexOfNextBranchInstruction (pc_index); 318*564d8bc2SJim Ingham 319*564d8bc2SJim Ingham Address run_to_address; 320*564d8bc2SJim Ingham 321*564d8bc2SJim Ingham // If we didn't find a branch, run to the end of the range. 322*564d8bc2SJim Ingham if (branch_index == UINT32_MAX) 323*564d8bc2SJim Ingham { 324*564d8bc2SJim Ingham branch_index = instructions->GetSize() - 2; 325*564d8bc2SJim Ingham } 326*564d8bc2SJim Ingham if (branch_index - pc_index > 1) 327*564d8bc2SJim Ingham { 328*564d8bc2SJim Ingham const bool is_internal = true; 329*564d8bc2SJim Ingham run_to_address = instructions->GetInstructionAtIndex(branch_index)->GetAddress(); 330*564d8bc2SJim Ingham m_next_branch_bp_sp = GetTarget().CreateBreakpoint(run_to_address, is_internal); 331*564d8bc2SJim Ingham m_next_branch_bp_sp->SetThreadID(m_thread.GetID()); 332*564d8bc2SJim Ingham return true; 333*564d8bc2SJim Ingham } 334*564d8bc2SJim Ingham } 335*564d8bc2SJim Ingham return false; 336*564d8bc2SJim Ingham } 337*564d8bc2SJim Ingham 338*564d8bc2SJim Ingham bool 339*564d8bc2SJim Ingham ThreadPlanStepRange::NextRangeBreakpointExplainsStop (lldb::StopInfoSP stop_info_sp) 340*564d8bc2SJim Ingham { 341*564d8bc2SJim Ingham if (!m_next_branch_bp_sp) 342*564d8bc2SJim Ingham return false; 343*564d8bc2SJim Ingham 344*564d8bc2SJim Ingham break_id_t bp_site_id = stop_info_sp->GetValue(); 345*564d8bc2SJim Ingham BreakpointSiteSP bp_site_sp = m_thread.GetProcess()->GetBreakpointSiteList().FindByID(bp_site_id); 346*564d8bc2SJim Ingham if (!bp_site_sp->IsBreakpointAtThisSite (m_next_branch_bp_sp->GetID())) 347*564d8bc2SJim Ingham return false; 348*564d8bc2SJim Ingham else 349*564d8bc2SJim Ingham return bp_site_sp->GetNumberOfOwners() == 1; 350*564d8bc2SJim Ingham } 351*564d8bc2SJim Ingham 352*564d8bc2SJim Ingham bool 353*564d8bc2SJim Ingham ThreadPlanStepRange::PlanExplainsStop () 354*564d8bc2SJim Ingham { 355*564d8bc2SJim Ingham // We always explain a stop. Either we've just done a single step, in which 356*564d8bc2SJim Ingham // case we'll do our ordinary processing, or we stopped for some 357*564d8bc2SJim Ingham // reason that isn't handled by our sub-plans, in which case we want to just stop right 358*564d8bc2SJim Ingham // away. 359*564d8bc2SJim Ingham 360*564d8bc2SJim Ingham LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 361*564d8bc2SJim Ingham StopInfoSP stop_info_sp = GetPrivateStopReason(); 362*564d8bc2SJim Ingham if (stop_info_sp) 363*564d8bc2SJim Ingham { 364*564d8bc2SJim Ingham StopReason reason = stop_info_sp->GetStopReason(); 365*564d8bc2SJim Ingham 366*564d8bc2SJim Ingham switch (reason) 367*564d8bc2SJim Ingham { 368*564d8bc2SJim Ingham case eStopReasonBreakpoint: 369*564d8bc2SJim Ingham if (NextRangeBreakpointExplainsStop(stop_info_sp)) 370*564d8bc2SJim Ingham return true; 371*564d8bc2SJim Ingham case eStopReasonWatchpoint: 372*564d8bc2SJim Ingham case eStopReasonSignal: 373*564d8bc2SJim Ingham case eStopReasonException: 374*564d8bc2SJim Ingham if (log) 375*564d8bc2SJim Ingham log->PutCString ("ThreadPlanStepInRange got asked if it explains the stop for some reason other than step."); 376*564d8bc2SJim Ingham SetPlanComplete(); 377*564d8bc2SJim Ingham break; 378*564d8bc2SJim Ingham default: 379*564d8bc2SJim Ingham break; 380*564d8bc2SJim Ingham } 381*564d8bc2SJim Ingham } 382*564d8bc2SJim Ingham return true; 383*564d8bc2SJim Ingham } 384*564d8bc2SJim Ingham 38530fdc8d8SChris Lattner bool 38630fdc8d8SChris Lattner ThreadPlanStepRange::WillStop () 38730fdc8d8SChris Lattner { 38830fdc8d8SChris Lattner return true; 38930fdc8d8SChris Lattner } 39030fdc8d8SChris Lattner 39130fdc8d8SChris Lattner StateType 39206e827ccSJim Ingham ThreadPlanStepRange::GetPlanRunState () 39330fdc8d8SChris Lattner { 394*564d8bc2SJim Ingham if (m_next_branch_bp_sp) 395*564d8bc2SJim Ingham return eStateRunning; 396*564d8bc2SJim Ingham else 39730fdc8d8SChris Lattner return eStateStepping; 39830fdc8d8SChris Lattner } 39930fdc8d8SChris Lattner 40030fdc8d8SChris Lattner bool 40130fdc8d8SChris Lattner ThreadPlanStepRange::MischiefManaged () 40230fdc8d8SChris Lattner { 40330fdc8d8SChris Lattner bool done = true; 40430fdc8d8SChris Lattner if (!IsPlanComplete()) 40530fdc8d8SChris Lattner { 40630fdc8d8SChris Lattner if (InRange()) 40730fdc8d8SChris Lattner { 40830fdc8d8SChris Lattner done = false; 40930fdc8d8SChris Lattner } 410b5c0d1ccSJim Ingham else 411b5c0d1ccSJim Ingham { 412b5c0d1ccSJim Ingham FrameComparison frame_order = CompareCurrentFrameToStartFrame(); 413b5c0d1ccSJim Ingham if (frame_order != eFrameCompareOlder) 41430fdc8d8SChris Lattner { 41530fdc8d8SChris Lattner if (m_no_more_plans) 41630fdc8d8SChris Lattner done = true; 41730fdc8d8SChris Lattner else 41830fdc8d8SChris Lattner done = false; 41930fdc8d8SChris Lattner } 42030fdc8d8SChris Lattner else 42130fdc8d8SChris Lattner done = true; 42230fdc8d8SChris Lattner } 423b5c0d1ccSJim Ingham } 42430fdc8d8SChris Lattner 42530fdc8d8SChris Lattner if (done) 42630fdc8d8SChris Lattner { 4272d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 42830fdc8d8SChris Lattner if (log) 42930fdc8d8SChris Lattner log->Printf("Completed step through range plan."); 43030fdc8d8SChris Lattner ThreadPlan::MischiefManaged (); 43130fdc8d8SChris Lattner return true; 43230fdc8d8SChris Lattner } 43330fdc8d8SChris Lattner else 43430fdc8d8SChris Lattner { 43530fdc8d8SChris Lattner return false; 43630fdc8d8SChris Lattner } 43730fdc8d8SChris Lattner 43830fdc8d8SChris Lattner } 439