without having to use RTTI. Removed the ThreadPlanContinue and replaced with a ShouldAutoContinue query that serves the same purpose. Having to push another plan to assert that if there's no other indication the target should continue when this plan is popped was flakey and error prone. This method is more stable, and fixed problems we were having with thread specific breakpoints. llvm-svn: 106378
177 lines
4.3 KiB
C++
177 lines
4.3 KiB
C++
//===-- ThreadPlanRunToAddress.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/ThreadPlanRunToAddress.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/Target.h"
|
|
#include "lldb/Target/Process.h"
|
|
#include "lldb/Target/Thread.h"
|
|
#include "lldb/Target/RegisterContext.h"
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
//----------------------------------------------------------------------
|
|
// ThreadPlanRunToAddress: Continue plan
|
|
//----------------------------------------------------------------------
|
|
|
|
ThreadPlanRunToAddress::ThreadPlanRunToAddress
|
|
(
|
|
Thread &thread,
|
|
Address &address,
|
|
bool stop_others
|
|
) :
|
|
ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to breakpoint plan", thread, eVoteNoOpinion, eVoteNoOpinion),
|
|
m_stop_others (stop_others),
|
|
m_address (LLDB_INVALID_ADDRESS),
|
|
m_break_id (LLDB_INVALID_BREAK_ID)
|
|
{
|
|
m_address = address.GetLoadAddress(&m_thread.GetProcess());
|
|
SetInitialBreakpoint();
|
|
}
|
|
|
|
ThreadPlanRunToAddress::ThreadPlanRunToAddress
|
|
(
|
|
Thread &thread,
|
|
lldb::addr_t address,
|
|
bool stop_others
|
|
) :
|
|
ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to breakpoint plan", thread, eVoteNoOpinion, eVoteNoOpinion),
|
|
m_stop_others (stop_others),
|
|
m_address (address),
|
|
m_break_id (LLDB_INVALID_BREAK_ID)
|
|
{
|
|
SetInitialBreakpoint();
|
|
}
|
|
|
|
void
|
|
ThreadPlanRunToAddress::SetInitialBreakpoint ()
|
|
{
|
|
Breakpoint *breakpoint;
|
|
breakpoint = m_thread.GetProcess().GetTarget().CreateBreakpoint (m_address, true).get();
|
|
if (breakpoint != NULL)
|
|
{
|
|
m_break_id = breakpoint->GetID();
|
|
breakpoint->SetThreadID(m_thread.GetID());
|
|
}
|
|
}
|
|
|
|
ThreadPlanRunToAddress::~ThreadPlanRunToAddress ()
|
|
{
|
|
if (m_break_id != LLDB_INVALID_BREAK_ID)
|
|
{
|
|
m_thread.GetProcess().GetTarget().RemoveBreakpointByID (m_break_id);
|
|
}
|
|
}
|
|
|
|
void
|
|
ThreadPlanRunToAddress::GetDescription (Stream *s, lldb::DescriptionLevel level)
|
|
{
|
|
if (level == lldb::eDescriptionLevelBrief)
|
|
{
|
|
s->Printf ("run to address: ");
|
|
s->Address (m_address, sizeof (addr_t));
|
|
}
|
|
else
|
|
{
|
|
s->Printf ("Run to address: ");
|
|
s->Address(m_address, sizeof (addr_t));
|
|
s->Printf (" using breakpoint: %d - ", m_break_id);
|
|
Breakpoint *breakpoint = m_thread.GetProcess().GetTarget().GetBreakpointByID (m_break_id).get();
|
|
if (breakpoint)
|
|
breakpoint->Dump (s);
|
|
else
|
|
s->Printf ("but the breakpoint has been deleted.");
|
|
}
|
|
}
|
|
|
|
bool
|
|
ThreadPlanRunToAddress::ValidatePlan (Stream *error)
|
|
{
|
|
// If we couldn't set the breakpoint for some reason, then this won't
|
|
// work.
|
|
if(m_break_id == LLDB_INVALID_BREAK_ID)
|
|
return false;
|
|
else
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
ThreadPlanRunToAddress::PlanExplainsStop ()
|
|
{
|
|
return AtOurAddress();
|
|
}
|
|
|
|
bool
|
|
ThreadPlanRunToAddress::ShouldStop (Event *event_ptr)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
ThreadPlanRunToAddress::StopOthers ()
|
|
{
|
|
return m_stop_others;
|
|
}
|
|
|
|
void
|
|
ThreadPlanRunToAddress::SetStopOthers (bool new_value)
|
|
{
|
|
m_stop_others = new_value;
|
|
}
|
|
|
|
StateType
|
|
ThreadPlanRunToAddress::RunState ()
|
|
{
|
|
return eStateRunning;
|
|
}
|
|
|
|
bool
|
|
ThreadPlanRunToAddress::WillStop ()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
ThreadPlanRunToAddress::MischiefManaged ()
|
|
{
|
|
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
|
|
|
|
if (AtOurAddress())
|
|
{
|
|
// Remove the breakpoint
|
|
if (m_break_id != LLDB_INVALID_BREAK_ID)
|
|
{
|
|
m_thread.GetProcess().GetTarget().RemoveBreakpointByID (m_break_id);
|
|
m_break_id = LLDB_INVALID_BREAK_ID;
|
|
}
|
|
|
|
if (log)
|
|
log->Printf("Completed run to address plan.");
|
|
ThreadPlan::MischiefManaged ();
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
ThreadPlanRunToAddress::AtOurAddress ()
|
|
{
|
|
lldb::addr_t current_address = m_thread.GetRegisterContext()->GetPC();
|
|
return m_address == current_address;
|
|
}
|