blob: 8de40e852f4c89cc03cca90a3ecff1f9c5e00649 [file] [log] [blame]
//===-- StopInfo.h ----------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef liblldb_StopInfo_h_
#define liblldb_StopInfo_h_
// C Includes
// C++ Includes
#include <string>
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-public.h"
#include "lldb/Target/Process.h"
namespace lldb_private {
class StopInfo
{
friend class Process::ProcessEventData;
friend class ThreadPlanBase;
public:
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
StopInfo (Thread &thread, uint64_t value);
virtual ~StopInfo()
{
}
bool
IsValid () const;
void
SetThread (const lldb::ThreadSP &thread_sp)
{
m_thread_wp = thread_sp;
}
lldb::ThreadSP
GetThread() const
{
return m_thread_wp.lock();
}
// The value of the StopInfo depends on the StopReason.
// StopReason Meaning
// ----------------------------------------------
// eStopReasonBreakpoint BreakpointSiteID
// eStopReasonSignal Signal number
// eStopReasonWatchpoint WatchpointLocationID
// eStopReasonPlanComplete No significance
uint64_t
GetValue() const
{
return m_value;
}
virtual lldb::StopReason
GetStopReason () const = 0;
// ShouldStopSynchronous will get called before any thread plans are consulted, and if it says we should
// resume the target, then we will just immediately resume. This should not run any code in or resume the
// target.
virtual bool
ShouldStopSynchronous (Event *event_ptr)
{
return true;
}
void
OverrideShouldNotify (bool override_value)
{
m_override_should_notify = override_value ? eLazyBoolYes : eLazyBoolNo;
}
// If should stop returns false, check if we should notify of this event
virtual bool
ShouldNotify (Event *event_ptr)
{
if (m_override_should_notify == eLazyBoolCalculate)
return DoShouldNotify (event_ptr);
else
return m_override_should_notify == eLazyBoolYes;
}
virtual void
WillResume (lldb::StateType resume_state)
{
// By default, don't do anything
}
virtual const char *
GetDescription ()
{
return m_description.c_str();
}
virtual void
SetDescription (const char *desc_cstr)
{
if (desc_cstr && desc_cstr[0])
m_description.assign (desc_cstr);
else
m_description.clear();
}
// Sometimes the thread plan logic will know that it wants a given stop to stop or not,
// regardless of what the ordinary logic for that StopInfo would dictate. The main example
// of this is the ThreadPlanCallFunction, which for instance knows - based on how that particular
// expression was executed - whether it wants all breakpoints to auto-continue or not.
// Use OverrideShouldStop on the StopInfo to implement this.
void
OverrideShouldStop (bool override_value)
{
m_override_should_stop = override_value ? eLazyBoolYes : eLazyBoolNo;
}
bool
GetOverrideShouldStop()
{
return m_override_should_stop != eLazyBoolCalculate;
}
bool
GetOverriddenShouldStopValue ()
{
return m_override_should_stop == eLazyBoolYes;
}
static lldb::StopInfoSP
CreateStopReasonWithBreakpointSiteID (Thread &thread, lldb::break_id_t break_id);
// This creates a StopInfo for the thread where the should_stop is already set, and won't be recalculated.
static lldb::StopInfoSP
CreateStopReasonWithBreakpointSiteID (Thread &thread, lldb::break_id_t break_id, bool should_stop);
static lldb::StopInfoSP
CreateStopReasonWithWatchpointID (Thread &thread, lldb::break_id_t watch_id);
static lldb::StopInfoSP
CreateStopReasonWithSignal (Thread &thread, int signo);
static lldb::StopInfoSP
CreateStopReasonToTrace (Thread &thread);
static lldb::StopInfoSP
CreateStopReasonWithPlan (lldb::ThreadPlanSP &plan,
lldb::ValueObjectSP return_valobj_sp,
lldb::ClangExpressionVariableSP expression_variable_sp);
static lldb::StopInfoSP
CreateStopReasonWithException (Thread &thread, const char *description);
static lldb::StopInfoSP
CreateStopReasonWithExec (Thread &thread);
static lldb::ValueObjectSP
GetReturnValueObject (lldb::StopInfoSP &stop_info_sp);
static lldb::ClangExpressionVariableSP
GetExpressionVariable (lldb::StopInfoSP &stop_info_sp);
protected:
// Perform any action that is associated with this stop. This is done as the
// Event is removed from the event queue. ProcessEventData::DoOnRemoval does the job.
virtual void
PerformAction (Event *event_ptr)
{
}
virtual bool
DoShouldNotify (Event *event_ptr)
{
return false;
}
// Stop the thread by default. Subclasses can override this to allow
// the thread to continue if desired. The ShouldStop method should not do anything
// that might run code. If you need to run code when deciding whether to stop
// at this StopInfo, that must be done in the PerformAction.
// The PerformAction will always get called before the ShouldStop. This is done by the
// ProcessEventData::DoOnRemoval, though the ThreadPlanBase needs to consult this later on.
virtual bool
ShouldStop (Event *event_ptr)
{
return true;
}
//------------------------------------------------------------------
// Classes that inherit from StackID can see and modify these
//------------------------------------------------------------------
lldb::ThreadWP m_thread_wp; // The thread corresponding to the stop reason.
uint32_t m_stop_id; // The process stop ID for which this stop info is valid
uint32_t m_resume_id; // This is the resume ID when we made this stop ID.
uint64_t m_value; // A generic value that can be used for things pertaining to this stop info
std::string m_description; // A textual description describing this stop.
LazyBool m_override_should_notify;
LazyBool m_override_should_stop;
// This determines whether the target has run since this stop info.
// N.B. running to evaluate a user expression does not count.
bool HasTargetRunSinceMe ();
// MakeStopInfoValid is necessary to allow saved stop infos to resurrect themselves as valid.
// It should only be used by Thread::RestoreThreadStateFromCheckpoint and to make sure the one-step
// needed for before-the-fact watchpoints does not prevent us from stopping
void
MakeStopInfoValid ();
private:
friend class Thread;
DISALLOW_COPY_AND_ASSIGN (StopInfo);
};
} // namespace lldb_private
#endif // liblldb_StopInfo_h_