Files
clang-p2996/lldb/source/Target/ThreadPlanRunToAddress.cpp
Jim Ingham b01e742af7 Two changes in this checkin. Added a ThreadPlanKind so that I can do some reasoning based on the kind of thread plan
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
2010-06-19 04:45:32 +00:00

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;
}