193 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			193 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			C++
		
	
	
	
//===-- ThreadPlanStepInstruction.cpp ---------------------------*- C++ -*-===//
 | 
						|
//
 | 
						|
//                     The LLVM Compiler Infrastructure
 | 
						|
//
 | 
						|
// This file is distributed under the University of Illinois Open Source
 | 
						|
// License. See LICENSE.TXT for details.
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
 | 
						|
#include "lldb/Target/ThreadPlanStepInstruction.h"
 | 
						|
 | 
						|
// C Includes
 | 
						|
// C++ Includes
 | 
						|
// Other libraries and framework includes
 | 
						|
// Project includes
 | 
						|
#include "lldb/lldb-private-log.h"
 | 
						|
#include "lldb/Core/Log.h"
 | 
						|
#include "lldb/Core/Stream.h"
 | 
						|
#include "lldb/Target/Process.h"
 | 
						|
#include "lldb/Target/RegisterContext.h"
 | 
						|
#include "lldb/Target/RegisterContext.h"
 | 
						|
#include "lldb/Target/StopInfo.h"
 | 
						|
#include "lldb/Target/Target.h"
 | 
						|
 | 
						|
using namespace lldb;
 | 
						|
using namespace lldb_private;
 | 
						|
 | 
						|
//----------------------------------------------------------------------
 | 
						|
// ThreadPlanStepInstruction: Step over the current instruction
 | 
						|
//----------------------------------------------------------------------
 | 
						|
 | 
						|
ThreadPlanStepInstruction::ThreadPlanStepInstruction
 | 
						|
(
 | 
						|
    Thread &thread,
 | 
						|
    bool step_over,
 | 
						|
    bool stop_other_threads,
 | 
						|
    Vote stop_vote,
 | 
						|
    Vote run_vote
 | 
						|
) :
 | 
						|
    ThreadPlan (ThreadPlan::eKindStepInstruction, "Step over single instruction", thread, stop_vote, run_vote),
 | 
						|
    m_instruction_addr (0),
 | 
						|
    m_stop_other_threads (stop_other_threads),
 | 
						|
    m_step_over (step_over),
 | 
						|
    m_stack_depth (0)
 | 
						|
{
 | 
						|
    m_instruction_addr = m_thread.GetRegisterContext()->GetPC(0);
 | 
						|
    m_stack_depth = m_thread.GetStackFrameCount();
 | 
						|
}
 | 
						|
 | 
						|
ThreadPlanStepInstruction::~ThreadPlanStepInstruction ()
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
ThreadPlanStepInstruction::GetDescription (Stream *s, lldb::DescriptionLevel level)
 | 
						|
{
 | 
						|
    if (level == lldb::eDescriptionLevelBrief)
 | 
						|
    {
 | 
						|
        if (m_step_over)
 | 
						|
            s->Printf ("instruction step over");
 | 
						|
        else
 | 
						|
            s->Printf ("instruction step into");
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        s->Printf ("Stepping one instruction past ");
 | 
						|
        s->Address(m_instruction_addr, sizeof (addr_t));
 | 
						|
        if (m_step_over)
 | 
						|
            s->Printf(" stepping over calls");
 | 
						|
        else
 | 
						|
            s->Printf(" stepping into calls");
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
bool
 | 
						|
ThreadPlanStepInstruction::ValidatePlan (Stream *error)
 | 
						|
{
 | 
						|
    // Since we read the instruction we're stepping over from the thread,
 | 
						|
    // this plan will always work.
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool
 | 
						|
ThreadPlanStepInstruction::PlanExplainsStop ()
 | 
						|
{
 | 
						|
    StopInfoSP stop_info_sp = GetPrivateStopReason();
 | 
						|
    if (stop_info_sp)
 | 
						|
    {
 | 
						|
        StopReason reason = stop_info_sp->GetStopReason();
 | 
						|
        if (reason == eStopReasonTrace || reason == eStopReasonNone)
 | 
						|
            return true;
 | 
						|
        else
 | 
						|
            return false;
 | 
						|
    }
 | 
						|
    return false;
 | 
						|
}
 | 
						|
 | 
						|
bool
 | 
						|
ThreadPlanStepInstruction::ShouldStop (Event *event_ptr)
 | 
						|
{
 | 
						|
    if (m_step_over)
 | 
						|
    {
 | 
						|
        LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
 | 
						|
        if (m_thread.GetStackFrameCount() <= m_stack_depth)
 | 
						|
        {
 | 
						|
            if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr)
 | 
						|
            {
 | 
						|
                SetPlanComplete();
 | 
						|
                return true;
 | 
						|
            }
 | 
						|
            else
 | 
						|
                return false;
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            // We've stepped in, step back out again:
 | 
						|
            StackFrame *return_frame = m_thread.GetStackFrameAtIndex(1).get();
 | 
						|
            if (return_frame)
 | 
						|
            {
 | 
						|
                if (log)
 | 
						|
                {
 | 
						|
                    StreamString s;
 | 
						|
                    s.PutCString ("Stepped in to: ");
 | 
						|
                    addr_t stop_addr = m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC();
 | 
						|
                    s.Address (stop_addr, m_thread.GetProcess().GetAddressByteSize());
 | 
						|
                    s.PutCString (" stepping out to: ");
 | 
						|
                    addr_t return_addr = return_frame->GetRegisterContext()->GetPC();
 | 
						|
                    s.Address (return_addr, m_thread.GetProcess().GetAddressByteSize());
 | 
						|
                    log->Printf("%s.", s.GetData());
 | 
						|
                }
 | 
						|
                m_thread.QueueThreadPlanForStepOut(false, NULL, true, m_stop_other_threads, eVoteNo, eVoteNoOpinion);
 | 
						|
                return false;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                if (log)
 | 
						|
                    log->Printf("Could not find previous frame, stopping.");
 | 
						|
                SetPlanComplete();
 | 
						|
                return true;
 | 
						|
            }
 | 
						|
 | 
						|
        }
 | 
						|
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr)
 | 
						|
        {
 | 
						|
            SetPlanComplete();
 | 
						|
            return true;
 | 
						|
        }
 | 
						|
        else
 | 
						|
            return false;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
bool
 | 
						|
ThreadPlanStepInstruction::StopOthers ()
 | 
						|
{
 | 
						|
    return m_stop_other_threads;
 | 
						|
}
 | 
						|
 | 
						|
StateType
 | 
						|
ThreadPlanStepInstruction::GetPlanRunState ()
 | 
						|
{
 | 
						|
    return eStateStepping;
 | 
						|
}
 | 
						|
 | 
						|
bool
 | 
						|
ThreadPlanStepInstruction::WillStop ()
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool
 | 
						|
ThreadPlanStepInstruction::MischiefManaged ()
 | 
						|
{
 | 
						|
    if (IsPlanComplete())
 | 
						|
    {
 | 
						|
        LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
 | 
						|
        if (log)
 | 
						|
            log->Printf("Completed single instruction step plan.");
 | 
						|
        ThreadPlan::MischiefManaged ();
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
}
 | 
						|
 |