forked from OSchip/llvm-project
Thread hardening part 3. Now lldb_private::Thread objects have std::weak_ptr
objects for the backlink to the lldb_private::Process. The issues we were running into before was someone was holding onto a shared pointer to a lldb_private::Thread for too long, and the lldb_private::Process parent object would get destroyed and the lldb_private::Thread had a "Process &m_process" member which would just treat whatever memory that used to be a Process as a valid Process. This was mostly happening for lldb_private::StackFrame objects that had a member like "Thread &m_thread". So this completes the internal strong/weak changes. Documented the ExecutionContext and ExecutionContextRef classes so that our LLDB developers can understand when and where to use ExecutionContext and ExecutionContextRef objects. llvm-svn: 151009
This commit is contained in:
parent
3508a00543
commit
1ac04c3088
|
@ -32,7 +32,7 @@ class StoppointCallbackContext
|
|||
public:
|
||||
StoppointCallbackContext();
|
||||
|
||||
StoppointCallbackContext(Event *event, Process* process, Thread *thread = NULL, StackFrame * frame = NULL, bool synchronously = false);
|
||||
StoppointCallbackContext(Event *event, const ExecutionContext &exe_ctx, bool synchronously = false);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Clear the object's state.
|
||||
|
@ -48,7 +48,7 @@ public:
|
|||
//------------------------------------------------------------------
|
||||
Event *event; // This is the event, the callback can modify this to indicate
|
||||
// the meaning of the breakpoint hit
|
||||
ExecutionContext exe_ctx; // This tells us where we have stopped, what thread.
|
||||
ExecutionContextRef exe_ctx_ref; // This tells us where we have stopped, what thread.
|
||||
bool is_synchronous; // Is the callback being executed synchronously with the breakpoint,
|
||||
// or asynchronously as the event is retrieved?
|
||||
};
|
||||
|
|
|
@ -6,6 +6,30 @@
|
|||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// Execution context objects refer to objects in the execution of the
|
||||
/// program that is being debugged. The consist of one or more of the
|
||||
/// following objects: target, process, thread, and frame. Many objects
|
||||
/// in the debugger need to track different executions contexts. For
|
||||
/// example, a local function variable might have an execution context
|
||||
/// that refers to a stack frame. A global or static variable might
|
||||
/// refer to a target since a stack frame isn't required in order to
|
||||
/// evaluate a global or static variable (a process isn't necessarily
|
||||
/// needed for a global variable since we might be able to read the
|
||||
/// variable value from a data section in one of the object files in
|
||||
/// a target). There are two types of objects that hold onto execution
|
||||
/// contexts: ExecutionContextRef and ExecutionContext. Both of these
|
||||
/// objects are deascribed below.
|
||||
///
|
||||
/// Not all objects in an ExectionContext objects will be valid. If you want
|
||||
/// to refer stronly (ExectionContext) or weakly (ExectionContextRef) to
|
||||
/// a process, then only the process and target references will be valid.
|
||||
/// For threads, only the thread, process and target references will be
|
||||
/// filled in. For frames, all of the objects will be filled in.
|
||||
///
|
||||
/// These classes are designed to be used as baton objects that get passed
|
||||
/// to a wide variety of functions that require execution contexts.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
|
||||
#ifndef liblldb_ExecutionContext_h_
|
||||
|
@ -16,37 +40,116 @@
|
|||
|
||||
namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class ExecutionContextRef ExecutionContext.h "lldb/Target/ExecutionContext.h"
|
||||
/// @brief A class that holds a weak reference to an execution context.
|
||||
///
|
||||
/// ExecutionContextRef objects are designed to hold onto an execution
|
||||
/// context that might change over time. For example, if an object wants
|
||||
/// to refer to a stack frame, it should hold onto an ExecutionContextRef
|
||||
/// to a frame object. The backing object that represents the stack frame
|
||||
/// might change over time and instaces of this object can track the logical
|
||||
/// object that refers to a frame even if it does change.
|
||||
///
|
||||
/// These objects also don't keep execution objects around longer than they
|
||||
/// should since they use weak pointers. For example if an object refers
|
||||
/// to a stack frame and a stack frame is no longer in a thread, then a
|
||||
/// ExecutionContextRef object that refers to that frame will not be able
|
||||
/// to get a shared pointer to those objects since they are no longer around.
|
||||
///
|
||||
/// ExecutionContextRef objects can also be used as objects in classes
|
||||
/// that want to track a "previous execution context". Since the weak
|
||||
/// references to the execution objects (target, process, thread and frame)
|
||||
/// don't keep these objects around, they are safe to keep around.
|
||||
///
|
||||
/// The general rule of thumb is all long lived objects that want to
|
||||
/// refer to execution contexts should use ExecutionContextRef objcts.
|
||||
/// The ExecutionContext class is used to temporarily get shared
|
||||
/// pointers to any execution context objects that are still around
|
||||
/// so they are guaranteed to exist during a function that requires the
|
||||
/// objects. ExecutionContext objects should NOT be used for long term
|
||||
/// storage since they will keep objects alive with extra shared pointer
|
||||
/// references to these objects.
|
||||
//----------------------------------------------------------------------
|
||||
class ExecutionContextRef
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------
|
||||
/// Default Constructor.
|
||||
///
|
||||
/// Initialize with NULL process and thread, and invalid frame
|
||||
/// index.
|
||||
//------------------------------------------------------------------
|
||||
ExecutionContextRef();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Copy Constructor.
|
||||
//------------------------------------------------------------------
|
||||
ExecutionContextRef (const ExecutionContextRef &rhs);
|
||||
|
||||
ExecutionContextRef (const ExecutionContext *exe_ctx);
|
||||
//------------------------------------------------------------------
|
||||
/// Construct using an ExecutionContext object that might be NULL.
|
||||
///
|
||||
/// If \a exe_ctx_ptr is valid, then make weak references to any
|
||||
/// valid objects in the ExecutionContext, othewise no weak
|
||||
/// references to any execution context objects will be made.
|
||||
//------------------------------------------------------------------
|
||||
ExecutionContextRef (const ExecutionContext *exe_ctx_ptr);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Construct using an ExecutionContext object.
|
||||
///
|
||||
/// Make weak references to any valid objects in the ExecutionContext.
|
||||
//------------------------------------------------------------------
|
||||
ExecutionContextRef (const ExecutionContext &exe_ctx);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Assignment operator
|
||||
///
|
||||
/// Copy all weak refernces in \a rhs.
|
||||
//------------------------------------------------------------------
|
||||
ExecutionContextRef &
|
||||
operator =(const ExecutionContextRef &rhs);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Assignment operator from a ExecutionContext
|
||||
///
|
||||
/// Make weak refernces to any stringly referenced objects in \a exe_ctx.
|
||||
//------------------------------------------------------------------
|
||||
ExecutionContextRef &
|
||||
operator =(const ExecutionContext &exe_ctx);
|
||||
|
||||
// Init using the target and all the selected items inside of it
|
||||
// (the process and its selected thread, and the thread's selected
|
||||
// frame). If there is no selected thread, default to the first thread
|
||||
// If there is no selected frame, default to the first frame.
|
||||
//------------------------------------------------------------------
|
||||
/// Construct using the target and all the selected items inside of it
|
||||
/// (the process and its selected thread, and the thread's selected
|
||||
/// frame). If there is no selected thread, default to the first thread
|
||||
/// If there is no selected frame, default to the first frame.
|
||||
//------------------------------------------------------------------
|
||||
ExecutionContextRef (Target *target, bool adopt_selected);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Construct using an execution context scope.
|
||||
///
|
||||
/// If the ExecutionContextScope object is valid and refers to a frame,
|
||||
/// make weak refernces too the frame, thread, process and target.
|
||||
/// If the ExecutionContextScope object is valid and refers to a thread,
|
||||
/// make weak refernces too the thread, process and target.
|
||||
/// If the ExecutionContextScope object is valid and refers to a process,
|
||||
/// make weak refernces too the process and target.
|
||||
/// If the ExecutionContextScope object is valid and refers to a target,
|
||||
/// make weak refernces too the target.
|
||||
//------------------------------------------------------------------
|
||||
ExecutionContextRef (ExecutionContextScope *exe_scope);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Construct using an execution context scope.
|
||||
///
|
||||
/// If the ExecutionContextScope object refers to a frame,
|
||||
/// make weak refernces too the frame, thread, process and target.
|
||||
/// If the ExecutionContextScope object refers to a thread,
|
||||
/// make weak refernces too the thread, process and target.
|
||||
/// If the ExecutionContextScope object refers to a process,
|
||||
/// make weak refernces too the process and target.
|
||||
/// If the ExecutionContextScope object refers to a target,
|
||||
/// make weak refernces too the target.
|
||||
//------------------------------------------------------------------
|
||||
ExecutionContextRef (ExecutionContextScope &exe_scope);
|
||||
|
||||
~ExecutionContextRef();
|
||||
|
@ -59,15 +162,75 @@ public:
|
|||
void
|
||||
Clear ();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Set accessor that creates a weak reference to the target
|
||||
/// referenced in \a target_sp.
|
||||
///
|
||||
/// If \a target_sp is valid this object will create a weak
|
||||
/// reference to that object, otherwise any previous target weak
|
||||
/// reference contained in this object will be reset.
|
||||
///
|
||||
/// Only the weak reference to the target will be updated, no other
|
||||
/// weak references will be modified. If you want this execution
|
||||
/// context to make a weak reference to the target's process, use
|
||||
/// the ExecutionContextRef::SetContext() functions.
|
||||
///
|
||||
/// @see ExecutionContextRef::SetContext(const lldb::TargetSP &, bool)
|
||||
//------------------------------------------------------------------
|
||||
void
|
||||
SetTargetSP (const lldb::TargetSP &target_sp);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Set accessor that creates a weak reference to the process
|
||||
/// referenced in \a process_sp.
|
||||
///
|
||||
/// If \a process_sp is valid this object will create a weak
|
||||
/// reference to that object, otherwise any previous process weak
|
||||
/// reference contained in this object will be reset.
|
||||
///
|
||||
/// Only the weak reference to the process will be updated, no other
|
||||
/// weak references will be modified. If you want this execution
|
||||
/// context to make a weak reference to the target, use the
|
||||
/// ExecutionContextRef::SetContext() functions.
|
||||
///
|
||||
/// @see ExecutionContextRef::SetContext(const lldb::ProcessSP &)
|
||||
//------------------------------------------------------------------
|
||||
void
|
||||
SetProcessSP (const lldb::ProcessSP &process_sp);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Set accessor that creates a weak reference to the thread
|
||||
/// referenced in \a thread_sp.
|
||||
///
|
||||
/// If \a thread_sp is valid this object will create a weak
|
||||
/// reference to that object, otherwise any previous thread weak
|
||||
/// reference contained in this object will be reset.
|
||||
///
|
||||
/// Only the weak reference to the thread will be updated, no other
|
||||
/// weak references will be modified. If you want this execution
|
||||
/// context to make a weak reference to the thread's process and
|
||||
/// target, use the ExecutionContextRef::SetContext() functions.
|
||||
///
|
||||
/// @see ExecutionContextRef::SetContext(const lldb::ThreadSP &)
|
||||
//------------------------------------------------------------------
|
||||
void
|
||||
SetThreadSP (const lldb::ThreadSP &thread_sp);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Set accessor that creates a weak reference to the frame
|
||||
/// referenced in \a frame_sp.
|
||||
///
|
||||
/// If \a frame_sp is valid this object will create a weak
|
||||
/// reference to that object, otherwise any previous frame weak
|
||||
/// reference contained in this object will be reset.
|
||||
///
|
||||
/// Only the weak reference to the frame will be updated, no other
|
||||
/// weak references will be modified. If you want this execution
|
||||
/// context to make a weak reference to the frame's thread, process
|
||||
/// and target, use the ExecutionContextRef::SetContext() functions.
|
||||
///
|
||||
/// @see ExecutionContextRef::SetContext(const lldb::StackFrameSP &)
|
||||
//------------------------------------------------------------------
|
||||
void
|
||||
SetFrameSP (const lldb::StackFrameSP &frame_sp);
|
||||
|
||||
|
@ -83,33 +246,83 @@ public:
|
|||
void
|
||||
SetFramePtr (StackFrame *frame);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get accessor that creates a strong reference from the weak target
|
||||
/// reference contained in this object.
|
||||
///
|
||||
/// @returns
|
||||
/// A shared pointer to a target that is not guaranteed to be valid.
|
||||
//------------------------------------------------------------------
|
||||
lldb::TargetSP
|
||||
GetTargetSP () const
|
||||
{
|
||||
return m_target_wp.lock();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get accessor that creates a strong reference from the weak process
|
||||
/// reference contained in this object.
|
||||
///
|
||||
/// @returns
|
||||
/// A shared pointer to a process that is not guaranteed to be valid.
|
||||
//------------------------------------------------------------------
|
||||
lldb::ProcessSP
|
||||
GetProcessSP () const
|
||||
{
|
||||
return m_process_wp.lock();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get accessor that creates a strong reference from the weak thread
|
||||
/// reference contained in this object.
|
||||
///
|
||||
/// @returns
|
||||
/// A shared pointer to a thread that is not guaranteed to be valid.
|
||||
//------------------------------------------------------------------
|
||||
lldb::ThreadSP
|
||||
GetThreadSP () const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get accessor that creates a strong reference from the weak frame
|
||||
/// reference contained in this object.
|
||||
///
|
||||
/// @returns
|
||||
/// A shared pointer to a frame that is not guaranteed to be valid.
|
||||
//------------------------------------------------------------------
|
||||
lldb::StackFrameSP
|
||||
GetFrameSP () const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Create an ExecutionContext object from this object.
|
||||
///
|
||||
/// Create strong references to any execution context objects that
|
||||
/// are still valid. Any of the returned shared pointers in the
|
||||
/// ExecutionContext objects is not guaranteed to be valid.
|
||||
/// @returns
|
||||
/// An execution context object that has strong references to
|
||||
/// any valid weak references in this object.
|
||||
//------------------------------------------------------------------
|
||||
ExecutionContext
|
||||
Lock () const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns true if this object has a weak reference to a thread.
|
||||
/// The return value is only an indication of wether this object has
|
||||
/// a weak reference and does not indicate wether the weak rerference
|
||||
/// is valid or not.
|
||||
//------------------------------------------------------------------
|
||||
bool
|
||||
HasThreadRef () const
|
||||
{
|
||||
return m_tid != LLDB_INVALID_THREAD_ID;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns true if this object has a weak reference to a frame.
|
||||
/// The return value is only an indication of wether this object has
|
||||
/// a weak reference and does not indicate wether the weak rerference
|
||||
/// is valid or not.
|
||||
//------------------------------------------------------------------
|
||||
bool
|
||||
HasFrameRef () const
|
||||
{
|
||||
|
@ -120,12 +333,12 @@ protected:
|
|||
//------------------------------------------------------------------
|
||||
// Member variables
|
||||
//------------------------------------------------------------------
|
||||
lldb::TargetWP m_target_wp; ///< The target that owns the process/thread/frame
|
||||
lldb::ProcessWP m_process_wp; ///< The process that owns the thread/frame
|
||||
mutable lldb::ThreadWP m_thread_wp; ///< The thread that owns the frame
|
||||
mutable lldb::StackFrameWP m_frame_wp; ///< The stack frame in thread.
|
||||
lldb::tid_t m_tid;
|
||||
StackID m_stack_id;
|
||||
lldb::TargetWP m_target_wp; ///< A weak reference to a target
|
||||
lldb::ProcessWP m_process_wp; ///< A weak reference to a process
|
||||
mutable lldb::ThreadWP m_thread_wp; ///< A weak reference to a thread
|
||||
mutable lldb::StackFrameWP m_frame_wp; ///< A weak reference to a frame
|
||||
lldb::tid_t m_tid; ///< The thread ID that this object refers to in case the backing object changes
|
||||
StackID m_stack_id; ///< The stack ID that this object refers to in case the backing object changes
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -133,35 +346,59 @@ protected:
|
|||
/// @brief A class that contains an execution context.
|
||||
///
|
||||
/// This baton object can be passed into any function that requires
|
||||
/// a context that specifies a process, thread and frame.
|
||||
/// a context that specifies a target, process, thread and frame.
|
||||
/// These objects are designed to be used for short term execution
|
||||
/// context object storage while a function might be trying to evaluate
|
||||
/// something that requires a thread or frame. ExecutionContextRef
|
||||
/// objects can be used to initialize one of these objects to turn
|
||||
/// the weak execution context object references to the target, process,
|
||||
/// thread and frame into strong references (shared pointers) so that
|
||||
/// functions can guarantee that these objects won't go away in the
|
||||
/// middle of a function.
|
||||
///
|
||||
/// Many lldb functions can evaluate or act upon a specific
|
||||
/// execution context. An expression could be evaluated for a specific
|
||||
/// process, thread, and frame. The thread object contains frames and
|
||||
/// can return StackFrame objects given a valid frame index using:
|
||||
/// StackFrame * Thread::GetFrameAtIndex (uint32_t idx).
|
||||
/// ExecutionContext objects should be used as short lived objects
|
||||
/// (typically on the stack) in order to lock down an execution context
|
||||
/// for local use and for passing down to other functions that also
|
||||
/// require specific contexts. They should NOT be used for long term
|
||||
/// storage, for long term storage use ExecutionContextRef objects.
|
||||
//----------------------------------------------------------------------
|
||||
class ExecutionContext
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------
|
||||
/// Default Constructor.
|
||||
///
|
||||
/// Initialize with NULL process and thread, and invalid frame
|
||||
/// index.
|
||||
//------------------------------------------------------------------
|
||||
ExecutionContext();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Copy constructor
|
||||
//------------------------------------------------------------------
|
||||
ExecutionContext (const ExecutionContext &rhs);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Adopt the target and optionally its current context.
|
||||
//------------------------------------------------------------------
|
||||
ExecutionContext (Target* t, bool fill_current_process_thread_frame = true);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Create execution contexts from shared pointers
|
||||
//------------------------------------------------------------------
|
||||
ExecutionContext (const lldb::TargetSP &target_sp, bool get_process);
|
||||
ExecutionContext (const lldb::ProcessSP &process_sp);
|
||||
ExecutionContext (const lldb::ThreadSP &thread_sp);
|
||||
ExecutionContext (const lldb::StackFrameSP &frame_sp);
|
||||
//------------------------------------------------------------------
|
||||
// Create execution contexts from weak pointers
|
||||
//------------------------------------------------------------------
|
||||
ExecutionContext (const lldb::TargetWP &target_wp, bool get_process);
|
||||
ExecutionContext (const lldb::ProcessWP &process_wp);
|
||||
ExecutionContext (const lldb::ThreadWP &thread_wp);
|
||||
ExecutionContext (const lldb::StackFrameWP &frame_wp);
|
||||
ExecutionContext (const ExecutionContextRef &exe_ctx_ref);
|
||||
ExecutionContext (const ExecutionContextRef *exe_ctx_ref);
|
||||
//------------------------------------------------------------------
|
||||
// Create execution contexts from execution context scopes
|
||||
//------------------------------------------------------------------
|
||||
ExecutionContext (ExecutionContextScope *exe_scope);
|
||||
ExecutionContext (ExecutionContextScope &exe_scope);
|
||||
|
||||
|
@ -213,81 +450,217 @@ public:
|
|||
uint32_t
|
||||
GetAddressByteSize() const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns a pointer to the target object.
|
||||
///
|
||||
/// The returned pointer might be NULL. Calling HasTargetScope(),
|
||||
/// HasProcessScope(), HasThreadScope(), or HasFrameScope()
|
||||
/// can help to pre-validate this pointer so that this accessor can
|
||||
/// freely be used without having to check for NULL each time.
|
||||
///
|
||||
/// @see ExecutionContext::HasTargetScope() const
|
||||
/// @see ExecutionContext::HasProcessScope() const
|
||||
/// @see ExecutionContext::HasThreadScope() const
|
||||
/// @see ExecutionContext::HasFrameScope() const
|
||||
//------------------------------------------------------------------
|
||||
Target *
|
||||
GetTargetPtr () const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns a pointer to the process object.
|
||||
///
|
||||
/// The returned pointer might be NULL. Calling HasProcessScope(),
|
||||
/// HasThreadScope(), or HasFrameScope() can help to pre-validate
|
||||
/// this pointer so that this accessor can freely be used without
|
||||
/// having to check for NULL each time.
|
||||
///
|
||||
/// @see ExecutionContext::HasProcessScope() const
|
||||
/// @see ExecutionContext::HasThreadScope() const
|
||||
/// @see ExecutionContext::HasFrameScope() const
|
||||
//------------------------------------------------------------------
|
||||
Process *
|
||||
GetProcessPtr () const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns a pointer to the thread object.
|
||||
///
|
||||
/// The returned pointer might be NULL. Calling HasThreadScope() or
|
||||
/// HasFrameScope() can help to pre-validate this pointer so that
|
||||
/// this accessor can freely be used without having to check for
|
||||
/// NULL each time.
|
||||
///
|
||||
/// @see ExecutionContext::HasThreadScope() const
|
||||
/// @see ExecutionContext::HasFrameScope() const
|
||||
//------------------------------------------------------------------
|
||||
Thread *
|
||||
GetThreadPtr () const
|
||||
{
|
||||
return m_thread_sp.get();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns a pointer to the frame object.
|
||||
///
|
||||
/// The returned pointer might be NULL. Calling HasFrameScope(),
|
||||
/// can help to pre-validate this pointer so that this accessor can
|
||||
/// freely be used without having to check for NULL each time.
|
||||
///
|
||||
/// @see ExecutionContext::HasFrameScope() const
|
||||
//------------------------------------------------------------------
|
||||
StackFrame *
|
||||
GetFramePtr () const
|
||||
{
|
||||
return m_frame_sp.get();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns a reference to the target object.
|
||||
///
|
||||
/// Clients should call HasTargetScope(), HasProcessScope(),
|
||||
/// HasThreadScope(), or HasFrameScope() prior to calling this
|
||||
/// function to ensure that this ExecutionContext object contains
|
||||
/// a valid target.
|
||||
///
|
||||
/// @see ExecutionContext::HasTargetScope() const
|
||||
/// @see ExecutionContext::HasProcessScope() const
|
||||
/// @see ExecutionContext::HasThreadScope() const
|
||||
/// @see ExecutionContext::HasFrameScope() const
|
||||
//------------------------------------------------------------------
|
||||
Target &
|
||||
GetTargetRef () const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns a reference to the process object.
|
||||
///
|
||||
/// Clients should call HasProcessScope(), HasThreadScope(), or
|
||||
/// HasFrameScope() prior to calling this function to ensure that
|
||||
/// this ExecutionContext object contains a valid target.
|
||||
///
|
||||
/// @see ExecutionContext::HasProcessScope() const
|
||||
/// @see ExecutionContext::HasThreadScope() const
|
||||
/// @see ExecutionContext::HasFrameScope() const
|
||||
//------------------------------------------------------------------
|
||||
Process &
|
||||
GetProcessRef () const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns a reference to the thread object.
|
||||
///
|
||||
/// Clients should call HasThreadScope(), or HasFrameScope() prior
|
||||
/// to calling this function to ensure that this ExecutionContext
|
||||
/// object contains a valid target.
|
||||
///
|
||||
/// @see ExecutionContext::HasThreadScope() const
|
||||
/// @see ExecutionContext::HasFrameScope() const
|
||||
//------------------------------------------------------------------
|
||||
Thread &
|
||||
GetThreadRef () const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns a reference to the thread object.
|
||||
///
|
||||
/// Clients should call HasFrameScope() prior to calling this
|
||||
/// function to ensure that this ExecutionContext object contains
|
||||
/// a valid target.
|
||||
///
|
||||
/// @see ExecutionContext::HasFrameScope() const
|
||||
//------------------------------------------------------------------
|
||||
StackFrame &
|
||||
GetFrameRef () const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get accessor to get the target shared pointer.
|
||||
///
|
||||
/// The returned shared pointer is not guaranteed to be valid.
|
||||
//------------------------------------------------------------------
|
||||
const lldb::TargetSP &
|
||||
GetTargetSP () const
|
||||
{
|
||||
return m_target_sp;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get accessor to get the process shared pointer.
|
||||
///
|
||||
/// The returned shared pointer is not guaranteed to be valid.
|
||||
//------------------------------------------------------------------
|
||||
const lldb::ProcessSP &
|
||||
GetProcessSP () const
|
||||
{
|
||||
return m_process_sp;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get accessor to get the thread shared pointer.
|
||||
///
|
||||
/// The returned shared pointer is not guaranteed to be valid.
|
||||
//------------------------------------------------------------------
|
||||
const lldb::ThreadSP &
|
||||
GetThreadSP () const
|
||||
{
|
||||
return m_thread_sp;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get accessor to get the frame shared pointer.
|
||||
///
|
||||
/// The returned shared pointer is not guaranteed to be valid.
|
||||
//------------------------------------------------------------------
|
||||
const lldb::StackFrameSP &
|
||||
GetFrameSP () const
|
||||
{
|
||||
return m_frame_sp;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Set accessor to set only the target shared pointer.
|
||||
//------------------------------------------------------------------
|
||||
void
|
||||
SetTargetSP (const lldb::TargetSP &target_sp);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Set accessor to set only the process shared pointer.
|
||||
//------------------------------------------------------------------
|
||||
void
|
||||
SetProcessSP (const lldb::ProcessSP &process_sp);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Set accessor to set only the thread shared pointer.
|
||||
//------------------------------------------------------------------
|
||||
void
|
||||
SetThreadSP (const lldb::ThreadSP &thread_sp);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Set accessor to set only the frame shared pointer.
|
||||
//------------------------------------------------------------------
|
||||
void
|
||||
SetFrameSP (const lldb::StackFrameSP &frame_sp);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Set accessor to set only the target shared pointer from a target
|
||||
/// pointer.
|
||||
//------------------------------------------------------------------
|
||||
void
|
||||
SetTargetPtr (Target* target);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Set accessor to set only the process shared pointer from a
|
||||
/// process pointer.
|
||||
//------------------------------------------------------------------
|
||||
void
|
||||
SetProcessPtr (Process *process);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Set accessor to set only the thread shared pointer from a thread
|
||||
/// pointer.
|
||||
//------------------------------------------------------------------
|
||||
void
|
||||
SetThreadPtr (Thread *thread);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Set accessor to set only the frame shared pointer from a frame
|
||||
/// pointer.
|
||||
//------------------------------------------------------------------
|
||||
void
|
||||
SetFramePtr (StackFrame *frame);
|
||||
|
||||
|
@ -322,7 +695,7 @@ public:
|
|||
SetContext (const lldb::ThreadSP &thread_sp);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Set the execution context using a thread shared pointer.
|
||||
// Set the execution context using a frame shared pointer.
|
||||
//
|
||||
// If "frame_sp" is valid, then set the frame, thread, process and
|
||||
// target in this context
|
||||
|
@ -330,8 +703,67 @@ public:
|
|||
//------------------------------------------------------------------
|
||||
void
|
||||
SetContext (const lldb::StackFrameSP &frame_sp);
|
||||
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns true the ExecutionContext object contains a valid
|
||||
/// target.
|
||||
///
|
||||
/// This function can be called after initializing an ExecutionContext
|
||||
/// object, and if it returns true, calls to GetTargetPtr() and
|
||||
/// GetTargetRef() do not need to be checked for validity.
|
||||
//------------------------------------------------------------------
|
||||
bool
|
||||
HasTargetScope () const
|
||||
{
|
||||
return m_target_sp;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns true the ExecutionContext object contains a valid
|
||||
/// target and process.
|
||||
///
|
||||
/// This function can be called after initializing an ExecutionContext
|
||||
/// object, and if it returns true, calls to GetTargetPtr() and
|
||||
/// GetTargetRef(), GetProcessPtr(), and GetProcessRef(), do not
|
||||
/// need to be checked for validity.
|
||||
//------------------------------------------------------------------
|
||||
bool
|
||||
HasProcessScope () const
|
||||
{
|
||||
return m_target_sp && m_process_sp;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns true the ExecutionContext object contains a valid
|
||||
/// target, process, and thread.
|
||||
///
|
||||
/// This function can be called after initializing an ExecutionContext
|
||||
/// object, and if it returns true, calls to GetTargetPtr(),
|
||||
/// GetTargetRef(), GetProcessPtr(), GetProcessRef(), GetThreadPtr(),
|
||||
/// and GetThreadRef() do not need to be checked for validity.
|
||||
//------------------------------------------------------------------
|
||||
bool
|
||||
HasThreadScope () const
|
||||
{
|
||||
return m_target_sp && m_process_sp && m_thread_sp;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns true the ExecutionContext object contains a valid
|
||||
/// target, process, thread and frame.
|
||||
///
|
||||
/// This function can be called after initializing an ExecutionContext
|
||||
/// object, and if it returns true, calls to GetTargetPtr(),
|
||||
/// GetTargetRef(), GetProcessPtr(), GetProcessRef(), GetThreadPtr(),
|
||||
/// GetThreadRef(), GetFramePtr(), and GetFrameRef() do not need
|
||||
/// to be checked for validity.
|
||||
//------------------------------------------------------------------
|
||||
bool
|
||||
HasFrameScope () const
|
||||
{
|
||||
return m_target_sp && m_process_sp && m_thread_sp && m_frame_sp;
|
||||
}
|
||||
|
||||
protected:
|
||||
//------------------------------------------------------------------
|
||||
// Member variables
|
||||
|
|
|
@ -203,19 +203,13 @@ public:
|
|||
static lldb::UserSettingsControllerSP &
|
||||
GetSettingsController ();
|
||||
|
||||
Thread (Process &process, lldb::tid_t tid);
|
||||
Thread (const lldb::ProcessSP &process_sp, lldb::tid_t tid);
|
||||
virtual ~Thread();
|
||||
|
||||
Process &
|
||||
GetProcess()
|
||||
lldb::ProcessSP
|
||||
GetProcess() const
|
||||
{
|
||||
return m_process;
|
||||
}
|
||||
|
||||
const Process &
|
||||
GetProcess() const
|
||||
{
|
||||
return m_process;
|
||||
return m_process_wp.lock();
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -829,25 +823,25 @@ protected:
|
|||
//------------------------------------------------------------------
|
||||
// Classes that inherit from Process can see and modify these
|
||||
//------------------------------------------------------------------
|
||||
Process & m_process; ///< The process that owns this thread.
|
||||
lldb::StopInfoSP m_actual_stop_info_sp; ///< The private stop reason for this thread
|
||||
const uint32_t m_index_id; ///< A unique 1 based index assigned to each thread for easy UI/command line access.
|
||||
lldb::RegisterContextSP m_reg_context_sp; ///< The register context for this thread's current register state.
|
||||
lldb::StateType m_state; ///< The state of our process.
|
||||
mutable Mutex m_state_mutex; ///< Multithreaded protection for m_state.
|
||||
plan_stack m_plan_stack; ///< The stack of plans this thread is executing.
|
||||
plan_stack m_completed_plan_stack; ///< Plans that have been completed by this stop. They get deleted when the thread resumes.
|
||||
plan_stack m_discarded_plan_stack; ///< Plans that have been discarded by this stop. They get deleted when the thread resumes.
|
||||
lldb::StackFrameListSP m_curr_frames_sp; ///< The stack frames that get lazily populated after a thread stops.
|
||||
lldb::StackFrameListSP m_prev_frames_sp; ///< The previous stack frames from the last time this thread stopped.
|
||||
int m_resume_signal; ///< The signal that should be used when continuing this thread.
|
||||
lldb::StateType m_resume_state; ///< This state is used to force a thread to be suspended from outside the ThreadPlan logic.
|
||||
lldb::ProcessWP m_process_wp; ///< The process that owns this thread.
|
||||
lldb::StopInfoSP m_actual_stop_info_sp; ///< The private stop reason for this thread
|
||||
const uint32_t m_index_id; ///< A unique 1 based index assigned to each thread for easy UI/command line access.
|
||||
lldb::RegisterContextSP m_reg_context_sp; ///< The register context for this thread's current register state.
|
||||
lldb::StateType m_state; ///< The state of our process.
|
||||
mutable Mutex m_state_mutex; ///< Multithreaded protection for m_state.
|
||||
plan_stack m_plan_stack; ///< The stack of plans this thread is executing.
|
||||
plan_stack m_completed_plan_stack; ///< Plans that have been completed by this stop. They get deleted when the thread resumes.
|
||||
plan_stack m_discarded_plan_stack; ///< Plans that have been discarded by this stop. They get deleted when the thread resumes.
|
||||
lldb::StackFrameListSP m_curr_frames_sp; ///< The stack frames that get lazily populated after a thread stops.
|
||||
lldb::StackFrameListSP m_prev_frames_sp; ///< The previous stack frames from the last time this thread stopped.
|
||||
int m_resume_signal; ///< The signal that should be used when continuing this thread.
|
||||
lldb::StateType m_resume_state; ///< This state is used to force a thread to be suspended from outside the ThreadPlan logic.
|
||||
lldb::StateType m_temporary_resume_state; ///< This state records what the thread was told to do by the thread plan logic for the current resume.
|
||||
/// It gets set in Thread::WillResume.
|
||||
std::auto_ptr<lldb_private::Unwind> m_unwinder_ap;
|
||||
bool m_destroy_called; // This is used internally to make sure derived Thread classes call DestroyThread.
|
||||
uint32_t m_thread_stop_reason_stop_id; // This is the stop id for which the StopInfo is valid. Can use this so you know that
|
||||
// the thread's m_actual_stop_info_sp is current and you don't have to fetch it again
|
||||
bool m_destroy_called; // This is used internally to make sure derived Thread classes call DestroyThread.
|
||||
uint32_t m_thread_stop_reason_stop_id; // This is the stop id for which the StopInfo is valid. Can use this so you know that
|
||||
// the thread's m_actual_stop_info_sp is current and you don't have to fetch it again
|
||||
|
||||
private:
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -39,8 +39,7 @@ public:
|
|||
// thread may be NULL in which case we only use the Target (e.g. if this is called pre-process-launch).
|
||||
virtual bool
|
||||
FirstNonPrologueInsn (AddressRange& func,
|
||||
Target& target,
|
||||
Thread* thread,
|
||||
const lldb_private::ExecutionContext &exe_ctx,
|
||||
Address& first_non_prologue_insn) = 0;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -487,14 +487,15 @@ SBBreakpoint::PrivateBreakpointHitCallback
|
|||
lldb::user_id_t break_loc_id
|
||||
)
|
||||
{
|
||||
BreakpointSP bp_sp(ctx->exe_ctx.GetTargetRef().GetBreakpointList().FindBreakpointByID(break_id));
|
||||
ExecutionContext exe_ctx (ctx->exe_ctx_ref);
|
||||
BreakpointSP bp_sp(exe_ctx.GetTargetRef().GetBreakpointList().FindBreakpointByID(break_id));
|
||||
if (baton && bp_sp)
|
||||
{
|
||||
CallbackData *data = (CallbackData *)baton;
|
||||
lldb_private::Breakpoint *bp = bp_sp.get();
|
||||
if (bp && data->callback)
|
||||
{
|
||||
Process *process = ctx->exe_ctx.GetProcessPtr();
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
if (process)
|
||||
{
|
||||
SBProcess sb_process (process->shared_from_this());
|
||||
|
@ -502,7 +503,7 @@ SBBreakpoint::PrivateBreakpointHitCallback
|
|||
SBBreakpointLocation sb_location;
|
||||
assert (bp_sp);
|
||||
sb_location.SetLocation (bp_sp->FindLocationByID (break_loc_id));
|
||||
Thread *thread = ctx->exe_ctx.GetThreadPtr();
|
||||
Thread *thread = exe_ctx.GetThreadPtr();
|
||||
if (thread)
|
||||
sb_thread.SetThread(thread->shared_from_this());
|
||||
|
||||
|
|
|
@ -95,17 +95,17 @@ SBThread::GetStopReason()
|
|||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
StopReason reason = eStopReasonInvalid;
|
||||
ThreadSP thread_sp(m_opaque_wp.lock());
|
||||
if (thread_sp)
|
||||
ExecutionContext exe_ctx (m_opaque_wp);
|
||||
if (exe_ctx.HasThreadScope())
|
||||
{
|
||||
Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
|
||||
StopInfoSP stop_info_sp = thread_sp->GetStopInfo ();
|
||||
Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
|
||||
StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
|
||||
if (stop_info_sp)
|
||||
reason = stop_info_sp->GetStopReason();
|
||||
}
|
||||
|
||||
if (log)
|
||||
log->Printf ("SBThread(%p)::GetStopReason () => %s", thread_sp.get(),
|
||||
log->Printf ("SBThread(%p)::GetStopReason () => %s", exe_ctx.GetThreadPtr(),
|
||||
Thread::StopReasonAsCString (reason));
|
||||
|
||||
return reason;
|
||||
|
@ -114,11 +114,11 @@ SBThread::GetStopReason()
|
|||
size_t
|
||||
SBThread::GetStopReasonDataCount ()
|
||||
{
|
||||
ThreadSP thread_sp(m_opaque_wp.lock());
|
||||
if (thread_sp)
|
||||
ExecutionContext exe_ctx (m_opaque_wp);
|
||||
if (exe_ctx.HasThreadScope())
|
||||
{
|
||||
Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
|
||||
StopInfoSP stop_info_sp = thread_sp->GetStopInfo ();
|
||||
Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
|
||||
StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
|
||||
if (stop_info_sp)
|
||||
{
|
||||
StopReason reason = stop_info_sp->GetStopReason();
|
||||
|
@ -134,7 +134,7 @@ SBThread::GetStopReasonDataCount ()
|
|||
case eStopReasonBreakpoint:
|
||||
{
|
||||
break_id_t site_id = stop_info_sp->GetValue();
|
||||
lldb::BreakpointSiteSP bp_site_sp (thread_sp->GetProcess().GetBreakpointSiteList().FindByID (site_id));
|
||||
lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
|
||||
if (bp_site_sp)
|
||||
return bp_site_sp->GetNumberOfOwners () * 2;
|
||||
else
|
||||
|
@ -159,11 +159,12 @@ SBThread::GetStopReasonDataCount ()
|
|||
uint64_t
|
||||
SBThread::GetStopReasonDataAtIndex (uint32_t idx)
|
||||
{
|
||||
ThreadSP thread_sp(m_opaque_wp.lock());
|
||||
if (thread_sp)
|
||||
ExecutionContext exe_ctx (m_opaque_wp);
|
||||
if (exe_ctx.HasThreadScope())
|
||||
{
|
||||
Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
|
||||
StopInfoSP stop_info_sp = thread_sp->GetStopInfo ();
|
||||
Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
|
||||
Thread *thread = exe_ctx.GetThreadPtr();
|
||||
StopInfoSP stop_info_sp = thread->GetStopInfo ();
|
||||
if (stop_info_sp)
|
||||
{
|
||||
StopReason reason = stop_info_sp->GetStopReason();
|
||||
|
@ -179,7 +180,7 @@ SBThread::GetStopReasonDataAtIndex (uint32_t idx)
|
|||
case eStopReasonBreakpoint:
|
||||
{
|
||||
break_id_t site_id = stop_info_sp->GetValue();
|
||||
lldb::BreakpointSiteSP bp_site_sp (thread_sp->GetProcess().GetBreakpointSiteList().FindByID (site_id));
|
||||
lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
|
||||
if (bp_site_sp)
|
||||
{
|
||||
uint32_t bp_index = idx / 2;
|
||||
|
@ -221,11 +222,11 @@ SBThread::GetStopDescription (char *dst, size_t dst_len)
|
|||
{
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
ThreadSP thread_sp(m_opaque_wp.lock());
|
||||
if (thread_sp)
|
||||
ExecutionContext exe_ctx (m_opaque_wp);
|
||||
if (exe_ctx.HasThreadScope())
|
||||
{
|
||||
Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
|
||||
StopInfoSP stop_info_sp = thread_sp->GetStopInfo ();
|
||||
Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
|
||||
StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
|
||||
if (stop_info_sp)
|
||||
{
|
||||
const char *stop_desc = stop_info_sp->GetDescription();
|
||||
|
@ -233,7 +234,7 @@ SBThread::GetStopDescription (char *dst, size_t dst_len)
|
|||
{
|
||||
if (log)
|
||||
log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
|
||||
thread_sp.get(), stop_desc);
|
||||
exe_ctx.GetThreadPtr(), stop_desc);
|
||||
if (dst)
|
||||
return ::snprintf (dst, dst_len, "%s", stop_desc);
|
||||
else
|
||||
|
@ -274,7 +275,7 @@ SBThread::GetStopDescription (char *dst, size_t dst_len)
|
|||
|
||||
case eStopReasonSignal:
|
||||
{
|
||||
stop_desc = thread_sp->GetProcess().GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue());
|
||||
stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue());
|
||||
if (stop_desc == NULL || stop_desc[0] == '\0')
|
||||
{
|
||||
static char signal_desc[] = "signal";
|
||||
|
@ -300,7 +301,7 @@ SBThread::GetStopDescription (char *dst, size_t dst_len)
|
|||
{
|
||||
if (log)
|
||||
log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
|
||||
thread_sp.get(), stop_desc);
|
||||
exe_ctx.GetThreadPtr(), stop_desc);
|
||||
|
||||
if (dst)
|
||||
return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte
|
||||
|
@ -322,11 +323,11 @@ SBValue
|
|||
SBThread::GetStopReturnValue ()
|
||||
{
|
||||
ValueObjectSP return_valobj_sp;
|
||||
ThreadSP thread_sp(m_opaque_wp.lock());
|
||||
if (thread_sp)
|
||||
ExecutionContext exe_ctx (m_opaque_wp);
|
||||
if (exe_ctx.HasThreadScope())
|
||||
{
|
||||
Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
|
||||
StopInfoSP stop_info_sp = thread_sp->GetStopInfo ();
|
||||
Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
|
||||
StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
|
||||
if (stop_info_sp)
|
||||
{
|
||||
return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
|
||||
|
@ -335,7 +336,7 @@ SBThread::GetStopReturnValue ()
|
|||
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
if (log)
|
||||
log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", thread_sp.get(),
|
||||
log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", exe_ctx.GetThreadPtr(),
|
||||
return_valobj_sp.get()
|
||||
? return_valobj_sp->GetValueAsCString()
|
||||
: "<no return value>");
|
||||
|
@ -353,17 +354,10 @@ SBThread::SetThread (const ThreadSP& lldb_object_sp)
|
|||
lldb::tid_t
|
||||
SBThread::GetThreadID () const
|
||||
{
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
|
||||
ThreadSP thread_sp(m_opaque_wp.lock());
|
||||
if (thread_sp)
|
||||
tid = thread_sp->GetID();
|
||||
|
||||
if (log)
|
||||
log->Printf ("SBThread(%p)::GetThreadID () => 0x%4.4llx", thread_sp.get(), tid);
|
||||
|
||||
return tid;
|
||||
return thread_sp->GetID();
|
||||
return LLDB_INVALID_THREAD_ID;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
|
@ -374,20 +368,21 @@ SBThread::GetIndexID () const
|
|||
return thread_sp->GetIndexID();
|
||||
return LLDB_INVALID_INDEX32;
|
||||
}
|
||||
|
||||
const char *
|
||||
SBThread::GetName () const
|
||||
{
|
||||
const char *name = NULL;
|
||||
ThreadSP thread_sp(m_opaque_wp.lock());
|
||||
if (thread_sp)
|
||||
ExecutionContext exe_ctx (m_opaque_wp);
|
||||
if (exe_ctx.HasThreadScope())
|
||||
{
|
||||
Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
|
||||
name = thread_sp->GetName();
|
||||
Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
|
||||
name = exe_ctx.GetThreadPtr()->GetName();
|
||||
}
|
||||
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
if (log)
|
||||
log->Printf ("SBThread(%p)::GetName () => %s", thread_sp.get(), name ? name : "NULL");
|
||||
log->Printf ("SBThread(%p)::GetName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL");
|
||||
|
||||
return name;
|
||||
}
|
||||
|
@ -396,16 +391,16 @@ const char *
|
|||
SBThread::GetQueueName () const
|
||||
{
|
||||
const char *name = NULL;
|
||||
ThreadSP thread_sp(m_opaque_wp.lock());
|
||||
if (thread_sp)
|
||||
ExecutionContext exe_ctx (m_opaque_wp);
|
||||
if (exe_ctx.HasThreadScope())
|
||||
{
|
||||
Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
|
||||
name = thread_sp->GetQueueName();
|
||||
Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
|
||||
name = exe_ctx.GetThreadPtr()->GetQueueName();
|
||||
}
|
||||
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
if (log)
|
||||
log->Printf ("SBThread(%p)::GetQueueName () => %s", thread_sp.get(), name ? name : "NULL");
|
||||
log->Printf ("SBThread(%p)::GetQueueName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL");
|
||||
|
||||
return name;
|
||||
}
|
||||
|
@ -416,24 +411,25 @@ SBThread::StepOver (lldb::RunMode stop_other_threads)
|
|||
{
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
ThreadSP thread_sp(m_opaque_wp.lock());
|
||||
ExecutionContext exe_ctx (m_opaque_wp);
|
||||
|
||||
if (log)
|
||||
log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", thread_sp.get(),
|
||||
log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", exe_ctx.GetThreadPtr(),
|
||||
Thread::RunModeAsCString (stop_other_threads));
|
||||
|
||||
if (thread_sp)
|
||||
if (exe_ctx.HasThreadScope())
|
||||
{
|
||||
Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
|
||||
Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
|
||||
Thread *thread = exe_ctx.GetThreadPtr();
|
||||
bool abort_other_plans = true;
|
||||
StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex (0));
|
||||
StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
|
||||
|
||||
if (frame_sp)
|
||||
{
|
||||
if (frame_sp->HasDebugInformation ())
|
||||
{
|
||||
SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
|
||||
thread_sp->QueueThreadPlanForStepRange (abort_other_plans,
|
||||
thread->QueueThreadPlanForStepRange (abort_other_plans,
|
||||
eStepTypeOver,
|
||||
sc.line_entry.range,
|
||||
sc,
|
||||
|
@ -443,22 +439,22 @@ SBThread::StepOver (lldb::RunMode stop_other_threads)
|
|||
}
|
||||
else
|
||||
{
|
||||
thread_sp->QueueThreadPlanForStepSingleInstruction (true,
|
||||
thread->QueueThreadPlanForStepSingleInstruction (true,
|
||||
abort_other_plans,
|
||||
stop_other_threads);
|
||||
}
|
||||
}
|
||||
|
||||
Process &process = thread_sp->GetProcess();
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
// Why do we need to set the current thread by ID here???
|
||||
process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
|
||||
Error error (process.Resume());
|
||||
process->GetThreadList().SetSelectedThreadByID (thread->GetID());
|
||||
Error error (process->Resume());
|
||||
if (error.Success())
|
||||
{
|
||||
// If we are doing synchronous mode, then wait for the
|
||||
// process to stop yet again!
|
||||
if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
|
||||
process.WaitForProcessToStop (NULL);
|
||||
if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
|
||||
process->WaitForProcessToStop (NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -468,47 +464,47 @@ SBThread::StepInto (lldb::RunMode stop_other_threads)
|
|||
{
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
|
||||
ThreadSP thread_sp(m_opaque_wp.lock());
|
||||
ExecutionContext exe_ctx (m_opaque_wp);
|
||||
|
||||
if (log)
|
||||
log->Printf ("SBThread(%p)::StepInto (stop_other_threads='%s')", thread_sp.get(),
|
||||
log->Printf ("SBThread(%p)::StepInto (stop_other_threads='%s')", exe_ctx.GetThreadPtr(),
|
||||
Thread::RunModeAsCString (stop_other_threads));
|
||||
if (thread_sp)
|
||||
if (exe_ctx.HasThreadScope())
|
||||
{
|
||||
Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
|
||||
Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
|
||||
bool abort_other_plans = true;
|
||||
|
||||
StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex (0));
|
||||
Thread *thread = exe_ctx.GetThreadPtr();
|
||||
StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
|
||||
|
||||
if (frame_sp && frame_sp->HasDebugInformation ())
|
||||
{
|
||||
bool avoid_code_without_debug_info = true;
|
||||
SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
|
||||
thread_sp->QueueThreadPlanForStepRange (abort_other_plans,
|
||||
eStepTypeInto,
|
||||
sc.line_entry.range,
|
||||
sc,
|
||||
stop_other_threads,
|
||||
avoid_code_without_debug_info);
|
||||
thread->QueueThreadPlanForStepRange (abort_other_plans,
|
||||
eStepTypeInto,
|
||||
sc.line_entry.range,
|
||||
sc,
|
||||
stop_other_threads,
|
||||
avoid_code_without_debug_info);
|
||||
}
|
||||
else
|
||||
{
|
||||
thread_sp->QueueThreadPlanForStepSingleInstruction (false,
|
||||
abort_other_plans,
|
||||
stop_other_threads);
|
||||
thread->QueueThreadPlanForStepSingleInstruction (false,
|
||||
abort_other_plans,
|
||||
stop_other_threads);
|
||||
}
|
||||
|
||||
Process &process = thread_sp->GetProcess();
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
// Why do we need to set the current thread by ID here???
|
||||
process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
|
||||
Error error (process.Resume());
|
||||
process->GetThreadList().SetSelectedThreadByID (thread->GetID());
|
||||
Error error (process->Resume());
|
||||
if (error.Success())
|
||||
{
|
||||
// If we are doing synchronous mode, then wait for the
|
||||
// process to stop yet again!
|
||||
if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
|
||||
process.WaitForProcessToStop (NULL);
|
||||
if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
|
||||
process->WaitForProcessToStop (NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -518,18 +514,20 @@ SBThread::StepOut ()
|
|||
{
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
ThreadSP thread_sp(m_opaque_wp.lock());
|
||||
ExecutionContext exe_ctx (m_opaque_wp);
|
||||
|
||||
if (log)
|
||||
log->Printf ("SBThread(%p)::StepOut ()", thread_sp.get());
|
||||
log->Printf ("SBThread(%p)::StepOut ()", exe_ctx.GetThreadPtr());
|
||||
|
||||
if (thread_sp)
|
||||
if (exe_ctx.HasThreadScope())
|
||||
{
|
||||
Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
|
||||
Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
|
||||
bool abort_other_plans = true;
|
||||
bool stop_other_threads = true;
|
||||
|
||||
thread_sp->QueueThreadPlanForStepOut (abort_other_plans,
|
||||
Thread *thread = exe_ctx.GetThreadPtr();
|
||||
|
||||
thread->QueueThreadPlanForStepOut (abort_other_plans,
|
||||
NULL,
|
||||
false,
|
||||
stop_other_threads,
|
||||
|
@ -537,15 +535,15 @@ SBThread::StepOut ()
|
|||
eVoteNoOpinion,
|
||||
0);
|
||||
|
||||
Process &process = thread_sp->GetProcess();
|
||||
process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
|
||||
Error error (process.Resume());
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
process->GetThreadList().SetSelectedThreadByID (thread->GetID());
|
||||
Error error (process->Resume());
|
||||
if (error.Success())
|
||||
{
|
||||
// If we are doing synchronous mode, then wait for the
|
||||
// process to stop yet again!
|
||||
if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
|
||||
process.WaitForProcessToStop (NULL);
|
||||
if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
|
||||
process->WaitForProcessToStop (NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -555,23 +553,23 @@ SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame)
|
|||
{
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
ThreadSP thread_sp(m_opaque_wp.lock());
|
||||
|
||||
ExecutionContext exe_ctx (m_opaque_wp);
|
||||
StackFrameSP frame_sp (sb_frame.GetFrameSP());
|
||||
if (log)
|
||||
{
|
||||
SBStream frame_desc_strm;
|
||||
sb_frame.GetDescription (frame_desc_strm);
|
||||
log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", thread_sp.get(), frame_sp.get(), frame_desc_strm.GetData());
|
||||
log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData());
|
||||
}
|
||||
|
||||
if (thread_sp)
|
||||
if (exe_ctx.HasThreadScope())
|
||||
{
|
||||
Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
|
||||
Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
|
||||
bool abort_other_plans = true;
|
||||
bool stop_other_threads = true;
|
||||
Thread *thread = exe_ctx.GetThreadPtr();
|
||||
|
||||
thread_sp->QueueThreadPlanForStepOut (abort_other_plans,
|
||||
thread->QueueThreadPlanForStepOut (abort_other_plans,
|
||||
NULL,
|
||||
false,
|
||||
stop_other_threads,
|
||||
|
@ -579,15 +577,15 @@ SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame)
|
|||
eVoteNoOpinion,
|
||||
frame_sp->GetFrameIndex());
|
||||
|
||||
Process &process = thread_sp->GetProcess();
|
||||
process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
|
||||
Error error (process.Resume());
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
process->GetThreadList().SetSelectedThreadByID (thread->GetID());
|
||||
Error error (process->Resume());
|
||||
if (error.Success())
|
||||
{
|
||||
// If we are doing synchronous mode, then wait for the
|
||||
// process to stop yet again!
|
||||
if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
|
||||
process.WaitForProcessToStop (NULL);
|
||||
if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
|
||||
process->WaitForProcessToStop (NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -597,24 +595,26 @@ SBThread::StepInstruction (bool step_over)
|
|||
{
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
ThreadSP thread_sp(m_opaque_wp.lock());
|
||||
ExecutionContext exe_ctx (m_opaque_wp);
|
||||
|
||||
|
||||
if (log)
|
||||
log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", thread_sp.get(), step_over);
|
||||
log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", exe_ctx.GetThreadPtr(), step_over);
|
||||
|
||||
if (thread_sp)
|
||||
if (exe_ctx.HasThreadScope())
|
||||
{
|
||||
Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
|
||||
thread_sp->QueueThreadPlanForStepSingleInstruction (step_over, true, true);
|
||||
Process &process = thread_sp->GetProcess();
|
||||
process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
|
||||
Error error (process.Resume());
|
||||
Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
|
||||
Thread *thread = exe_ctx.GetThreadPtr();
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true);
|
||||
process->GetThreadList().SetSelectedThreadByID (thread->GetID());
|
||||
Error error (process->Resume());
|
||||
if (error.Success())
|
||||
{
|
||||
// If we are doing synchronous mode, then wait for the
|
||||
// process to stop yet again!
|
||||
if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
|
||||
process.WaitForProcessToStop (NULL);
|
||||
if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
|
||||
process->WaitForProcessToStop (NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -624,28 +624,31 @@ SBThread::RunToAddress (lldb::addr_t addr)
|
|||
{
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
ThreadSP thread_sp(m_opaque_wp.lock());
|
||||
ExecutionContext exe_ctx (m_opaque_wp);
|
||||
|
||||
if (log)
|
||||
log->Printf ("SBThread(%p)::RunToAddress (addr=0x%llx)", thread_sp.get(), addr);
|
||||
log->Printf ("SBThread(%p)::RunToAddress (addr=0x%llx)", exe_ctx.GetThreadPtr(), addr);
|
||||
|
||||
if (thread_sp)
|
||||
if (exe_ctx.HasThreadScope())
|
||||
{
|
||||
Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
|
||||
bool abort_other_plans = true;
|
||||
bool stop_other_threads = true;
|
||||
|
||||
Address target_addr (NULL, addr);
|
||||
|
||||
thread_sp->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads);
|
||||
Process &process = thread_sp->GetProcess();
|
||||
process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
|
||||
Error error (process.Resume());
|
||||
Thread *thread = exe_ctx.GetThreadPtr();
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
|
||||
thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads);
|
||||
process->GetThreadList().SetSelectedThreadByID (thread->GetID());
|
||||
Error error (process->Resume());
|
||||
if (error.Success())
|
||||
{
|
||||
// If we are doing synchronous mode, then wait for the
|
||||
// process to stop yet again!
|
||||
if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
|
||||
process.WaitForProcessToStop (NULL);
|
||||
if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
|
||||
process->WaitForProcessToStop (NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -659,7 +662,7 @@ SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
|
|||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
char path[PATH_MAX];
|
||||
|
||||
ThreadSP thread_sp(m_opaque_wp.lock());
|
||||
ExecutionContext exe_ctx (m_opaque_wp);
|
||||
StackFrameSP frame_sp (sb_frame.GetFrameSP());
|
||||
|
||||
if (log)
|
||||
|
@ -668,15 +671,17 @@ SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
|
|||
sb_frame.GetDescription (frame_desc_strm);
|
||||
sb_file_spec->GetPath (path, sizeof(path));
|
||||
log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)",
|
||||
thread_sp.get(),
|
||||
exe_ctx.GetThreadPtr(),
|
||||
frame_sp.get(),
|
||||
frame_desc_strm.GetData(),
|
||||
path, line);
|
||||
}
|
||||
|
||||
if (thread_sp)
|
||||
if (exe_ctx.HasThreadScope())
|
||||
{
|
||||
Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
|
||||
Target *target = exe_ctx.GetTargetPtr();
|
||||
Mutex::Locker api_locker (target->GetAPIMutex());
|
||||
Thread *thread = exe_ctx.GetThreadPtr();
|
||||
|
||||
if (line == 0)
|
||||
{
|
||||
|
@ -687,9 +692,9 @@ SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
|
|||
StackFrameSP frame_sp;
|
||||
if (!frame_sp)
|
||||
{
|
||||
frame_sp = thread_sp->GetSelectedFrame ();
|
||||
frame_sp = thread->GetSelectedFrame ();
|
||||
if (!frame_sp)
|
||||
frame_sp = thread_sp->GetStackFrameAtIndex (0);
|
||||
frame_sp = thread->GetStackFrameAtIndex (0);
|
||||
}
|
||||
|
||||
SymbolContext frame_sc;
|
||||
|
@ -741,7 +746,6 @@ SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
|
|||
const bool stop_other_threads = true;
|
||||
const bool check_inlines = true;
|
||||
const bool exact = false;
|
||||
Target *target = &thread_sp->GetProcess().GetTarget();
|
||||
|
||||
SymbolContextList sc_list;
|
||||
const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec,
|
||||
|
@ -781,20 +785,22 @@ SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
|
|||
}
|
||||
else
|
||||
{
|
||||
thread_sp->QueueThreadPlanForStepUntil (abort_other_plans,
|
||||
&step_over_until_addrs[0],
|
||||
step_over_until_addrs.size(),
|
||||
stop_other_threads,
|
||||
frame_sp->GetFrameIndex());
|
||||
thread->QueueThreadPlanForStepUntil (abort_other_plans,
|
||||
&step_over_until_addrs[0],
|
||||
step_over_until_addrs.size(),
|
||||
stop_other_threads,
|
||||
frame_sp->GetFrameIndex());
|
||||
|
||||
thread_sp->GetProcess().GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
|
||||
sb_error.ref() = thread_sp->GetProcess().Resume();
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
|
||||
process->GetThreadList().SetSelectedThreadByID (thread->GetID());
|
||||
sb_error.ref() = process->Resume();
|
||||
if (sb_error->Success())
|
||||
{
|
||||
// If we are doing synchronous mode, then wait for the
|
||||
// process to stop yet again!
|
||||
if (thread_sp->GetProcess().GetTarget().GetDebugger().GetAsyncExecution () == false)
|
||||
thread_sp->GetProcess().WaitForProcessToStop (NULL);
|
||||
if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
|
||||
process->WaitForProcessToStop (NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -809,10 +815,10 @@ SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
|
|||
bool
|
||||
SBThread::Suspend()
|
||||
{
|
||||
ThreadSP thread_sp(m_opaque_wp.lock());
|
||||
if (thread_sp)
|
||||
ExecutionContext exe_ctx (m_opaque_wp);
|
||||
if (exe_ctx.HasThreadScope())
|
||||
{
|
||||
thread_sp->SetResumeState (eStateSuspended);
|
||||
exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -821,10 +827,10 @@ SBThread::Suspend()
|
|||
bool
|
||||
SBThread::Resume ()
|
||||
{
|
||||
ThreadSP thread_sp(m_opaque_wp.lock());
|
||||
if (thread_sp)
|
||||
ExecutionContext exe_ctx (m_opaque_wp);
|
||||
if (exe_ctx.HasThreadScope())
|
||||
{
|
||||
thread_sp->SetResumeState (eStateRunning);
|
||||
exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -833,9 +839,9 @@ SBThread::Resume ()
|
|||
bool
|
||||
SBThread::IsSuspended()
|
||||
{
|
||||
ThreadSP thread_sp(m_opaque_wp.lock());
|
||||
if (thread_sp)
|
||||
return thread_sp->GetResumeState () == eStateSuspended;
|
||||
ExecutionContext exe_ctx (m_opaque_wp);
|
||||
if (exe_ctx.HasThreadScope())
|
||||
return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -845,12 +851,11 @@ SBThread::GetProcess ()
|
|||
|
||||
SBProcess sb_process;
|
||||
ProcessSP process_sp;
|
||||
ThreadSP thread_sp(m_opaque_wp.lock());
|
||||
if (thread_sp)
|
||||
ExecutionContext exe_ctx (m_opaque_wp);
|
||||
if (exe_ctx.HasThreadScope())
|
||||
{
|
||||
// Have to go up to the target so we can get a shared pointer to our process...
|
||||
process_sp = thread_sp->GetProcess().GetTarget().GetProcessSP();
|
||||
sb_process.SetSP (process_sp);
|
||||
sb_process.SetSP (exe_ctx.GetProcessSP());
|
||||
}
|
||||
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
@ -858,7 +863,7 @@ SBThread::GetProcess ()
|
|||
{
|
||||
SBStream frame_desc_strm;
|
||||
sb_process.GetDescription (frame_desc_strm);
|
||||
log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", thread_sp.get(),
|
||||
log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", exe_ctx.GetThreadPtr(),
|
||||
process_sp.get(), frame_desc_strm.GetData());
|
||||
}
|
||||
|
||||
|
@ -871,15 +876,15 @@ SBThread::GetNumFrames ()
|
|||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
uint32_t num_frames = 0;
|
||||
ThreadSP thread_sp(m_opaque_wp.lock());
|
||||
if (thread_sp)
|
||||
ExecutionContext exe_ctx (m_opaque_wp);
|
||||
if (exe_ctx.HasThreadScope())
|
||||
{
|
||||
Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
|
||||
num_frames = thread_sp->GetStackFrameCount();
|
||||
Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
|
||||
num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
|
||||
}
|
||||
|
||||
if (log)
|
||||
log->Printf ("SBThread(%p)::GetNumFrames () => %u", thread_sp.get(), num_frames);
|
||||
log->Printf ("SBThread(%p)::GetNumFrames () => %u", exe_ctx.GetThreadPtr(), num_frames);
|
||||
|
||||
return num_frames;
|
||||
}
|
||||
|
@ -891,11 +896,11 @@ SBThread::GetFrameAtIndex (uint32_t idx)
|
|||
|
||||
SBFrame sb_frame;
|
||||
StackFrameSP frame_sp;
|
||||
ThreadSP thread_sp(m_opaque_wp.lock());
|
||||
if (thread_sp)
|
||||
ExecutionContext exe_ctx (m_opaque_wp);
|
||||
if (exe_ctx.HasThreadScope())
|
||||
{
|
||||
Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
|
||||
frame_sp = thread_sp->GetStackFrameAtIndex (idx);
|
||||
Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
|
||||
frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx);
|
||||
sb_frame.SetFrameSP (frame_sp);
|
||||
}
|
||||
|
||||
|
@ -904,7 +909,7 @@ SBThread::GetFrameAtIndex (uint32_t idx)
|
|||
SBStream frame_desc_strm;
|
||||
sb_frame.GetDescription (frame_desc_strm);
|
||||
log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
|
||||
thread_sp.get(), idx, frame_sp.get(), frame_desc_strm.GetData());
|
||||
exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData());
|
||||
}
|
||||
|
||||
return sb_frame;
|
||||
|
@ -917,11 +922,11 @@ SBThread::GetSelectedFrame ()
|
|||
|
||||
SBFrame sb_frame;
|
||||
StackFrameSP frame_sp;
|
||||
ThreadSP thread_sp(m_opaque_wp.lock());
|
||||
if (thread_sp)
|
||||
ExecutionContext exe_ctx (m_opaque_wp);
|
||||
if (exe_ctx.HasThreadScope())
|
||||
{
|
||||
Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
|
||||
frame_sp = thread_sp->GetSelectedFrame ();
|
||||
Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
|
||||
frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame ();
|
||||
sb_frame.SetFrameSP (frame_sp);
|
||||
}
|
||||
|
||||
|
@ -930,7 +935,7 @@ SBThread::GetSelectedFrame ()
|
|||
SBStream frame_desc_strm;
|
||||
sb_frame.GetDescription (frame_desc_strm);
|
||||
log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
|
||||
thread_sp.get(), frame_sp.get(), frame_desc_strm.GetData());
|
||||
exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData());
|
||||
}
|
||||
|
||||
return sb_frame;
|
||||
|
@ -943,14 +948,15 @@ SBThread::SetSelectedFrame (uint32_t idx)
|
|||
|
||||
SBFrame sb_frame;
|
||||
StackFrameSP frame_sp;
|
||||
ThreadSP thread_sp(m_opaque_wp.lock());
|
||||
if (thread_sp)
|
||||
ExecutionContext exe_ctx (m_opaque_wp);
|
||||
if (exe_ctx.HasThreadScope())
|
||||
{
|
||||
Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
|
||||
frame_sp = thread_sp->GetStackFrameAtIndex (idx);
|
||||
Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
|
||||
Thread *thread = exe_ctx.GetThreadPtr();
|
||||
frame_sp = thread->GetStackFrameAtIndex (idx);
|
||||
if (frame_sp)
|
||||
{
|
||||
thread_sp->SetSelectedFrame (frame_sp.get());
|
||||
thread->SetSelectedFrame (frame_sp.get());
|
||||
sb_frame.SetFrameSP (frame_sp);
|
||||
}
|
||||
}
|
||||
|
@ -960,7 +966,7 @@ SBThread::SetSelectedFrame (uint32_t idx)
|
|||
SBStream frame_desc_strm;
|
||||
sb_frame.GetDescription (frame_desc_strm);
|
||||
log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
|
||||
thread_sp.get(), idx, frame_sp.get(), frame_desc_strm.GetData());
|
||||
exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData());
|
||||
}
|
||||
return sb_frame;
|
||||
}
|
||||
|
@ -983,10 +989,10 @@ SBThread::GetDescription (SBStream &description) const
|
|||
{
|
||||
Stream &strm = description.ref();
|
||||
|
||||
ThreadSP thread_sp(m_opaque_wp.lock());
|
||||
if (thread_sp)
|
||||
ExecutionContext exe_ctx (m_opaque_wp);
|
||||
if (exe_ctx.HasThreadScope())
|
||||
{
|
||||
strm.Printf("SBThread: tid = 0x%4.4llx", thread_sp->GetID());
|
||||
strm.Printf("SBThread: tid = 0x%4.4llx", exe_ctx.GetThreadPtr()->GetID());
|
||||
}
|
||||
else
|
||||
strm.PutCString ("No value");
|
||||
|
|
|
@ -18,13 +18,14 @@ using namespace lldb_private;
|
|||
|
||||
StoppointCallbackContext::StoppointCallbackContext() :
|
||||
event (NULL),
|
||||
exe_ctx()
|
||||
exe_ctx_ref (),
|
||||
is_synchronous (false)
|
||||
{
|
||||
}
|
||||
|
||||
StoppointCallbackContext::StoppointCallbackContext(Event *e, Process* p, Thread *t, StackFrame *f, bool synchronously) :
|
||||
StoppointCallbackContext::StoppointCallbackContext(Event *e, const ExecutionContext &exe_ctx, bool synchronously) :
|
||||
event (e),
|
||||
exe_ctx (p, t, f),
|
||||
exe_ctx_ref (exe_ctx),
|
||||
is_synchronous(synchronously)
|
||||
{
|
||||
}
|
||||
|
@ -33,6 +34,6 @@ void
|
|||
StoppointCallbackContext::Clear()
|
||||
{
|
||||
event = NULL;
|
||||
exe_ctx.Clear();
|
||||
exe_ctx_ref.Clear();
|
||||
is_synchronous = false;
|
||||
}
|
||||
|
|
|
@ -799,7 +799,8 @@ CommandObjectBreakpointCommand::BreakpointOptionsCallbackFunction
|
|||
|
||||
if (commands.GetSize() > 0)
|
||||
{
|
||||
Target *target = context->exe_ctx.GetTargetPtr();
|
||||
ExecutionContext exe_ctx (context->exe_ctx_ref);
|
||||
Target *target = exe_ctx.GetTargetPtr();
|
||||
if (target)
|
||||
{
|
||||
CommandReturnObject result;
|
||||
|
@ -817,7 +818,7 @@ CommandObjectBreakpointCommand::BreakpointOptionsCallbackFunction
|
|||
bool print_results = true;
|
||||
|
||||
debugger.GetCommandInterpreter().HandleCommands (commands,
|
||||
&(context->exe_ctx),
|
||||
&exe_ctx,
|
||||
stop_on_continue,
|
||||
data->stop_on_error,
|
||||
echo_commands,
|
||||
|
|
|
@ -96,17 +96,20 @@ public:
|
|||
bool prefix_with_altname = m_command_options.alternate_name;
|
||||
bool prefix_with_name = !prefix_with_altname;
|
||||
reg_value.Dump(&strm, reg_info, prefix_with_name, prefix_with_altname, m_format_options.GetFormat());
|
||||
if (((reg_info->encoding == eEncodingUint) || (reg_info->encoding == eEncodingSint)) &&
|
||||
(reg_info->byte_size == reg_ctx->GetThread().GetProcess().GetAddressByteSize()))
|
||||
if ((reg_info->encoding == eEncodingUint) || (reg_info->encoding == eEncodingSint))
|
||||
{
|
||||
addr_t reg_addr = reg_value.GetAsUInt64(LLDB_INVALID_ADDRESS);
|
||||
if (reg_addr != LLDB_INVALID_ADDRESS)
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
if (process && reg_info->byte_size == process->GetAddressByteSize())
|
||||
{
|
||||
Address so_reg_addr;
|
||||
if (exe_ctx.GetTargetRef().GetSectionLoadList().ResolveLoadAddress(reg_addr, so_reg_addr))
|
||||
addr_t reg_addr = reg_value.GetAsUInt64(LLDB_INVALID_ADDRESS);
|
||||
if (reg_addr != LLDB_INVALID_ADDRESS)
|
||||
{
|
||||
strm.PutCString (" ");
|
||||
so_reg_addr.Dump(&strm, exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription);
|
||||
Address so_reg_addr;
|
||||
if (exe_ctx.GetTargetRef().GetSectionLoadList().ResolveLoadAddress(reg_addr, so_reg_addr))
|
||||
{
|
||||
strm.PutCString (" ");
|
||||
so_reg_addr.Dump(&strm, exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -375,7 +375,9 @@ ValueObjectRegister::UpdateValue ()
|
|||
{
|
||||
if (m_reg_value.GetData (m_data))
|
||||
{
|
||||
m_data.SetAddressByteSize(m_reg_ctx_sp->GetThread().GetProcess().GetAddressByteSize());
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
if (process)
|
||||
m_data.SetAddressByteSize(process->GetAddressByteSize());
|
||||
m_value.SetContext(Value::eContextTypeRegisterInfo, (void *)&m_reg_info);
|
||||
m_value.SetValueType(Value::eValueTypeHostAddress);
|
||||
m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
|
||||
|
|
|
@ -1496,7 +1496,8 @@ ScriptInterpreterPython::BreakpointCallbackFunction
|
|||
if (!context)
|
||||
return true;
|
||||
|
||||
Target *target = context->exe_ctx.GetTargetPtr();
|
||||
ExecutionContext exe_ctx (context->exe_ctx_ref);
|
||||
Target *target = exe_ctx.GetTargetPtr();
|
||||
|
||||
if (!target)
|
||||
return true;
|
||||
|
@ -1511,7 +1512,7 @@ ScriptInterpreterPython::BreakpointCallbackFunction
|
|||
if (python_function_name != NULL
|
||||
&& python_function_name[0] != '\0')
|
||||
{
|
||||
const StackFrameSP stop_frame_sp (context->exe_ctx.GetFrameSP());
|
||||
const StackFrameSP stop_frame_sp (exe_ctx.GetFrameSP());
|
||||
BreakpointSP breakpoint_sp = target->GetBreakpointByID (break_id);
|
||||
if (breakpoint_sp)
|
||||
{
|
||||
|
|
|
@ -264,14 +264,14 @@ ABIMacOSX_arm::PrepareTrivialCall (Thread &thread,
|
|||
}
|
||||
|
||||
|
||||
Target *target = &thread.GetProcess().GetTarget();
|
||||
TargetSP target_sp (thread.CalculateTarget());
|
||||
Address so_addr;
|
||||
|
||||
// Figure out if our return address is ARM or Thumb by using the
|
||||
// Address::GetCallableLoadAddress(Target*) which will figure out the ARM
|
||||
// thumb-ness and set the correct address bits for us.
|
||||
so_addr.SetLoadAddress (return_addr, target);
|
||||
return_addr = so_addr.GetCallableLoadAddress (target);
|
||||
so_addr.SetLoadAddress (return_addr, target_sp.get());
|
||||
return_addr = so_addr.GetCallableLoadAddress (target_sp.get());
|
||||
|
||||
// Set "lr" to the return address
|
||||
if (!reg_ctx->WriteRegisterFromUnsigned (ra_reg_num, return_addr))
|
||||
|
@ -283,8 +283,8 @@ ABIMacOSX_arm::PrepareTrivialCall (Thread &thread,
|
|||
|
||||
// If bit zero or 1 is set, this must be a thumb function, no need to figure
|
||||
// this out from the symbols.
|
||||
so_addr.SetLoadAddress (function_addr, target);
|
||||
function_addr = so_addr.GetCallableLoadAddress (target);
|
||||
so_addr.SetLoadAddress (function_addr, target_sp.get());
|
||||
function_addr = so_addr.GetCallableLoadAddress (target_sp.get());
|
||||
|
||||
const RegisterInfo *cpsr_reg_info = reg_ctx->GetRegisterInfoByName("cpsr");
|
||||
const uint32_t curr_cpsr = reg_ctx->ReadRegisterAsUnsigned(cpsr_reg_info, 0);
|
||||
|
@ -319,10 +319,11 @@ ABIMacOSX_arm::GetArgumentValues (Thread &thread,
|
|||
uint32_t num_values = values.GetSize();
|
||||
|
||||
|
||||
ExecutionContext exe_ctx (thread.shared_from_this());
|
||||
// For now, assume that the types in the AST values come from the Target's
|
||||
// scratch AST.
|
||||
|
||||
clang::ASTContext *ast_context = thread.CalculateTarget()->GetScratchClangASTContext()->getASTContext();
|
||||
clang::ASTContext *ast_context = exe_ctx.GetTargetRef().GetScratchClangASTContext()->getASTContext();
|
||||
|
||||
// Extract the register context so we can read arguments from registers
|
||||
|
||||
|
@ -364,7 +365,7 @@ ABIMacOSX_arm::GetArgumentValues (Thread &thread,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (bit_width <= (thread.GetProcess().GetAddressByteSize() * 8))
|
||||
if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8))
|
||||
{
|
||||
if (value_idx < 4)
|
||||
{
|
||||
|
@ -407,7 +408,7 @@ ABIMacOSX_arm::GetArgumentValues (Thread &thread,
|
|||
// Arguments 5 on up are on the stack
|
||||
const uint32_t arg_byte_size = (bit_width + (8-1)) / 8;
|
||||
Error error;
|
||||
if (!thread.GetProcess().ReadScalarIntegerFromMemory(sp, arg_byte_size, is_signed, value->GetScalar(), error))
|
||||
if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory(sp, arg_byte_size, is_signed, value->GetScalar(), error))
|
||||
return false;
|
||||
|
||||
sp += arg_byte_size;
|
||||
|
|
|
@ -418,9 +418,12 @@ ABIMacOSX_i386::PrepareNormalCall (Thread &thread,
|
|||
addr_t return_addr,
|
||||
ValueList &args) const
|
||||
{
|
||||
ExecutionContext exe_ctx (thread.shared_from_this());
|
||||
RegisterContext *reg_ctx = thread.GetRegisterContext().get();
|
||||
if (!reg_ctx)
|
||||
return false;
|
||||
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
Error error;
|
||||
uint32_t fp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
|
||||
uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
|
||||
|
@ -528,7 +531,7 @@ ABIMacOSX_i386::PrepareNormalCall (Thread &thread,
|
|||
|
||||
sp -= (cstr_length + 1);
|
||||
|
||||
if (thread.GetProcess().WriteMemory(sp, cstr, cstr_length + 1, error) != (cstr_length + 1))
|
||||
if (process->WriteMemory(sp, cstr, cstr_length + 1, error) != (cstr_length + 1))
|
||||
return false;
|
||||
|
||||
// Put the address of the string into the argument array.
|
||||
|
@ -563,14 +566,14 @@ ABIMacOSX_i386::PrepareNormalCall (Thread &thread,
|
|||
size_t numChunks = argLayout.size();
|
||||
|
||||
for (index = 0; index < numChunks; ++index)
|
||||
if (thread.GetProcess().WriteMemory(sp + (index * 4), &argLayout[index], sizeof(uint32_t), error) != sizeof(uint32_t))
|
||||
if (process->WriteMemory(sp + (index * 4), &argLayout[index], sizeof(uint32_t), error) != sizeof(uint32_t))
|
||||
return false;
|
||||
|
||||
// The return address is pushed onto the stack.
|
||||
|
||||
sp -= 4;
|
||||
uint32_t returnAddressU32 = return_addr;
|
||||
if (thread.GetProcess().WriteMemory (sp, &returnAddressU32, sizeof(returnAddressU32), error) != sizeof(returnAddressU32))
|
||||
if (process->WriteMemory (sp, &returnAddressU32, sizeof(returnAddressU32), error) != sizeof(returnAddressU32))
|
||||
return false;
|
||||
|
||||
// %esp is set to the actual stack value.
|
||||
|
@ -595,13 +598,13 @@ static bool
|
|||
ReadIntegerArgument (Scalar &scalar,
|
||||
unsigned int bit_width,
|
||||
bool is_signed,
|
||||
Process &process,
|
||||
Process *process,
|
||||
addr_t ¤t_stack_argument)
|
||||
{
|
||||
|
||||
uint32_t byte_size = (bit_width + (8-1))/8;
|
||||
Error error;
|
||||
if (process.ReadScalarIntegerFromMemory(current_stack_argument, byte_size, is_signed, scalar, error))
|
||||
if (process->ReadScalarIntegerFromMemory(current_stack_argument, byte_size, is_signed, scalar, error))
|
||||
{
|
||||
current_stack_argument += byte_size;
|
||||
return true;
|
||||
|
@ -652,29 +655,29 @@ ABIMacOSX_i386::GetArgumentValues (Thread &thread,
|
|||
default:
|
||||
return false;
|
||||
case Value::eContextTypeClangType:
|
||||
{
|
||||
void *value_type = value->GetClangType();
|
||||
bool is_signed;
|
||||
|
||||
if (ClangASTContext::IsIntegerType (value_type, is_signed))
|
||||
{
|
||||
size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
|
||||
void *value_type = value->GetClangType();
|
||||
bool is_signed;
|
||||
|
||||
ReadIntegerArgument(value->GetScalar(),
|
||||
bit_width,
|
||||
is_signed,
|
||||
thread.GetProcess(),
|
||||
current_stack_argument);
|
||||
if (ClangASTContext::IsIntegerType (value_type, is_signed))
|
||||
{
|
||||
size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
|
||||
|
||||
ReadIntegerArgument(value->GetScalar(),
|
||||
bit_width,
|
||||
is_signed,
|
||||
thread.GetProcess().get(),
|
||||
current_stack_argument);
|
||||
}
|
||||
else if (ClangASTContext::IsPointerType (value_type))
|
||||
{
|
||||
ReadIntegerArgument(value->GetScalar(),
|
||||
32,
|
||||
false,
|
||||
thread.GetProcess().get(),
|
||||
current_stack_argument);
|
||||
}
|
||||
}
|
||||
else if (ClangASTContext::IsPointerType (value_type))
|
||||
{
|
||||
ReadIntegerArgument(value->GetScalar(),
|
||||
32,
|
||||
false,
|
||||
thread.GetProcess(),
|
||||
current_stack_argument);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -450,7 +450,7 @@ static bool ReadIntegerArgument(Scalar &scalar,
|
|||
{
|
||||
uint32_t byte_size = (bit_width + (8-1))/8;
|
||||
Error error;
|
||||
if (thread.GetProcess().ReadScalarIntegerFromMemory(current_stack_argument, byte_size, is_signed, scalar, error))
|
||||
if (thread.GetProcess()->ReadScalarIntegerFromMemory(current_stack_argument, byte_size, is_signed, scalar, error))
|
||||
{
|
||||
current_stack_argument += byte_size;
|
||||
return true;
|
||||
|
@ -690,12 +690,11 @@ ABISysV_x86_64::GetReturnValueObjectSimple (Thread &thread,
|
|||
}
|
||||
|
||||
ValueObjectSP
|
||||
ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread,
|
||||
ClangASTType &ast_type) const
|
||||
ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &ast_type) const
|
||||
{
|
||||
|
||||
ValueObjectSP return_valobj_sp;
|
||||
|
||||
ExecutionContext exe_ctx (thread.shared_from_this());
|
||||
return_valobj_sp = GetReturnValueObjectSimple(thread, ast_type);
|
||||
if (return_valobj_sp)
|
||||
return return_valobj_sp;
|
||||
|
@ -715,15 +714,15 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread,
|
|||
size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, ret_value_type);
|
||||
if (ClangASTContext::IsAggregateType(ret_value_type))
|
||||
{
|
||||
Target &target = thread.GetProcess().GetTarget();
|
||||
Target *target = exe_ctx.GetTargetPtr();
|
||||
bool is_memory = true;
|
||||
if (bit_width <= 128)
|
||||
{
|
||||
ByteOrder target_byte_order = target.GetArchitecture().GetByteOrder();
|
||||
ByteOrder target_byte_order = target->GetArchitecture().GetByteOrder();
|
||||
DataBufferSP data_sp (new DataBufferHeap(16, 0));
|
||||
DataExtractor return_ext (data_sp,
|
||||
target_byte_order,
|
||||
target.GetArchitecture().GetAddressByteSize());
|
||||
target->GetArchitecture().GetAddressByteSize());
|
||||
|
||||
const RegisterInfo *rax_info = reg_ctx_sp->GetRegisterInfoByName("rax", 0);
|
||||
const RegisterInfo *rdx_info = reg_ctx_sp->GetRegisterInfoByName("rdx", 0);
|
||||
|
|
|
@ -546,7 +546,8 @@ DynamicLoaderMacOSXDYLD::NotifyBreakpointHit (void *baton,
|
|||
if (dyld_instance->InitializeFromAllImageInfos())
|
||||
return dyld_instance->GetStopWhenImagesChange();
|
||||
|
||||
Process *process = context->exe_ctx.GetProcessPtr();
|
||||
ExecutionContext exe_ctx (context->exe_ctx_ref);
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
const lldb::ABISP &abi = process->GetABI();
|
||||
if (abi != NULL)
|
||||
{
|
||||
|
@ -565,7 +566,7 @@ DynamicLoaderMacOSXDYLD::NotifyBreakpointHit (void *baton,
|
|||
input_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type);
|
||||
argument_values.PushValue (input_value);
|
||||
|
||||
if (abi->GetArgumentValues (context->exe_ctx.GetThreadRef(), argument_values))
|
||||
if (abi->GetArgumentValues (exe_ctx.GetThreadRef(), argument_values))
|
||||
{
|
||||
uint32_t dyld_mode = argument_values.GetValueAtIndex(0)->GetScalar().UInt (-1);
|
||||
if (dyld_mode != -1)
|
||||
|
@ -1555,7 +1556,8 @@ DynamicLoaderMacOSXDYLD::GetStepThroughTrampolinePlan (Thread &thread, bool stop
|
|||
if (trampoline_name)
|
||||
{
|
||||
SymbolContextList target_symbols;
|
||||
ModuleList &images = thread.GetProcess().GetTarget().GetImages();
|
||||
TargetSP target_sp (thread.CalculateTarget());
|
||||
ModuleList &images = target_sp->GetImages();
|
||||
|
||||
images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode, target_symbols);
|
||||
|
||||
|
@ -1611,7 +1613,7 @@ DynamicLoaderMacOSXDYLD::GetStepThroughTrampolinePlan (Thread &thread, bool stop
|
|||
if (target_symbols.GetContextAtIndex(i, context))
|
||||
{
|
||||
context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range);
|
||||
lldb::addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(&thread.GetProcess().GetTarget());
|
||||
lldb::addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(target_sp.get());
|
||||
addresses[i] = load_addr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -400,7 +400,8 @@ AppleObjCTrampolineHandler::AppleObjCVTables::RefreshTrampolines (void *baton,
|
|||
{
|
||||
// The Update function is called with the address of an added region. So we grab that address, and
|
||||
// feed it into ReadRegions. Of course, our friend the ABI will get the values for us.
|
||||
Process *process = context->exe_ctx.GetProcessPtr();
|
||||
ExecutionContext exe_ctx (context->exe_ctx_ref);
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
const ABI *abi = process->GetABI().get();
|
||||
|
||||
ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
|
||||
|
@ -411,14 +412,14 @@ AppleObjCTrampolineHandler::AppleObjCVTables::RefreshTrampolines (void *baton,
|
|||
input_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type);
|
||||
argument_values.PushValue(input_value);
|
||||
|
||||
bool success = abi->GetArgumentValues (context->exe_ctx.GetThreadRef(), argument_values);
|
||||
bool success = abi->GetArgumentValues (exe_ctx.GetThreadRef(), argument_values);
|
||||
if (!success)
|
||||
return false;
|
||||
|
||||
// Now get a pointer value from the zeroth argument.
|
||||
Error error;
|
||||
DataExtractor data;
|
||||
error = argument_values.GetValueAtIndex(0)->GetValueAsData (&(context->exe_ctx),
|
||||
error = argument_values.GetValueAtIndex(0)->GetValueAsData (&exe_ctx,
|
||||
clang_ast_context->getASTContext(),
|
||||
data,
|
||||
0,
|
||||
|
|
|
@ -152,7 +152,7 @@ AppleThreadPlanStepThroughObjCTrampoline::ShouldStop (Event *event_ptr)
|
|||
if (log)
|
||||
log->Printf("Running to ObjC method implementation: 0x%llx", target_addr);
|
||||
|
||||
ObjCLanguageRuntime *objc_runtime = GetThread().GetProcess().GetObjCLanguageRuntime();
|
||||
ObjCLanguageRuntime *objc_runtime = GetThread().GetProcess()->GetObjCLanguageRuntime();
|
||||
assert (objc_runtime != NULL);
|
||||
objc_runtime->AddToMethodCache (m_isa_addr, m_sel_addr, target_addr);
|
||||
if (log)
|
||||
|
|
|
@ -249,7 +249,7 @@ OperatingSystemDarwinKernel::UpdateThreadList (ThreadList &old_thread_list, Thre
|
|||
|
||||
ThreadSP thread_sp (old_thread_list.FindThreadByID (tid, false));
|
||||
if (!thread_sp)
|
||||
thread_sp.reset (new ThreadMemory (*m_process, tid, valobj_sp));
|
||||
thread_sp.reset (new ThreadMemory (m_process->shared_from_this(), tid, valobj_sp));
|
||||
|
||||
new_thread_list.AddThread(thread_sp);
|
||||
|
||||
|
|
|
@ -312,7 +312,7 @@ ProcessKDP::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_threa
|
|||
lldb::tid_t tid = cpu_mask_bit;
|
||||
ThreadSP thread_sp (old_thread_list.FindThreadByID (tid, false));
|
||||
if (!thread_sp)
|
||||
thread_sp.reset(new ThreadKDP (*this, tid));
|
||||
thread_sp.reset(new ThreadKDP (shared_from_this(), tid));
|
||||
new_thread_list.AddThread(thread_sp);
|
||||
}
|
||||
return new_thread_list.GetSize(false);
|
||||
|
|
|
@ -33,11 +33,15 @@ RegisterContextKDP_arm::~RegisterContextKDP_arm()
|
|||
int
|
||||
RegisterContextKDP_arm::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
|
||||
{
|
||||
Error error;
|
||||
if (m_kdp_thread.GetKDPProcess().GetCommunication().SendRequestReadRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
|
||||
ProcessSP process_sp (CalculateProcess());
|
||||
if (process_sp)
|
||||
{
|
||||
if (error.Success())
|
||||
return 0;
|
||||
Error error;
|
||||
if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
|
||||
{
|
||||
if (error.Success())
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -45,11 +49,15 @@ RegisterContextKDP_arm::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
|
|||
int
|
||||
RegisterContextKDP_arm::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
|
||||
{
|
||||
Error error;
|
||||
if (m_kdp_thread.GetKDPProcess().GetCommunication().SendRequestReadRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
|
||||
ProcessSP process_sp (CalculateProcess());
|
||||
if (process_sp)
|
||||
{
|
||||
if (error.Success())
|
||||
return 0;
|
||||
Error error;
|
||||
if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
|
||||
{
|
||||
if (error.Success())
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -57,11 +65,15 @@ RegisterContextKDP_arm::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
|
|||
int
|
||||
RegisterContextKDP_arm::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
|
||||
{
|
||||
Error error;
|
||||
if (m_kdp_thread.GetKDPProcess().GetCommunication().SendRequestReadRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
|
||||
ProcessSP process_sp (CalculateProcess());
|
||||
if (process_sp)
|
||||
{
|
||||
if (error.Success())
|
||||
return 0;
|
||||
Error error;
|
||||
if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
|
||||
{
|
||||
if (error.Success())
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -69,11 +81,15 @@ RegisterContextKDP_arm::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
|
|||
int
|
||||
RegisterContextKDP_arm::DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg)
|
||||
{
|
||||
Error error;
|
||||
if (m_kdp_thread.GetKDPProcess().GetCommunication().SendRequestReadRegisters (tid, DBGRegSet, &dbg, sizeof(dbg), error))
|
||||
ProcessSP process_sp (CalculateProcess());
|
||||
if (process_sp)
|
||||
{
|
||||
if (error.Success())
|
||||
return 0;
|
||||
Error error;
|
||||
if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, DBGRegSet, &dbg, sizeof(dbg), error))
|
||||
{
|
||||
if (error.Success())
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -33,11 +33,15 @@ RegisterContextKDP_i386::~RegisterContextKDP_i386()
|
|||
int
|
||||
RegisterContextKDP_i386::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
|
||||
{
|
||||
Error error;
|
||||
if (m_kdp_thread.GetKDPProcess().GetCommunication().SendRequestReadRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
|
||||
ProcessSP process_sp (CalculateProcess());
|
||||
if (process_sp)
|
||||
{
|
||||
if (error.Success())
|
||||
return 0;
|
||||
Error error;
|
||||
if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
|
||||
{
|
||||
if (error.Success())
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -45,11 +49,15 @@ RegisterContextKDP_i386::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
|
|||
int
|
||||
RegisterContextKDP_i386::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
|
||||
{
|
||||
Error error;
|
||||
if (m_kdp_thread.GetKDPProcess().GetCommunication().SendRequestReadRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
|
||||
ProcessSP process_sp (CalculateProcess());
|
||||
if (process_sp)
|
||||
{
|
||||
if (error.Success())
|
||||
return 0;
|
||||
Error error;
|
||||
if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
|
||||
{
|
||||
if (error.Success())
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -57,11 +65,15 @@ RegisterContextKDP_i386::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
|
|||
int
|
||||
RegisterContextKDP_i386::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
|
||||
{
|
||||
Error error;
|
||||
if (m_kdp_thread.GetKDPProcess().GetCommunication().SendRequestReadRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
|
||||
ProcessSP process_sp (CalculateProcess());
|
||||
if (process_sp)
|
||||
{
|
||||
if (error.Success())
|
||||
return 0;
|
||||
Error error;
|
||||
if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
|
||||
{
|
||||
if (error.Success())
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -69,19 +81,19 @@ RegisterContextKDP_i386::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
|
|||
int
|
||||
RegisterContextKDP_i386::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
|
||||
{
|
||||
return ::thread_set_state(tid, flavor, (thread_state_t)&gpr, GPRWordCount);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
RegisterContextKDP_i386::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
|
||||
{
|
||||
return ::thread_set_state(tid, flavor, (thread_state_t)&fpu, FPUWordCount);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
RegisterContextKDP_i386::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
|
||||
{
|
||||
return ::thread_set_state(tid, flavor, (thread_state_t)&exc, EXCWordCount);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -36,18 +36,18 @@ using namespace lldb_private;
|
|||
// Thread Registers
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
ThreadKDP::ThreadKDP (ProcessKDP &process, lldb::tid_t tid) :
|
||||
Thread(process, tid),
|
||||
ThreadKDP::ThreadKDP (const lldb::ProcessSP &process_sp, lldb::tid_t tid) :
|
||||
Thread(process_sp, tid),
|
||||
m_thread_name (),
|
||||
m_dispatch_queue_name (),
|
||||
m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS)
|
||||
{
|
||||
ProcessKDPLog::LogIf(KDP_LOG_THREAD, "%p: ThreadKDP::ThreadKDP (pid = %i, tid = 0x%4.4x)", this, m_process.GetID(), GetID());
|
||||
ProcessKDPLog::LogIf(KDP_LOG_THREAD, "%p: ThreadKDP::ThreadKDP (tid = 0x%4.4x)", this, GetID());
|
||||
}
|
||||
|
||||
ThreadKDP::~ThreadKDP ()
|
||||
{
|
||||
ProcessKDPLog::LogIf(KDP_LOG_THREAD, "%p: ThreadKDP::~ThreadKDP (pid = %i, tid = 0x%4.4x)", this, m_process.GetID(), GetID());
|
||||
ProcessKDPLog::LogIf(KDP_LOG_THREAD, "%p: ThreadKDP::~ThreadKDP (tid = 0x%4.4x)", this, GetID());
|
||||
DestroyThread();
|
||||
}
|
||||
|
||||
|
@ -157,20 +157,24 @@ ThreadKDP::CreateRegisterContextForFrame (StackFrame *frame)
|
|||
|
||||
if (concrete_frame_idx == 0)
|
||||
{
|
||||
switch (GetKDPProcess().GetCommunication().GetCPUType())
|
||||
ProcessSP process_sp (CalculateProcess());
|
||||
if (process_sp)
|
||||
{
|
||||
case llvm::MachO::CPUTypeARM:
|
||||
reg_ctx_sp.reset (new RegisterContextKDP_arm (*this, concrete_frame_idx));
|
||||
break;
|
||||
case llvm::MachO::CPUTypeI386:
|
||||
reg_ctx_sp.reset (new RegisterContextKDP_i386 (*this, concrete_frame_idx));
|
||||
break;
|
||||
case llvm::MachO::CPUTypeX86_64:
|
||||
reg_ctx_sp.reset (new RegisterContextKDP_x86_64 (*this, concrete_frame_idx));
|
||||
break;
|
||||
default:
|
||||
assert (!"Add CPU type support in KDP");
|
||||
break;
|
||||
switch (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().GetCPUType())
|
||||
{
|
||||
case llvm::MachO::CPUTypeARM:
|
||||
reg_ctx_sp.reset (new RegisterContextKDP_arm (*this, concrete_frame_idx));
|
||||
break;
|
||||
case llvm::MachO::CPUTypeI386:
|
||||
reg_ctx_sp.reset (new RegisterContextKDP_i386 (*this, concrete_frame_idx));
|
||||
break;
|
||||
case llvm::MachO::CPUTypeX86_64:
|
||||
reg_ctx_sp.reset (new RegisterContextKDP_x86_64 (*this, concrete_frame_idx));
|
||||
break;
|
||||
default:
|
||||
assert (!"Add CPU type support in KDP");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (m_unwinder_ap.get())
|
||||
|
@ -181,26 +185,30 @@ ThreadKDP::CreateRegisterContextForFrame (StackFrame *frame)
|
|||
lldb::StopInfoSP
|
||||
ThreadKDP::GetPrivateStopReason ()
|
||||
{
|
||||
const uint32_t process_stop_id = GetProcess().GetStopID();
|
||||
if (m_thread_stop_reason_stop_id != process_stop_id ||
|
||||
(m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
|
||||
ProcessSP process_sp (GetProcess());
|
||||
if (process_sp)
|
||||
{
|
||||
// TODO: can we query the initial state of the thread here?
|
||||
// For now I am just going to pretend that a SIGSTOP happened.
|
||||
const uint32_t process_stop_id = process_sp->GetStopID();
|
||||
if (m_thread_stop_reason_stop_id != process_stop_id ||
|
||||
(m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
|
||||
{
|
||||
// TODO: can we query the initial state of the thread here?
|
||||
// For now I am just going to pretend that a SIGSTOP happened.
|
||||
|
||||
SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, SIGSTOP));
|
||||
SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, SIGSTOP));
|
||||
|
||||
// If GetKDPProcess().SetThreadStopInfo() doesn't find a stop reason
|
||||
// for this thread, then m_actual_stop_info_sp will not ever contain
|
||||
// a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false"
|
||||
// check will never be able to tell us if we have the correct stop info
|
||||
// for this thread and we will continually send qThreadStopInfo packets
|
||||
// down to the remote KDP server, so we need to keep our own notion
|
||||
// of the stop ID that m_actual_stop_info_sp is valid for (even if it
|
||||
// contains nothing). We use m_thread_stop_reason_stop_id for this below.
|
||||
// m_thread_stop_reason_stop_id = process_stop_id;
|
||||
// m_actual_stop_info_sp.reset();
|
||||
// If GetKDPProcess().SetThreadStopInfo() doesn't find a stop reason
|
||||
// for this thread, then m_actual_stop_info_sp will not ever contain
|
||||
// a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false"
|
||||
// check will never be able to tell us if we have the correct stop info
|
||||
// for this thread and we will continually send qThreadStopInfo packets
|
||||
// down to the remote KDP server, so we need to keep our own notion
|
||||
// of the stop ID that m_actual_stop_info_sp is valid for (even if it
|
||||
// contains nothing). We use m_thread_stop_reason_stop_id for this below.
|
||||
// m_thread_stop_reason_stop_id = process_stop_id;
|
||||
// m_actual_stop_info_sp.reset();
|
||||
|
||||
}
|
||||
}
|
||||
return m_actual_stop_info_sp;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ class ProcessKDP;
|
|||
class ThreadKDP : public lldb_private::Thread
|
||||
{
|
||||
public:
|
||||
ThreadKDP (ProcessKDP &process,
|
||||
ThreadKDP (const lldb::ProcessSP &process_sp,
|
||||
lldb::tid_t tid);
|
||||
|
||||
virtual
|
||||
|
@ -47,12 +47,6 @@ public:
|
|||
virtual void
|
||||
ClearStackFrames ();
|
||||
|
||||
ProcessKDP &
|
||||
GetKDPProcess ()
|
||||
{
|
||||
return (ProcessKDP &)m_process;
|
||||
}
|
||||
|
||||
void
|
||||
Dump (lldb_private::Log *log, uint32_t index);
|
||||
|
||||
|
|
|
@ -85,7 +85,9 @@ RegisterContextLLDB::RegisterContextLLDB
|
|||
void
|
||||
RegisterContextLLDB::InitializeZerothFrame()
|
||||
{
|
||||
ExecutionContext exe_ctx(m_thread.shared_from_this());
|
||||
StackFrameSP frame_sp (m_thread.GetStackFrameAtIndex (0));
|
||||
exe_ctx.SetFrameSP (frame_sp);
|
||||
|
||||
LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
|
||||
|
||||
|
@ -158,7 +160,7 @@ RegisterContextLLDB::InitializeZerothFrame()
|
|||
if (active_row && log)
|
||||
{
|
||||
StreamString active_row_strm;
|
||||
active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(&m_thread.GetProcess().GetTarget()));
|
||||
active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
|
||||
log->Printf("%*sFrame %u active row: %s",
|
||||
m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, active_row_strm.GetString().c_str());
|
||||
}
|
||||
|
@ -210,7 +212,7 @@ RegisterContextLLDB::InitializeZerothFrame()
|
|||
m_frame_number < 100 ? m_frame_number : 100, "",
|
||||
m_thread.GetIndexID(),
|
||||
m_frame_number,
|
||||
(uint64_t) m_current_pc.GetLoadAddress (&m_thread.GetProcess().GetTarget()),
|
||||
(uint64_t) m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr()),
|
||||
(uint64_t) m_cfa,
|
||||
m_full_unwind_plan_sp->GetSourceName().GetCString());
|
||||
}
|
||||
|
@ -274,13 +276,15 @@ RegisterContextLLDB::InitializeNonZerothFrame()
|
|||
return;
|
||||
}
|
||||
|
||||
ExecutionContext exe_ctx(m_thread.shared_from_this());
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
// Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs
|
||||
// this will strip bit zero in case we read a PC from memory or from the LR.
|
||||
ABI *abi = m_thread.GetProcess().GetABI().get();
|
||||
ABI *abi = process->GetABI().get();
|
||||
if (abi)
|
||||
pc = abi->FixCodeAddress(pc);
|
||||
|
||||
m_thread.GetProcess().GetTarget().GetSectionLoadList().ResolveLoadAddress (pc, m_current_pc);
|
||||
process->GetTarget().GetSectionLoadList().ResolveLoadAddress (pc, m_current_pc);
|
||||
|
||||
// If we don't have a Module for some reason, we're not going to find symbol/function information - just
|
||||
// stick in some reasonable defaults and hope we can unwind past this frame.
|
||||
|
@ -294,7 +298,7 @@ RegisterContextLLDB::InitializeNonZerothFrame()
|
|||
|
||||
// Test the pc value to see if we know it's in an unmapped/non-executable region of memory.
|
||||
uint32_t permissions;
|
||||
if (m_thread.GetProcess().GetLoadAddressPermissions(pc, permissions)
|
||||
if (process->GetLoadAddressPermissions(pc, permissions)
|
||||
&& (permissions & ePermissionsExecutable) == 0)
|
||||
{
|
||||
// If this is the second frame off the stack, we may have unwound the first frame
|
||||
|
@ -366,7 +370,7 @@ RegisterContextLLDB::InitializeNonZerothFrame()
|
|||
|
||||
// cfa_regval should point into the stack memory; if we can query memory region permissions,
|
||||
// see if the memory is allocated & readable.
|
||||
if (m_thread.GetProcess().GetLoadAddressPermissions(cfa_regval, permissions)
|
||||
if (process->GetLoadAddressPermissions(cfa_regval, permissions)
|
||||
&& (permissions & ePermissionsReadable) == 0)
|
||||
{
|
||||
m_frame_type = eNotAValidFrame;
|
||||
|
@ -495,7 +499,7 @@ RegisterContextLLDB::InitializeNonZerothFrame()
|
|||
if (active_row && log)
|
||||
{
|
||||
StreamString active_row_strm;
|
||||
active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(&m_thread.GetProcess().GetTarget()));
|
||||
active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
|
||||
log->Printf("%*sFrame %u active row: %s",
|
||||
m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, active_row_strm.GetString().c_str());
|
||||
}
|
||||
|
@ -510,7 +514,7 @@ RegisterContextLLDB::InitializeNonZerothFrame()
|
|||
if (active_row && log)
|
||||
{
|
||||
StreamString active_row_strm;
|
||||
active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(&m_thread.GetProcess().GetTarget()));
|
||||
active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
|
||||
log->Printf("%*sFrame %u active row: %s",
|
||||
m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, active_row_strm.GetString().c_str());
|
||||
}
|
||||
|
@ -594,7 +598,7 @@ RegisterContextLLDB::InitializeNonZerothFrame()
|
|||
{
|
||||
log->Printf("%*sFrame %u initialized frame current pc is 0x%llx cfa is 0x%llx",
|
||||
m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
|
||||
(uint64_t) m_current_pc.GetLoadAddress (&m_thread.GetProcess().GetTarget()), (uint64_t) m_cfa);
|
||||
(uint64_t) m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr()), (uint64_t) m_cfa);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -671,8 +675,9 @@ RegisterContextLLDB::GetFullUnwindPlanForFrame ()
|
|||
UnwindPlanSP unwind_plan_sp;
|
||||
LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
|
||||
UnwindPlanSP arch_default_unwind_plan_sp;
|
||||
|
||||
ABI *abi = m_thread.GetProcess().GetABI().get();
|
||||
ExecutionContext exe_ctx(m_thread.shared_from_this());
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
ABI *abi = process ? process->GetABI().get() : NULL;
|
||||
if (abi)
|
||||
{
|
||||
arch_default_unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
|
||||
|
@ -699,9 +704,9 @@ RegisterContextLLDB::GetFullUnwindPlanForFrame ()
|
|||
if ((!m_sym_ctx_valid || m_sym_ctx.function == NULL) && behaves_like_zeroth_frame && m_current_pc.IsValid())
|
||||
{
|
||||
uint32_t permissions;
|
||||
addr_t current_pc_addr = m_current_pc.GetLoadAddress (&m_thread.GetProcess().GetTarget());
|
||||
addr_t current_pc_addr = m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr());
|
||||
if (current_pc_addr == 0
|
||||
|| (m_thread.GetProcess().GetLoadAddressPermissions(current_pc_addr, permissions)
|
||||
|| (process->GetLoadAddressPermissions(current_pc_addr, permissions)
|
||||
&& (permissions & ePermissionsExecutable) == 0))
|
||||
{
|
||||
unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
|
||||
|
@ -749,8 +754,7 @@ RegisterContextLLDB::GetFullUnwindPlanForFrame ()
|
|||
// right thing. It'd be nice if there was a way to ask the eh_frame directly if it is asynchronous
|
||||
// (can be trusted at every instruction point) or synchronous (the normal case - only at call sites).
|
||||
// But there is not.
|
||||
if (m_thread.GetProcess().GetDynamicLoader()
|
||||
&& m_thread.GetProcess().GetDynamicLoader()->AlwaysRelyOnEHUnwindInfo (m_sym_ctx))
|
||||
if (process->GetDynamicLoader() && process->GetDynamicLoader()->AlwaysRelyOnEHUnwindInfo (m_sym_ctx))
|
||||
{
|
||||
unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite (m_current_offset_backed_up_one);
|
||||
if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc))
|
||||
|
@ -1075,12 +1079,15 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
ExecutionContext exe_ctx(m_thread.shared_from_this());
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
if (have_unwindplan_regloc == false)
|
||||
{
|
||||
// If a volatile register is being requested, we don't want to forward the next frame's register contents
|
||||
// up the stack -- the register is not retrievable at this frame.
|
||||
ABI *abi = m_thread.GetProcess().GetABI().get();
|
||||
ABI *abi = process ? process->GetABI().get() : NULL;
|
||||
if (abi)
|
||||
{
|
||||
const RegisterInfo *reg_info = GetRegisterInfoAtIndex(lldb_regnum);
|
||||
|
@ -1198,10 +1205,9 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
|
|||
{
|
||||
DataExtractor dwarfdata (unwindplan_regloc.GetDWARFExpressionBytes(),
|
||||
unwindplan_regloc.GetDWARFExpressionLength(),
|
||||
m_thread.GetProcess().GetByteOrder(), m_thread.GetProcess().GetAddressByteSize());
|
||||
process->GetByteOrder(), process->GetAddressByteSize());
|
||||
DWARFExpression dwarfexpr (dwarfdata, 0, unwindplan_regloc.GetDWARFExpressionLength());
|
||||
dwarfexpr.SetRegisterKind (unwindplan_registerkind);
|
||||
ExecutionContext exe_ctx (&m_thread.GetProcess(), &m_thread, NULL);
|
||||
Value result;
|
||||
Error error;
|
||||
if (dwarfexpr.Evaluate (&exe_ctx, NULL, NULL, NULL, this, 0, NULL, result, &error))
|
||||
|
@ -1432,7 +1438,7 @@ RegisterContextLLDB::GetStartPC (addr_t& start_pc)
|
|||
{
|
||||
return ReadPC (start_pc);
|
||||
}
|
||||
start_pc = m_start_pc.GetLoadAddress (&m_thread.GetProcess().GetTarget());
|
||||
start_pc = m_start_pc.GetLoadAddress (CalculateTarget().get());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -134,11 +134,15 @@ RegisterContextMemory::ReadAllRegisterValues (DataBufferSP &data_sp)
|
|||
{
|
||||
if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
|
||||
{
|
||||
Error error;
|
||||
if (m_thread.GetProcess().ReadMemory(m_reg_data_addr, data_sp->GetBytes(), data_sp->GetByteSize(), error) == data_sp->GetByteSize())
|
||||
ProcessSP process_sp (CalculateProcess());
|
||||
if (process_sp)
|
||||
{
|
||||
SetAllRegisterValid (true);
|
||||
return true;
|
||||
Error error;
|
||||
if (process_sp->ReadMemory(m_reg_data_addr, data_sp->GetBytes(), data_sp->GetByteSize(), error) == data_sp->GetByteSize())
|
||||
{
|
||||
SetAllRegisterValid (true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -149,10 +153,14 @@ RegisterContextMemory::WriteAllRegisterValues (const DataBufferSP &data_sp)
|
|||
{
|
||||
if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
|
||||
{
|
||||
Error error;
|
||||
SetAllRegisterValid (false);
|
||||
if (m_thread.GetProcess().WriteMemory(m_reg_data_addr, data_sp->GetBytes(), data_sp->GetByteSize(), error) == data_sp->GetByteSize())
|
||||
return true;
|
||||
ProcessSP process_sp (CalculateProcess());
|
||||
if (process_sp)
|
||||
{
|
||||
Error error;
|
||||
SetAllRegisterValid (false);
|
||||
if (process_sp->WriteMemory(m_reg_data_addr, data_sp->GetBytes(), data_sp->GetByteSize(), error) == data_sp->GetByteSize())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "lldb/Breakpoint/Watchpoint.h"
|
||||
#include "lldb/Core/ArchSpec.h"
|
||||
#include "lldb/Core/StreamString.h"
|
||||
#include "lldb/Target/ExecutionContext.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/RegisterContext.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
|
@ -31,7 +32,9 @@ StopInfoMachException::GetDescription ()
|
|||
{
|
||||
if (m_description.empty() && m_value != 0)
|
||||
{
|
||||
const llvm::Triple::ArchType cpu = m_thread.GetProcess().GetTarget().GetArchitecture().GetMachine();
|
||||
ExecutionContext exe_ctx (m_thread.shared_from_this());
|
||||
Target *target = exe_ctx.GetTargetPtr();
|
||||
const llvm::Triple::ArchType cpu = target ? target->GetArchitecture().GetMachine() : llvm::Triple::InvalidArch;
|
||||
|
||||
const char *exc_desc = NULL;
|
||||
const char *code_label = "code";
|
||||
|
@ -252,7 +255,9 @@ StopInfoMachException::CreateStopReasonWithMachException
|
|||
{
|
||||
if (exc_type != 0)
|
||||
{
|
||||
const llvm::Triple::ArchType cpu = thread.GetProcess().GetTarget().GetArchitecture().GetMachine();
|
||||
ExecutionContext exe_ctx (thread.shared_from_this());
|
||||
Target *target = exe_ctx.GetTargetPtr();
|
||||
const llvm::Triple::ArchType cpu = target ? target->GetArchitecture().GetMachine() : llvm::Triple::InvalidArch;
|
||||
|
||||
switch (exc_type)
|
||||
{
|
||||
|
@ -306,8 +311,9 @@ StopInfoMachException::CreateStopReasonWithMachException
|
|||
|
||||
// It's a watchpoint, then.
|
||||
// The exc_sub_code indicates the data break address.
|
||||
lldb::WatchpointSP wp_sp =
|
||||
thread.GetProcess().GetTarget().GetWatchpointList().FindByAddress((lldb::addr_t)exc_sub_code);
|
||||
lldb::WatchpointSP wp_sp;
|
||||
if (target)
|
||||
wp_sp = target->GetWatchpointList().FindByAddress((lldb::addr_t)exc_sub_code);
|
||||
if (wp_sp)
|
||||
{
|
||||
// Debugserver may piggyback the hardware index of the fired watchpoint in the exception data.
|
||||
|
@ -345,7 +351,11 @@ StopInfoMachException::CreateStopReasonWithMachException
|
|||
if (is_software_breakpoint)
|
||||
{
|
||||
addr_t pc = thread.GetRegisterContext()->GetPC();
|
||||
lldb::BreakpointSiteSP bp_site_sp = thread.GetProcess().GetBreakpointSiteList().FindByAddress(pc);
|
||||
ProcessSP process_sp (thread.CalculateProcess());
|
||||
|
||||
lldb::BreakpointSiteSP bp_site_sp;
|
||||
if (process_sp)
|
||||
bp_site_sp = process_sp->GetBreakpointSiteList().FindByAddress(pc);
|
||||
if (bp_site_sp)
|
||||
{
|
||||
// If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread,
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
ThreadMemory::ThreadMemory (Process &process,
|
||||
ThreadMemory::ThreadMemory (const ProcessSP &process_sp,
|
||||
tid_t tid,
|
||||
const ValueObjectSP &thread_info_valobj_sp) :
|
||||
Thread (process, tid),
|
||||
Thread (process_sp, tid),
|
||||
m_thread_info_valobj_sp (thread_info_valobj_sp)
|
||||
{
|
||||
}
|
||||
|
@ -47,9 +47,13 @@ ThreadMemory::GetRegisterContext ()
|
|||
{
|
||||
if (!m_reg_context_sp)
|
||||
{
|
||||
OperatingSystem *os = m_process.GetOperatingSystem ();
|
||||
if (os)
|
||||
m_reg_context_sp = os->CreateRegisterContextForThread (this);
|
||||
ProcessSP process_sp (GetProcess());
|
||||
if (process_sp)
|
||||
{
|
||||
OperatingSystem *os = process_sp->GetOperatingSystem ();
|
||||
if (os)
|
||||
m_reg_context_sp = os->CreateRegisterContextForThread (this);
|
||||
}
|
||||
}
|
||||
return m_reg_context_sp;
|
||||
}
|
||||
|
@ -77,24 +81,29 @@ ThreadMemory::CreateRegisterContextForFrame (StackFrame *frame)
|
|||
lldb::StopInfoSP
|
||||
ThreadMemory::GetPrivateStopReason ()
|
||||
{
|
||||
const uint32_t process_stop_id = GetProcess().GetStopID();
|
||||
if (m_thread_stop_reason_stop_id != process_stop_id ||
|
||||
(m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
|
||||
ProcessSP process_sp (GetProcess());
|
||||
|
||||
if (process_sp)
|
||||
{
|
||||
// If GetGDBProcess().SetThreadStopInfo() doesn't find a stop reason
|
||||
// for this thread, then m_actual_stop_info_sp will not ever contain
|
||||
// a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false"
|
||||
// check will never be able to tell us if we have the correct stop info
|
||||
// for this thread and we will continually send qThreadStopInfo packets
|
||||
// down to the remote GDB server, so we need to keep our own notion
|
||||
// of the stop ID that m_actual_stop_info_sp is valid for (even if it
|
||||
// contains nothing). We use m_thread_stop_reason_stop_id for this below.
|
||||
m_thread_stop_reason_stop_id = process_stop_id;
|
||||
m_actual_stop_info_sp.reset();
|
||||
|
||||
OperatingSystem *os = m_process.GetOperatingSystem ();
|
||||
if (os)
|
||||
m_actual_stop_info_sp = os->CreateThreadStopReason (this);
|
||||
const uint32_t process_stop_id = process_sp->GetStopID();
|
||||
if (m_thread_stop_reason_stop_id != process_stop_id ||
|
||||
(m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
|
||||
{
|
||||
// If GetGDBProcess().SetThreadStopInfo() doesn't find a stop reason
|
||||
// for this thread, then m_actual_stop_info_sp will not ever contain
|
||||
// a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false"
|
||||
// check will never be able to tell us if we have the correct stop info
|
||||
// for this thread and we will continually send qThreadStopInfo packets
|
||||
// down to the remote GDB server, so we need to keep our own notion
|
||||
// of the stop ID that m_actual_stop_info_sp is valid for (even if it
|
||||
// contains nothing). We use m_thread_stop_reason_stop_id for this below.
|
||||
m_thread_stop_reason_stop_id = process_stop_id;
|
||||
m_actual_stop_info_sp.reset();
|
||||
|
||||
OperatingSystem *os = process_sp->GetOperatingSystem ();
|
||||
if (os)
|
||||
m_actual_stop_info_sp = os->CreateThreadStopReason (this);
|
||||
}
|
||||
}
|
||||
return m_actual_stop_info_sp;
|
||||
|
||||
|
|
|
@ -17,9 +17,9 @@ class ThreadMemory :
|
|||
{
|
||||
public:
|
||||
|
||||
ThreadMemory (lldb_private::Process &process,
|
||||
lldb::tid_t tid,
|
||||
const lldb::ValueObjectSP &thread_info_valobj_sp);
|
||||
ThreadMemory (const lldb::ProcessSP &process_sp,
|
||||
lldb::tid_t tid,
|
||||
const lldb::ValueObjectSP &thread_info_valobj_sp);
|
||||
|
||||
virtual
|
||||
~ThreadMemory();
|
||||
|
|
|
@ -42,7 +42,8 @@ UnwindLLDB::DoGetFrameCount()
|
|||
if (!AddFirstFrame ())
|
||||
return 0;
|
||||
|
||||
ABI *abi = m_thread.GetProcess().GetABI().get();
|
||||
ProcessSP process_sp (m_thread.GetProcess());
|
||||
ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
|
||||
|
||||
while (AddOneMoreFrame (abi))
|
||||
{
|
||||
|
@ -186,7 +187,8 @@ UnwindLLDB::DoGetFrameInfoAtIndex (uint32_t idx, addr_t& cfa, addr_t& pc)
|
|||
return false;
|
||||
}
|
||||
|
||||
ABI *abi = m_thread.GetProcess().GetABI().get();
|
||||
ProcessSP process_sp (m_thread.GetProcess());
|
||||
ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
|
||||
|
||||
while (idx >= m_frames.size() && AddOneMoreFrame (abi))
|
||||
;
|
||||
|
@ -217,7 +219,8 @@ UnwindLLDB::DoCreateRegisterContextForFrame (StackFrame *frame)
|
|||
return reg_ctx_sp;
|
||||
}
|
||||
|
||||
ABI *abi = m_thread.GetProcess().GetABI().get();
|
||||
ProcessSP process_sp (m_thread.GetProcess());
|
||||
ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
|
||||
|
||||
while (idx >= m_frames.size())
|
||||
{
|
||||
|
|
|
@ -12,9 +12,10 @@
|
|||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "lldb/Core/ArchSpec.h"
|
||||
#include "lldb/Target/Thread.h"
|
||||
#include "lldb/Target/ExecutionContext.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "lldb/Target/Thread.h"
|
||||
|
||||
#include "RegisterContextMacOSXFrameBackchain.h"
|
||||
|
||||
|
@ -32,14 +33,19 @@ UnwindMacOSXFrameBackchain::DoGetFrameCount()
|
|||
{
|
||||
if (m_cursors.empty())
|
||||
{
|
||||
const ArchSpec& target_arch = m_thread.GetProcess().GetTarget().GetArchitecture ();
|
||||
// Frame zero should always be supplied by the thread...
|
||||
StackFrameSP frame_sp (m_thread.GetStackFrameAtIndex (0));
|
||||
|
||||
if (target_arch.GetAddressByteSize() == 8)
|
||||
GetStackFrameData_x86_64 (frame_sp.get());
|
||||
else
|
||||
GetStackFrameData_i386 (frame_sp.get());
|
||||
ExecutionContext exe_ctx (m_thread.shared_from_this());
|
||||
Target *target = exe_ctx.GetTargetPtr();
|
||||
if (target)
|
||||
{
|
||||
const ArchSpec& target_arch = target->GetArchitecture ();
|
||||
// Frame zero should always be supplied by the thread...
|
||||
exe_ctx.SetFrameSP (m_thread.GetStackFrameAtIndex (0));
|
||||
|
||||
if (target_arch.GetAddressByteSize() == 8)
|
||||
GetStackFrameData_x86_64 (exe_ctx);
|
||||
else
|
||||
GetStackFrameData_i386 (exe_ctx);
|
||||
}
|
||||
}
|
||||
return m_cursors.size();
|
||||
}
|
||||
|
@ -75,10 +81,16 @@ UnwindMacOSXFrameBackchain::DoCreateRegisterContextForFrame (StackFrame *frame)
|
|||
}
|
||||
|
||||
size_t
|
||||
UnwindMacOSXFrameBackchain::GetStackFrameData_i386 (StackFrame *first_frame)
|
||||
UnwindMacOSXFrameBackchain::GetStackFrameData_i386 (const ExecutionContext &exe_ctx)
|
||||
{
|
||||
m_cursors.clear();
|
||||
|
||||
StackFrame *first_frame = exe_ctx.GetFramePtr();
|
||||
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
if (process == NULL)
|
||||
return 0;
|
||||
|
||||
std::pair<lldb::addr_t, lldb::addr_t> fp_pc_pair;
|
||||
|
||||
struct Frame_i386
|
||||
|
@ -103,7 +115,7 @@ UnwindMacOSXFrameBackchain::GetStackFrameData_i386 (StackFrame *first_frame)
|
|||
while (frame.fp != 0 && frame.pc != 0 && ((frame.fp & 7) == 0))
|
||||
{
|
||||
// Read both the FP and PC (8 bytes)
|
||||
if (m_thread.GetProcess().ReadMemory (frame.fp, &frame.fp, k_frame_size, error) != k_frame_size)
|
||||
if (process->ReadMemory (frame.fp, &frame.fp, k_frame_size, error) != k_frame_size)
|
||||
break;
|
||||
if (frame.pc >= 0x1000)
|
||||
{
|
||||
|
@ -137,7 +149,7 @@ UnwindMacOSXFrameBackchain::GetStackFrameData_i386 (StackFrame *first_frame)
|
|||
// previous PC by dereferencing the SP
|
||||
lldb::addr_t first_frame_sp = reg_ctx->GetSP (0);
|
||||
// Read the real second frame return address into frame.pc
|
||||
if (first_frame_sp && m_thread.GetProcess().ReadMemory (first_frame_sp, &frame.pc, sizeof(frame.pc), error) == sizeof(frame.pc))
|
||||
if (first_frame_sp && process->ReadMemory (first_frame_sp, &frame.pc, sizeof(frame.pc), error) == sizeof(frame.pc))
|
||||
{
|
||||
cursor.fp = m_cursors.front().fp;
|
||||
cursor.pc = frame.pc; // Set the new second frame PC
|
||||
|
@ -163,10 +175,16 @@ UnwindMacOSXFrameBackchain::GetStackFrameData_i386 (StackFrame *first_frame)
|
|||
|
||||
|
||||
size_t
|
||||
UnwindMacOSXFrameBackchain::GetStackFrameData_x86_64 (StackFrame *first_frame)
|
||||
UnwindMacOSXFrameBackchain::GetStackFrameData_x86_64 (const ExecutionContext &exe_ctx)
|
||||
{
|
||||
m_cursors.clear();
|
||||
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
if (process == NULL)
|
||||
return 0;
|
||||
|
||||
StackFrame *first_frame = exe_ctx.GetFramePtr();
|
||||
|
||||
std::pair<lldb::addr_t, lldb::addr_t> fp_pc_pair;
|
||||
|
||||
struct Frame_x86_64
|
||||
|
@ -190,7 +208,7 @@ UnwindMacOSXFrameBackchain::GetStackFrameData_x86_64 (StackFrame *first_frame)
|
|||
while (frame.fp != 0 && frame.pc != 0 && ((frame.fp & 7) == 0))
|
||||
{
|
||||
// Read both the FP and PC (16 bytes)
|
||||
if (m_thread.GetProcess().ReadMemory (frame.fp, &frame.fp, k_frame_size, error) != k_frame_size)
|
||||
if (process->ReadMemory (frame.fp, &frame.fp, k_frame_size, error) != k_frame_size)
|
||||
break;
|
||||
|
||||
if (frame.pc >= 0x1000)
|
||||
|
@ -225,7 +243,7 @@ UnwindMacOSXFrameBackchain::GetStackFrameData_x86_64 (StackFrame *first_frame)
|
|||
// previous PC by dereferencing the SP
|
||||
lldb::addr_t first_frame_sp = reg_ctx->GetSP (0);
|
||||
// Read the real second frame return address into frame.pc
|
||||
if (m_thread.GetProcess().ReadMemory (first_frame_sp, &frame.pc, sizeof(frame.pc), error) == sizeof(frame.pc))
|
||||
if (process->ReadMemory (first_frame_sp, &frame.pc, sizeof(frame.pc), error) == sizeof(frame.pc))
|
||||
{
|
||||
cursor.fp = m_cursors.front().fp;
|
||||
cursor.pc = frame.pc; // Set the new second frame PC
|
||||
|
|
|
@ -60,10 +60,10 @@ private:
|
|||
std::vector<Cursor> m_cursors;
|
||||
|
||||
size_t
|
||||
GetStackFrameData_i386 (lldb_private::StackFrame *first_frame);
|
||||
GetStackFrameData_i386 (const lldb_private::ExecutionContext &exe_ctx);
|
||||
|
||||
size_t
|
||||
GetStackFrameData_x86_64 (lldb_private::StackFrame *first_frame);
|
||||
GetStackFrameData_x86_64 (const lldb_private::ExecutionContext &exe_ctx);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// For UnwindMacOSXFrameBackchain only
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "lldb/Core/RegisterValue.h"
|
||||
#include "lldb/Core/Scalar.h"
|
||||
#include "lldb/Core/StreamString.h"
|
||||
#include "lldb/Target/ExecutionContext.h"
|
||||
// Project includes
|
||||
#include "Utility/StringExtractorGDBRemote.h"
|
||||
#include "ProcessGDBRemote.h"
|
||||
|
@ -61,18 +62,6 @@ GDBRemoteRegisterContext::~GDBRemoteRegisterContext()
|
|||
{
|
||||
}
|
||||
|
||||
ProcessGDBRemote &
|
||||
GDBRemoteRegisterContext::GetGDBProcess()
|
||||
{
|
||||
return static_cast<ProcessGDBRemote &>(m_thread.GetProcess());
|
||||
}
|
||||
|
||||
ThreadGDBRemote &
|
||||
GDBRemoteRegisterContext::GetGDBThread()
|
||||
{
|
||||
return static_cast<ThreadGDBRemote &>(m_thread);
|
||||
}
|
||||
|
||||
void
|
||||
GDBRemoteRegisterContext::InvalidateAllRegisters ()
|
||||
{
|
||||
|
@ -158,7 +147,14 @@ GDBRemoteRegisterContext::PrivateSetRegisterValue (uint32_t reg, StringExtractor
|
|||
bool
|
||||
GDBRemoteRegisterContext::ReadRegisterBytes (const RegisterInfo *reg_info, DataExtractor &data)
|
||||
{
|
||||
GDBRemoteCommunicationClient &gdb_comm (GetGDBProcess().GetGDBRemote());
|
||||
ExecutionContext exe_ctx (CalculateThread());
|
||||
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
Thread *thread = exe_ctx.GetThreadPtr();
|
||||
if (process == NULL || thread == NULL)
|
||||
return false;
|
||||
|
||||
GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
|
||||
|
||||
InvalidateIfNeeded(false);
|
||||
|
||||
|
@ -170,7 +166,8 @@ GDBRemoteRegisterContext::ReadRegisterBytes (const RegisterInfo *reg_info, DataE
|
|||
if (gdb_comm.GetSequenceMutex (locker))
|
||||
{
|
||||
const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
|
||||
if (thread_suffix_supported || GetGDBProcess().GetGDBRemote().SetCurrentThread(m_thread.GetID()))
|
||||
ProcessSP process_sp (m_thread.GetProcess());
|
||||
if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetID()))
|
||||
{
|
||||
char packet[64];
|
||||
StringExtractorGDBRemote response;
|
||||
|
@ -238,7 +235,14 @@ GDBRemoteRegisterContext::WriteRegister (const RegisterInfo *reg_info,
|
|||
bool
|
||||
GDBRemoteRegisterContext::WriteRegisterBytes (const lldb_private::RegisterInfo *reg_info, DataExtractor &data, uint32_t data_offset)
|
||||
{
|
||||
GDBRemoteCommunicationClient &gdb_comm (GetGDBProcess().GetGDBRemote());
|
||||
ExecutionContext exe_ctx (CalculateThread());
|
||||
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
Thread *thread = exe_ctx.GetThreadPtr();
|
||||
if (process == NULL || thread == NULL)
|
||||
return false;
|
||||
|
||||
GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
|
||||
// FIXME: This check isn't right because IsRunning checks the Public state, but this
|
||||
// is work you need to do - for instance in ShouldStop & friends - before the public
|
||||
// state has been changed.
|
||||
|
@ -264,7 +268,8 @@ GDBRemoteRegisterContext::WriteRegisterBytes (const lldb_private::RegisterInfo *
|
|||
if (gdb_comm.GetSequenceMutex (locker))
|
||||
{
|
||||
const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
|
||||
if (thread_suffix_supported || GetGDBProcess().GetGDBRemote().SetCurrentThread(m_thread.GetID()))
|
||||
ProcessSP process_sp (m_thread.GetProcess());
|
||||
if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetID()))
|
||||
{
|
||||
uint32_t offset, end_offset;
|
||||
StreamString packet;
|
||||
|
@ -334,7 +339,15 @@ GDBRemoteRegisterContext::WriteRegisterBytes (const lldb_private::RegisterInfo *
|
|||
bool
|
||||
GDBRemoteRegisterContext::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
|
||||
{
|
||||
GDBRemoteCommunicationClient &gdb_comm (GetGDBProcess().GetGDBRemote());
|
||||
ExecutionContext exe_ctx (CalculateThread());
|
||||
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
Thread *thread = exe_ctx.GetThreadPtr();
|
||||
if (process == NULL || thread == NULL)
|
||||
return false;
|
||||
|
||||
GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
|
||||
|
||||
StringExtractorGDBRemote response;
|
||||
|
||||
Mutex::Locker locker;
|
||||
|
@ -342,7 +355,8 @@ GDBRemoteRegisterContext::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
|
|||
{
|
||||
char packet[32];
|
||||
const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
|
||||
if (thread_suffix_supported || GetGDBProcess().GetGDBRemote().SetCurrentThread(m_thread.GetID()))
|
||||
ProcessSP process_sp (m_thread.GetProcess());
|
||||
if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetID()))
|
||||
{
|
||||
int packet_len = 0;
|
||||
if (thread_suffix_supported)
|
||||
|
@ -382,13 +396,22 @@ GDBRemoteRegisterContext::WriteAllRegisterValues (const lldb::DataBufferSP &data
|
|||
if (!data_sp || data_sp->GetBytes() == NULL || data_sp->GetByteSize() == 0)
|
||||
return false;
|
||||
|
||||
GDBRemoteCommunicationClient &gdb_comm (GetGDBProcess().GetGDBRemote());
|
||||
ExecutionContext exe_ctx (CalculateThread());
|
||||
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
Thread *thread = exe_ctx.GetThreadPtr();
|
||||
if (process == NULL || thread == NULL)
|
||||
return false;
|
||||
|
||||
GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
|
||||
|
||||
StringExtractorGDBRemote response;
|
||||
Mutex::Locker locker;
|
||||
if (gdb_comm.GetSequenceMutex (locker))
|
||||
{
|
||||
const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
|
||||
if (thread_suffix_supported || GetGDBProcess().GetGDBRemote().SetCurrentThread(m_thread.GetID()))
|
||||
ProcessSP process_sp (m_thread.GetProcess());
|
||||
if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetID()))
|
||||
{
|
||||
// The data_sp contains the entire G response packet including the
|
||||
// G, and if the thread suffix is supported, it has the thread suffix
|
||||
|
|
|
@ -240,12 +240,6 @@ protected:
|
|||
void
|
||||
SetAllRegisterValid (bool b);
|
||||
|
||||
ProcessGDBRemote &
|
||||
GetGDBProcess();
|
||||
|
||||
ThreadGDBRemote &
|
||||
GetGDBThread();
|
||||
|
||||
GDBRemoteDynamicRegisterInfo &m_reg_info;
|
||||
std::vector<bool> m_reg_valid;
|
||||
lldb_private::DataExtractor m_reg_data;
|
||||
|
|
|
@ -1125,7 +1125,7 @@ ProcessGDBRemote::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new
|
|||
tid_t tid = thread_ids[i];
|
||||
ThreadSP thread_sp (old_thread_list.FindThreadByID (tid, false));
|
||||
if (!thread_sp)
|
||||
thread_sp.reset (new ThreadGDBRemote (*this, tid));
|
||||
thread_sp.reset (new ThreadGDBRemote (shared_from_this(), tid));
|
||||
new_thread_list.AddThread(thread_sp);
|
||||
}
|
||||
}
|
||||
|
@ -1201,7 +1201,7 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
|
|||
if (!thread_sp)
|
||||
{
|
||||
// Create the thread if we need to
|
||||
thread_sp.reset (new ThreadGDBRemote (*this, tid));
|
||||
thread_sp.reset (new ThreadGDBRemote (shared_from_this(), tid));
|
||||
m_thread_list.AddThread(thread_sp);
|
||||
}
|
||||
}
|
||||
|
@ -1292,7 +1292,7 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
|
|||
else if (reason.compare("breakpoint") == 0)
|
||||
{
|
||||
addr_t pc = gdb_thread->GetRegisterContext()->GetPC();
|
||||
lldb::BreakpointSiteSP bp_site_sp = gdb_thread->GetProcess().GetBreakpointSiteList().FindByAddress(pc);
|
||||
lldb::BreakpointSiteSP bp_site_sp = gdb_thread->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
|
||||
if (bp_site_sp)
|
||||
{
|
||||
// If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread,
|
||||
|
@ -1335,7 +1335,7 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
|
|||
// Currently we are going to assume SIGTRAP means we are either
|
||||
// hitting a breakpoint or hardware single stepping.
|
||||
addr_t pc = gdb_thread->GetRegisterContext()->GetPC();
|
||||
lldb::BreakpointSiteSP bp_site_sp = gdb_thread->GetProcess().GetBreakpointSiteList().FindByAddress(pc);
|
||||
lldb::BreakpointSiteSP bp_site_sp = gdb_thread->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
|
||||
if (bp_site_sp)
|
||||
{
|
||||
// If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread,
|
||||
|
|
|
@ -32,18 +32,25 @@ using namespace lldb_private;
|
|||
// Thread Registers
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
ThreadGDBRemote::ThreadGDBRemote (ProcessGDBRemote &process, lldb::tid_t tid) :
|
||||
Thread(process, tid),
|
||||
ThreadGDBRemote::ThreadGDBRemote (const ProcessSP &process_sp, lldb::tid_t tid) :
|
||||
Thread(process_sp, tid),
|
||||
m_thread_name (),
|
||||
m_dispatch_queue_name (),
|
||||
m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS)
|
||||
{
|
||||
ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", this, m_process.GetID(), GetID());
|
||||
ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::ThreadGDBRemote (pid = %i, tid = 0x%4.4x)",
|
||||
this,
|
||||
process_sp ? process_sp->GetID() : LLDB_INVALID_PROCESS_ID,
|
||||
GetID());
|
||||
}
|
||||
|
||||
ThreadGDBRemote::~ThreadGDBRemote ()
|
||||
{
|
||||
ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::~ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", this, m_process.GetID(), GetID());
|
||||
ProcessSP process_sp(GetProcess());
|
||||
ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::~ThreadGDBRemote (pid = %i, tid = 0x%4.4x)",
|
||||
this,
|
||||
process_sp ? process_sp->GetID() : LLDB_INVALID_PROCESS_ID,
|
||||
GetID());
|
||||
DestroyThread();
|
||||
}
|
||||
|
||||
|
@ -60,8 +67,16 @@ const char *
|
|||
ThreadGDBRemote::GetQueueName ()
|
||||
{
|
||||
// Always re-fetch the dispatch queue name since it can change
|
||||
|
||||
if (m_thread_dispatch_qaddr != 0 || m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS)
|
||||
return GetGDBProcess().GetDispatchQueueNameForThread (m_thread_dispatch_qaddr, m_dispatch_queue_name);
|
||||
{
|
||||
ProcessSP process_sp (GetProcess());
|
||||
if (process_sp)
|
||||
{
|
||||
ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get());
|
||||
return gdb_process->GetDispatchQueueNameForThread (m_thread_dispatch_qaddr, m_dispatch_queue_name);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -79,32 +94,37 @@ ThreadGDBRemote::WillResume (StateType resume_state)
|
|||
if (log)
|
||||
log->Printf ("Resuming thread: %4.4llx with state: %s.", GetID(), StateAsCString(resume_state));
|
||||
|
||||
ProcessGDBRemote &process = GetGDBProcess();
|
||||
switch (resume_state)
|
||||
ProcessSP process_sp (GetProcess());
|
||||
if (process_sp)
|
||||
{
|
||||
case eStateSuspended:
|
||||
case eStateStopped:
|
||||
// Don't append anything for threads that should stay stopped.
|
||||
break;
|
||||
ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get());
|
||||
switch (resume_state)
|
||||
{
|
||||
case eStateSuspended:
|
||||
case eStateStopped:
|
||||
// Don't append anything for threads that should stay stopped.
|
||||
break;
|
||||
|
||||
case eStateRunning:
|
||||
if (m_process.GetUnixSignals().SignalIsValid (signo))
|
||||
process.m_continue_C_tids.push_back(std::make_pair(GetID(), signo));
|
||||
else
|
||||
process.m_continue_c_tids.push_back(GetID());
|
||||
break;
|
||||
case eStateRunning:
|
||||
if (gdb_process->GetUnixSignals().SignalIsValid (signo))
|
||||
gdb_process->m_continue_C_tids.push_back(std::make_pair(GetID(), signo));
|
||||
else
|
||||
gdb_process->m_continue_c_tids.push_back(GetID());
|
||||
break;
|
||||
|
||||
case eStateStepping:
|
||||
if (m_process.GetUnixSignals().SignalIsValid (signo))
|
||||
process.m_continue_S_tids.push_back(std::make_pair(GetID(), signo));
|
||||
else
|
||||
process.m_continue_s_tids.push_back(GetID());
|
||||
break;
|
||||
case eStateStepping:
|
||||
if (gdb_process->GetUnixSignals().SignalIsValid (signo))
|
||||
gdb_process->m_continue_S_tids.push_back(std::make_pair(GetID(), signo));
|
||||
else
|
||||
gdb_process->m_continue_s_tids.push_back(GetID());
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -167,8 +187,16 @@ ThreadGDBRemote::CreateRegisterContextForFrame (StackFrame *frame)
|
|||
if (frame)
|
||||
concrete_frame_idx = frame->GetConcreteFrameIndex ();
|
||||
|
||||
|
||||
if (concrete_frame_idx == 0)
|
||||
reg_ctx_sp.reset (new GDBRemoteRegisterContext (*this, concrete_frame_idx, GetGDBProcess().m_register_info, read_all_registers_at_once));
|
||||
{
|
||||
ProcessSP process_sp (GetProcess());
|
||||
if (process_sp)
|
||||
{
|
||||
ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get());
|
||||
reg_ctx_sp.reset (new GDBRemoteRegisterContext (*this, concrete_frame_idx, gdb_process->m_register_info, read_all_registers_at_once));
|
||||
}
|
||||
}
|
||||
else if (m_unwinder_ap.get())
|
||||
reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame);
|
||||
return reg_ctx_sp;
|
||||
|
@ -185,25 +213,29 @@ ThreadGDBRemote::PrivateSetRegisterValue (uint32_t reg, StringExtractor &respons
|
|||
lldb::StopInfoSP
|
||||
ThreadGDBRemote::GetPrivateStopReason ()
|
||||
{
|
||||
const uint32_t process_stop_id = GetProcess().GetStopID();
|
||||
if (m_thread_stop_reason_stop_id != process_stop_id ||
|
||||
(m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
|
||||
ProcessSP process_sp (GetProcess());
|
||||
if (process_sp)
|
||||
{
|
||||
// If GetGDBProcess().SetThreadStopInfo() doesn't find a stop reason
|
||||
// for this thread, then m_actual_stop_info_sp will not ever contain
|
||||
// a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false"
|
||||
// check will never be able to tell us if we have the correct stop info
|
||||
// for this thread and we will continually send qThreadStopInfo packets
|
||||
// down to the remote GDB server, so we need to keep our own notion
|
||||
// of the stop ID that m_actual_stop_info_sp is valid for (even if it
|
||||
// contains nothing). We use m_thread_stop_reason_stop_id for this below.
|
||||
m_thread_stop_reason_stop_id = process_stop_id;
|
||||
m_actual_stop_info_sp.reset();
|
||||
const uint32_t process_stop_id = process_sp->GetStopID();
|
||||
if (m_thread_stop_reason_stop_id != process_stop_id ||
|
||||
(m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
|
||||
{
|
||||
// If GetGDBProcess().SetThreadStopInfo() doesn't find a stop reason
|
||||
// for this thread, then m_actual_stop_info_sp will not ever contain
|
||||
// a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false"
|
||||
// check will never be able to tell us if we have the correct stop info
|
||||
// for this thread and we will continually send qThreadStopInfo packets
|
||||
// down to the remote GDB server, so we need to keep our own notion
|
||||
// of the stop ID that m_actual_stop_info_sp is valid for (even if it
|
||||
// contains nothing). We use m_thread_stop_reason_stop_id for this below.
|
||||
m_thread_stop_reason_stop_id = process_stop_id;
|
||||
m_actual_stop_info_sp.reset();
|
||||
|
||||
StringExtractorGDBRemote stop_packet;
|
||||
ProcessGDBRemote &gdb_process = GetGDBProcess();
|
||||
if (gdb_process.GetGDBRemote().GetThreadStopInfo(GetID(), stop_packet))
|
||||
gdb_process.SetThreadStopInfo (stop_packet);
|
||||
StringExtractorGDBRemote stop_packet;
|
||||
ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get());
|
||||
if (gdb_process->GetGDBRemote().GetThreadStopInfo(GetID(), stop_packet))
|
||||
gdb_process->SetThreadStopInfo (stop_packet);
|
||||
}
|
||||
}
|
||||
return m_actual_stop_info_sp;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ class ProcessGDBRemote;
|
|||
class ThreadGDBRemote : public lldb_private::Thread
|
||||
{
|
||||
public:
|
||||
ThreadGDBRemote (ProcessGDBRemote &process, lldb::tid_t tid);
|
||||
ThreadGDBRemote (const lldb::ProcessSP &process_sp, lldb::tid_t tid);
|
||||
|
||||
virtual
|
||||
~ThreadGDBRemote ();
|
||||
|
@ -47,18 +47,6 @@ public:
|
|||
virtual void
|
||||
ClearStackFrames ();
|
||||
|
||||
ProcessGDBRemote &
|
||||
GetGDBProcess ()
|
||||
{
|
||||
return (ProcessGDBRemote &)m_process;
|
||||
}
|
||||
|
||||
const ProcessGDBRemote &
|
||||
GetGDBProcess () const
|
||||
{
|
||||
return (ProcessGDBRemote &)m_process;
|
||||
}
|
||||
|
||||
void
|
||||
Dump (lldb_private::Log *log, uint32_t index);
|
||||
|
||||
|
|
|
@ -354,7 +354,7 @@ ProcessMachCore::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_
|
|||
const uint32_t num_threads = core_objfile->GetNumThreadContexts ();
|
||||
for (lldb::tid_t tid = 0; tid < num_threads; ++tid)
|
||||
{
|
||||
ThreadSP thread_sp(new ThreadMachCore (*this, tid));
|
||||
ThreadSP thread_sp(new ThreadMachCore (shared_from_this(), tid));
|
||||
new_thread_list.AddThread (thread_sp);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,11 +35,12 @@ using namespace lldb_private;
|
|||
// Thread Registers
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
ThreadMachCore::ThreadMachCore (ProcessMachCore &process, lldb::tid_t tid) :
|
||||
Thread(process, tid),
|
||||
ThreadMachCore::ThreadMachCore (const lldb::ProcessSP &process_sp, lldb::tid_t tid) :
|
||||
Thread(process_sp, tid),
|
||||
m_thread_name (),
|
||||
m_dispatch_queue_name (),
|
||||
m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS)
|
||||
m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS),
|
||||
m_thread_reg_ctx_sp ()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -106,38 +107,51 @@ ThreadMachCore::CreateRegisterContextForFrame (StackFrame *frame)
|
|||
|
||||
if (concrete_frame_idx == 0)
|
||||
{
|
||||
ObjectFile *core_objfile = GetMachCoreProcess ().GetCoreObjectFile ();
|
||||
if (core_objfile)
|
||||
reg_ctx_sp = core_objfile->GetThreadContextAtIndex (GetID(), *this);
|
||||
if (!m_thread_reg_ctx_sp)
|
||||
{
|
||||
ProcessSP process_sp (GetProcess());
|
||||
|
||||
ObjectFile *core_objfile = static_cast<ProcessMachCore *>(process_sp.get())->GetCoreObjectFile ();
|
||||
if (core_objfile)
|
||||
m_thread_reg_ctx_sp = core_objfile->GetThreadContextAtIndex (GetID(), *this);
|
||||
}
|
||||
reg_ctx_sp = m_thread_reg_ctx_sp;
|
||||
}
|
||||
else if (m_unwinder_ap.get())
|
||||
{
|
||||
reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame);
|
||||
}
|
||||
return reg_ctx_sp;
|
||||
}
|
||||
|
||||
lldb::StopInfoSP
|
||||
ThreadMachCore::GetPrivateStopReason ()
|
||||
{
|
||||
const uint32_t process_stop_id = GetProcess().GetStopID();
|
||||
if (m_thread_stop_reason_stop_id != process_stop_id ||
|
||||
(m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
|
||||
ProcessSP process_sp (GetProcess());
|
||||
|
||||
if (process_sp)
|
||||
{
|
||||
// TODO: can we query the initial state of the thread here?
|
||||
// For now I am just going to pretend that a SIGSTOP happened.
|
||||
const uint32_t process_stop_id = process_sp->GetStopID();
|
||||
if (m_thread_stop_reason_stop_id != process_stop_id ||
|
||||
(m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
|
||||
{
|
||||
// TODO: can we query the initial state of the thread here?
|
||||
// For now I am just going to pretend that a SIGSTOP happened.
|
||||
|
||||
SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, SIGSTOP));
|
||||
SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, SIGSTOP));
|
||||
|
||||
// If GetKDPProcess().SetThreadStopInfo() doesn't find a stop reason
|
||||
// for this thread, then m_actual_stop_info_sp will not ever contain
|
||||
// a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false"
|
||||
// check will never be able to tell us if we have the correct stop info
|
||||
// for this thread and we will continually send qThreadStopInfo packets
|
||||
// down to the remote KDP server, so we need to keep our own notion
|
||||
// of the stop ID that m_actual_stop_info_sp is valid for (even if it
|
||||
// contains nothing). We use m_thread_stop_reason_stop_id for this below.
|
||||
// m_thread_stop_reason_stop_id = process_stop_id;
|
||||
// m_actual_stop_info_sp.reset();
|
||||
// If GetKDPProcess().SetThreadStopInfo() doesn't find a stop reason
|
||||
// for this thread, then m_actual_stop_info_sp will not ever contain
|
||||
// a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false"
|
||||
// check will never be able to tell us if we have the correct stop info
|
||||
// for this thread and we will continually send qThreadStopInfo packets
|
||||
// down to the remote KDP server, so we need to keep our own notion
|
||||
// of the stop ID that m_actual_stop_info_sp is valid for (even if it
|
||||
// contains nothing). We use m_thread_stop_reason_stop_id for this below.
|
||||
// m_thread_stop_reason_stop_id = process_stop_id;
|
||||
// m_actual_stop_info_sp.reset();
|
||||
|
||||
}
|
||||
}
|
||||
return m_actual_stop_info_sp;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ class ProcessMachCore;
|
|||
class ThreadMachCore : public lldb_private::Thread
|
||||
{
|
||||
public:
|
||||
ThreadMachCore (ProcessMachCore &process,
|
||||
ThreadMachCore (const lldb::ProcessSP &process_sp,
|
||||
lldb::tid_t tid);
|
||||
|
||||
virtual
|
||||
|
@ -40,12 +40,6 @@ public:
|
|||
virtual void
|
||||
ClearStackFrames ();
|
||||
|
||||
ProcessMachCore &
|
||||
GetMachCoreProcess ()
|
||||
{
|
||||
return (ProcessMachCore &)m_process;
|
||||
}
|
||||
|
||||
static bool
|
||||
ThreadIDIsValid (lldb::tid_t thread);
|
||||
|
||||
|
@ -86,6 +80,7 @@ protected:
|
|||
std::string m_thread_name;
|
||||
std::string m_dispatch_queue_name;
|
||||
lldb::addr_t m_thread_dispatch_qaddr;
|
||||
lldb::RegisterContextSP m_thread_reg_ctx_sp;
|
||||
//------------------------------------------------------------------
|
||||
// Member variables.
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -133,7 +133,7 @@ UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly (AddressRange&
|
|||
if (log && log->GetVerbose ())
|
||||
{
|
||||
StreamString strm;
|
||||
lldb::addr_t base_addr = range.GetBaseAddress().GetLoadAddress(&thread.GetProcess().GetTarget());
|
||||
lldb::addr_t base_addr = range.GetBaseAddress().GetLoadAddress(thread.CalculateTarget().get());
|
||||
strm.Printf ("Resulting unwind rows for [0x%llx - 0x%llx):", base_addr, base_addr + range.GetByteSize());
|
||||
unwind_plan.Dump(strm, &thread, base_addr);
|
||||
log->PutCString (strm.GetData());
|
||||
|
@ -153,8 +153,7 @@ UnwindAssemblyInstEmulation::GetFastUnwindPlan (AddressRange& func,
|
|||
|
||||
bool
|
||||
UnwindAssemblyInstEmulation::FirstNonPrologueInsn (AddressRange& func,
|
||||
Target& target,
|
||||
Thread* thread,
|
||||
const ExecutionContext &exe_ctx,
|
||||
Address& first_non_prologue_insn)
|
||||
{
|
||||
return false;
|
||||
|
|
|
@ -38,8 +38,7 @@ public:
|
|||
// thread may be NULL in which case we only use the Target (e.g. if this is called pre-process-launch).
|
||||
virtual bool
|
||||
FirstNonPrologueInsn (lldb_private::AddressRange& func,
|
||||
lldb_private::Target& target,
|
||||
lldb_private::Thread* thread,
|
||||
const lldb_private::ExecutionContext &exe_ctx,
|
||||
lldb_private::Address& first_non_prologue_insn);
|
||||
|
||||
static lldb_private::UnwindAssembly *
|
||||
|
|
|
@ -117,7 +117,7 @@ static int x86_64_register_map_initialized = 0;
|
|||
class AssemblyParse_x86 {
|
||||
public:
|
||||
|
||||
AssemblyParse_x86 (Target &target, Thread *thread, int cpu, AddressRange func);
|
||||
AssemblyParse_x86 (const ExecutionContext &exe_ctx, int cpu, AddressRange func);
|
||||
|
||||
bool get_non_call_site_unwind_plan (UnwindPlan &unwind_plan);
|
||||
|
||||
|
@ -140,8 +140,7 @@ private:
|
|||
bool machine_regno_to_lldb_regno (int machine_regno, uint32_t& lldb_regno);
|
||||
bool instruction_length (Address addr, int &length);
|
||||
|
||||
Target &m_target;
|
||||
Thread* m_thread;
|
||||
const ExecutionContext m_exe_ctx;
|
||||
|
||||
AddressRange m_func_bounds;
|
||||
|
||||
|
@ -162,14 +161,20 @@ private:
|
|||
DISALLOW_COPY_AND_ASSIGN (AssemblyParse_x86);
|
||||
};
|
||||
|
||||
AssemblyParse_x86::AssemblyParse_x86 (Target& target, Thread* thread, int cpu, AddressRange func) :
|
||||
m_target (target), m_thread (thread), m_func_bounds(func), m_cur_insn (),
|
||||
m_machine_ip_regnum (-1), m_machine_sp_regnum (-1), m_machine_fp_regnum (-1),
|
||||
m_lldb_ip_regnum (-1), m_lldb_sp_regnum (-1), m_lldb_fp_regnum (-1),
|
||||
m_wordsize (-1), m_cpu(cpu)
|
||||
AssemblyParse_x86::AssemblyParse_x86 (const ExecutionContext &exe_ctx, int cpu, AddressRange func) :
|
||||
m_exe_ctx (exe_ctx),
|
||||
m_func_bounds(func),
|
||||
m_cur_insn (),
|
||||
m_machine_ip_regnum (LLDB_INVALID_REGNUM),
|
||||
m_machine_sp_regnum (LLDB_INVALID_REGNUM),
|
||||
m_machine_fp_regnum (LLDB_INVALID_REGNUM),
|
||||
m_lldb_ip_regnum (LLDB_INVALID_REGNUM),
|
||||
m_lldb_sp_regnum (LLDB_INVALID_REGNUM),
|
||||
m_lldb_fp_regnum (LLDB_INVALID_REGNUM),
|
||||
m_wordsize (-1),
|
||||
m_cpu(cpu)
|
||||
{
|
||||
int *initialized_flag = NULL;
|
||||
m_lldb_ip_regnum = m_lldb_sp_regnum = m_lldb_fp_regnum = -1;
|
||||
if (cpu == k_i386)
|
||||
{
|
||||
m_machine_ip_regnum = k_machine_eip;
|
||||
|
@ -191,9 +196,10 @@ AssemblyParse_x86::AssemblyParse_x86 (Target& target, Thread* thread, int cpu, A
|
|||
if (m_func_bounds.GetByteSize() == 0)
|
||||
m_func_bounds.SetByteSize(512);
|
||||
|
||||
if (m_thread && *initialized_flag == 0)
|
||||
Thread *thread = m_exe_ctx.GetThreadPtr();
|
||||
if (thread && *initialized_flag == 0)
|
||||
{
|
||||
RegisterContext *reg_ctx = m_thread->GetRegisterContext().get();
|
||||
RegisterContext *reg_ctx = thread->GetRegisterContext().get();
|
||||
if (reg_ctx)
|
||||
{
|
||||
struct regmap_ent *ent;
|
||||
|
@ -501,7 +507,7 @@ AssemblyParse_x86::instruction_length (Address addr, int &length)
|
|||
} InitializeLLVM;
|
||||
|
||||
EDDisassemblerRef disasm;
|
||||
EDInstRef cur_insn;
|
||||
EDInstRef cur_insn;
|
||||
|
||||
if (EDGetDisassembler (&disasm, triple, kEDAssemblySyntaxX86ATT) != 0)
|
||||
{
|
||||
|
@ -511,7 +517,7 @@ AssemblyParse_x86::instruction_length (Address addr, int &length)
|
|||
uint64_t addr_offset = addr.GetOffset();
|
||||
struct edis_byte_read_token arg;
|
||||
arg.address = &addr;
|
||||
arg.target = &m_target;
|
||||
arg.target = m_exe_ctx.GetTargetPtr();
|
||||
if (EDCreateInsts (&cur_insn, 1, disasm, read_byte_for_edis, addr_offset, &arg) != 1)
|
||||
{
|
||||
return false;
|
||||
|
@ -558,6 +564,7 @@ AssemblyParse_x86::get_non_call_site_unwind_plan (UnwindPlan &unwind_plan)
|
|||
unwind_plan.AppendRow (row);
|
||||
const bool prefer_file_cache = true;
|
||||
|
||||
Target *target = m_exe_ctx.GetTargetPtr();
|
||||
while (m_func_bounds.ContainsFileAddress (m_cur_insn) && non_prologue_insn_count < 10)
|
||||
{
|
||||
int stack_offset, insn_len;
|
||||
|
@ -569,7 +576,7 @@ AssemblyParse_x86::get_non_call_site_unwind_plan (UnwindPlan &unwind_plan)
|
|||
// An unrecognized/junk instruction
|
||||
break;
|
||||
}
|
||||
if (m_target.ReadMemory (m_cur_insn, prefer_file_cache, m_cur_insn_bytes, insn_len, error) == -1)
|
||||
if (target->ReadMemory (m_cur_insn, prefer_file_cache, m_cur_insn_bytes, insn_len, error) == -1)
|
||||
{
|
||||
// Error reading the instruction out of the file, stop scanning
|
||||
break;
|
||||
|
@ -679,7 +686,7 @@ loopnext:
|
|||
Address last_insn (m_func_bounds.GetBaseAddress());
|
||||
last_insn.SetOffset (last_insn.GetOffset() + m_func_bounds.GetByteSize() - 1);
|
||||
uint8_t bytebuf[1];
|
||||
if (m_target.ReadMemory (last_insn, prefer_file_cache, bytebuf, 1, error) != -1)
|
||||
if (target->ReadMemory (last_insn, prefer_file_cache, bytebuf, 1, error) != -1)
|
||||
{
|
||||
if (bytebuf[0] == 0xc3) // ret aka retq
|
||||
{
|
||||
|
@ -728,10 +735,12 @@ AssemblyParse_x86::get_fast_unwind_plan (AddressRange& func, UnwindPlan &unwind_
|
|||
if (!func.GetBaseAddress().IsValid())
|
||||
return false;
|
||||
|
||||
Target *target = m_exe_ctx.GetTargetPtr();
|
||||
|
||||
uint8_t bytebuf[4];
|
||||
Error error;
|
||||
const bool prefer_file_cache = true;
|
||||
if (m_target.ReadMemory (func.GetBaseAddress(), prefer_file_cache, bytebuf, sizeof (bytebuf), error) == -1)
|
||||
if (target->ReadMemory (func.GetBaseAddress(), prefer_file_cache, bytebuf, sizeof (bytebuf), error) == -1)
|
||||
return false;
|
||||
|
||||
uint8_t i386_prologue[] = {0x55, 0x89, 0xe5};
|
||||
|
@ -790,6 +799,7 @@ AssemblyParse_x86::find_first_non_prologue_insn (Address &address)
|
|||
}
|
||||
|
||||
const bool prefer_file_cache = true;
|
||||
Target *target = m_exe_ctx.GetTargetPtr();
|
||||
while (m_func_bounds.ContainsFileAddress (m_cur_insn))
|
||||
{
|
||||
Error error;
|
||||
|
@ -799,7 +809,7 @@ AssemblyParse_x86::find_first_non_prologue_insn (Address &address)
|
|||
// An error parsing the instruction, i.e. probably data/garbage - stop scanning
|
||||
break;
|
||||
}
|
||||
if (m_target.ReadMemory (m_cur_insn, prefer_file_cache, m_cur_insn_bytes, insn_len, error) == -1)
|
||||
if (target->ReadMemory (m_cur_insn, prefer_file_cache, m_cur_insn_bytes, insn_len, error) == -1)
|
||||
{
|
||||
// Error reading the instruction out of the file, stop scanning
|
||||
break;
|
||||
|
@ -843,21 +853,23 @@ UnwindAssembly_x86::~UnwindAssembly_x86 ()
|
|||
bool
|
||||
UnwindAssembly_x86::GetNonCallSiteUnwindPlanFromAssembly (AddressRange& func, Thread& thread, UnwindPlan& unwind_plan)
|
||||
{
|
||||
AssemblyParse_x86 asm_parse(thread.GetProcess().GetTarget(), &thread, m_cpu, func);
|
||||
ExecutionContext exe_ctx (thread.shared_from_this());
|
||||
AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, func);
|
||||
return asm_parse.get_non_call_site_unwind_plan (unwind_plan);
|
||||
}
|
||||
|
||||
bool
|
||||
UnwindAssembly_x86::GetFastUnwindPlan (AddressRange& func, Thread& thread, UnwindPlan &unwind_plan)
|
||||
{
|
||||
AssemblyParse_x86 asm_parse(thread.GetProcess().GetTarget(), &thread, m_cpu, func);
|
||||
ExecutionContext exe_ctx (thread.shared_from_this());
|
||||
AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, func);
|
||||
return asm_parse.get_fast_unwind_plan (func, unwind_plan);
|
||||
}
|
||||
|
||||
bool
|
||||
UnwindAssembly_x86::FirstNonPrologueInsn (AddressRange& func, Target& target, Thread* thread, Address& first_non_prologue_insn)
|
||||
UnwindAssembly_x86::FirstNonPrologueInsn (AddressRange& func, const ExecutionContext &exe_ctx, Address& first_non_prologue_insn)
|
||||
{
|
||||
AssemblyParse_x86 asm_parse(target, thread, m_cpu, func);
|
||||
AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, func);
|
||||
return asm_parse.find_first_non_prologue_insn (first_non_prologue_insn);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,8 +32,7 @@ public:
|
|||
// thread may be NULL in which case we only use the Target (e.g. if this is called pre-process-launch).
|
||||
virtual bool
|
||||
FirstNonPrologueInsn (lldb_private::AddressRange& func,
|
||||
lldb_private::Target& target,
|
||||
lldb_private::Thread* thread,
|
||||
const lldb_private::ExecutionContext &exe_ctx,
|
||||
lldb_private::Address& first_non_prologue_insn);
|
||||
|
||||
static lldb_private::UnwindAssembly *
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "lldb/Symbol/UnwindPlan.h"
|
||||
#include "lldb/Symbol/UnwindTable.h"
|
||||
#include "lldb/Target/ABI.h"
|
||||
#include "lldb/Target/ExecutionContext.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/Thread.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
|
@ -224,7 +225,8 @@ FuncUnwinders::GetFirstNonPrologueInsn (Target& target)
|
|||
{
|
||||
if (m_first_non_prologue_insn.IsValid())
|
||||
return m_first_non_prologue_insn;
|
||||
m_assembly_profiler->FirstNonPrologueInsn (m_range, target, NULL, m_first_non_prologue_insn);
|
||||
ExecutionContext exe_ctx (target.shared_from_this(), false);
|
||||
m_assembly_profiler->FirstNonPrologueInsn (m_range, exe_ctx, m_first_non_prologue_insn);
|
||||
return m_first_non_prologue_insn;
|
||||
}
|
||||
|
||||
|
|
|
@ -387,7 +387,8 @@ UnwindPlan::Dump (Stream& s, Thread *thread, lldb::addr_t base_addr) const
|
|||
if (m_plan_valid_address_range.GetBaseAddress().IsValid() && m_plan_valid_address_range.GetByteSize() > 0)
|
||||
{
|
||||
s.PutCString ("Address range of this UnwindPlan: ");
|
||||
m_plan_valid_address_range.Dump (&s, &thread->GetProcess().GetTarget(), Address::DumpStyleSectionNameOffset);
|
||||
TargetSP target_sp(thread->CalculateTarget());
|
||||
m_plan_valid_address_range.Dump (&s, target_sp.get(), Address::DumpStyleSectionNameOffset);
|
||||
s.EOL();
|
||||
}
|
||||
else
|
||||
|
|
|
@ -105,8 +105,8 @@ ABI::GetRegisterInfoByKind (RegisterKind reg_kind, uint32_t reg_num, RegisterInf
|
|||
|
||||
ValueObjectSP
|
||||
ABI::GetReturnValueObject (Thread &thread,
|
||||
ClangASTType &ast_type,
|
||||
bool persistent) const
|
||||
ClangASTType &ast_type,
|
||||
bool persistent) const
|
||||
{
|
||||
if (!ast_type.IsValid())
|
||||
return ValueObjectSP();
|
||||
|
@ -123,7 +123,7 @@ ABI::GetReturnValueObject (Thread &thread,
|
|||
|
||||
if (persistent)
|
||||
{
|
||||
ClangPersistentVariables& persistent_variables = thread.GetProcess().GetTarget().GetPersistentVariables();
|
||||
ClangPersistentVariables& persistent_variables = thread.CalculateTarget()->GetPersistentVariables();
|
||||
ConstString persistent_variable_name (persistent_variables.GetNextPersistentVariableName());
|
||||
|
||||
lldb::ValueObjectSP const_valobj_sp;
|
||||
|
|
|
@ -72,6 +72,50 @@ ExecutionContext::ExecutionContext (const lldb::StackFrameSP &frame_sp) :
|
|||
SetContext (frame_sp);
|
||||
}
|
||||
|
||||
ExecutionContext::ExecutionContext (const lldb::TargetWP &target_wp, bool get_process) :
|
||||
m_target_sp (),
|
||||
m_process_sp (),
|
||||
m_thread_sp (),
|
||||
m_frame_sp ()
|
||||
{
|
||||
lldb::TargetSP target_sp(target_wp.lock());
|
||||
if (target_sp)
|
||||
SetContext (target_sp, get_process);
|
||||
}
|
||||
|
||||
ExecutionContext::ExecutionContext (const lldb::ProcessWP &process_wp) :
|
||||
m_target_sp (),
|
||||
m_process_sp (),
|
||||
m_thread_sp (),
|
||||
m_frame_sp ()
|
||||
{
|
||||
lldb::ProcessSP process_sp(process_wp.lock());
|
||||
if (process_sp)
|
||||
SetContext (process_sp);
|
||||
}
|
||||
|
||||
ExecutionContext::ExecutionContext (const lldb::ThreadWP &thread_wp) :
|
||||
m_target_sp (),
|
||||
m_process_sp (),
|
||||
m_thread_sp (),
|
||||
m_frame_sp ()
|
||||
{
|
||||
lldb::ThreadSP thread_sp(thread_wp.lock());
|
||||
if (thread_sp)
|
||||
SetContext (thread_sp);
|
||||
}
|
||||
|
||||
ExecutionContext::ExecutionContext (const lldb::StackFrameWP &frame_wp) :
|
||||
m_target_sp (),
|
||||
m_process_sp (),
|
||||
m_thread_sp (),
|
||||
m_frame_sp ()
|
||||
{
|
||||
lldb::StackFrameSP frame_sp(frame_wp.lock());
|
||||
if (frame_sp)
|
||||
SetContext (frame_sp);
|
||||
}
|
||||
|
||||
ExecutionContext::ExecutionContext (Target* t, bool fill_current_process_thread_frame) :
|
||||
m_target_sp (t->shared_from_this()),
|
||||
m_process_sp (),
|
||||
|
@ -208,28 +252,36 @@ ExecutionContext::GetBestExecutionContextScope () const
|
|||
Target &
|
||||
ExecutionContext::GetTargetRef () const
|
||||
{
|
||||
#if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
|
||||
assert (m_target_sp.get());
|
||||
#endif
|
||||
return *m_target_sp;
|
||||
}
|
||||
|
||||
Process &
|
||||
ExecutionContext::GetProcessRef () const
|
||||
{
|
||||
#if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
|
||||
assert (m_process_sp.get());
|
||||
#endif
|
||||
return *m_process_sp;
|
||||
}
|
||||
|
||||
Thread &
|
||||
ExecutionContext::GetThreadRef () const
|
||||
{
|
||||
#if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
|
||||
assert (m_thread_sp.get());
|
||||
#endif
|
||||
return *m_thread_sp;
|
||||
}
|
||||
|
||||
StackFrame &
|
||||
ExecutionContext::GetFrameRef () const
|
||||
{
|
||||
#if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
|
||||
assert (m_frame_sp.get());
|
||||
#endif
|
||||
return *m_frame_sp;
|
||||
}
|
||||
|
||||
|
@ -324,7 +376,7 @@ ExecutionContext::SetContext (const lldb::ThreadSP &thread_sp)
|
|||
m_thread_sp = thread_sp;
|
||||
if (thread_sp)
|
||||
{
|
||||
m_process_sp = thread_sp->GetProcess().shared_from_this();
|
||||
m_process_sp = thread_sp->GetProcess();
|
||||
if (m_process_sp)
|
||||
m_target_sp = m_process_sp->GetTarget().shared_from_this();
|
||||
else
|
||||
|
@ -346,7 +398,7 @@ ExecutionContext::SetContext (const lldb::StackFrameSP &frame_sp)
|
|||
m_thread_sp = frame_sp->CalculateThread();
|
||||
if (m_thread_sp)
|
||||
{
|
||||
m_process_sp = m_thread_sp->GetProcess().shared_from_this();
|
||||
m_process_sp = m_thread_sp->GetProcess();
|
||||
if (m_process_sp)
|
||||
m_target_sp = m_process_sp->GetTarget().shared_from_this();
|
||||
else
|
||||
|
|
|
@ -27,7 +27,7 @@ using namespace lldb_private;
|
|||
RegisterContext::RegisterContext (Thread &thread, uint32_t concrete_frame_idx) :
|
||||
m_thread (thread),
|
||||
m_concrete_frame_idx (concrete_frame_idx),
|
||||
m_stop_id (thread.GetProcess().GetStopID())
|
||||
m_stop_id (thread.GetProcess()->GetStopID())
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -41,9 +41,19 @@ RegisterContext::~RegisterContext()
|
|||
void
|
||||
RegisterContext::InvalidateIfNeeded (bool force)
|
||||
{
|
||||
const uint32_t this_stop_id = GetStopID();
|
||||
const uint32_t process_stop_id = m_thread.GetProcess().GetStopID();
|
||||
if (force || process_stop_id != this_stop_id)
|
||||
ProcessSP process_sp (m_thread.GetProcess());
|
||||
bool invalidate = force;
|
||||
uint32_t process_stop_id = UINT32_MAX;
|
||||
|
||||
if (process_sp)
|
||||
process_stop_id = process_sp->GetStopID();
|
||||
else
|
||||
invalidate = true;
|
||||
|
||||
if (!invalidate)
|
||||
invalidate = process_stop_id != GetStopID();
|
||||
|
||||
if (invalidate)
|
||||
{
|
||||
InvalidateAllRegisters ();
|
||||
SetStopID (process_stop_id);
|
||||
|
@ -279,33 +289,39 @@ RegisterContext::ReadRegisterValueFromMemory (const RegisterInfo *reg_info,
|
|||
return error;
|
||||
}
|
||||
|
||||
Process &process = m_thread.GetProcess();
|
||||
uint8_t src[RegisterValue::kMaxRegisterByteSize];
|
||||
|
||||
// Read the memory
|
||||
const uint32_t bytes_read = process.ReadMemory (src_addr, src, src_len, error);
|
||||
|
||||
// Make sure the memory read succeeded...
|
||||
if (bytes_read != src_len)
|
||||
ProcessSP process_sp (m_thread.GetProcess());
|
||||
if (process_sp)
|
||||
{
|
||||
if (error.Success())
|
||||
uint8_t src[RegisterValue::kMaxRegisterByteSize];
|
||||
|
||||
// Read the memory
|
||||
const uint32_t bytes_read = process_sp->ReadMemory (src_addr, src, src_len, error);
|
||||
|
||||
// Make sure the memory read succeeded...
|
||||
if (bytes_read != src_len)
|
||||
{
|
||||
// This might happen if we read _some_ bytes but not all
|
||||
error.SetErrorStringWithFormat("read %u of %u bytes", bytes_read, src_len);
|
||||
if (error.Success())
|
||||
{
|
||||
// This might happen if we read _some_ bytes but not all
|
||||
error.SetErrorStringWithFormat("read %u of %u bytes", bytes_read, src_len);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
return error;
|
||||
|
||||
// We now have a memory buffer that contains the part or all of the register
|
||||
// value. Set the register value using this memory data.
|
||||
// TODO: we might need to add a parameter to this function in case the byte
|
||||
// order of the memory data doesn't match the process. For now we are assuming
|
||||
// they are the same.
|
||||
reg_value.SetFromMemoryData (reg_info,
|
||||
src,
|
||||
src_len,
|
||||
process_sp->GetByteOrder(),
|
||||
error);
|
||||
}
|
||||
|
||||
// We now have a memory buffer that contains the part or all of the register
|
||||
// value. Set the register value using this memory data.
|
||||
// TODO: we might need to add a parameter to this function in case the byte
|
||||
// order of the memory data doesn't match the process. For now we are assuming
|
||||
// they are the same.
|
||||
reg_value.SetFromMemoryData (reg_info,
|
||||
src,
|
||||
src_len,
|
||||
process.GetByteOrder(),
|
||||
error);
|
||||
else
|
||||
error.SetErrorString("invalid process");
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -320,37 +336,42 @@ RegisterContext::WriteRegisterValueToMemory (const RegisterInfo *reg_info,
|
|||
|
||||
Error error;
|
||||
|
||||
Process &process = m_thread.GetProcess();
|
||||
|
||||
// TODO: we might need to add a parameter to this function in case the byte
|
||||
// order of the memory data doesn't match the process. For now we are assuming
|
||||
// they are the same.
|
||||
|
||||
const uint32_t bytes_copied = reg_value.GetAsMemoryData (reg_info,
|
||||
dst,
|
||||
dst_len,
|
||||
process.GetByteOrder(),
|
||||
error);
|
||||
|
||||
if (error.Success())
|
||||
ProcessSP process_sp (m_thread.GetProcess());
|
||||
if (process_sp)
|
||||
{
|
||||
if (bytes_copied == 0)
|
||||
|
||||
// TODO: we might need to add a parameter to this function in case the byte
|
||||
// order of the memory data doesn't match the process. For now we are assuming
|
||||
// they are the same.
|
||||
|
||||
const uint32_t bytes_copied = reg_value.GetAsMemoryData (reg_info,
|
||||
dst,
|
||||
dst_len,
|
||||
process_sp->GetByteOrder(),
|
||||
error);
|
||||
|
||||
if (error.Success())
|
||||
{
|
||||
error.SetErrorString("byte copy failed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint32_t bytes_written = process.WriteMemory (dst_addr, dst, bytes_copied, error);
|
||||
if (bytes_written != bytes_copied)
|
||||
if (bytes_copied == 0)
|
||||
{
|
||||
if (error.Success())
|
||||
error.SetErrorString("byte copy failed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint32_t bytes_written = process_sp->WriteMemory (dst_addr, dst, bytes_copied, error);
|
||||
if (bytes_written != bytes_copied)
|
||||
{
|
||||
// This might happen if we read _some_ bytes but not all
|
||||
error.SetErrorStringWithFormat("only wrote %u of %u bytes", bytes_written, bytes_copied);
|
||||
if (error.Success())
|
||||
{
|
||||
// This might happen if we read _some_ bytes but not all
|
||||
error.SetErrorStringWithFormat("only wrote %u of %u bytes", bytes_written, bytes_copied);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
error.SetErrorString("invalid process");
|
||||
|
||||
return error;
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ StackFrame::StackFrame (const ThreadSP &thread_sp,
|
|||
m_frame_index (frame_idx),
|
||||
m_concrete_frame_index (unwind_frame_index),
|
||||
m_reg_context_sp (reg_context_sp),
|
||||
m_id (pc_addr.GetLoadAddress (&thread_sp->GetProcess().GetTarget()), cfa, NULL),
|
||||
m_id (pc_addr.GetLoadAddress (thread_sp->CalculateTarget().get()), cfa, NULL),
|
||||
m_frame_code_addr (pc_addr),
|
||||
m_sc (),
|
||||
m_flags (),
|
||||
|
|
|
@ -401,14 +401,14 @@ StackFrameList::SetSelectedFrameByIndex (uint32_t idx)
|
|||
void
|
||||
StackFrameList::SetDefaultFileAndLineToSelectedFrame()
|
||||
{
|
||||
if (m_thread.GetID() == m_thread.GetProcess().GetThreadList().GetSelectedThread()->GetID())
|
||||
if (m_thread.GetID() == m_thread.GetProcess()->GetThreadList().GetSelectedThread()->GetID())
|
||||
{
|
||||
StackFrameSP frame_sp (GetFrameAtIndex (GetSelectedFrameIndex()));
|
||||
if (frame_sp)
|
||||
{
|
||||
SymbolContext sc = frame_sp->GetSymbolContext(eSymbolContextLineEntry);
|
||||
if (sc.line_entry.file)
|
||||
m_thread.GetProcess().GetTarget().GetSourceManager().SetDefaultFileAndLine (sc.line_entry.file,
|
||||
m_thread.CalculateTarget()->GetSourceManager().SetDefaultFileAndLine (sc.line_entry.file,
|
||||
sc.line_entry.line);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,8 +34,8 @@ using namespace lldb_private;
|
|||
|
||||
StopInfo::StopInfo (Thread &thread, uint64_t value) :
|
||||
m_thread (thread),
|
||||
m_stop_id (thread.GetProcess().GetStopID()),
|
||||
m_resume_id (thread.GetProcess().GetResumeID()),
|
||||
m_stop_id (thread.GetProcess()->GetStopID()),
|
||||
m_resume_id (thread.GetProcess()->GetResumeID()),
|
||||
m_value (value)
|
||||
{
|
||||
}
|
||||
|
@ -43,20 +43,20 @@ StopInfo::StopInfo (Thread &thread, uint64_t value) :
|
|||
bool
|
||||
StopInfo::IsValid () const
|
||||
{
|
||||
return m_thread.GetProcess().GetStopID() == m_stop_id;
|
||||
return m_thread.GetProcess()->GetStopID() == m_stop_id;
|
||||
}
|
||||
|
||||
void
|
||||
StopInfo::MakeStopInfoValid ()
|
||||
{
|
||||
m_stop_id = m_thread.GetProcess().GetStopID();
|
||||
m_resume_id = m_thread.GetProcess().GetResumeID();
|
||||
m_stop_id = m_thread.GetProcess()->GetStopID();
|
||||
m_resume_id = m_thread.GetProcess()->GetResumeID();
|
||||
}
|
||||
|
||||
bool
|
||||
StopInfo::HasTargetRunSinceMe ()
|
||||
{
|
||||
lldb::StateType ret_type = m_thread.GetProcess().GetPrivateState();
|
||||
lldb::StateType ret_type = m_thread.GetProcess()->GetPrivateState();
|
||||
if (ret_type == eStateRunning)
|
||||
{
|
||||
return true;
|
||||
|
@ -69,8 +69,8 @@ StopInfo::HasTargetRunSinceMe ()
|
|||
// and resumes caused by expressions, and check if there are any resumes NOT caused
|
||||
// by expressions.
|
||||
|
||||
uint32_t curr_resume_id = m_thread.GetProcess().GetResumeID();
|
||||
uint32_t last_user_expression_id = m_thread.GetProcess().GetLastUserExpressionResumeID ();
|
||||
uint32_t curr_resume_id = m_thread.GetProcess()->GetResumeID();
|
||||
uint32_t last_user_expression_id = m_thread.GetProcess()->GetLastUserExpressionResumeID ();
|
||||
if (curr_resume_id == m_resume_id)
|
||||
{
|
||||
return false;
|
||||
|
@ -101,7 +101,7 @@ public:
|
|||
m_should_perform_action (true),
|
||||
m_address (LLDB_INVALID_ADDRESS)
|
||||
{
|
||||
BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (m_value));
|
||||
BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value));
|
||||
if (bp_site_sp)
|
||||
{
|
||||
m_address = bp_site_sp->GetLoadAddress();
|
||||
|
@ -116,7 +116,7 @@ public:
|
|||
m_should_perform_action (true),
|
||||
m_address (LLDB_INVALID_ADDRESS)
|
||||
{
|
||||
BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (m_value));
|
||||
BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value));
|
||||
if (bp_site_sp)
|
||||
{
|
||||
m_address = bp_site_sp->GetLoadAddress();
|
||||
|
@ -139,15 +139,11 @@ public:
|
|||
if (!m_should_stop_is_valid)
|
||||
{
|
||||
// Only check once if we should stop at a breakpoint
|
||||
BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (m_value));
|
||||
BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value));
|
||||
if (bp_site_sp)
|
||||
{
|
||||
StoppointCallbackContext context (event_ptr,
|
||||
&m_thread.GetProcess(),
|
||||
&m_thread,
|
||||
m_thread.GetStackFrameAtIndex(0).get(),
|
||||
true);
|
||||
|
||||
ExecutionContext exe_ctx (m_thread.GetStackFrameAtIndex(0));
|
||||
StoppointCallbackContext context (event_ptr, exe_ctx, true);
|
||||
m_should_stop = bp_site_sp->ShouldStop (&context);
|
||||
}
|
||||
else
|
||||
|
@ -173,7 +169,7 @@ public:
|
|||
|
||||
LogSP log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
|
||||
|
||||
BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (m_value));
|
||||
BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value));
|
||||
|
||||
if (bp_site_sp)
|
||||
{
|
||||
|
@ -197,11 +193,8 @@ public:
|
|||
|
||||
m_should_stop = false;
|
||||
|
||||
StoppointCallbackContext context (event_ptr,
|
||||
&m_thread.GetProcess(),
|
||||
&m_thread,
|
||||
m_thread.GetStackFrameAtIndex(0).get(),
|
||||
false);
|
||||
ExecutionContext exe_ctx (m_thread.GetStackFrameAtIndex(0));
|
||||
StoppointCallbackContext context (event_ptr, exe_ctx, false);
|
||||
|
||||
for (size_t j = 0; j < num_owners; j++)
|
||||
{
|
||||
|
@ -222,7 +215,7 @@ public:
|
|||
ValueObjectSP result_value_sp;
|
||||
const bool discard_on_error = true;
|
||||
Error error;
|
||||
result_code = ClangUserExpression::EvaluateWithError (context.exe_ctx,
|
||||
result_code = ClangUserExpression::EvaluateWithError (exe_ctx,
|
||||
eExecutionPolicyAlways,
|
||||
lldb::eLanguageTypeUnknown,
|
||||
ClangUserExpression::eResultTypeAny,
|
||||
|
@ -256,7 +249,7 @@ public:
|
|||
}
|
||||
else
|
||||
{
|
||||
Debugger &debugger = context.exe_ctx.GetTargetRef().GetDebugger();
|
||||
Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
|
||||
StreamSP error_sp = debugger.GetAsyncErrorStream ();
|
||||
error_sp->Printf ("Stopped due to an error evaluating condition of breakpoint ");
|
||||
bp_loc_sp->GetDescription (error_sp.get(), eDescriptionLevelBrief);
|
||||
|
@ -286,7 +279,7 @@ public:
|
|||
// to get out of there. So set it here.
|
||||
// When we figure out how to nest breakpoint hits then this will change.
|
||||
|
||||
Debugger &debugger = m_thread.GetProcess().GetTarget().GetDebugger();
|
||||
Debugger &debugger = m_thread.CalculateTarget()->GetDebugger();
|
||||
bool old_async = debugger.GetAsyncExecution();
|
||||
debugger.SetAsyncExecution (true);
|
||||
|
||||
|
@ -326,7 +319,7 @@ public:
|
|||
virtual bool
|
||||
ShouldNotify (Event *event_ptr)
|
||||
{
|
||||
BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (m_value));
|
||||
BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value));
|
||||
if (bp_site_sp)
|
||||
{
|
||||
bool all_internal = true;
|
||||
|
@ -349,7 +342,7 @@ public:
|
|||
{
|
||||
if (m_description.empty())
|
||||
{
|
||||
BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (m_value));
|
||||
BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value));
|
||||
if (bp_site_sp)
|
||||
{
|
||||
StreamString strm;
|
||||
|
@ -422,16 +415,12 @@ public:
|
|||
return m_should_stop;
|
||||
|
||||
WatchpointSP wp_sp =
|
||||
m_thread.GetProcess().GetTarget().GetWatchpointList().FindByID(GetValue());
|
||||
m_thread.CalculateTarget()->GetWatchpointList().FindByID(GetValue());
|
||||
if (wp_sp)
|
||||
{
|
||||
// Check if we should stop at a watchpoint.
|
||||
StoppointCallbackContext context (event_ptr,
|
||||
&m_thread.GetProcess(),
|
||||
&m_thread,
|
||||
m_thread.GetStackFrameAtIndex(0).get(),
|
||||
true);
|
||||
|
||||
ExecutionContext exe_ctx (m_thread.GetStackFrameAtIndex(0));
|
||||
StoppointCallbackContext context (event_ptr, exe_ctx, true);
|
||||
m_should_stop = wp_sp->ShouldStop (&context);
|
||||
}
|
||||
else
|
||||
|
@ -459,14 +448,11 @@ public:
|
|||
m_should_stop = true;
|
||||
|
||||
WatchpointSP wp_sp =
|
||||
m_thread.GetProcess().GetTarget().GetWatchpointList().FindByID(GetValue());
|
||||
m_thread.CalculateTarget()->GetWatchpointList().FindByID(GetValue());
|
||||
if (wp_sp)
|
||||
{
|
||||
StoppointCallbackContext context (event_ptr,
|
||||
&m_thread.GetProcess(),
|
||||
&m_thread,
|
||||
m_thread.GetStackFrameAtIndex(0).get(),
|
||||
false);
|
||||
ExecutionContext exe_ctx (m_thread.GetStackFrameAtIndex(0));
|
||||
StoppointCallbackContext context (event_ptr, exe_ctx, false);
|
||||
bool stop_requested = wp_sp->InvokeCallback (&context);
|
||||
// Also make sure that the callback hasn't continued the target.
|
||||
// If it did, when we'll set m_should_start to false and get out of here.
|
||||
|
@ -483,16 +469,11 @@ public:
|
|||
{
|
||||
// We need to make sure the user sees any parse errors in their condition, so we'll hook the
|
||||
// constructor errors up to the debugger's Async I/O.
|
||||
StoppointCallbackContext context (event_ptr,
|
||||
&m_thread.GetProcess(),
|
||||
&m_thread,
|
||||
m_thread.GetStackFrameAtIndex(0).get(),
|
||||
false);
|
||||
ExecutionResults result_code;
|
||||
ValueObjectSP result_value_sp;
|
||||
const bool discard_on_error = true;
|
||||
Error error;
|
||||
result_code = ClangUserExpression::EvaluateWithError (context.exe_ctx,
|
||||
result_code = ClangUserExpression::EvaluateWithError (exe_ctx,
|
||||
eExecutionPolicyAlways,
|
||||
lldb::eLanguageTypeUnknown,
|
||||
ClangUserExpression::eResultTypeAny,
|
||||
|
@ -532,7 +513,7 @@ public:
|
|||
}
|
||||
else
|
||||
{
|
||||
Debugger &debugger = context.exe_ctx.GetTargetRef().GetDebugger();
|
||||
Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
|
||||
StreamSP error_sp = debugger.GetAsyncErrorStream ();
|
||||
error_sp->Printf ("Stopped due to an error evaluating condition of watchpoint ");
|
||||
wp_sp->GetDescription (error_sp.get(), eDescriptionLevelBrief);
|
||||
|
@ -609,7 +590,7 @@ public:
|
|||
virtual bool
|
||||
ShouldStop (Event *event_ptr)
|
||||
{
|
||||
return m_thread.GetProcess().GetUnixSignals().GetShouldStop (m_value);
|
||||
return m_thread.GetProcess()->GetUnixSignals().GetShouldStop (m_value);
|
||||
}
|
||||
|
||||
|
||||
|
@ -617,14 +598,14 @@ public:
|
|||
virtual bool
|
||||
ShouldNotify (Event *event_ptr)
|
||||
{
|
||||
return m_thread.GetProcess().GetUnixSignals().GetShouldNotify (m_value);
|
||||
return m_thread.GetProcess()->GetUnixSignals().GetShouldNotify (m_value);
|
||||
}
|
||||
|
||||
|
||||
virtual void
|
||||
WillResume (lldb::StateType resume_state)
|
||||
{
|
||||
if (m_thread.GetProcess().GetUnixSignals().GetShouldSuppress(m_value) == false)
|
||||
if (m_thread.GetProcess()->GetUnixSignals().GetShouldSuppress(m_value) == false)
|
||||
m_thread.SetResumeSignal(m_value);
|
||||
}
|
||||
|
||||
|
@ -634,7 +615,7 @@ public:
|
|||
if (m_description.empty())
|
||||
{
|
||||
StreamString strm;
|
||||
const char *signal_name = m_thread.GetProcess().GetUnixSignals().GetSignalAsCString (m_value);
|
||||
const char *signal_name = m_thread.GetProcess()->GetUnixSignals().GetSignalAsCString (m_value);
|
||||
if (signal_name)
|
||||
strm.Printf("signal %s", signal_name);
|
||||
else
|
||||
|
|
|
@ -43,12 +43,12 @@
|
|||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
Thread::Thread (Process &process, lldb::tid_t tid) :
|
||||
Thread::Thread (const ProcessSP &process_sp, lldb::tid_t tid) :
|
||||
UserID (tid),
|
||||
ThreadInstanceSettings (GetSettingsController()),
|
||||
m_process (process),
|
||||
m_process_wp (process_sp),
|
||||
m_actual_stop_info_sp (),
|
||||
m_index_id (process.GetNextThreadIndexID ()),
|
||||
m_index_id (process_sp->GetNextThreadIndexID ()),
|
||||
m_reg_context_sp (),
|
||||
m_state (eStateUnloaded),
|
||||
m_state_mutex (Mutex::eMutexTypeRecursive),
|
||||
|
@ -99,9 +99,11 @@ Thread::GetStopInfo ()
|
|||
return StopInfo::CreateStopReasonWithPlan (plan_sp, GetReturnValueObject());
|
||||
else
|
||||
{
|
||||
if (m_actual_stop_info_sp
|
||||
ProcessSP process_sp (GetProcess());
|
||||
if (process_sp
|
||||
&& m_actual_stop_info_sp
|
||||
&& m_actual_stop_info_sp->IsValid()
|
||||
&& m_thread_stop_reason_stop_id == m_process.GetStopID())
|
||||
&& m_thread_stop_reason_stop_id == process_sp->GetStopID())
|
||||
return m_actual_stop_info_sp;
|
||||
else
|
||||
return GetPrivateStopReason ();
|
||||
|
@ -114,7 +116,11 @@ Thread::SetStopInfo (const lldb::StopInfoSP &stop_info_sp)
|
|||
m_actual_stop_info_sp = stop_info_sp;
|
||||
if (m_actual_stop_info_sp)
|
||||
m_actual_stop_info_sp->MakeStopInfoValid();
|
||||
m_thread_stop_reason_stop_id = GetProcess().GetStopID();
|
||||
ProcessSP process_sp (GetProcess());
|
||||
if (process_sp)
|
||||
m_thread_stop_reason_stop_id = process_sp->GetStopID();
|
||||
else
|
||||
m_thread_stop_reason_stop_id = UINT32_MAX;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -138,8 +144,9 @@ Thread::CheckpointThreadState (ThreadStateCheckpoint &saved_state)
|
|||
return false;
|
||||
|
||||
saved_state.stop_info_sp = GetStopInfo();
|
||||
saved_state.orig_stop_id = GetProcess().GetStopID();
|
||||
|
||||
ProcessSP process_sp (GetProcess());
|
||||
if (process_sp)
|
||||
saved_state.orig_stop_id = process_sp->GetStopID();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -193,7 +200,7 @@ Thread::SetupForResume ()
|
|||
// plan is.
|
||||
|
||||
lldb::addr_t pc = GetRegisterContext()->GetPC();
|
||||
BreakpointSiteSP bp_site_sp = GetProcess().GetBreakpointSiteList().FindByAddress(pc);
|
||||
BreakpointSiteSP bp_site_sp = GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
|
||||
if (bp_site_sp && bp_site_sp->IsEnabled())
|
||||
{
|
||||
// Note, don't assume there's a ThreadPlanStepOverBreakpoint, the target may not require anything
|
||||
|
@ -234,7 +241,7 @@ Thread::WillResume (StateType resume_state)
|
|||
// the target, 'cause that slows down single stepping. So assume that if we got to the point where
|
||||
// we're about to resume, and we haven't yet had to fetch the stop reason, then it doesn't need to know
|
||||
// about the fact that we are resuming...
|
||||
const uint32_t process_stop_id = GetProcess().GetStopID();
|
||||
const uint32_t process_stop_id = GetProcess()->GetStopID();
|
||||
if (m_thread_stop_reason_stop_id == process_stop_id &&
|
||||
(m_actual_stop_info_sp && m_actual_stop_info_sp->IsValid()))
|
||||
{
|
||||
|
@ -1018,13 +1025,18 @@ Thread::DumpThreadPlans (lldb_private::Stream *s) const
|
|||
TargetSP
|
||||
Thread::CalculateTarget ()
|
||||
{
|
||||
return m_process.CalculateTarget();
|
||||
TargetSP target_sp;
|
||||
ProcessSP process_sp(GetProcess());
|
||||
if (process_sp)
|
||||
target_sp = process_sp->CalculateTarget();
|
||||
return target_sp;
|
||||
|
||||
}
|
||||
|
||||
ProcessSP
|
||||
Thread::CalculateProcess ()
|
||||
{
|
||||
return m_process.shared_from_this();
|
||||
return GetProcess();
|
||||
}
|
||||
|
||||
ThreadSP
|
||||
|
@ -1042,9 +1054,7 @@ Thread::CalculateStackFrame ()
|
|||
void
|
||||
Thread::CalculateExecutionContext (ExecutionContext &exe_ctx)
|
||||
{
|
||||
m_process.CalculateExecutionContext (exe_ctx);
|
||||
exe_ctx.SetThreadPtr (this);
|
||||
exe_ctx.SetFramePtr (NULL);
|
||||
exe_ctx.SetContext (shared_from_this());
|
||||
}
|
||||
|
||||
|
||||
|
@ -1073,11 +1083,13 @@ Thread::GetFrameWithConcreteFrameIndex (uint32_t unwind_idx)
|
|||
void
|
||||
Thread::DumpUsingSettingsFormat (Stream &strm, uint32_t frame_idx)
|
||||
{
|
||||
ExecutionContext exe_ctx;
|
||||
ExecutionContext exe_ctx (shared_from_this());
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
if (process == NULL)
|
||||
return;
|
||||
|
||||
StackFrameSP frame_sp;
|
||||
SymbolContext frame_sc;
|
||||
CalculateExecutionContext (exe_ctx);
|
||||
|
||||
if (frame_idx != LLDB_INVALID_INDEX32)
|
||||
{
|
||||
frame_sp = GetStackFrameAtIndex (frame_idx);
|
||||
|
@ -1088,7 +1100,7 @@ Thread::DumpUsingSettingsFormat (Stream &strm, uint32_t frame_idx)
|
|||
}
|
||||
}
|
||||
|
||||
const char *thread_format = GetProcess().GetTarget().GetDebugger().GetThreadFormat();
|
||||
const char *thread_format = exe_ctx.GetTargetRef().GetDebugger().GetThreadFormat();
|
||||
assert (thread_format);
|
||||
const char *end = NULL;
|
||||
Debugger::FormatPrompt (thread_format,
|
||||
|
@ -1203,10 +1215,19 @@ Thread::RunModeAsCString (lldb::RunMode mode)
|
|||
size_t
|
||||
Thread::GetStatus (Stream &strm, uint32_t start_frame, uint32_t num_frames, uint32_t num_frames_with_source)
|
||||
{
|
||||
ExecutionContext exe_ctx (shared_from_this());
|
||||
Target *target = exe_ctx.GetTargetPtr();
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
size_t num_frames_shown = 0;
|
||||
strm.Indent();
|
||||
strm.Printf("%c ", GetProcess().GetThreadList().GetSelectedThread().get() == this ? '*' : ' ');
|
||||
if (GetProcess().GetTarget().GetDebugger().GetUseExternalEditor())
|
||||
bool is_selected = false;
|
||||
if (process)
|
||||
{
|
||||
if (process->GetThreadList().GetSelectedThread().get() == this)
|
||||
is_selected = true;
|
||||
}
|
||||
strm.Printf("%c ", is_selected ? '*' : ' ');
|
||||
if (target && target->GetDebugger().GetUseExternalEditor())
|
||||
{
|
||||
StackFrameSP frame_sp = GetStackFrameAtIndex(start_frame);
|
||||
if (frame_sp)
|
||||
|
@ -1294,7 +1315,7 @@ Thread::GetUnwinder ()
|
|||
{
|
||||
if (m_unwinder_ap.get() == NULL)
|
||||
{
|
||||
const ArchSpec target_arch (GetProcess().GetTarget().GetArchitecture ());
|
||||
const ArchSpec target_arch (CalculateTarget()->GetArchitecture ());
|
||||
const llvm::Triple::ArchType machine = target_arch.GetMachine();
|
||||
switch (machine)
|
||||
{
|
||||
|
|
|
@ -54,20 +54,24 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
|
|||
{
|
||||
SetOkayToDiscard (discard_on_error);
|
||||
|
||||
Process& process = thread.GetProcess();
|
||||
Target& target = process.GetTarget();
|
||||
const ABI *abi = process.GetABI().get();
|
||||
ProcessSP process_sp (thread.GetProcess());
|
||||
if (!process_sp)
|
||||
return;
|
||||
|
||||
const ABI *abi = process_sp->GetABI().get();
|
||||
|
||||
if (!abi)
|
||||
return;
|
||||
|
||||
TargetSP target_sp (thread.CalculateTarget());
|
||||
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
|
||||
|
||||
SetBreakpoints();
|
||||
|
||||
m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize();
|
||||
|
||||
Module *exe_module = target.GetExecutableModulePointer();
|
||||
Module *exe_module = target_sp->GetExecutableModulePointer();
|
||||
|
||||
if (exe_module == NULL)
|
||||
{
|
||||
|
@ -95,7 +99,7 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
|
|||
}
|
||||
}
|
||||
|
||||
addr_t start_load_addr = m_start_addr.GetLoadAddress(&target);
|
||||
addr_t start_load_addr = m_start_addr.GetLoadAddress (target_sp.get());
|
||||
|
||||
// Checkpoint the thread state so we can restore it later.
|
||||
if (log && log->GetVerbose())
|
||||
|
@ -110,7 +114,7 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
|
|||
// Now set the thread state to "no reason" so we don't run with whatever signal was outstanding...
|
||||
thread.SetStopInfoToNothing();
|
||||
|
||||
addr_t FunctionLoadAddr = m_function_addr.GetLoadAddress(&target);
|
||||
addr_t FunctionLoadAddr = m_function_addr.GetLoadAddress (target_sp.get());
|
||||
|
||||
if (this_arg && cmd_arg)
|
||||
{
|
||||
|
@ -170,20 +174,24 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
|
|||
{
|
||||
SetOkayToDiscard (discard_on_error);
|
||||
|
||||
Process& process = thread.GetProcess();
|
||||
Target& target = process.GetTarget();
|
||||
const ABI *abi = process.GetABI().get();
|
||||
ProcessSP process_sp (thread.GetProcess());
|
||||
if (!process_sp)
|
||||
return;
|
||||
|
||||
const ABI *abi = process_sp->GetABI().get();
|
||||
|
||||
if (!abi)
|
||||
return;
|
||||
|
||||
|
||||
TargetSP target_sp (thread.CalculateTarget());
|
||||
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
|
||||
|
||||
SetBreakpoints();
|
||||
|
||||
m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize();
|
||||
|
||||
Module *exe_module = target.GetExecutableModulePointer();
|
||||
Module *exe_module = target_sp->GetExecutableModulePointer();
|
||||
|
||||
if (exe_module == NULL)
|
||||
{
|
||||
|
@ -211,7 +219,7 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
|
|||
}
|
||||
}
|
||||
|
||||
addr_t start_load_addr = m_start_addr.GetLoadAddress(&target);
|
||||
addr_t start_load_addr = m_start_addr.GetLoadAddress(target_sp.get());
|
||||
|
||||
// Checkpoint the thread state so we can restore it later.
|
||||
if (log && log->GetVerbose())
|
||||
|
@ -226,7 +234,7 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
|
|||
// Now set the thread state to "no reason" so we don't run with whatever signal was outstanding...
|
||||
thread.SetStopInfoToNothing();
|
||||
|
||||
addr_t FunctionLoadAddr = m_function_addr.GetLoadAddress(&target);
|
||||
addr_t FunctionLoadAddr = m_function_addr.GetLoadAddress(target_sp.get());
|
||||
|
||||
if (!abi->PrepareTrivialCall (thread,
|
||||
m_function_sp,
|
||||
|
@ -285,7 +293,8 @@ ThreadPlanCallFunction::DoTakedown ()
|
|||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
|
||||
if (!m_takedown_done)
|
||||
{
|
||||
const ABI *abi = m_thread.GetProcess().GetABI().get();
|
||||
ProcessSP process_sp (m_thread.GetProcess());
|
||||
const ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
|
||||
if (abi && m_return_type.IsValid())
|
||||
{
|
||||
m_return_valobj_sp = abi->GetReturnValueObject (m_thread, m_return_type);
|
||||
|
@ -325,7 +334,8 @@ ThreadPlanCallFunction::GetDescription (Stream *s, DescriptionLevel level)
|
|||
}
|
||||
else
|
||||
{
|
||||
s->Printf("Thread plan to call 0x%llx", m_function_addr.GetLoadAddress(&m_thread.GetProcess().GetTarget()));
|
||||
TargetSP target_sp (m_thread.CalculateTarget());
|
||||
s->Printf("Thread plan to call 0x%llx", m_function_addr.GetLoadAddress(target_sp.get()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -362,8 +372,11 @@ ThreadPlanCallFunction::PlanExplainsStop ()
|
|||
|
||||
if (m_real_stop_info_sp && m_real_stop_info_sp->GetStopReason() == eStopReasonBreakpoint)
|
||||
{
|
||||
ProcessSP process_sp (m_thread.CalculateProcess());
|
||||
uint64_t break_site_id = m_real_stop_info_sp->GetValue();
|
||||
BreakpointSiteSP bp_site_sp = m_thread.GetProcess().GetBreakpointSiteList().FindByID(break_site_id);
|
||||
BreakpointSiteSP bp_site_sp;
|
||||
if (process_sp)
|
||||
bp_site_sp = process_sp->GetBreakpointSiteList().FindByID(break_site_id);
|
||||
if (bp_site_sp)
|
||||
{
|
||||
uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
|
||||
|
@ -475,13 +488,17 @@ ThreadPlanCallFunction::MischiefManaged ()
|
|||
void
|
||||
ThreadPlanCallFunction::SetBreakpoints ()
|
||||
{
|
||||
m_cxx_language_runtime = m_thread.GetProcess().GetLanguageRuntime(eLanguageTypeC_plus_plus);
|
||||
m_objc_language_runtime = m_thread.GetProcess().GetLanguageRuntime(eLanguageTypeObjC);
|
||||
ProcessSP process_sp (m_thread.CalculateProcess());
|
||||
if (process_sp)
|
||||
{
|
||||
m_cxx_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeC_plus_plus);
|
||||
m_objc_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeObjC);
|
||||
|
||||
if (m_cxx_language_runtime)
|
||||
m_cxx_language_runtime->SetExceptionBreakpoints();
|
||||
if (m_objc_language_runtime)
|
||||
m_objc_language_runtime->SetExceptionBreakpoints();
|
||||
if (m_cxx_language_runtime)
|
||||
m_cxx_language_runtime->SetExceptionBreakpoints();
|
||||
if (m_objc_language_runtime)
|
||||
m_objc_language_runtime->SetExceptionBreakpoints();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -64,7 +64,7 @@ ThreadPlanCallUserExpression::GetRealStopInfo()
|
|||
{
|
||||
StopInfoSP stop_info_sp = ThreadPlanCallFunction::GetRealStopInfo();
|
||||
lldb::addr_t addr = GetStopAddress();
|
||||
DynamicCheckerFunctions *checkers = m_thread.GetProcess().GetDynamicCheckers();
|
||||
DynamicCheckerFunctions *checkers = m_thread.GetProcess()->GetDynamicCheckers();
|
||||
StreamString s;
|
||||
|
||||
if (checkers && checkers->DoCheckersExplainStop(addr, s))
|
||||
|
|
|
@ -39,7 +39,7 @@ ThreadPlanRunToAddress::ThreadPlanRunToAddress
|
|||
m_addresses (),
|
||||
m_break_ids ()
|
||||
{
|
||||
m_addresses.push_back (address.GetOpcodeLoadAddress (&m_thread.GetProcess().GetTarget()));
|
||||
m_addresses.push_back (address.GetOpcodeLoadAddress (m_thread.CalculateTarget().get()));
|
||||
SetInitialBreakpoints();
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ ThreadPlanRunToAddress::ThreadPlanRunToAddress
|
|||
m_addresses (),
|
||||
m_break_ids ()
|
||||
{
|
||||
m_addresses.push_back(m_thread.GetProcess().GetTarget().GetOpcodeLoadAddress(address));
|
||||
m_addresses.push_back(m_thread.CalculateTarget()->GetOpcodeLoadAddress(address));
|
||||
SetInitialBreakpoints();
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ ThreadPlanRunToAddress::ThreadPlanRunToAddress
|
|||
{
|
||||
// Convert all addressses into opcode addresses to make sure we set
|
||||
// breakpoints at the correct address.
|
||||
Target &target = thread.GetProcess().GetTarget();
|
||||
Target &target = thread.GetProcess()->GetTarget();
|
||||
std::vector<lldb::addr_t>::iterator pos, end = m_addresses.end();
|
||||
for (pos = m_addresses.begin(); pos != end; ++pos)
|
||||
*pos = target.GetOpcodeLoadAddress (*pos);
|
||||
|
@ -88,7 +88,7 @@ ThreadPlanRunToAddress::SetInitialBreakpoints ()
|
|||
for (size_t i = 0; i < num_addresses; i++)
|
||||
{
|
||||
Breakpoint *breakpoint;
|
||||
breakpoint = m_thread.GetProcess().GetTarget().CreateBreakpoint (m_addresses[i], true).get();
|
||||
breakpoint = m_thread.CalculateTarget()->CreateBreakpoint (m_addresses[i], true).get();
|
||||
if (breakpoint != NULL)
|
||||
{
|
||||
m_break_ids[i] = breakpoint->GetID();
|
||||
|
@ -102,7 +102,7 @@ ThreadPlanRunToAddress::~ThreadPlanRunToAddress ()
|
|||
size_t num_break_ids = m_break_ids.size();
|
||||
for (size_t i = 0; i < num_break_ids; i++)
|
||||
{
|
||||
m_thread.GetProcess().GetTarget().RemoveBreakpointByID (m_break_ids[i]);
|
||||
m_thread.CalculateTarget()->RemoveBreakpointByID (m_break_ids[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,7 +153,7 @@ ThreadPlanRunToAddress::GetDescription (Stream *s, lldb::DescriptionLevel level)
|
|||
|
||||
s->Address(m_addresses[i], sizeof (addr_t));
|
||||
s->Printf (" using breakpoint: %d - ", m_break_ids[i]);
|
||||
Breakpoint *breakpoint = m_thread.GetProcess().GetTarget().GetBreakpointByID (m_break_ids[i]).get();
|
||||
Breakpoint *breakpoint = m_thread.CalculateTarget()->GetBreakpointByID (m_break_ids[i]).get();
|
||||
if (breakpoint)
|
||||
breakpoint->Dump (s);
|
||||
else
|
||||
|
@ -236,7 +236,7 @@ ThreadPlanRunToAddress::MischiefManaged ()
|
|||
{
|
||||
if (m_break_ids[i] != LLDB_INVALID_BREAK_ID)
|
||||
{
|
||||
m_thread.GetProcess().GetTarget().RemoveBreakpointByID (m_break_ids[i]);
|
||||
m_thread.CalculateTarget()->RemoveBreakpointByID (m_break_ids[i]);
|
||||
m_break_ids[i] = LLDB_INVALID_BREAK_ID;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ ThreadPlanStepInRange::ShouldStop (Event *event_ptr)
|
|||
{
|
||||
StreamString s;
|
||||
s.Address (m_thread.GetRegisterContext()->GetPC(),
|
||||
m_thread.GetProcess().GetTarget().GetArchitecture().GetAddressByteSize());
|
||||
m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize());
|
||||
log->Printf("ThreadPlanStepInRange reached %s.", s.GetData());
|
||||
}
|
||||
|
||||
|
|
|
@ -123,10 +123,10 @@ ThreadPlanStepInstruction::ShouldStop (Event *event_ptr)
|
|||
StreamString s;
|
||||
s.PutCString ("Stepped in to: ");
|
||||
addr_t stop_addr = m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC();
|
||||
s.Address (stop_addr, m_thread.GetProcess().GetTarget().GetArchitecture().GetAddressByteSize());
|
||||
s.Address (stop_addr, m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize());
|
||||
s.PutCString (" stepping out to: ");
|
||||
addr_t return_addr = return_frame->GetRegisterContext()->GetPC();
|
||||
s.Address (return_addr, m_thread.GetProcess().GetTarget().GetArchitecture().GetAddressByteSize());
|
||||
s.Address (return_addr, m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize());
|
||||
log->Printf("%s.", s.GetData());
|
||||
}
|
||||
m_thread.QueueThreadPlanForStepOut(false, NULL, true, m_stop_other_threads, eVoteNo, eVoteNoOpinion, 0);
|
||||
|
|
|
@ -84,8 +84,8 @@ ThreadPlanStepOut::ThreadPlanStepOut
|
|||
// Find the return address and set a breakpoint there:
|
||||
// FIXME - can we do this more securely if we know first_insn?
|
||||
|
||||
m_return_addr = return_frame_sp->GetFrameCodeAddress().GetLoadAddress(&m_thread.GetProcess().GetTarget());
|
||||
Breakpoint *return_bp = m_thread.GetProcess().GetTarget().CreateBreakpoint (m_return_addr, true).get();
|
||||
m_return_addr = return_frame_sp->GetFrameCodeAddress().GetLoadAddress(&m_thread.GetProcess()->GetTarget());
|
||||
Breakpoint *return_bp = m_thread.CalculateTarget()->CreateBreakpoint (m_return_addr, true).get();
|
||||
if (return_bp != NULL)
|
||||
{
|
||||
return_bp->SetThreadID(m_thread.GetID());
|
||||
|
@ -116,7 +116,7 @@ ThreadPlanStepOut::DidPush()
|
|||
ThreadPlanStepOut::~ThreadPlanStepOut ()
|
||||
{
|
||||
if (m_return_bp_id != LLDB_INVALID_BREAK_ID)
|
||||
m_thread.GetProcess().GetTarget().RemoveBreakpointByID(m_return_bp_id);
|
||||
m_thread.CalculateTarget()->RemoveBreakpointByID(m_return_bp_id);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -191,7 +191,7 @@ ThreadPlanStepOut::PlanExplainsStop ()
|
|||
case eStopReasonBreakpoint:
|
||||
{
|
||||
// If this is OUR breakpoint, we're fine, otherwise we don't know why this happened...
|
||||
BreakpointSiteSP site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (stop_info_sp->GetValue()));
|
||||
BreakpointSiteSP site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (stop_info_sp->GetValue()));
|
||||
if (site_sp && site_sp->IsBreakpointAtThisSite (m_return_bp_id))
|
||||
{
|
||||
const uint32_t num_frames = m_thread.GetStackFrameCount();
|
||||
|
@ -301,7 +301,7 @@ ThreadPlanStepOut::WillResume (StateType resume_state, bool current_plan)
|
|||
|
||||
if (current_plan)
|
||||
{
|
||||
Breakpoint *return_bp = m_thread.GetProcess().GetTarget().GetBreakpointByID(m_return_bp_id).get();
|
||||
Breakpoint *return_bp = m_thread.CalculateTarget()->GetBreakpointByID(m_return_bp_id).get();
|
||||
if (return_bp != NULL)
|
||||
return_bp->SetEnabled (true);
|
||||
}
|
||||
|
@ -313,7 +313,7 @@ ThreadPlanStepOut::WillStop ()
|
|||
{
|
||||
if (m_return_bp_id != LLDB_INVALID_BREAK_ID)
|
||||
{
|
||||
Breakpoint *return_bp = m_thread.GetProcess().GetTarget().GetBreakpointByID(m_return_bp_id).get();
|
||||
Breakpoint *return_bp = m_thread.CalculateTarget()->GetBreakpointByID(m_return_bp_id).get();
|
||||
if (return_bp != NULL)
|
||||
return_bp->SetEnabled (false);
|
||||
}
|
||||
|
@ -337,7 +337,7 @@ ThreadPlanStepOut::MischiefManaged ()
|
|||
log->Printf("Completed step out plan.");
|
||||
if (m_return_bp_id != LLDB_INVALID_BREAK_ID)
|
||||
{
|
||||
m_thread.GetProcess().GetTarget().RemoveBreakpointByID (m_return_bp_id);
|
||||
m_thread.CalculateTarget()->RemoveBreakpointByID (m_return_bp_id);
|
||||
m_return_bp_id = LLDB_INVALID_BREAK_ID;
|
||||
}
|
||||
|
||||
|
@ -424,7 +424,7 @@ ThreadPlanStepOut::CalculateReturnValue ()
|
|||
{
|
||||
ClangASTType ast_type (return_type->GetClangAST(), return_clang_type);
|
||||
|
||||
lldb::ABISP abi_sp = m_thread.GetProcess().GetABI();
|
||||
lldb::ABISP abi_sp = m_thread.GetProcess()->GetABI();
|
||||
if (abi_sp)
|
||||
{
|
||||
m_return_valobj_sp = abi_sp->GetReturnValueObject(m_thread, ast_type);
|
||||
|
|
|
@ -38,7 +38,7 @@ ThreadPlanStepOverBreakpoint::ThreadPlanStepOverBreakpoint (Thread &thread) :
|
|||
|
||||
{
|
||||
m_breakpoint_addr = m_thread.GetRegisterContext()->GetPC();
|
||||
m_breakpoint_site_id = m_thread.GetProcess().GetBreakpointSiteList().FindIDByAddress (m_breakpoint_addr);
|
||||
m_breakpoint_site_id = m_thread.GetProcess()->GetBreakpointSiteList().FindIDByAddress (m_breakpoint_addr);
|
||||
}
|
||||
|
||||
ThreadPlanStepOverBreakpoint::~ThreadPlanStepOverBreakpoint ()
|
||||
|
@ -88,9 +88,9 @@ ThreadPlanStepOverBreakpoint::WillResume (StateType resume_state, bool current_p
|
|||
|
||||
if (current_plan)
|
||||
{
|
||||
BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByAddress (m_breakpoint_addr));
|
||||
BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByAddress (m_breakpoint_addr));
|
||||
if (bp_site_sp && bp_site_sp->IsEnabled())
|
||||
m_thread.GetProcess().DisableBreakpoint (bp_site_sp.get());
|
||||
m_thread.GetProcess()->DisableBreakpoint (bp_site_sp.get());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -98,9 +98,9 @@ ThreadPlanStepOverBreakpoint::WillResume (StateType resume_state, bool current_p
|
|||
bool
|
||||
ThreadPlanStepOverBreakpoint::WillStop ()
|
||||
{
|
||||
BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByAddress (m_breakpoint_addr));
|
||||
BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByAddress (m_breakpoint_addr));
|
||||
if (bp_site_sp)
|
||||
m_thread.GetProcess().EnableBreakpoint (bp_site_sp.get());
|
||||
m_thread.GetProcess()->EnableBreakpoint (bp_site_sp.get());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -121,9 +121,9 @@ ThreadPlanStepOverBreakpoint::MischiefManaged ()
|
|||
if (log)
|
||||
log->Printf("Completed step over breakpoint plan.");
|
||||
// Otherwise, re-enable the breakpoint we were stepping over, and we're done.
|
||||
BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByAddress (m_breakpoint_addr));
|
||||
BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByAddress (m_breakpoint_addr));
|
||||
if (bp_site_sp)
|
||||
m_thread.GetProcess().EnableBreakpoint (bp_site_sp.get());
|
||||
m_thread.GetProcess()->EnableBreakpoint (bp_site_sp.get());
|
||||
ThreadPlan::MischiefManaged ();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ ThreadPlanStepOverRange::ShouldStop (Event *event_ptr)
|
|||
{
|
||||
StreamString s;
|
||||
s.Address (m_thread.GetRegisterContext()->GetPC(),
|
||||
m_thread.GetProcess().GetTarget().GetArchitecture().GetAddressByteSize());
|
||||
m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize());
|
||||
log->Printf("ThreadPlanStepOverRange reached %s.", s.GetData());
|
||||
}
|
||||
|
||||
|
|
|
@ -89,14 +89,14 @@ ThreadPlanStepRange::DumpRanges(Stream *s)
|
|||
size_t num_ranges = m_address_ranges.size();
|
||||
if (num_ranges == 1)
|
||||
{
|
||||
m_address_ranges[0].Dump (s, &m_thread.GetProcess().GetTarget(), Address::DumpStyleLoadAddress);
|
||||
m_address_ranges[0].Dump (s, m_thread.CalculateTarget().get(), Address::DumpStyleLoadAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t i = 0; i < num_ranges; i++)
|
||||
{
|
||||
s->PutCString("%d: ");
|
||||
m_address_ranges[i].Dump (s, &m_thread.GetProcess().GetTarget(), Address::DumpStyleLoadAddress);
|
||||
m_address_ranges[i].Dump (s, m_thread.CalculateTarget().get(), Address::DumpStyleLoadAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ ThreadPlanStepRange::InRange ()
|
|||
size_t num_ranges = m_address_ranges.size();
|
||||
for (size_t i = 0; i < num_ranges; i++)
|
||||
{
|
||||
ret_value = m_address_ranges[i].ContainsLoadAddress(pc_load_addr, &m_thread.GetProcess().GetTarget());
|
||||
ret_value = m_address_ranges[i].ContainsLoadAddress(pc_load_addr, m_thread.CalculateTarget().get());
|
||||
if (ret_value)
|
||||
break;
|
||||
}
|
||||
|
@ -136,13 +136,13 @@ ThreadPlanStepRange::InRange ()
|
|||
{
|
||||
StreamString s;
|
||||
m_addr_context.line_entry.range.Dump (&s,
|
||||
&m_thread.GetProcess().GetTarget(),
|
||||
m_thread.CalculateTarget().get(),
|
||||
Address::DumpStyleLoadAddress);
|
||||
|
||||
log->Printf ("Step range plan stepped to another range of same line: %s", s.GetData());
|
||||
}
|
||||
}
|
||||
else if (new_context.line_entry.range.GetBaseAddress().GetLoadAddress(&m_thread.GetProcess().GetTarget())
|
||||
else if (new_context.line_entry.range.GetBaseAddress().GetLoadAddress(m_thread.CalculateTarget().get())
|
||||
!= pc_load_addr)
|
||||
{
|
||||
// Another thing that sometimes happens here is that we step out of one line into the MIDDLE of another
|
||||
|
@ -157,7 +157,7 @@ ThreadPlanStepRange::InRange ()
|
|||
{
|
||||
StreamString s;
|
||||
m_addr_context.line_entry.range.Dump (&s,
|
||||
&m_thread.GetProcess().GetTarget(),
|
||||
m_thread.CalculateTarget().get(),
|
||||
Address::DumpStyleLoadAddress);
|
||||
|
||||
log->Printf ("Step range plan stepped to the middle of new line(%d): %s, continuing to clear this line.",
|
||||
|
@ -184,11 +184,11 @@ ThreadPlanStepRange::InSymbol()
|
|||
lldb::addr_t cur_pc = m_thread.GetRegisterContext()->GetPC();
|
||||
if (m_addr_context.function != NULL)
|
||||
{
|
||||
return m_addr_context.function->GetAddressRange().ContainsLoadAddress (cur_pc, &m_thread.GetProcess().GetTarget());
|
||||
return m_addr_context.function->GetAddressRange().ContainsLoadAddress (cur_pc, m_thread.CalculateTarget().get());
|
||||
}
|
||||
else if (m_addr_context.symbol != NULL)
|
||||
{
|
||||
return m_addr_context.symbol->GetAddressRangeRef().ContainsLoadAddress (cur_pc, &m_thread.GetProcess().GetTarget());
|
||||
return m_addr_context.symbol->GetAddressRangeRef().ContainsLoadAddress (cur_pc, m_thread.CalculateTarget().get());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -56,8 +56,8 @@ ThreadPlanStepThrough::ThreadPlanStepThrough (Thread &thread, bool stop_others)
|
|||
|
||||
if (return_frame_sp)
|
||||
{
|
||||
m_backstop_addr = return_frame_sp->GetFrameCodeAddress().GetLoadAddress(&m_thread.GetProcess().GetTarget());
|
||||
Breakpoint *return_bp = m_thread.GetProcess().GetTarget().CreateBreakpoint (m_backstop_addr, true).get();
|
||||
m_backstop_addr = return_frame_sp->GetFrameCodeAddress().GetLoadAddress(m_thread.CalculateTarget().get());
|
||||
Breakpoint *return_bp = m_thread.GetProcess()->GetTarget().CreateBreakpoint (m_backstop_addr, true).get();
|
||||
if (return_bp != NULL)
|
||||
{
|
||||
return_bp->SetThreadID(m_thread.GetID());
|
||||
|
@ -76,7 +76,7 @@ ThreadPlanStepThrough::~ThreadPlanStepThrough ()
|
|||
{
|
||||
if (m_backstop_bkpt_id != LLDB_INVALID_BREAK_ID)
|
||||
{
|
||||
m_thread.GetProcess().GetTarget().RemoveBreakpointByID (m_backstop_bkpt_id);
|
||||
m_thread.GetProcess()->GetTarget().RemoveBreakpointByID (m_backstop_bkpt_id);
|
||||
m_backstop_bkpt_id = LLDB_INVALID_BREAK_ID;
|
||||
}
|
||||
}
|
||||
|
@ -91,11 +91,11 @@ ThreadPlanStepThrough::DidPush ()
|
|||
void
|
||||
ThreadPlanStepThrough::LookForPlanToStepThroughFromCurrentPC()
|
||||
{
|
||||
m_sub_plan_sp = m_thread.GetProcess().GetDynamicLoader()->GetStepThroughTrampolinePlan (m_thread, m_stop_others);
|
||||
m_sub_plan_sp = m_thread.GetProcess()->GetDynamicLoader()->GetStepThroughTrampolinePlan (m_thread, m_stop_others);
|
||||
// If that didn't come up with anything, try the ObjC runtime plugin:
|
||||
if (!m_sub_plan_sp.get())
|
||||
{
|
||||
ObjCLanguageRuntime *objc_runtime = m_thread.GetProcess().GetObjCLanguageRuntime();
|
||||
ObjCLanguageRuntime *objc_runtime = m_thread.GetProcess()->GetObjCLanguageRuntime();
|
||||
if (objc_runtime)
|
||||
m_sub_plan_sp = objc_runtime->GetStepThroughTrampolinePlan (m_thread, m_stop_others);
|
||||
}
|
||||
|
@ -244,7 +244,7 @@ ThreadPlanStepThrough::MischiefManaged ()
|
|||
ThreadPlan::MischiefManaged ();
|
||||
if (m_backstop_bkpt_id != LLDB_INVALID_BREAK_ID)
|
||||
{
|
||||
m_thread.GetProcess().GetTarget().RemoveBreakpointByID (m_backstop_bkpt_id);
|
||||
m_thread.GetProcess()->GetTarget().RemoveBreakpointByID (m_backstop_bkpt_id);
|
||||
m_backstop_bkpt_id = LLDB_INVALID_BREAK_ID;
|
||||
}
|
||||
return true;
|
||||
|
@ -258,7 +258,7 @@ ThreadPlanStepThrough::HitOurBackstopBreakpoint()
|
|||
if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint)
|
||||
{
|
||||
break_id_t stop_value = (break_id_t) stop_info_sp->GetValue();
|
||||
BreakpointSiteSP cur_site_sp = m_thread.GetProcess().GetBreakpointSiteList().FindByID(stop_value);
|
||||
BreakpointSiteSP cur_site_sp = m_thread.GetProcess()->GetBreakpointSiteList().FindByID(stop_value);
|
||||
if (cur_site_sp && cur_site_sp->IsBreakpointAtThisSite(m_backstop_bkpt_id))
|
||||
{
|
||||
size_t current_stack_depth = m_thread.GetStackFrameCount();
|
||||
|
|
|
@ -55,7 +55,7 @@ ThreadPlanStepUntil::ThreadPlanStepUntil
|
|||
|
||||
SetOkayToDiscard(true);
|
||||
// Stash away our "until" addresses:
|
||||
Target &target = m_thread.GetProcess().GetTarget();
|
||||
TargetSP target_sp (m_thread.CalculateTarget());
|
||||
|
||||
StackFrameSP frame_sp (m_thread.GetStackFrameAtIndex (frame_idx));
|
||||
if (frame_sp)
|
||||
|
@ -71,7 +71,7 @@ ThreadPlanStepUntil::ThreadPlanStepUntil
|
|||
{
|
||||
// TODO: add inline functionality
|
||||
m_return_addr = return_frame_sp->GetStackID().GetPC();
|
||||
Breakpoint *return_bp = target.CreateBreakpoint (m_return_addr, true).get();
|
||||
Breakpoint *return_bp = target_sp->CreateBreakpoint (m_return_addr, true).get();
|
||||
if (return_bp != NULL)
|
||||
{
|
||||
return_bp->SetThreadID(thread_id);
|
||||
|
@ -84,7 +84,7 @@ ThreadPlanStepUntil::ThreadPlanStepUntil
|
|||
// Now set breakpoints on all our return addresses:
|
||||
for (int i = 0; i < num_addresses; i++)
|
||||
{
|
||||
Breakpoint *until_bp = target.CreateBreakpoint (address_list[i], true).get();
|
||||
Breakpoint *until_bp = target_sp->CreateBreakpoint (address_list[i], true).get();
|
||||
if (until_bp != NULL)
|
||||
{
|
||||
until_bp->SetThreadID(thread_id);
|
||||
|
@ -106,17 +106,20 @@ ThreadPlanStepUntil::~ThreadPlanStepUntil ()
|
|||
void
|
||||
ThreadPlanStepUntil::Clear()
|
||||
{
|
||||
Target &target = m_thread.GetProcess().GetTarget();
|
||||
if (m_return_bp_id != LLDB_INVALID_BREAK_ID)
|
||||
TargetSP target_sp (m_thread.CalculateTarget());
|
||||
if (target_sp)
|
||||
{
|
||||
target.RemoveBreakpointByID(m_return_bp_id);
|
||||
m_return_bp_id = LLDB_INVALID_BREAK_ID;
|
||||
}
|
||||
if (m_return_bp_id != LLDB_INVALID_BREAK_ID)
|
||||
{
|
||||
target_sp->RemoveBreakpointByID(m_return_bp_id);
|
||||
m_return_bp_id = LLDB_INVALID_BREAK_ID;
|
||||
}
|
||||
|
||||
until_collection::iterator pos, end = m_until_points.end();
|
||||
for (pos = m_until_points.begin(); pos != end; pos++)
|
||||
{
|
||||
target.RemoveBreakpointByID((*pos).second);
|
||||
until_collection::iterator pos, end = m_until_points.end();
|
||||
for (pos = m_until_points.begin(); pos != end; pos++)
|
||||
{
|
||||
target_sp->RemoveBreakpointByID((*pos).second);
|
||||
}
|
||||
}
|
||||
m_until_points.clear();
|
||||
}
|
||||
|
@ -187,7 +190,7 @@ ThreadPlanStepUntil::AnalyzeStop()
|
|||
case eStopReasonBreakpoint:
|
||||
{
|
||||
// If this is OUR breakpoint, we're fine, otherwise we don't know why this happened...
|
||||
BreakpointSiteSP this_site = m_thread.GetProcess().GetBreakpointSiteList().FindByID (stop_info_sp->GetValue());
|
||||
BreakpointSiteSP this_site = m_thread.GetProcess()->GetBreakpointSiteList().FindByID (stop_info_sp->GetValue());
|
||||
if (!this_site)
|
||||
{
|
||||
m_explains_stop = false;
|
||||
|
@ -305,17 +308,20 @@ ThreadPlanStepUntil::WillResume (StateType resume_state, bool current_plan)
|
|||
ThreadPlan::WillResume (resume_state, current_plan);
|
||||
if (current_plan)
|
||||
{
|
||||
Target &target = m_thread.GetProcess().GetTarget();
|
||||
Breakpoint *return_bp = target.GetBreakpointByID(m_return_bp_id).get();
|
||||
if (return_bp != NULL)
|
||||
return_bp->SetEnabled (true);
|
||||
|
||||
until_collection::iterator pos, end = m_until_points.end();
|
||||
for (pos = m_until_points.begin(); pos != end; pos++)
|
||||
TargetSP target_sp (m_thread.CalculateTarget());
|
||||
if (target_sp)
|
||||
{
|
||||
Breakpoint *until_bp = target.GetBreakpointByID((*pos).second).get();
|
||||
if (until_bp != NULL)
|
||||
until_bp->SetEnabled (true);
|
||||
Breakpoint *return_bp = target_sp->GetBreakpointByID(m_return_bp_id).get();
|
||||
if (return_bp != NULL)
|
||||
return_bp->SetEnabled (true);
|
||||
|
||||
until_collection::iterator pos, end = m_until_points.end();
|
||||
for (pos = m_until_points.begin(); pos != end; pos++)
|
||||
{
|
||||
Breakpoint *until_bp = target_sp->GetBreakpointByID((*pos).second).get();
|
||||
if (until_bp != NULL)
|
||||
until_bp->SetEnabled (true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -328,17 +334,20 @@ ThreadPlanStepUntil::WillResume (StateType resume_state, bool current_plan)
|
|||
bool
|
||||
ThreadPlanStepUntil::WillStop ()
|
||||
{
|
||||
Target &target = m_thread.GetProcess().GetTarget();
|
||||
Breakpoint *return_bp = target.GetBreakpointByID(m_return_bp_id).get();
|
||||
if (return_bp != NULL)
|
||||
return_bp->SetEnabled (false);
|
||||
|
||||
until_collection::iterator pos, end = m_until_points.end();
|
||||
for (pos = m_until_points.begin(); pos != end; pos++)
|
||||
TargetSP target_sp (m_thread.CalculateTarget());
|
||||
if (target_sp)
|
||||
{
|
||||
Breakpoint *until_bp = target.GetBreakpointByID((*pos).second).get();
|
||||
if (until_bp != NULL)
|
||||
until_bp->SetEnabled (false);
|
||||
Breakpoint *return_bp = target_sp->GetBreakpointByID(m_return_bp_id).get();
|
||||
if (return_bp != NULL)
|
||||
return_bp->SetEnabled (false);
|
||||
|
||||
until_collection::iterator pos, end = m_until_points.end();
|
||||
for (pos = m_until_points.begin(); pos != end; pos++)
|
||||
{
|
||||
Breakpoint *until_bp = target_sp->GetBreakpointByID((*pos).second).get();
|
||||
if (until_bp != NULL)
|
||||
until_bp->SetEnabled (false);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -119,7 +119,7 @@ ThreadPlanTestCondition::ShouldStop (Event *event_ptr)
|
|||
else
|
||||
{
|
||||
// Now we have to change the event to a breakpoint event and mark it up appropriately:
|
||||
Process::ProcessEventData *new_data = new Process::ProcessEventData (m_thread.GetProcess().shared_from_this(), eStateStopped);
|
||||
Process::ProcessEventData *new_data = new Process::ProcessEventData (m_thread.GetProcess(), eStateStopped);
|
||||
event_ptr->SetData(new_data);
|
||||
event_ptr->SetType(Process::eBroadcastBitStateChanged);
|
||||
SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID (m_thread,
|
||||
|
|
|
@ -55,7 +55,12 @@ ThreadPlanTracer::GetLogStream ()
|
|||
if (m_stream_sp.get())
|
||||
return m_stream_sp.get();
|
||||
else
|
||||
return &m_thread.GetProcess().GetTarget().GetDebugger().GetOutputStream();
|
||||
{
|
||||
TargetSP target_sp (m_thread.CalculateTarget());
|
||||
if (target_sp)
|
||||
return &target_sp->GetDebugger().GetOutputStream();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -109,7 +114,7 @@ Disassembler *
|
|||
ThreadPlanAssemblyTracer::GetDisassembler ()
|
||||
{
|
||||
if (m_disassembler_ap.get() == NULL)
|
||||
m_disassembler_ap.reset(Disassembler::FindPlugin(m_thread.GetProcess().GetTarget().GetArchitecture(), NULL));
|
||||
m_disassembler_ap.reset(Disassembler::FindPlugin(m_thread.GetProcess()->GetTarget().GetArchitecture(), NULL));
|
||||
return m_disassembler_ap.get();
|
||||
}
|
||||
|
||||
|
@ -118,13 +123,16 @@ ThreadPlanAssemblyTracer::GetIntPointerType()
|
|||
{
|
||||
if (!m_intptr_type.IsValid ())
|
||||
{
|
||||
Target &target = m_thread.GetProcess().GetTarget();
|
||||
Module *exe_module = target.GetExecutableModulePointer();
|
||||
|
||||
if (exe_module)
|
||||
TargetSP target_sp (m_thread.CalculateTarget());
|
||||
if (target_sp)
|
||||
{
|
||||
m_intptr_type = TypeFromUser(exe_module->GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, m_thread.GetProcess().GetAddressByteSize() * 8),
|
||||
exe_module->GetClangASTContext().getASTContext());
|
||||
Module *exe_module = target_sp->GetExecutableModulePointer();
|
||||
|
||||
if (exe_module)
|
||||
{
|
||||
m_intptr_type = TypeFromUser(exe_module->GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, target_sp->GetArchitecture().GetAddressByteSize() * 8),
|
||||
exe_module->GetClangASTContext().getASTContext());
|
||||
}
|
||||
}
|
||||
}
|
||||
return m_intptr_type;
|
||||
|
@ -173,11 +181,11 @@ ThreadPlanAssemblyTracer::Log ()
|
|||
RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
|
||||
|
||||
lldb::addr_t pc = reg_ctx->GetPC();
|
||||
Process &process = m_thread.GetProcess();
|
||||
ProcessSP process_sp (m_thread.GetProcess());
|
||||
Address pc_addr;
|
||||
bool addr_valid = false;
|
||||
uint8_t buffer[16] = {0}; // Must be big enough for any single instruction
|
||||
addr_valid = process.GetTarget().GetSectionLoadList().ResolveLoadAddress (pc, pc_addr);
|
||||
addr_valid = process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress (pc, pc_addr);
|
||||
|
||||
pc_addr.Dump(stream, &m_thread, Address::DumpStyleResolvedDescription, Address::DumpStyleModuleWithFileAddress);
|
||||
stream->PutCString (" ");
|
||||
|
@ -186,13 +194,13 @@ ThreadPlanAssemblyTracer::Log ()
|
|||
if (disassembler)
|
||||
{
|
||||
Error err;
|
||||
process.ReadMemory(pc, buffer, sizeof(buffer), err);
|
||||
process_sp->ReadMemory(pc, buffer, sizeof(buffer), err);
|
||||
|
||||
if (err.Success())
|
||||
{
|
||||
DataExtractor extractor(buffer, sizeof(buffer),
|
||||
process.GetByteOrder(),
|
||||
process.GetAddressByteSize());
|
||||
process_sp->GetByteOrder(),
|
||||
process_sp->GetAddressByteSize());
|
||||
|
||||
if (addr_valid)
|
||||
disassembler->DecodeInstructions (pc_addr, extractor, 0, 1, false);
|
||||
|
@ -217,7 +225,7 @@ ThreadPlanAssemblyTracer::Log ()
|
|||
}
|
||||
}
|
||||
|
||||
const ABI *abi = process.GetABI().get();
|
||||
const ABI *abi = process_sp->GetABI().get();
|
||||
TypeFromUser intptr_type = GetIntPointerType();
|
||||
|
||||
if (abi && intptr_type.IsValid())
|
||||
|
|
Loading…
Reference in New Issue