summaryrefslogtreecommitdiff
path: root/include/lldb/Target
diff options
context:
space:
mode:
Diffstat (limited to 'include/lldb/Target')
-rw-r--r--include/lldb/Target/ABI.h63
-rw-r--r--include/lldb/Target/CPPLanguageRuntime.h2
-rw-r--r--include/lldb/Target/ExecutionContext.h38
-rw-r--r--include/lldb/Target/ExecutionContextScope.h2
-rw-r--r--include/lldb/Target/FileAction.h68
-rw-r--r--include/lldb/Target/JITLoader.h90
-rw-r--r--include/lldb/Target/JITLoaderList.h60
-rw-r--r--include/lldb/Target/MemoryRegionInfo.h104
-rw-r--r--include/lldb/Target/NativeRegisterContext.h190
-rw-r--r--include/lldb/Target/NativeRegisterContextRegisterInfo.h44
-rw-r--r--include/lldb/Target/ObjCLanguageRuntime.h41
-rw-r--r--include/lldb/Target/PathMappingList.h2
-rw-r--r--include/lldb/Target/Platform.h84
-rw-r--r--include/lldb/Target/Process.h977
-rw-r--r--include/lldb/Target/ProcessInfo.h188
-rw-r--r--include/lldb/Target/ProcessLaunchInfo.h225
-rw-r--r--include/lldb/Target/Queue.h13
-rw-r--r--include/lldb/Target/QueueItem.h53
-rw-r--r--include/lldb/Target/QueueList.h4
-rw-r--r--include/lldb/Target/RegisterContext.h43
-rw-r--r--include/lldb/Target/StackFrame.h6
-rw-r--r--include/lldb/Target/StopInfo.h7
-rw-r--r--include/lldb/Target/SystemRuntime.h79
-rw-r--r--include/lldb/Target/Target.h79
-rw-r--r--include/lldb/Target/TargetList.h2
-rw-r--r--include/lldb/Target/Thread.h256
-rw-r--r--include/lldb/Target/ThreadPlan.h38
-rw-r--r--include/lldb/Target/ThreadPlanCallFunction.h8
-rw-r--r--include/lldb/Target/ThreadPlanCallUserExpression.h26
-rw-r--r--include/lldb/Target/ThreadPlanShouldStopHere.h85
-rw-r--r--include/lldb/Target/ThreadPlanStepInRange.h39
-rw-r--r--include/lldb/Target/ThreadPlanStepInstruction.h2
-rw-r--r--include/lldb/Target/ThreadPlanStepOut.h27
-rw-r--r--include/lldb/Target/ThreadPlanStepOverRange.h19
-rw-r--r--include/lldb/Target/ThreadPlanStepRange.h1
-rw-r--r--include/lldb/Target/UnwindAssembly.h5
36 files changed, 1975 insertions, 995 deletions
diff --git a/include/lldb/Target/ABI.h b/include/lldb/Target/ABI.h
index cc6c46cf0ec9d..8809c0047fa0c 100644
--- a/include/lldb/Target/ABI.h
+++ b/include/lldb/Target/ABI.h
@@ -20,24 +20,58 @@
#include "llvm/ADT/ArrayRef.h"
+// forward define the llvm::Type class
+namespace llvm { class Type; }
+
namespace lldb_private {
class ABI :
public PluginInterface
{
public:
+
+ struct CallArgument
+ {
+ enum eType
+ {
+ HostPointer = 0, /* pointer to host data */
+ TargetValue , /* value is on the target or literal */
+ };
+ eType type; /* value of eType */
+ size_t size; /* size in bytes of this argument */
+ union {
+ lldb::addr_t value; /* literal value */
+ uint8_t *data; /* host data pointer */
+ };
+ };
+
virtual
~ABI();
virtual size_t
GetRedZoneSize () const = 0;
-
+
virtual bool
- PrepareTrivialCall (Thread &thread,
- lldb::addr_t sp,
- lldb::addr_t functionAddress,
- lldb::addr_t returnAddress,
- llvm::ArrayRef<lldb::addr_t> args) const = 0;
+ PrepareTrivialCall ( lldb_private::Thread &thread,
+ lldb::addr_t sp,
+ lldb::addr_t functionAddress,
+ lldb::addr_t returnAddress,
+ llvm::ArrayRef<lldb::addr_t> args) const = 0;
+
+ // Prepare trivial call used from ThreadPlanFunctionCallGDB
+ // AD:
+ // . Because i don't want to change other ABI's this is not declared pure virtual.
+ // The dummy implementation will simply fail. Only HexagonABI will currently
+ // use this method.
+ // . Two PrepareTrivialCall's is not good design so perhaps this should be combined.
+ //
+ virtual bool
+ PrepareTrivialCall ( lldb_private::Thread &thread,
+ lldb::addr_t sp,
+ lldb::addr_t functionAddress,
+ lldb::addr_t returnAddress,
+ llvm::Type &prototype,
+ llvm::ArrayRef<CallArgument> args) const;
virtual bool
GetArgumentValues (Thread &thread,
@@ -48,16 +82,26 @@ public:
ClangASTType &type,
bool persistent = true) const;
+ // specialized to work with llvm IR types
+ lldb::ValueObjectSP
+ GetReturnValueObject (Thread &thread,
+ llvm::Type &type,
+ bool persistent = true) const;
+
// Set the Return value object in the current frame as though a function with
virtual Error
SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) = 0;
protected:
// This is the method the ABI will call to actually calculate the return value.
- // Don't put it in a persistant value object, that will be done by the ABI::GetReturnValueObject.
+ // Don't put it in a persistent value object, that will be done by the ABI::GetReturnValueObject.
virtual lldb::ValueObjectSP
- GetReturnValueObjectImpl (Thread &thread,
- ClangASTType &type) const = 0;
+ GetReturnValueObjectImpl (Thread &thread, ClangASTType &ast_type) const = 0;
+
+ // specialized to work with llvm IR types
+ virtual lldb::ValueObjectSP
+ GetReturnValueObjectImpl( Thread &thread, llvm::Type &ir_type ) const;
+
public:
virtual bool
CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan) = 0;
@@ -108,7 +152,6 @@ public:
virtual bool
FunctionCallsChangeCFA () = 0;
-
bool
GetRegisterInfoByName (const ConstString &name, RegisterInfo &info);
diff --git a/include/lldb/Target/CPPLanguageRuntime.h b/include/lldb/Target/CPPLanguageRuntime.h
index 98a4ab88cb25e..daf8a67d2a9db 100644
--- a/include/lldb/Target/CPPLanguageRuntime.h
+++ b/include/lldb/Target/CPPLanguageRuntime.h
@@ -136,7 +136,7 @@ public:
static bool
StripNamespacesFromVariableName (const char *name, const char *&base_name_start, const char *&base_name_end);
- // in some cases, compilers will output different names for one same type. when tht happens, it might be impossible
+ // in some cases, compilers will output different names for one same type. when that happens, it might be impossible
// to construct SBType objects for a valid type, because the name that is available is not the same as the name that
// can be used as a search key in FindTypes(). the equivalents map here is meant to return possible alternative names
// for a type through which a search can be conducted. Currently, this is only enabled for C++ but can be extended
diff --git a/include/lldb/Target/ExecutionContext.h b/include/lldb/Target/ExecutionContext.h
index f825c2e72e6da..50f2beaf949b0 100644
--- a/include/lldb/Target/ExecutionContext.h
+++ b/include/lldb/Target/ExecutionContext.h
@@ -18,10 +18,10 @@
/// 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.
+/// objects are described below.
///
/// Not all objects in an ExectionContext objects will be valid. If you want
-/// to refer stronly (ExectionContext) or weakly (ExectionContextRef) to
+/// to refer strongly (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.
@@ -49,7 +49,7 @@ namespace lldb_private {
/// 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
+/// might change over time and instances 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
@@ -64,7 +64,7 @@ namespace lldb_private {
/// 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.
+/// refer to execution contexts should use ExecutionContextRef objects.
/// 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
@@ -89,7 +89,7 @@ public:
/// 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
+ /// valid objects in the ExecutionContext, otherwise no weak
/// references to any execution context objects will be made.
//------------------------------------------------------------------
ExecutionContextRef (const ExecutionContext *exe_ctx_ptr);
@@ -104,7 +104,7 @@ public:
//------------------------------------------------------------------
/// Assignment operator
///
- /// Copy all weak refernces in \a rhs.
+ /// Copy all weak references in \a rhs.
//------------------------------------------------------------------
ExecutionContextRef &
operator =(const ExecutionContextRef &rhs);
@@ -112,7 +112,7 @@ public:
//------------------------------------------------------------------
/// Assignment operator from a ExecutionContext
///
- /// Make weak refernces to any stringly referenced objects in \a exe_ctx.
+ /// Make weak references to any strongly referenced objects in \a exe_ctx.
//------------------------------------------------------------------
ExecutionContextRef &
operator =(const ExecutionContext &exe_ctx);
@@ -129,13 +129,13 @@ public:
/// 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.
+ /// make weak references 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.
+ /// make weak references 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.
+ /// make weak references too the process and target.
/// If the ExecutionContextScope object is valid and refers to a target,
- /// make weak refernces too the target.
+ /// make weak references too the target.
//------------------------------------------------------------------
ExecutionContextRef (ExecutionContextScope *exe_scope);
@@ -143,13 +143,13 @@ public:
/// Construct using an execution context scope.
///
/// If the ExecutionContextScope object refers to a frame,
- /// make weak refernces too the frame, thread, process and target.
+ /// make weak references too the frame, thread, process and target.
/// If the ExecutionContextScope object refers to a thread,
- /// make weak refernces too the thread, process and target.
+ /// make weak references too the thread, process and target.
/// If the ExecutionContextScope object refers to a process,
- /// make weak refernces too the process and target.
+ /// make weak references too the process and target.
/// If the ExecutionContextScope object refers to a target,
- /// make weak refernces too the target.
+ /// make weak references too the target.
//------------------------------------------------------------------
ExecutionContextRef (ExecutionContextScope &exe_scope);
@@ -302,8 +302,8 @@ public:
//------------------------------------------------------------------
/// 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
+ /// The return value is only an indication of whether this object has
+ /// a weak reference and does not indicate whether the weak reference
/// is valid or not.
//------------------------------------------------------------------
bool
@@ -314,8 +314,8 @@ public:
//------------------------------------------------------------------
/// 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
+ /// The return value is only an indication of whether this object has
+ /// a weak reference and does not indicate whether the weak reference
/// is valid or not.
//------------------------------------------------------------------
bool
diff --git a/include/lldb/Target/ExecutionContextScope.h b/include/lldb/Target/ExecutionContextScope.h
index 7ba40971af2c1..4a1b17d5a1142 100644
--- a/include/lldb/Target/ExecutionContextScope.h
+++ b/include/lldb/Target/ExecutionContextScope.h
@@ -29,7 +29,7 @@ namespace lldb_private {
/// ExecutionContext object in the object state. Examples of these
/// objects include: Process, Thread, RegisterContext and StackFrame.
///
-/// Bbjects can contain a valid pointer to an instance of this so they
+/// Objects can contain a valid pointer to an instance of this so they
/// can reconstruct the execution context.
///
/// Objects that adhere to this protocol can reconstruct enough of a
diff --git a/include/lldb/Target/FileAction.h b/include/lldb/Target/FileAction.h
new file mode 100644
index 0000000000000..db84c0ef468c5
--- /dev/null
+++ b/include/lldb/Target/FileAction.h
@@ -0,0 +1,68 @@
+//===-- ProcessLaunchInfo.h -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Target_FileAction_h
+#define liblldb_Target_FileAction_h
+
+#include <string>
+
+namespace lldb_private
+{
+
+class FileAction
+{
+ public:
+ enum Action
+ {
+ eFileActionNone,
+ eFileActionClose,
+ eFileActionDuplicate,
+ eFileActionOpen
+ };
+
+ FileAction();
+
+ void Clear();
+
+ bool Close(int fd);
+
+ bool Duplicate(int fd, int dup_fd);
+
+ bool Open(int fd, const char *path, bool read, bool write);
+
+ int
+ GetFD() const
+ {
+ return m_fd;
+ }
+
+ Action
+ GetAction() const
+ {
+ return m_action;
+ }
+
+ int
+ GetActionArgument() const
+ {
+ return m_arg;
+ }
+
+ const char *GetPath() const;
+
+ protected:
+ Action m_action; // The action for this file
+ int m_fd; // An existing file descriptor
+ int m_arg; // oflag for eFileActionOpen*, dup_fd for eFileActionDuplicate
+ std::string m_path; // A file path to use for opening after fork or posix_spawn
+};
+
+} // namespace lldb_private
+
+#endif
diff --git a/include/lldb/Target/JITLoader.h b/include/lldb/Target/JITLoader.h
new file mode 100644
index 0000000000000..c15ae5a876f11
--- /dev/null
+++ b/include/lldb/Target/JITLoader.h
@@ -0,0 +1,90 @@
+//===-- JITLoader.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_JITLoader_h_
+#define liblldb_JITLoader_h_
+
+#include <vector>
+
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Target/JITLoaderList.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class JITLoader JITLoader.h "lldb/Target/JITLoader.h"
+/// @brief A plug-in interface definition class for JIT loaders.
+///
+/// Plugins of this kind listen for code generated at runtime in the
+/// target. They are very similar to dynamic loader, with the difference
+/// that they do not have information about the target's dyld and
+/// that there may be multiple JITLoader plugins per process, while
+/// there is at most one DynamicLoader.
+//----------------------------------------------------------------------
+class JITLoader :
+ public PluginInterface
+{
+public:
+ //------------------------------------------------------------------
+ /// Find a JIT loader plugin for a given process.
+ ///
+ /// Scans the installed DynamicLoader plug-ins and tries to find
+ /// all applicable instances for the current process.
+ ///
+ /// @param[in] process
+ /// The process for which to try and locate a JIT loader
+ /// plug-in instance.
+ ///
+ //------------------------------------------------------------------
+ static void
+ LoadPlugins (Process *process, lldb_private::JITLoaderList &list);
+
+ //------------------------------------------------------------------
+ /// Construct with a process.
+ //------------------------------------------------------------------
+ JITLoader (Process *process);
+
+ virtual
+ ~JITLoader ();
+
+ //------------------------------------------------------------------
+ /// Called after attaching a process.
+ ///
+ /// Allow JITLoader plug-ins to execute some code after
+ /// attaching to a process.
+ //------------------------------------------------------------------
+ virtual void
+ DidAttach () = 0;
+
+ //------------------------------------------------------------------
+ /// Called after launching a process.
+ ///
+ /// Allow JITLoader plug-ins to execute some code after
+ /// the process has stopped for the first time on launch.
+ //------------------------------------------------------------------
+ virtual void
+ DidLaunch () = 0;
+
+ //------------------------------------------------------------------
+ /// Called after a new shared object has been loaded so that it can
+ /// be probed for JIT entry point hooks.
+ //------------------------------------------------------------------
+ virtual void
+ ModulesDidLoad (lldb_private::ModuleList &module_list) = 0;
+
+protected:
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ Process* m_process;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_JITLoader_h_
diff --git a/include/lldb/Target/JITLoaderList.h b/include/lldb/Target/JITLoaderList.h
new file mode 100644
index 0000000000000..f933a61e9952f
--- /dev/null
+++ b/include/lldb/Target/JITLoaderList.h
@@ -0,0 +1,60 @@
+//===-- JITLoaderList.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_JITLoaderList_h_
+#define liblldb_JITLoaderList_h_
+
+#include <vector>
+
+#include "lldb/lldb-forward.h"
+#include "lldb/Host/Mutex.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class JITLoaderList JITLoaderList.h "lldb/Target/JITLoaderList.h"
+///
+/// Class used by the Process to hold a list of its JITLoaders.
+//----------------------------------------------------------------------
+class JITLoaderList
+{
+public:
+
+ JITLoaderList();
+ ~JITLoaderList();
+
+ void
+ Append (const lldb::JITLoaderSP &jit_loader_sp);
+
+ void
+ Remove (const lldb::JITLoaderSP &jit_loader_sp);
+
+ size_t
+ GetSize() const;
+
+ lldb::JITLoaderSP
+ GetLoaderAtIndex (size_t idx);
+
+ void
+ DidLaunch();
+
+ void
+ DidAttach();
+
+ void
+ ModulesDidLoad (ModuleList &module_list);
+
+private:
+ std::vector<lldb::JITLoaderSP> m_jit_loaders_vec;
+ lldb_private::Mutex m_jit_loaders_mutex;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_JITLoaderList_h_
diff --git a/include/lldb/Target/MemoryRegionInfo.h b/include/lldb/Target/MemoryRegionInfo.h
new file mode 100644
index 0000000000000..0726ad15e8769
--- /dev/null
+++ b/include/lldb/Target/MemoryRegionInfo.h
@@ -0,0 +1,104 @@
+//===-- MemoryRegionInfo.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_MemoryRegionInfo_h
+#define lldb_MemoryRegionInfo_h
+
+#include "lldb/Core/RangeMap.h"
+#include "lldb/Utility/Range.h"
+
+namespace lldb_private
+{
+ class MemoryRegionInfo
+ {
+ public:
+ typedef Range<lldb::addr_t, lldb::addr_t> RangeType;
+
+ enum OptionalBool {
+ eDontKnow = -1,
+ eNo = 0,
+ eYes = 1
+ };
+
+ MemoryRegionInfo () :
+ m_range (),
+ m_read (eDontKnow),
+ m_write (eDontKnow),
+ m_execute (eDontKnow)
+ {
+ }
+
+ ~MemoryRegionInfo ()
+ {
+ }
+
+ RangeType &
+ GetRange()
+ {
+ return m_range;
+ }
+
+ void
+ Clear()
+ {
+ m_range.Clear();
+ m_read = m_write = m_execute = eDontKnow;
+ }
+
+ const RangeType &
+ GetRange() const
+ {
+ return m_range;
+ }
+
+ OptionalBool
+ GetReadable () const
+ {
+ return m_read;
+ }
+
+ OptionalBool
+ GetWritable () const
+ {
+ return m_write;
+ }
+
+ OptionalBool
+ GetExecutable () const
+ {
+ return m_execute;
+ }
+
+ void
+ SetReadable (OptionalBool val)
+ {
+ m_read = val;
+ }
+
+ void
+ SetWritable (OptionalBool val)
+ {
+ m_write = val;
+ }
+
+ void
+ SetExecutable (OptionalBool val)
+ {
+ m_execute = val;
+ }
+
+ protected:
+ RangeType m_range;
+ OptionalBool m_read;
+ OptionalBool m_write;
+ OptionalBool m_execute;
+ };
+}
+
+#endif // #ifndef lldb_MemoryRegionInfo_h
diff --git a/include/lldb/Target/NativeRegisterContext.h b/include/lldb/Target/NativeRegisterContext.h
new file mode 100644
index 0000000000000..fa4ab013f2341
--- /dev/null
+++ b/include/lldb/Target/NativeRegisterContext.h
@@ -0,0 +1,190 @@
+//===-- NativeRegisterContext.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_NativeRegisterContext_h_
+#define liblldb_NativeRegisterContext_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+class NativeThreadProtocol;
+
+class NativeRegisterContext:
+ public std::enable_shared_from_this<NativeRegisterContext>
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ NativeRegisterContext (NativeThreadProtocol &thread, uint32_t concrete_frame_idx);
+
+ virtual
+ ~NativeRegisterContext ();
+
+ // void
+ // InvalidateIfNeeded (bool force);
+
+ //------------------------------------------------------------------
+ // Subclasses must override these functions
+ //------------------------------------------------------------------
+ // virtual void
+ // InvalidateAllRegisters () = 0;
+
+ virtual uint32_t
+ GetRegisterCount () const = 0;
+
+ virtual const RegisterInfo *
+ GetRegisterInfoAtIndex (uint32_t reg) const = 0;
+
+ const char *
+ GetRegisterSetNameForRegisterAtIndex (uint32_t reg_index) const;
+
+ virtual uint32_t
+ GetRegisterSetCount () const = 0;
+
+ virtual const RegisterSet *
+ GetRegisterSet (uint32_t set_index) const = 0;
+
+ virtual Error
+ ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value) = 0;
+
+ virtual Error
+ WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value) = 0;
+
+ virtual Error
+ ReadAllRegisterValues (lldb::DataBufferSP &data_sp) = 0;
+
+ virtual Error
+ WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) = 0;
+
+ uint32_t
+ ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) const;
+
+ //------------------------------------------------------------------
+ // Subclasses can override these functions if desired
+ //------------------------------------------------------------------
+ virtual uint32_t
+ NumSupportedHardwareBreakpoints ();
+
+ virtual uint32_t
+ SetHardwareBreakpoint (lldb::addr_t addr, size_t size);
+
+ virtual bool
+ ClearHardwareBreakpoint (uint32_t hw_idx);
+
+ virtual uint32_t
+ NumSupportedHardwareWatchpoints ();
+
+ virtual uint32_t
+ SetHardwareWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags);
+
+ virtual bool
+ ClearHardwareWatchpoint (uint32_t hw_index);
+
+ virtual bool
+ HardwareSingleStep (bool enable);
+
+ virtual Error
+ ReadRegisterValueFromMemory (const lldb_private::RegisterInfo *reg_info, lldb::addr_t src_addr, lldb::addr_t src_len, RegisterValue &reg_value);
+
+ virtual Error
+ WriteRegisterValueToMemory (const lldb_private::RegisterInfo *reg_info, lldb::addr_t dst_addr, lldb::addr_t dst_len, const RegisterValue &reg_value);
+
+ //------------------------------------------------------------------
+ // Subclasses should not override these
+ //------------------------------------------------------------------
+ virtual lldb::tid_t
+ GetThreadID() const;
+
+ virtual NativeThreadProtocol &
+ GetThread ()
+ {
+ return m_thread;
+ }
+
+ const RegisterInfo *
+ GetRegisterInfoByName (const char *reg_name, uint32_t start_idx = 0);
+
+ const RegisterInfo *
+ GetRegisterInfo (uint32_t reg_kind, uint32_t reg_num);
+
+ lldb::addr_t
+ GetPC (lldb::addr_t fail_value = LLDB_INVALID_ADDRESS);
+
+ Error
+ SetPC (lldb::addr_t pc);
+
+ lldb::addr_t
+ GetSP (lldb::addr_t fail_value = LLDB_INVALID_ADDRESS);
+
+ Error
+ SetSP (lldb::addr_t sp);
+
+ lldb::addr_t
+ GetFP (lldb::addr_t fail_value = LLDB_INVALID_ADDRESS);
+
+ Error
+ SetFP (lldb::addr_t fp);
+
+ const char *
+ GetRegisterName (uint32_t reg);
+
+ lldb::addr_t
+ GetReturnAddress (lldb::addr_t fail_value = LLDB_INVALID_ADDRESS);
+
+ lldb::addr_t
+ GetFlags (lldb::addr_t fail_value = 0);
+
+ lldb::addr_t
+ ReadRegisterAsUnsigned (uint32_t reg, lldb::addr_t fail_value);
+
+ lldb::addr_t
+ ReadRegisterAsUnsigned (const RegisterInfo *reg_info, lldb::addr_t fail_value);
+
+ Error
+ WriteRegisterFromUnsigned (uint32_t reg, uint64_t uval);
+
+ Error
+ WriteRegisterFromUnsigned (const RegisterInfo *reg_info, uint64_t uval);
+
+ // uint32_t
+ // GetStopID () const
+ // {
+ // return m_stop_id;
+ // }
+
+ // void
+ // SetStopID (uint32_t stop_id)
+ // {
+ // m_stop_id = stop_id;
+ // }
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from RegisterContext can see and modify these
+ //------------------------------------------------------------------
+ NativeThreadProtocol &m_thread; // The thread that this register context belongs to.
+ uint32_t m_concrete_frame_idx; // The concrete frame index for this register context
+ // uint32_t m_stop_id; // The stop ID that any data in this context is valid for
+
+private:
+ //------------------------------------------------------------------
+ // For RegisterContext only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (NativeRegisterContext);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_NativeRegisterContext_h_
diff --git a/include/lldb/Target/NativeRegisterContextRegisterInfo.h b/include/lldb/Target/NativeRegisterContextRegisterInfo.h
new file mode 100644
index 0000000000000..5631005ca56e4
--- /dev/null
+++ b/include/lldb/Target/NativeRegisterContextRegisterInfo.h
@@ -0,0 +1,44 @@
+//===-- NativeRegisterContextRegisterInfo.h ----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_NativeRegisterContextRegisterInfo_h
+#define lldb_NativeRegisterContextRegisterInfo_h
+
+#include <memory>
+
+#include "NativeRegisterContext.h"
+#include "Plugins/Process/Utility/RegisterInfoInterface.h"
+
+namespace lldb_private
+{
+ class NativeRegisterContextRegisterInfo: public NativeRegisterContext
+ {
+ public:
+ ///
+ /// Construct a NativeRegisterContextRegisterInfo, taking ownership
+ /// of the register_info_interface pointer.
+ ///
+ NativeRegisterContextRegisterInfo (NativeThreadProtocol &thread,
+ uint32_t concrete_frame_idx,
+ RegisterInfoInterface *register_info_interface);
+
+ uint32_t
+ GetRegisterCount () const override;
+
+ const RegisterInfo *
+ GetRegisterInfoAtIndex (uint32_t reg_index) const override;
+
+ const RegisterInfoInterface&
+ GetRegisterInfoInterface () const;
+
+ private:
+ std::unique_ptr<RegisterInfoInterface> m_register_info_interface_up;
+ };
+}
+#endif
diff --git a/include/lldb/Target/ObjCLanguageRuntime.h b/include/lldb/Target/ObjCLanguageRuntime.h
index 7bac57256444b..12254f942e426 100644
--- a/include/lldb/Target/ObjCLanguageRuntime.h
+++ b/include/lldb/Target/ObjCLanguageRuntime.h
@@ -20,6 +20,7 @@
// Project includes
#include "lldb/lldb-private.h"
#include "lldb/Core/PluginInterface.h"
+#include "lldb/Symbol/ClangASTType.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/TypeVendor.h"
#include "lldb/Target/LanguageRuntime.h"
@@ -221,7 +222,7 @@ public:
Describe (std::function <void (ObjCISA)> const &superclass_func,
std::function <bool (const char*, const char*)> const &instance_method_func,
std::function <bool (const char*, const char*)> const &class_method_func,
- std::function <bool (const char *, const char *, lldb::addr_t, uint64_t)> const &ivar_func)
+ std::function <bool (const char *, const char *, lldb::addr_t, uint64_t)> const &ivar_func) const
{
return false;
}
@@ -238,6 +239,25 @@ public:
m_type_wp = type_sp;
}
+ struct iVarDescriptor {
+ ConstString m_name;
+ ClangASTType m_type;
+ uint64_t m_size;
+ int32_t m_offset;
+ };
+
+ virtual size_t
+ GetNumIVars ()
+ {
+ return 0;
+ }
+
+ virtual iVarDescriptor
+ GetIVarAtIndex (size_t idx)
+ {
+ return iVarDescriptor();
+ }
+
protected:
bool
IsPointerValid (lldb::addr_t value,
@@ -252,6 +272,25 @@ public:
lldb::TypeWP m_type_wp;
};
+ class EncodingToType
+ {
+ public:
+ virtual ClangASTType RealizeType (ClangASTContext& ast_ctx, const char* name, bool allow_unknownanytype);
+ virtual ClangASTType RealizeType (const char* name, bool allow_unknownanytype);
+
+ virtual ClangASTType RealizeType (clang::ASTContext& ast_ctx, const char* name, bool allow_unknownanytype) = 0;
+
+ virtual ~EncodingToType();
+
+ protected:
+ std::unique_ptr<ClangASTContext> m_scratch_ast_ctx_ap;
+ };
+
+ typedef std::shared_ptr<EncodingToType> EncodingToTypeSP;
+
+ virtual EncodingToTypeSP
+ GetEncodingToType ();
+
virtual ClassDescriptorSP
GetClassDescriptor (ValueObject& in_value);
diff --git a/include/lldb/Target/PathMappingList.h b/include/lldb/Target/PathMappingList.h
index b5bcbbfd768fe..17185cb684958 100644
--- a/include/lldb/Target/PathMappingList.h
+++ b/include/lldb/Target/PathMappingList.h
@@ -78,7 +78,7 @@ public:
bool notify);
bool
- Remove (off_t index, bool notify);
+ Remove (size_t index, bool notify);
bool
Remove (const ConstString &path, bool notify);
diff --git a/include/lldb/Target/Platform.h b/include/lldb/Target/Platform.h
index 80011fd120de2..e3d6abe3f398e 100644
--- a/include/lldb/Target/Platform.h
+++ b/include/lldb/Target/Platform.h
@@ -18,6 +18,7 @@
// Other libraries and framework includes
// Project includes
+#include "lldb/lldb-private-forward.h"
#include "lldb/lldb-public.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/ConstString.h"
@@ -25,6 +26,10 @@
#include "lldb/Interpreter/Options.h"
#include "lldb/Host/Mutex.h"
+// TODO pull NativeDelegate class out of NativeProcessProtocol so we
+// can just forward ref the NativeDelegate rather than include it here.
+#include "../../../source/Host/common/NativeProcessProtocol.h"
+
namespace lldb_private {
//----------------------------------------------------------------------
@@ -174,13 +179,13 @@ namespace lldb_private {
/// m_arch - The architecture we are looking for when resolving
/// the symbol file.
/// m_uuid - The UUID of the executable and symbol file. This
- /// can often be used to match up an exectuable with
+ /// can often be used to match up an executable with
/// a symbol file, or resolve an symbol file in a
/// symbol file bundle.
///
/// @param[out] sym_file
/// The resolved symbol file spec if the returned error
- /// indicates succes.
+ /// indicates success.
///
/// @return
/// Returns an error that describes success or failure.
@@ -215,7 +220,7 @@ namespace lldb_private {
bool
GetOSKernelDescription (std::string &s);
- // Returns the the name of the platform
+ // Returns the name of the platform
ConstString
GetName ();
@@ -241,7 +246,7 @@ namespace lldb_private {
//
// Remote classes must be connected for this to succeed. Local
// subclasses don't need to override this function as it will just
- // call the Host::GetOSVersion().
+ // call the HostInfo::GetOSVersion().
//------------------------------------------------------------------
virtual bool
GetRemoteOSVersion ()
@@ -326,7 +331,8 @@ namespace lldb_private {
//----------------------------------------------------------------------
virtual FileSpecList
LocateExecutableScriptingResources (Target *target,
- Module &module);
+ Module &module,
+ Stream* feedback_stream);
virtual Error
GetSharedModule (const ModuleSpec &module_spec,
@@ -349,7 +355,7 @@ namespace lldb_private {
/// A zero based architecture index
///
/// @param[out] arch
- /// A copy of the archgitecture at index if the return value is
+ /// A copy of the architecture at index if the return value is
/// \b true.
///
/// @return
@@ -413,7 +419,7 @@ namespace lldb_private {
/// attempt to attach to the process with the process ID of \a pid.
/// The platform subclass should return an appropriate ProcessSP
/// subclass that is attached to the process, or an empty shared
- /// pointer with an appriopriate error.
+ /// pointer with an appropriate error.
///
/// @param[in] pid
/// The process ID that we should attempt to attach to.
@@ -422,7 +428,7 @@ namespace lldb_private {
/// An appropriate ProcessSP containing a valid shared pointer
/// to the default Process subclass for the platform that is
/// attached to the process, or an empty shared pointer with an
- /// appriopriate error fill into the \a error object.
+ /// appropriate error fill into the \a error object.
//------------------------------------------------------------------
virtual lldb::ProcessSP
Attach (ProcessAttachInfo &attach_info,
@@ -858,13 +864,72 @@ namespace lldb_private {
virtual const std::vector<ConstString> &
GetTrapHandlerSymbolNames ();
+ //------------------------------------------------------------------
+ /// Launch a process for debugging.
+ ///
+ /// This differs from Launch in that it returns a NativeProcessProtocol.
+ /// Currently used by lldb-gdbserver.
+ ///
+ /// @param[in] launch_info
+ /// Information required to launch the process.
+ ///
+ /// @param[in] native_delegate
+ /// The delegate that will receive messages regarding the
+ /// inferior. Must outlive the NativeProcessProtocol
+ /// instance.
+ ///
+ /// @param[out] process_sp
+ /// On successful return from the method, this parameter
+ /// contains the shared pointer to the
+ /// NativeProcessProtocol that can be used to manipulate
+ /// the native process.
+ ///
+ /// @return
+ /// An error object indicating if the operation succeeded,
+ /// and if not, what error occurred.
+ //------------------------------------------------------------------
+ virtual Error
+ LaunchNativeProcess (
+ ProcessLaunchInfo &launch_info,
+ lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate,
+ NativeProcessProtocolSP &process_sp);
+
+ //------------------------------------------------------------------
+ /// Attach to an existing process on the given platform.
+ ///
+ /// This method differs from Attach() in that it returns a
+ /// NativeProcessProtocol. Currently this is used by lldb-gdbserver.
+ ///
+ /// @param[in] pid
+ /// pid of the process locatable by the platform.
+ ///
+ /// @param[in] native_delegate
+ /// The delegate that will receive messages regarding the
+ /// inferior. Must outlive the NativeProcessProtocol
+ /// instance.
+ ///
+ /// @param[out] process_sp
+ /// On successful return from the method, this parameter
+ /// contains the shared pointer to the
+ /// NativeProcessProtocol that can be used to manipulate
+ /// the native process.
+ ///
+ /// @return
+ /// An error object indicating if the operation succeeded,
+ /// and if not, what error occurred.
+ //------------------------------------------------------------------
+ virtual Error
+ AttachNativeProcess (lldb::pid_t pid,
+ lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate,
+ NativeProcessProtocolSP &process_sp);
+
protected:
bool m_is_host;
// Set to true when we are able to actually set the OS version while
// being connected. For remote platforms, we might set the version ahead
// of time before we actually connect and this version might change when
// we actually connect to a remote platform. For the host platform this
- // will be set to the once we call Host::GetOSVersion().
+ // will be set to the once we call HostInfo::GetOSVersion().
bool m_os_version_set_while_connected;
bool m_system_arch_set_while_connected;
ConstString m_sdk_sysroot; // the root location of where the SDK files are all located
@@ -892,6 +957,7 @@ namespace lldb_private {
std::string m_local_cache_directory;
std::vector<ConstString> m_trap_handlers;
bool m_calculated_trap_handlers;
+ Mutex m_trap_handler_mutex;
//------------------------------------------------------------------
/// Ask the Platform subclass to fill in the list of trap handler names
diff --git a/include/lldb/Target/Process.h b/include/lldb/Target/Process.h
index b74347d37e686..641707c58deba 100644
--- a/include/lldb/Target/Process.h
+++ b/include/lldb/Target/Process.h
@@ -42,7 +42,11 @@
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Target/JITLoaderList.h"
#include "lldb/Target/Memory.h"
+#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Target/ProcessInfo.h"
+#include "lldb/Target/ProcessLaunchInfo.h"
#include "lldb/Target/QueueList.h"
#include "lldb/Target/ThreadList.h"
#include "lldb/Target/UnixSignals.h"
@@ -104,232 +108,6 @@ public:
typedef std::shared_ptr<ProcessProperties> ProcessPropertiesSP;
//----------------------------------------------------------------------
-// ProcessInfo
-//
-// A base class for information for a process. This can be used to fill
-// out information for a process prior to launching it, or it can be
-// used for an instance of a process and can be filled in with the
-// existing values for that process.
-//----------------------------------------------------------------------
-class ProcessInfo
-{
-public:
- ProcessInfo () :
- m_executable (),
- m_arguments (),
- m_environment (),
- m_uid (UINT32_MAX),
- m_gid (UINT32_MAX),
- m_arch(),
- m_pid (LLDB_INVALID_PROCESS_ID)
- {
- }
-
- ProcessInfo (const char *name,
- const ArchSpec &arch,
- lldb::pid_t pid) :
- m_executable (name, false),
- m_arguments (),
- m_environment(),
- m_uid (UINT32_MAX),
- m_gid (UINT32_MAX),
- m_arch (arch),
- m_pid (pid)
- {
- }
-
- void
- Clear ()
- {
- m_executable.Clear();
- m_arguments.Clear();
- m_environment.Clear();
- m_uid = UINT32_MAX;
- m_gid = UINT32_MAX;
- m_arch.Clear();
- m_pid = LLDB_INVALID_PROCESS_ID;
- }
-
- const char *
- GetName() const
- {
- return m_executable.GetFilename().GetCString();
- }
-
- size_t
- GetNameLength() const
- {
- return m_executable.GetFilename().GetLength();
- }
-
- FileSpec &
- GetExecutableFile ()
- {
- return m_executable;
- }
-
- void
- SetExecutableFile (const FileSpec &exe_file, bool add_exe_file_as_first_arg)
- {
- if (exe_file)
- {
- m_executable = exe_file;
- if (add_exe_file_as_first_arg)
- {
- char filename[PATH_MAX];
- if (exe_file.GetPath(filename, sizeof(filename)))
- m_arguments.InsertArgumentAtIndex (0, filename);
- }
- }
- else
- {
- m_executable.Clear();
- }
- }
-
- const FileSpec &
- GetExecutableFile () const
- {
- return m_executable;
- }
-
- uint32_t
- GetUserID() const
- {
- return m_uid;
- }
-
- uint32_t
- GetGroupID() const
- {
- return m_gid;
- }
-
- bool
- UserIDIsValid () const
- {
- return m_uid != UINT32_MAX;
- }
-
- bool
- GroupIDIsValid () const
- {
- return m_gid != UINT32_MAX;
- }
-
- void
- SetUserID (uint32_t uid)
- {
- m_uid = uid;
- }
-
- void
- SetGroupID (uint32_t gid)
- {
- m_gid = gid;
- }
-
- ArchSpec &
- GetArchitecture ()
- {
- return m_arch;
- }
-
- const ArchSpec &
- GetArchitecture () const
- {
- return m_arch;
- }
-
- void
- SetArchitecture (ArchSpec arch)
- {
- m_arch = arch;
- }
-
- lldb::pid_t
- GetProcessID () const
- {
- return m_pid;
- }
-
- void
- SetProcessID (lldb::pid_t pid)
- {
- m_pid = pid;
- }
-
- bool
- ProcessIDIsValid() const
- {
- return m_pid != LLDB_INVALID_PROCESS_ID;
- }
-
- void
- Dump (Stream &s, Platform *platform) const;
-
- Args &
- GetArguments ()
- {
- return m_arguments;
- }
-
- const Args &
- GetArguments () const
- {
- return m_arguments;
- }
-
- const char *
- GetArg0 () const
- {
- if (m_arg0.empty())
- return NULL;
- return m_arg0.c_str();
- }
-
- void
- SetArg0 (const char *arg)
- {
- if (arg && arg[0])
- m_arg0 = arg;
- else
- m_arg0.clear();
- }
-
- void
- SetArguments (const Args& args, bool first_arg_is_executable);
-
- void
- SetArguments (char const **argv, bool first_arg_is_executable);
-
- Args &
- GetEnvironmentEntries ()
- {
- return m_environment;
- }
-
- const Args &
- GetEnvironmentEntries () const
- {
- return m_environment;
- }
-
-protected:
- FileSpec m_executable;
- std::string m_arg0; // argv[0] if supported. If empty, then use m_executable.
- // Not all process plug-ins support specifying an argv[0]
- // that differs from the resolved platform executable
- // (which is in m_executable)
- Args m_arguments; // All program arguments except argv[0]
- Args m_environment;
- uint32_t m_uid;
- uint32_t m_gid;
- ArchSpec m_arch;
- lldb::pid_t m_pid;
-};
-
-//----------------------------------------------------------------------
// ProcessInstanceInfo
//
// Describes an existing process and any discoverable information that
@@ -434,445 +212,10 @@ protected:
lldb::pid_t m_parent_pid;
};
-
//----------------------------------------------------------------------
-// ProcessLaunchInfo
+// ProcessAttachInfo
//
-// Describes any information that is required to launch a process.
-//----------------------------------------------------------------------
-
-class ProcessLaunchInfo : public ProcessInfo
-{
-public:
-
- class FileAction
- {
- public:
- enum Action
- {
- eFileActionNone,
- eFileActionClose,
- eFileActionDuplicate,
- eFileActionOpen
- };
-
-
- FileAction () :
- m_action (eFileActionNone),
- m_fd (-1),
- m_arg (-1),
- m_path ()
- {
- }
-
- void
- Clear()
- {
- m_action = eFileActionNone;
- m_fd = -1;
- m_arg = -1;
- m_path.clear();
- }
-
- bool
- Close (int fd);
-
- bool
- Duplicate (int fd, int dup_fd);
-
- bool
- Open (int fd, const char *path, bool read, bool write);
-
-#ifndef LLDB_DISABLE_POSIX
- static bool
- AddPosixSpawnFileAction (void *file_actions,
- const FileAction *info,
- Log *log,
- Error& error);
-#endif
-
- int
- GetFD () const
- {
- return m_fd;
- }
-
- Action
- GetAction () const
- {
- return m_action;
- }
-
- int
- GetActionArgument () const
- {
- return m_arg;
- }
-
- const char *
- GetPath () const
- {
- if (m_path.empty())
- return NULL;
- return m_path.c_str();
- }
-
- protected:
- Action m_action; // The action for this file
- int m_fd; // An existing file descriptor
- int m_arg; // oflag for eFileActionOpen*, dup_fd for eFileActionDuplicate
- std::string m_path; // A file path to use for opening after fork or posix_spawn
- };
-
- ProcessLaunchInfo () :
- ProcessInfo(),
- m_working_dir (),
- m_plugin_name (),
- m_shell (),
- m_flags (0),
- m_file_actions (),
- m_pty (),
- m_resume_count (0),
- m_monitor_callback (NULL),
- m_monitor_callback_baton (NULL),
- m_monitor_signals (false),
- m_hijack_listener_sp ()
- {
- }
-
- ProcessLaunchInfo (const char *stdin_path,
- const char *stdout_path,
- const char *stderr_path,
- const char *working_directory,
- uint32_t launch_flags) :
- ProcessInfo(),
- m_working_dir (),
- m_plugin_name (),
- m_shell (),
- m_flags (launch_flags),
- m_file_actions (),
- m_pty (),
- m_resume_count (0),
- m_monitor_callback (NULL),
- m_monitor_callback_baton (NULL),
- m_monitor_signals (false),
- m_hijack_listener_sp ()
- {
- if (stdin_path)
- {
- ProcessLaunchInfo::FileAction file_action;
- const bool read = true;
- const bool write = false;
- if (file_action.Open(STDIN_FILENO, stdin_path, read, write))
- AppendFileAction (file_action);
- }
- if (stdout_path)
- {
- ProcessLaunchInfo::FileAction file_action;
- const bool read = false;
- const bool write = true;
- if (file_action.Open(STDOUT_FILENO, stdout_path, read, write))
- AppendFileAction (file_action);
- }
- if (stderr_path)
- {
- ProcessLaunchInfo::FileAction file_action;
- const bool read = false;
- const bool write = true;
- if (file_action.Open(STDERR_FILENO, stderr_path, read, write))
- AppendFileAction (file_action);
- }
- if (working_directory)
- SetWorkingDirectory(working_directory);
- }
-
- void
- AppendFileAction (const FileAction &info)
- {
- m_file_actions.push_back(info);
- }
-
- bool
- AppendCloseFileAction (int fd)
- {
- FileAction file_action;
- if (file_action.Close (fd))
- {
- AppendFileAction (file_action);
- return true;
- }
- return false;
- }
-
- bool
- AppendDuplicateFileAction (int fd, int dup_fd)
- {
- FileAction file_action;
- if (file_action.Duplicate (fd, dup_fd))
- {
- AppendFileAction (file_action);
- return true;
- }
- return false;
- }
-
- bool
- AppendOpenFileAction (int fd, const char *path, bool read, bool write)
- {
- FileAction file_action;
- if (file_action.Open (fd, path, read, write))
- {
- AppendFileAction (file_action);
- return true;
- }
- return false;
- }
-
- bool
- AppendSuppressFileAction (int fd, bool read, bool write)
- {
- FileAction file_action;
- if (file_action.Open (fd, "/dev/null", read, write))
- {
- AppendFileAction (file_action);
- return true;
- }
- return false;
- }
-
- void
- FinalizeFileActions (Target *target,
- bool default_to_use_pty);
-
- size_t
- GetNumFileActions () const
- {
- return m_file_actions.size();
- }
-
- const FileAction *
- GetFileActionAtIndex (size_t idx) const
- {
- if (idx < m_file_actions.size())
- return &m_file_actions[idx];
- return NULL;
- }
-
- const FileAction *
- GetFileActionForFD (int fd) const
- {
- for (size_t idx=0, count=m_file_actions.size(); idx < count; ++idx)
- {
- if (m_file_actions[idx].GetFD () == fd)
- return &m_file_actions[idx];
- }
- return NULL;
- }
-
- Flags &
- GetFlags ()
- {
- return m_flags;
- }
-
- const Flags &
- GetFlags () const
- {
- return m_flags;
- }
-
- const char *
- GetWorkingDirectory () const
- {
- if (m_working_dir.empty())
- return NULL;
- return m_working_dir.c_str();
- }
-
- void
- SetWorkingDirectory (const char *working_dir)
- {
- if (working_dir && working_dir[0])
- m_working_dir.assign (working_dir);
- else
- m_working_dir.clear();
- }
-
- void
- SwapWorkingDirectory (std::string &working_dir)
- {
- m_working_dir.swap (working_dir);
- }
-
-
- const char *
- GetProcessPluginName () const
- {
- if (m_plugin_name.empty())
- return NULL;
- return m_plugin_name.c_str();
- }
-
- void
- SetProcessPluginName (const char *plugin)
- {
- if (plugin && plugin[0])
- m_plugin_name.assign (plugin);
- else
- m_plugin_name.clear();
- }
-
- const char *
- GetShell () const
- {
- if (m_shell.empty())
- return NULL;
- return m_shell.c_str();
- }
-
- void
- SetShell (const char * path)
- {
- if (path && path[0])
- {
- m_shell.assign (path);
- m_flags.Set (lldb::eLaunchFlagLaunchInShell);
- }
- else
- {
- m_shell.clear();
- m_flags.Clear (lldb::eLaunchFlagLaunchInShell);
- }
- }
-
- uint32_t
- GetResumeCount () const
- {
- return m_resume_count;
- }
-
- void
- SetResumeCount (uint32_t c)
- {
- m_resume_count = c;
- }
-
- bool
- GetLaunchInSeparateProcessGroup ()
- {
- return m_flags.Test(lldb::eLaunchFlagLaunchInSeparateProcessGroup);
- }
-
- void
- SetLaunchInSeparateProcessGroup (bool separate)
- {
- if (separate)
- m_flags.Set(lldb::eLaunchFlagLaunchInSeparateProcessGroup);
- else
- m_flags.Clear (lldb::eLaunchFlagLaunchInSeparateProcessGroup);
-
- }
-
- void
- Clear ()
- {
- ProcessInfo::Clear();
- m_working_dir.clear();
- m_plugin_name.clear();
- m_shell.clear();
- m_flags.Clear();
- m_file_actions.clear();
- m_resume_count = 0;
- m_hijack_listener_sp.reset();
- }
-
- bool
- ConvertArgumentsForLaunchingInShell (Error &error,
- bool localhost,
- bool will_debug,
- bool first_arg_is_full_shell_command,
- int32_t num_resumes);
-
- void
- SetMonitorProcessCallback (Host::MonitorChildProcessCallback callback,
- void *baton,
- bool monitor_signals)
- {
- m_monitor_callback = callback;
- m_monitor_callback_baton = baton;
- m_monitor_signals = monitor_signals;
- }
-
- Host::MonitorChildProcessCallback
- GetMonitorProcessCallback ()
- {
- return m_monitor_callback;
- }
-
- const void*
- GetMonitorProcessBaton () const
- {
- return m_monitor_callback_baton;
- }
-
- // If the LaunchInfo has a monitor callback, then arrange to monitor the process.
- // Return true if the LaunchInfo has taken care of monitoring the process, and false if the
- // caller might want to monitor the process themselves.
-
- bool
- MonitorProcess () const
- {
- if (GetFlags().Test(lldb::eLaunchFlagsDontMonitorProcess))
- return true;
-
- if (m_monitor_callback && ProcessIDIsValid())
- {
- Host::StartMonitoringChildProcess (m_monitor_callback,
- m_monitor_callback_baton,
- GetProcessID(),
- m_monitor_signals);
- return true;
- }
- return false;
- }
-
- lldb_utility::PseudoTerminal &
- GetPTY ()
- {
- return m_pty;
- }
-
- lldb::ListenerSP
- GetHijackListener () const
- {
- return m_hijack_listener_sp;
- }
-
- void
- SetHijackListener (const lldb::ListenerSP &listener_sp)
- {
- m_hijack_listener_sp = listener_sp;
- }
-
-
-protected:
- std::string m_working_dir;
- std::string m_plugin_name;
- std::string m_shell;
- Flags m_flags; // Bitwise OR of bits from lldb::LaunchFlags
- std::vector<FileAction> m_file_actions; // File actions for any other files
- lldb_utility::PseudoTerminal m_pty;
- uint32_t m_resume_count; // How many times do we resume after launching
- Host::MonitorChildProcessCallback m_monitor_callback;
- void *m_monitor_callback_baton;
- bool m_monitor_signals;
- lldb::ListenerSP m_hijack_listener_sp;
-};
-
-//----------------------------------------------------------------------
-// ProcessLaunchInfo
-//
-// Describes any information that is required to launch a process.
+// Describes any information that is required to attach to a process.
//----------------------------------------------------------------------
class ProcessAttachInfo : public ProcessInstanceInfo
@@ -884,7 +227,8 @@ public:
m_resume_count (0),
m_wait_for_launch (false),
m_ignore_existing (true),
- m_continue_once_attached (false)
+ m_continue_once_attached (false),
+ m_detach_on_error (true)
{
}
@@ -894,12 +238,14 @@ public:
m_resume_count (0),
m_wait_for_launch (false),
m_ignore_existing (true),
- m_continue_once_attached (false)
+ m_continue_once_attached (false),
+ m_detach_on_error(true)
{
ProcessInfo::operator= (launch_info);
SetProcessPluginName (launch_info.GetProcessPluginName());
SetResumeCount (launch_info.GetResumeCount());
SetHijackListener(launch_info.GetHijackListener());
+ m_detach_on_error = launch_info.GetDetachOnError();
}
bool
@@ -1002,7 +348,18 @@ public:
m_hijack_listener_sp = listener_sp;
}
-
+ bool
+ GetDetachOnError () const
+ {
+ return m_detach_on_error;
+ }
+
+ void
+ SetDetachOnError (bool enable)
+ {
+ m_detach_on_error = enable;
+ }
+
protected:
lldb::ListenerSP m_hijack_listener_sp;
std::string m_plugin_name;
@@ -1010,6 +367,7 @@ protected:
bool m_wait_for_launch;
bool m_ignore_existing;
bool m_continue_once_attached; // Supports the use-case scenario of immediately continuing the process once attached.
+ bool m_detach_on_error; // If we are debugging remotely, instruct the stub to detach rather than killing the target on error.
};
class ProcessLaunchCommandOptions : public Options
@@ -1034,6 +392,7 @@ public:
OptionParsingStarting ()
{
launch_info.Clear();
+ disable_aslr = eLazyBoolCalculate;
}
const OptionDefinition*
@@ -1049,6 +408,7 @@ public:
// Instance variables to hold the values for command options.
ProcessLaunchInfo launch_info;
+ lldb_private::LazyBool disable_aslr;
};
//----------------------------------------------------------------------
@@ -1321,91 +681,6 @@ inline bool operator!= (const ProcessModID &lhs, const ProcessModID &rhs)
return false;
}
-class MemoryRegionInfo
-{
-public:
- typedef Range<lldb::addr_t, lldb::addr_t> RangeType;
-
- enum OptionalBool {
- eDontKnow = -1,
- eNo = 0,
- eYes = 1
- };
-
- MemoryRegionInfo () :
- m_range (),
- m_read (eDontKnow),
- m_write (eDontKnow),
- m_execute (eDontKnow)
- {
- }
-
- ~MemoryRegionInfo ()
- {
- }
-
- RangeType &
- GetRange()
- {
- return m_range;
- }
-
- void
- Clear()
- {
- m_range.Clear();
- m_read = m_write = m_execute = eDontKnow;
- }
-
- const RangeType &
- GetRange() const
- {
- return m_range;
- }
-
- OptionalBool
- GetReadable () const
- {
- return m_read;
- }
-
- OptionalBool
- GetWritable () const
- {
- return m_write;
- }
-
- OptionalBool
- GetExecutable () const
- {
- return m_execute;
- }
-
- void
- SetReadable (OptionalBool val)
- {
- m_read = val;
- }
-
- void
- SetWritable (OptionalBool val)
- {
- m_write = val;
- }
-
- void
- SetExecutable (OptionalBool val)
- {
- m_execute = val;
- }
-
-protected:
- RangeType m_range;
- OptionalBool m_read;
- OptionalBool m_write;
- OptionalBool m_execute;
-};
-
//----------------------------------------------------------------------
/// @class Process Process.h "lldb/Target/Process.h"
/// @brief A plug-in interface definition class for debugging a process.
@@ -1418,7 +693,8 @@ class Process :
public ExecutionContextScope,
public PluginInterface
{
- friend class ClangFunction; // For WaitForStateChangeEventsPrivate
+ friend class ClangFunction; // For WaitForStateChangeEventsPrivate
+ friend class Debugger; // For PopProcessIOHandler and ProcessIOHandlerIsActive
friend class ProcessEventData;
friend class StopInfo;
friend class Target;
@@ -1619,10 +895,17 @@ public:
//------------------------------------------------------------------
/// Construct with a shared pointer to a target, and the Process listener.
+ /// Uses the Host UnixSignalsSP by default.
//------------------------------------------------------------------
Process(Target &target, Listener &listener);
//------------------------------------------------------------------
+ /// Construct with a shared pointer to a target, the Process listener,
+ /// and the appropriate UnixSignalsSP for the process.
+ //------------------------------------------------------------------
+ Process(Target &target, Listener &listener, const UnixSignalsSP &unix_signals_sp);
+
+ //------------------------------------------------------------------
/// Destructor.
///
/// The destructor is virtual since this class is designed to be
@@ -1753,10 +1036,6 @@ public:
///
/// Launch a new process by spawning a new process using the
/// target object's executable module's file as the file to launch.
- /// Arguments are given in \a argv, and the environment variables
- /// are in \a envp. Standard input and output files can be
- /// optionally re-directed to \a stdin_path, \a stdout_path, and
- /// \a stderr_path.
///
/// This function is not meant to be overridden by Process
/// subclasses. It will first call Process::WillLaunch (Module *)
@@ -1766,32 +1045,9 @@ public:
/// DoLaunch returns \b true, then Process::DidLaunch() will be
/// called.
///
- /// @param[in] argv
- /// The argument array.
- ///
- /// @param[in] envp
- /// The environment array.
- ///
- /// @param[in] launch_flags
- /// Flags to modify the launch (@see lldb::LaunchFlags)
- ///
- /// @param[in] stdin_path
- /// The path to use when re-directing the STDIN of the new
- /// process. If all stdXX_path arguments are NULL, a pseudo
- /// terminal will be used.
- ///
- /// @param[in] stdout_path
- /// The path to use when re-directing the STDOUT of the new
- /// process. If all stdXX_path arguments are NULL, a pseudo
- /// terminal will be used.
- ///
- /// @param[in] stderr_path
- /// The path to use when re-directing the STDERR of the new
- /// process. If all stdXX_path arguments are NULL, a pseudo
- /// terminal will be used.
- ///
- /// @param[in] working_directory
- /// The working directory to have the child process run in
+ /// @param[in] launch_info
+ /// Details regarding the environment, STDIN/STDOUT/STDERR
+ /// redirection, working path, etc. related to the requested launch.
///
/// @return
/// An error object. Call GetID() to get the process ID if
@@ -1824,6 +1080,22 @@ public:
GetDynamicLoader ();
//------------------------------------------------------------------
+ // Returns AUXV structure found in many ELF-based environments.
+ //
+ // The default action is to return an empty data buffer.
+ //
+ // @return
+ // A data buffer containing the contents of the AUXV data.
+ //------------------------------------------------------------------
+ virtual const lldb::DataBufferSP
+ GetAuxvData();
+
+protected:
+ virtual JITLoaderList &
+ GetJITLoaders ();
+
+public:
+ //------------------------------------------------------------------
/// Get the system runtime plug-in for this process.
///
/// @return
@@ -1930,7 +1202,7 @@ public:
//------------------------------------------------------------------
/// Register for process and thread notifications.
///
- /// Clients can register nofication callbacks by filling out a
+ /// Clients can register notification callbacks by filling out a
/// Process::Notifications structure and calling this function.
///
/// @param[in] callbacks
@@ -1946,7 +1218,7 @@ public:
//------------------------------------------------------------------
/// Unregister for process and thread notifications.
///
- /// Clients can unregister nofication callbacks by passing a copy of
+ /// Clients can unregister notification callbacks by passing a copy of
/// the original baton and callbacks in \a callbacks.
///
/// @param[in] callbacks
@@ -2056,10 +1328,18 @@ public:
Error
Signal (int signal);
- virtual UnixSignals &
+ void
+ SetUnixSignals (const UnixSignalsSP &signals_sp)
+ {
+ assert (signals_sp && "null signals_sp");
+ m_unix_signals_sp = signals_sp;
+ }
+
+ UnixSignals &
GetUnixSignals ()
{
- return m_unix_signals;
+ assert (m_unix_signals_sp && "null m_unix_signals_sp");
+ return *m_unix_signals_sp;
}
//==================================================================
@@ -2183,11 +1463,17 @@ public:
//------------------------------------------------------------------
/// Called after attaching a process.
///
+ /// @param[in] process_arch
+ /// If you can figure out the process architecture after attach, fill it in here.
+ ///
/// Allow Process plug-ins to execute some code after attaching to
/// a process.
//------------------------------------------------------------------
virtual void
- DidAttach () {}
+ DidAttach (ArchSpec &process_arch)
+ {
+ process_arch.Clear();
+ }
//------------------------------------------------------------------
@@ -2229,46 +1515,21 @@ public:
//------------------------------------------------------------------
/// Launch a new process.
///
- /// Launch a new process by spawning a new process using \a module's
- /// file as the file to launch. Arguments are given in \a argv,
- /// and the environment variables are in \a envp. Standard input
- /// and output files can be optionally re-directed to \a stdin_path,
- /// \a stdout_path, and \a stderr_path.
+ /// Launch a new process by spawning a new process using
+ /// \a exe_module's file as the file to launch. Launch details are
+ /// provided in \a launch_info.
///
- /// @param[in] module
+ /// @param[in] exe_module
/// The module from which to extract the file specification and
/// launch.
///
- /// @param[in] argv
- /// The argument array.
- ///
- /// @param[in] envp
- /// The environment array.
- ///
- /// @param[in] launch_flags
- /// Flags to modify the launch (@see lldb::LaunchFlags)
- ///
- /// @param[in] stdin_path
- /// The path to use when re-directing the STDIN of the new
- /// process. If all stdXX_path arguments are NULL, a pseudo
- /// terminal will be used.
- ///
- /// @param[in] stdout_path
- /// The path to use when re-directing the STDOUT of the new
- /// process. If all stdXX_path arguments are NULL, a pseudo
- /// terminal will be used.
- ///
- /// @param[in] stderr_path
- /// The path to use when re-directing the STDERR of the new
- /// process. If all stdXX_path arguments are NULL, a pseudo
- /// terminal will be used.
- ///
- /// @param[in] working_directory
- /// The working directory to have the child process run in
+ /// @param[in] launch_info
+ /// Details (e.g. arguments, stdio redirection, etc.) for the
+ /// requested launch.
///
/// @return
- /// A new valid process ID, or LLDB_INVALID_PROCESS_ID if
- /// launching fails.
+ /// An Error instance indicating success or failure of the
+ /// operation.
//------------------------------------------------------------------
virtual Error
DoLaunch (Module *exe_module,
@@ -2454,7 +1715,7 @@ public:
DoSignal (int signal)
{
Error error;
- error.SetErrorStringWithFormat("error: %s does not support senging signals to processes", GetPluginName().GetCString());
+ error.SetErrorStringWithFormat("error: %s does not support sending signals to processes", GetPluginName().GetCString());
return error;
}
@@ -2546,14 +1807,14 @@ public:
lldb::StateType
GetState ();
- ExecutionResults
+ lldb::ExpressionResults
RunThreadPlan (ExecutionContext &exe_ctx,
lldb::ThreadPlanSP &thread_plan_sp,
const EvaluateExpressionOptions &options,
Stream &errors);
static const char *
- ExecutionResultAsCString (ExecutionResults result);
+ ExecutionResultAsCString (lldb::ExpressionResults result);
void
GetStatus (Stream &ostrm);
@@ -2568,6 +1829,9 @@ public:
void
SendAsyncInterrupt ();
+ void
+ ModulesDidLoad (ModuleList &module_list);
+
protected:
void
@@ -2904,7 +2168,7 @@ public:
///
/// The value contained in \a scalar will be swapped to match the
/// byte order of the process that is being debugged. If \a size is
- /// less than the size of scalar, the least significate \a size bytes
+ /// less than the size of scalar, the least significant \a size bytes
/// from scalar will be written. If \a size is larger than the byte
/// size of scalar, then the extra space will be padded with zeros
/// and the scalar value will be placed in the least significant
@@ -3070,7 +2334,8 @@ public:
lldb::ModuleSP
ReadModuleFromMemory (const FileSpec& file_spec,
- lldb::addr_t header_addr);
+ lldb::addr_t header_addr,
+ size_t size_to_read = 512);
//------------------------------------------------------------------
/// Attempt to get the attributes for a region of memory in the process.
@@ -3412,6 +2677,25 @@ public:
bool wait_always = true,
Listener *hijack_listener = NULL);
+
+ //--------------------------------------------------------------------------------------
+ /// Waits for the process state to be running within a given msec timeout.
+ ///
+ /// The main purpose of this is to implement an interlock waiting for HandlePrivateEvent
+ /// to push an IOHandler.
+ ///
+ /// @param[in] timeout_msec
+ /// The maximum time length to wait for the process to transition to the
+ /// eStateRunning state, specified in milliseconds.
+ ///
+ /// @return
+ /// true if successfully signalled that process started and IOHandler pushes, false
+ /// if it timed out.
+ //--------------------------------------------------------------------------------------
+ bool
+ SyncIOHandler (uint64_t timeout_msec);
+
+
lldb::StateType
WaitForStateChangedEvents (const TimeValue *timeout,
lldb::EventSP &event_sp,
@@ -3582,12 +2866,6 @@ public:
void
SetSTDIOFileDescriptor (int file_descriptor);
- void
- WatchForSTDIN (IOHandler &io_handler);
-
- void
- CancelWatchForSTDIN (bool exited);
-
//------------------------------------------------------------------
// Add a permanent region of memory that should never be read or
// written to. This can be used to ensure that memory reads or writes
@@ -3633,8 +2911,17 @@ public:
else
return m_public_run_lock;
}
-
+
+public:
+ virtual Error
+ SendEventData(const char *data)
+ {
+ Error return_error ("Sending an event is not supported for this process.");
+ return return_error;
+ }
+
protected:
+
//------------------------------------------------------------------
// NextEventAction provides a way to register an action on the next
// event that is delivered to this process. There is currently only
@@ -3690,13 +2977,9 @@ protected:
class AttachCompletionHandler : public NextEventAction
{
public:
- AttachCompletionHandler (Process *process, uint32_t exec_count) :
- NextEventAction (process),
- m_exec_count (exec_count)
- {
- }
+ AttachCompletionHandler (Process *process, uint32_t exec_count);
- virtual
+ virtual
~AttachCompletionHandler()
{
}
@@ -3753,7 +3036,7 @@ protected:
Broadcaster m_private_state_control_broadcaster; // This is the control broadcaster, used to pause, resume & stop the private state thread.
Listener m_private_state_listener; // This is the listener for the private state thread.
Predicate<bool> m_private_state_control_wait; /// This Predicate is used to signal that a control operation is complete.
- lldb::thread_t m_private_state_thread; // Thread ID for the thread that watches interal state events
+ lldb::thread_t m_private_state_thread; // Thread ID for the thread that watches internal state events
ProcessModID m_mod_id; ///< Tracks the state of the process over stops and other alterations.
uint32_t m_process_unique_id; ///< Each lldb_private::Process class that is created gets a unique integer ID that increments with each new instance
uint32_t m_thread_index_id; ///< Each thread is created with a 1 based index that won't get re-used.
@@ -3773,10 +3056,11 @@ protected:
Listener &m_listener;
BreakpointSiteList m_breakpoint_site_list; ///< This is the list of breakpoint locations we intend to insert in the target.
std::unique_ptr<DynamicLoader> m_dyld_ap;
+ std::unique_ptr<JITLoaderList> m_jit_loaders_ap;
std::unique_ptr<DynamicCheckerFunctions> m_dynamic_checkers_ap; ///< The functions used by the expression parser to validate data that expressions use.
std::unique_ptr<OperatingSystem> m_os_ap;
std::unique_ptr<SystemRuntime> m_system_runtime_ap;
- UnixSignals m_unix_signals; /// This is the current signal set for this process.
+ UnixSignalsSP m_unix_signals_sp; /// This is the current signal set for this process.
lldb::ABISP m_abi_sp;
lldb::IOHandlerSP m_process_input_reader;
Communication m_stdio_communication;
@@ -3785,6 +3069,7 @@ protected:
std::string m_stderr_data;
Mutex m_profile_data_comm_mutex;
std::vector<std::string> m_profile_data;
+ Predicate<bool> m_iohandler_sync;
MemoryCache m_memory_cache;
AllocatedMemoryCache m_allocated_memory_cache;
bool m_should_detach; /// Should we detach if the process object goes away with an explicit call to Kill or Detach?
@@ -3874,15 +3159,15 @@ protected:
static void
STDIOReadThreadBytesReceived (void *baton, const void *src, size_t src_len);
- void
+ bool
PushProcessIOHandler ();
- void
+ bool
PopProcessIOHandler ();
- void
- ResetProcessIOHandler ();
-
+ bool
+ ProcessIOHandlerIsActive ();
+
Error
HaltForDestroyOrDetach(lldb::EventSP &exit_event_sp);
diff --git a/include/lldb/Target/ProcessInfo.h b/include/lldb/Target/ProcessInfo.h
new file mode 100644
index 0000000000000..0570cfc986510
--- /dev/null
+++ b/include/lldb/Target/ProcessInfo.h
@@ -0,0 +1,188 @@
+//===-- ProcessInfo.h -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ProcessInfo_h_
+#define liblldb_ProcessInfo_h_
+
+// LLDB headers
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Interpreter/Args.h"
+
+namespace lldb_private
+{
+ //----------------------------------------------------------------------
+ // ProcessInfo
+ //
+ // A base class for information for a process. This can be used to fill
+ // out information for a process prior to launching it, or it can be
+ // used for an instance of a process and can be filled in with the
+ // existing values for that process.
+ //----------------------------------------------------------------------
+ class ProcessInfo
+ {
+ public:
+ ProcessInfo ();
+
+ ProcessInfo (const char *name,
+ const ArchSpec &arch,
+ lldb::pid_t pid);
+
+ void
+ Clear ();
+
+ const char *
+ GetName() const;
+
+ size_t
+ GetNameLength() const;
+
+ FileSpec &
+ GetExecutableFile ()
+ {
+ return m_executable;
+ }
+
+ void
+ SetExecutableFile (const FileSpec &exe_file, bool add_exe_file_as_first_arg);
+
+ const FileSpec &
+ GetExecutableFile () const
+ {
+ return m_executable;
+ }
+
+ uint32_t
+ GetUserID() const
+ {
+ return m_uid;
+ }
+
+ uint32_t
+ GetGroupID() const
+ {
+ return m_gid;
+ }
+
+ bool
+ UserIDIsValid () const
+ {
+ return m_uid != UINT32_MAX;
+ }
+
+ bool
+ GroupIDIsValid () const
+ {
+ return m_gid != UINT32_MAX;
+ }
+
+ void
+ SetUserID (uint32_t uid)
+ {
+ m_uid = uid;
+ }
+
+ void
+ SetGroupID (uint32_t gid)
+ {
+ m_gid = gid;
+ }
+
+ ArchSpec &
+ GetArchitecture ()
+ {
+ return m_arch;
+ }
+
+ const ArchSpec &
+ GetArchitecture () const
+ {
+ return m_arch;
+ }
+
+ void
+ SetArchitecture (ArchSpec arch)
+ {
+ m_arch = arch;
+ }
+
+ lldb::pid_t
+ GetProcessID () const
+ {
+ return m_pid;
+ }
+
+ void
+ SetProcessID (lldb::pid_t pid)
+ {
+ m_pid = pid;
+ }
+
+ bool
+ ProcessIDIsValid() const
+ {
+ return m_pid != LLDB_INVALID_PROCESS_ID;
+ }
+
+ void
+ Dump (Stream &s, Platform *platform) const;
+
+ Args &
+ GetArguments ()
+ {
+ return m_arguments;
+ }
+
+ const Args &
+ GetArguments () const
+ {
+ return m_arguments;
+ }
+
+ const char *
+ GetArg0 () const;
+
+ void
+ SetArg0 (const char *arg);
+
+ void
+ SetArguments (const Args& args, bool first_arg_is_executable);
+
+ void
+ SetArguments (char const **argv, bool first_arg_is_executable);
+
+ Args &
+ GetEnvironmentEntries ()
+ {
+ return m_environment;
+ }
+
+ const Args &
+ GetEnvironmentEntries () const
+ {
+ return m_environment;
+ }
+
+ protected:
+ FileSpec m_executable;
+ std::string m_arg0; // argv[0] if supported. If empty, then use m_executable.
+ // Not all process plug-ins support specifying an argv[0]
+ // that differs from the resolved platform executable
+ // (which is in m_executable)
+ Args m_arguments; // All program arguments except argv[0]
+ Args m_environment;
+ uint32_t m_uid;
+ uint32_t m_gid;
+ ArchSpec m_arch;
+ lldb::pid_t m_pid;
+ };
+}
+
+#endif // #ifndef liblldb_ProcessInfo_h_
+
diff --git a/include/lldb/Target/ProcessLaunchInfo.h b/include/lldb/Target/ProcessLaunchInfo.h
new file mode 100644
index 0000000000000..77d829a7e4762
--- /dev/null
+++ b/include/lldb/Target/ProcessLaunchInfo.h
@@ -0,0 +1,225 @@
+//===-- ProcessLaunchInfo.h -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ProcessLaunch_Info_h
+#define liblldb_ProcessLaunch_Info_h
+
+// C++ Headers
+#include <string>
+
+// LLDB Headers
+#include "lldb/Core/Flags.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Target/FileAction.h"
+#include "lldb/Target/ProcessInfo.h"
+#include "lldb/Utility/PseudoTerminal.h"
+
+namespace lldb_private
+{
+
+ //----------------------------------------------------------------------
+ // ProcessLaunchInfo
+ //
+ // Describes any information that is required to launch a process.
+ //----------------------------------------------------------------------
+
+ class ProcessLaunchInfo : public ProcessInfo
+ {
+ public:
+
+ ProcessLaunchInfo ();
+
+ ProcessLaunchInfo (const char *stdin_path,
+ const char *stdout_path,
+ const char *stderr_path,
+ const char *working_directory,
+ uint32_t launch_flags);
+
+ void
+ AppendFileAction (const FileAction &info)
+ {
+ m_file_actions.push_back(info);
+ }
+
+ bool
+ AppendCloseFileAction (int fd);
+
+ bool
+ AppendDuplicateFileAction (int fd, int dup_fd);
+
+ bool
+ AppendOpenFileAction (int fd, const char *path, bool read, bool write);
+
+ bool
+ AppendSuppressFileAction (int fd, bool read, bool write);
+
+ void
+ FinalizeFileActions (Target *target,
+ bool default_to_use_pty);
+
+ size_t
+ GetNumFileActions () const
+ {
+ return m_file_actions.size();
+ }
+
+ const FileAction *
+ GetFileActionAtIndex (size_t idx) const;
+
+ const FileAction *
+ GetFileActionForFD (int fd) const;
+
+ Flags &
+ GetFlags ()
+ {
+ return m_flags;
+ }
+
+ const Flags &
+ GetFlags () const
+ {
+ return m_flags;
+ }
+
+ const char *
+ GetWorkingDirectory () const;
+
+ void
+ SetWorkingDirectory (const char *working_dir);
+
+ void
+ SwapWorkingDirectory (std::string &working_dir)
+ {
+ m_working_dir.swap (working_dir);
+ }
+
+ const char *
+ GetProcessPluginName () const;
+
+ void
+ SetProcessPluginName (const char *plugin);
+
+ const char *
+ GetShell () const;
+
+ void
+ SetShell (const char * path);
+
+ uint32_t
+ GetResumeCount () const
+ {
+ return m_resume_count;
+ }
+
+ void
+ SetResumeCount (uint32_t c)
+ {
+ m_resume_count = c;
+ }
+
+ bool
+ GetLaunchInSeparateProcessGroup ()
+ {
+ return m_flags.Test(lldb::eLaunchFlagLaunchInSeparateProcessGroup);
+ }
+
+ void
+ SetLaunchInSeparateProcessGroup (bool separate);
+
+ void
+ Clear ();
+
+ bool
+ ConvertArgumentsForLaunchingInShell (Error &error,
+ bool localhost,
+ bool will_debug,
+ bool first_arg_is_full_shell_command,
+ int32_t num_resumes);
+
+ void
+ SetMonitorProcessCallback (Host::MonitorChildProcessCallback callback,
+ void *baton,
+ bool monitor_signals);
+
+ Host::MonitorChildProcessCallback
+ GetMonitorProcessCallback ()
+ {
+ return m_monitor_callback;
+ }
+
+ const void*
+ GetMonitorProcessBaton () const
+ {
+ return m_monitor_callback_baton;
+ }
+
+ // If the LaunchInfo has a monitor callback, then arrange to monitor the process.
+ // Return true if the LaunchInfo has taken care of monitoring the process, and false if the
+ // caller might want to monitor the process themselves.
+
+ bool
+ MonitorProcess () const;
+
+ lldb_utility::PseudoTerminal &
+ GetPTY ()
+ {
+ return m_pty;
+ }
+
+ lldb::ListenerSP
+ GetHijackListener () const
+ {
+ return m_hijack_listener_sp;
+ }
+
+ void
+ SetHijackListener (const lldb::ListenerSP &listener_sp)
+ {
+ m_hijack_listener_sp = listener_sp;
+ }
+
+
+ void
+ SetLaunchEventData (const char *data)
+ {
+ m_event_data.assign (data);
+ }
+
+ const char *
+ GetLaunchEventData () const
+ {
+ return m_event_data.c_str();
+ }
+
+ void
+ SetDetachOnError (bool enable);
+
+ bool
+ GetDetachOnError () const
+ {
+ return m_flags.Test(lldb::eLaunchFlagDetachOnError);
+ }
+
+ protected:
+ std::string m_working_dir;
+ std::string m_plugin_name;
+ std::string m_shell;
+ Flags m_flags; // Bitwise OR of bits from lldb::LaunchFlags
+ std::vector<FileAction> m_file_actions; // File actions for any other files
+ lldb_utility::PseudoTerminal m_pty;
+ uint32_t m_resume_count; // How many times do we resume after launching
+ Host::MonitorChildProcessCallback m_monitor_callback;
+ void *m_monitor_callback_baton;
+ bool m_monitor_signals;
+ std::string m_event_data; // A string passed to the plugin launch, having no meaning to the upper levels of lldb.
+ lldb::ListenerSP m_hijack_listener_sp;
+ };
+}
+
+#endif // liblldb_ProcessLaunch_Info_h
diff --git a/include/lldb/Target/Queue.h b/include/lldb/Target/Queue.h
index 32ee24aebc118..514481fe8c9d8 100644
--- a/include/lldb/Target/Queue.h
+++ b/include/lldb/Target/Queue.h
@@ -168,6 +168,18 @@ public:
m_pending_items.push_back (item);
}
+ //------------------------------------------------------------------
+ /// Return the kind (serial, concurrent) of this queue
+ ///
+ /// @return
+ // Whether this is a serial or a concurrent queue
+ //------------------------------------------------------------------
+ lldb::QueueKind
+ GetKind ();
+
+ void
+ SetKind (lldb::QueueKind kind);
+
private:
//------------------------------------------------------------------
// For Queue only
@@ -180,6 +192,7 @@ private:
uint32_t m_pending_work_items_count;
std::vector<lldb::QueueItemSP> m_pending_items;
lldb::addr_t m_dispatch_queue_t_addr; // address of libdispatch dispatch_queue_t for this Queue
+ lldb::QueueKind m_kind;
DISALLOW_COPY_AND_ASSIGN (Queue);
};
diff --git a/include/lldb/Target/QueueItem.h b/include/lldb/Target/QueueItem.h
index 76270da3bee6f..c69c825a7976d 100644
--- a/include/lldb/Target/QueueItem.h
+++ b/include/lldb/Target/QueueItem.h
@@ -14,6 +14,7 @@
#include "lldb/lldb-private.h"
#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/ConstString.h"
@@ -37,7 +38,7 @@ class QueueItem :
{
public:
- QueueItem (lldb::QueueSP queue_sp);
+ QueueItem (lldb::QueueSP queue_sp, lldb::ProcessSP process_sp, lldb::addr_t item_ref, lldb_private::Address address);
~QueueItem ();
@@ -49,7 +50,7 @@ public:
/// represents. eQueueItemKindUnknown may be returned.
//------------------------------------------------------------------
lldb::QueueItemKind
- GetKind () const;
+ GetKind ();
//------------------------------------------------------------------
/// Set the type of work item this is
@@ -124,10 +125,7 @@ public:
}
lldb::addr_t
- GetItemThatEnqueuedThis ()
- {
- return m_item_that_enqueued_this_ref;
- }
+ GetItemThatEnqueuedThis ();
void
SetEnqueueingThreadID (lldb::tid_t tid)
@@ -136,10 +134,7 @@ public:
}
lldb::tid_t
- GetEnqueueingThreadID ()
- {
- return m_enqueueing_thread_id;
- }
+ GetEnqueueingThreadID ();
void
SetEnqueueingQueueID (lldb::queue_id_t qid)
@@ -148,10 +143,7 @@ public:
}
lldb::queue_id_t
- GetEnqueueingQueueID ()
- {
- return m_enqueueing_queue_id;
- }
+ GetEnqueueingQueueID ();
void
SetTargetQueueID (lldb::queue_id_t qid)
@@ -166,10 +158,7 @@ public:
}
uint32_t
- GetStopID ()
- {
- return m_stop_id;
- }
+ GetStopID ();
void
SetEnqueueingBacktrace (std::vector<lldb::addr_t> backtrace)
@@ -178,10 +167,7 @@ public:
}
std::vector<lldb::addr_t> &
- GetEnqueueingBacktrace ()
- {
- return m_backtrace;
- }
+ GetEnqueueingBacktrace ();
void
SetThreadLabel (std::string thread_name)
@@ -190,10 +176,7 @@ public:
}
std::string
- GetThreadLabel ()
- {
- return m_thread_label;
- }
+ GetThreadLabel ();
void
SetQueueLabel (std::string queue_name)
@@ -202,10 +185,7 @@ public:
}
std::string
- GetQueueLabel ()
- {
- return m_queue_label;
- }
+ GetQueueLabel ();
void
SetTargetQueueLabel (std::string queue_name)
@@ -213,11 +193,22 @@ public:
m_target_queue_label = queue_name;
}
+ lldb::ProcessSP
+ GetProcessSP ();
+
protected:
+ void
+ FetchEntireItem ();
+
+
lldb::QueueWP m_queue_wp;
- lldb::QueueItemKind m_kind;
+ lldb::ProcessWP m_process_wp;
+
+ lldb::addr_t m_item_ref; // the token we can be used to fetch more information about this queue item
lldb_private::Address m_address;
+ bool m_have_fetched_entire_item;
+ lldb::QueueItemKind m_kind;
lldb::addr_t m_item_that_enqueued_this_ref; // a handle that we can pass into libBacktraceRecording
// to get the QueueItem that enqueued this item
lldb::tid_t m_enqueueing_thread_id; // thread that enqueued this item
diff --git a/include/lldb/Target/QueueList.h b/include/lldb/Target/QueueList.h
index 964c1099233e8..12a0ea52d7f4a 100644
--- a/include/lldb/Target/QueueList.h
+++ b/include/lldb/Target/QueueList.h
@@ -98,7 +98,7 @@ public:
///
/// @return
/// A QueueSP to the queue requested, if it is present in the QueueList.
- /// An empty QueueSP willbe returned if this queue was not found.
+ /// An empty QueueSP will be returned if this queue was not found.
//------------------------------------------------------------------
lldb::QueueSP
FindQueueByID (lldb::queue_id_t qid);
@@ -114,7 +114,7 @@ public:
///
/// @return
/// A QueueSP to the queue requested, if it is present in the QueueList.
- /// An empty QueueSP willbe returned if this queue was not found.
+ /// An empty QueueSP will be returned if this queue was not found.
//------------------------------------------------------------------
lldb::QueueSP
FindQueueByIndexID (uint32_t index_id);
diff --git a/include/lldb/Target/RegisterContext.h b/include/lldb/Target/RegisterContext.h
index 421acc03cb227..9108d4575259c 100644
--- a/include/lldb/Target/RegisterContext.h
+++ b/include/lldb/Target/RegisterContext.h
@@ -86,9 +86,44 @@ public:
bool
CopyFromRegisterContext (lldb::RegisterContextSP context);
-
+
+ //------------------------------------------------------------------
+ /// Convert from a given register numbering scheme to the lldb register
+ /// numbering scheme
+ ///
+ /// There may be multiple ways to enumerate the registers for a given
+ /// architecture. ABI references will specify one to be used with
+ /// DWARF, the register numberings from stabs (aka "gcc"), there may
+ /// be a variation used for eh_frame unwind instructions (e.g. on Darwin),
+ /// and so on. Register 5 by itself is meaningless - RegisterKind
+ /// enumeration tells you what context that number should be translated as.
+ ///
+ /// Inside lldb, register numbers are in the eRegisterKindLLDB scheme;
+ /// arguments which take a register number should take one in that
+ /// scheme.
+ ///
+ /// eRegisterKindGeneric is a special numbering scheme which gives us
+ /// constant values for the pc, frame register, stack register, etc., for
+ /// use within lldb. They may not be defined for all architectures but
+ /// it allows generic code to translate these common registers into the
+ /// lldb numbering scheme.
+ ///
+ /// This method translates a given register kind + register number into
+ /// the eRegisterKindLLDB register numbering.
+ ///
+ /// @param [in] kind
+ /// The register numbering scheme (RegisterKind) that the following
+ /// register number is in.
+ ///
+ /// @param [in] num
+ /// A register number in the 'kind' register numbering scheme.
+ ///
+ /// @return
+ /// The equivalent register number in the eRegisterKindLLDB
+ /// numbering scheme, if possible, else LLDB_INVALID_REGNUM.
+ //------------------------------------------------------------------
virtual uint32_t
- ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) = 0;
+ ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num) = 0;
//------------------------------------------------------------------
// Subclasses can override these functions if desired
@@ -136,7 +171,7 @@ public:
GetRegisterInfoByName (const char *reg_name, uint32_t start_idx = 0);
const RegisterInfo *
- GetRegisterInfo (uint32_t reg_kind, uint32_t reg_num);
+ GetRegisterInfo (lldb::RegisterKind reg_kind, uint32_t reg_num);
uint64_t
GetPC (uint64_t fail_value = LLDB_INVALID_ADDRESS);
@@ -179,7 +214,7 @@ public:
bool
WriteRegisterFromUnsigned (const RegisterInfo *reg_info, uint64_t uval);
bool
- ConvertBetweenRegisterKinds (int source_rk, uint32_t source_regnum, int target_rk, uint32_t& target_regnum);
+ ConvertBetweenRegisterKinds (lldb::RegisterKind source_rk, uint32_t source_regnum, lldb::RegisterKind target_rk, uint32_t& target_regnum);
//------------------------------------------------------------------
// lldb::ExecutionContextScope pure virtual functions
diff --git a/include/lldb/Target/StackFrame.h b/include/lldb/Target/StackFrame.h
index e7b57cd26ac95..1274dcc64bd3b 100644
--- a/include/lldb/Target/StackFrame.h
+++ b/include/lldb/Target/StackFrame.h
@@ -177,7 +177,7 @@ public:
///
/// The StackFrame maintains this SymbolContext and adds additional information
/// to it on an as-needed basis. This helps to avoid different functions
- /// looking up symbolic information for a given pc value multple times.
+ /// looking up symbolic information for a given pc value multiple times.
///
/// @params [in] resolve_scope
/// Flags from the SymbolContextItem enumerated type which specify what
@@ -261,7 +261,7 @@ public:
///
/// @param[in] get_file_globals
/// Whether to also retrieve compilation-unit scoped variables
- /// that are visisble to the entire compilation unit (e.g. file
+ /// that are visible to the entire compilation unit (e.g. file
/// static in C, globals that are homed in this CU).
///
/// @return
@@ -279,7 +279,7 @@ public:
///
/// @param[in] get_file_globals
/// Whether to also retrieve compilation-unit scoped variables
- /// that are visisble to the entire compilation unit (e.g. file
+ /// that are visible to the entire compilation unit (e.g. file
/// static in C, globals that are homed in this CU).
///
/// @return
diff --git a/include/lldb/Target/StopInfo.h b/include/lldb/Target/StopInfo.h
index 3435d392e2b99..8de40e852f4c8 100644
--- a/include/lldb/Target/StopInfo.h
+++ b/include/lldb/Target/StopInfo.h
@@ -157,7 +157,9 @@ public:
CreateStopReasonToTrace (Thread &thread);
static lldb::StopInfoSP
- CreateStopReasonWithPlan (lldb::ThreadPlanSP &plan, lldb::ValueObjectSP return_valobj_sp);
+ CreateStopReasonWithPlan (lldb::ThreadPlanSP &plan,
+ lldb::ValueObjectSP return_valobj_sp,
+ lldb::ClangExpressionVariableSP expression_variable_sp);
static lldb::StopInfoSP
CreateStopReasonWithException (Thread &thread, const char *description);
@@ -168,6 +170,9 @@ public:
static lldb::ValueObjectSP
GetReturnValueObject (lldb::StopInfoSP &stop_info_sp);
+ static lldb::ClangExpressionVariableSP
+ GetExpressionVariable (lldb::StopInfoSP &stop_info_sp);
+
protected:
// Perform any action that is associated with this stop. This is done as the
// Event is removed from the event queue. ProcessEventData::DoOnRemoval does the job.
diff --git a/include/lldb/Target/SystemRuntime.h b/include/lldb/Target/SystemRuntime.h
index 363ce122c4f3c..18f38f79bdbdd 100644
--- a/include/lldb/Target/SystemRuntime.h
+++ b/include/lldb/Target/SystemRuntime.h
@@ -20,6 +20,7 @@
#include "lldb/Core/ConstString.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/PluginInterface.h"
+#include "lldb/Core/StructuredData.h"
#include "lldb/Target/QueueList.h"
#include "lldb/Target/QueueItem.h"
#include "lldb/lldb-private.h"
@@ -222,7 +223,7 @@ public:
/// get the queue name and return it.
///
/// @param [in] dispatch_qaddr
- /// The address of the dispatch_queue_t structure for this thread.
+ /// The address of the dispatch_qaddr pointer for this thread.
///
/// @return
/// The string of this queue's name. An empty string is returned if the
@@ -244,7 +245,7 @@ public:
/// get the queue ID and return it.
///
/// @param [in] dispatch_qaddr
- /// The address of the dispatch_queue_t structure for this thread.
+ /// The address of the dispatch_qaddr pointer for this thread.
///
/// @return
/// The queue ID, or if it could not be retrieved, LLDB_INVALID_QUEUE_ID.
@@ -256,6 +257,26 @@ public:
}
//------------------------------------------------------------------
+ /// Get the libdispatch_queue_t address for the queue given the thread's dispatch_qaddr.
+ ///
+ /// On systems using libdispatch queues, a thread may be associated with a queue.
+ /// There will be a call to get the thread's dispatch_qaddr.
+ /// Given the thread's dispatch_qaddr, find the libdispatch_queue_t address and
+ /// return it.
+ ///
+ /// @param [in] dispatch_qaddr
+ /// The address of the dispatch_qaddr pointer for this thread.
+ ///
+ /// @return
+ /// The libdispatch_queue_t address, or LLDB_INVALID_ADDRESS if unavailable/not found.
+ //------------------------------------------------------------------
+ virtual lldb::addr_t
+ GetLibdispatchQueueAddressFromThreadQAddress (lldb::addr_t dispatch_qaddr)
+ {
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ //------------------------------------------------------------------
/// Get the pending work items for a libdispatch Queue
///
/// If this system/process is using libdispatch and the runtime can do so,
@@ -270,6 +291,60 @@ public:
{
}
+ //------------------------------------------------------------------
+ /// Complete the fields in a QueueItem
+ ///
+ /// PopulatePendingItemsForQueue() may not fill in all of the QueueItem
+ /// details; when the remaining fields are needed, they will be
+ /// fetched by call this method.
+ ///
+ /// @param [in] queue_item
+ /// The QueueItem that we will be completing.
+ ///
+ /// @param [in] item_ref
+ /// The item_ref token that is needed to retrieve the rest of the
+ /// information about the QueueItem.
+ //------------------------------------------------------------------
+ virtual void
+ CompleteQueueItem (lldb_private::QueueItem *queue_item, lldb::addr_t item_ref)
+ {
+ }
+
+ //------------------------------------------------------------------
+ /// Add key-value pairs to the StructuredData dictionary object with
+ /// information debugserver may need when constructing the jThreadExtendedInfo
+ /// packet.
+ ///
+ /// @param [out] dict
+ /// Dictionary to which key-value pairs should be added; they will
+ /// be sent to the remote gdb server stub as arguments in the
+ /// jThreadExtendedInfo request.
+ //------------------------------------------------------------------
+ virtual void
+ AddThreadExtendedInfoPacketHints (lldb_private::StructuredData::ObjectSP dict)
+ {
+ }
+
+ /// Determine whether it is safe to run an expression on a given thread
+ ///
+ /// If a system must not run functions on a thread in some particular state,
+ /// this method gives a way for it to flag that the expression should not be
+ /// run.
+ ///
+ /// @param [in] thread_sp
+ /// The thread we want to run the expression on.
+ ///
+ /// @return
+ /// True will be returned if there are no known problems with running an
+ /// expression on this thread. False means that the inferior function
+ /// call should not be made on this thread.
+ //------------------------------------------------------------------
+ virtual bool
+ SafeToCallFunctionsOnThisThread (lldb::ThreadSP thread_sp)
+ {
+ return true;
+ }
+
protected:
//------------------------------------------------------------------
// Member variables.
diff --git a/include/lldb/Target/Target.h b/include/lldb/Target/Target.h
index e65a511ab77aa..64f3edf0fc4f8 100644
--- a/include/lldb/Target/Target.h
+++ b/include/lldb/Target/Target.h
@@ -82,6 +82,12 @@ public:
SetDisableASLR (bool b);
bool
+ GetDetachOnError () const;
+
+ void
+ SetDetachOnError (bool b);
+
+ bool
GetDisableSTDIO () const;
void
@@ -201,9 +207,15 @@ public:
m_stop_others(true),
m_debug(false),
m_trap_exceptions(true),
+ m_generate_debug_info(false),
+ m_result_is_internal(false),
m_use_dynamic(lldb::eNoDynamicValues),
- m_timeout_usec(default_timeout)
- {}
+ m_timeout_usec(default_timeout),
+ m_one_thread_timeout_usec(0),
+ m_cancel_callback (nullptr),
+ m_cancel_callback_baton (nullptr)
+ {
+ }
ExecutionPolicy
GetExecutionPolicy () const
@@ -301,6 +313,18 @@ public:
m_timeout_usec = timeout;
}
+ uint32_t
+ GetOneThreadTimeoutUsec () const
+ {
+ return m_one_thread_timeout_usec;
+ }
+
+ void
+ SetOneThreadTimeoutUsec (uint32_t timeout = 0)
+ {
+ m_one_thread_timeout_usec = timeout;
+ }
+
bool
GetTryAllThreads () const
{
@@ -335,6 +359,20 @@ public:
SetDebug(bool b)
{
m_debug = b;
+ if (m_debug)
+ m_generate_debug_info = true;
+ }
+
+ bool
+ GetGenerateDebugInfo() const
+ {
+ return m_generate_debug_info;
+ }
+
+ void
+ SetGenerateDebugInfo(bool b)
+ {
+ m_generate_debug_info = b;
}
bool
@@ -348,6 +386,34 @@ public:
{
m_trap_exceptions = b;
}
+
+ void
+ SetCancelCallback (lldb::ExpressionCancelCallback callback, void *baton)
+ {
+ m_cancel_callback_baton = baton;
+ m_cancel_callback = callback;
+ }
+
+ bool
+ InvokeCancelCallback (lldb::ExpressionEvaluationPhase phase) const
+ {
+ if (m_cancel_callback == nullptr)
+ return false;
+ else
+ return m_cancel_callback (phase, m_cancel_callback_baton);
+ }
+
+ void
+ SetResultIsInternal (bool b)
+ {
+ m_result_is_internal = b;
+ }
+
+ bool
+ GetResultIsInternal () const
+ {
+ return m_result_is_internal;
+ }
private:
ExecutionPolicy m_execution_policy;
@@ -360,8 +426,13 @@ private:
bool m_stop_others;
bool m_debug;
bool m_trap_exceptions;
+ bool m_generate_debug_info;
+ bool m_result_is_internal;
lldb::DynamicValueType m_use_dynamic;
uint32_t m_timeout_usec;
+ uint32_t m_one_thread_timeout_usec;
+ lldb::ExpressionCancelCallback m_cancel_callback;
+ void *m_cancel_callback_baton;
};
//----------------------------------------------------------------------
@@ -513,7 +584,7 @@ public:
/// in a target.
///
/// @param[in] s
- /// The stream to which to dump the object descripton.
+ /// The stream to which to dump the object description.
//------------------------------------------------------------------
void
Dump (Stream *s, lldb::DescriptionLevel description_level);
@@ -1086,7 +1157,7 @@ public:
// we provide a way for expressions to be evaluated from the Target itself.
// If an expression is going to be run, then it should have a frame filled
// in in th execution context.
- ExecutionResults
+ lldb::ExpressionResults
EvaluateExpression (const char *expression,
StackFrame *frame,
lldb::ValueObjectSP &result_valobj_sp,
diff --git a/include/lldb/Target/TargetList.h b/include/lldb/Target/TargetList.h
index 41404e11c7fa0..6abf13e8704c2 100644
--- a/include/lldb/Target/TargetList.h
+++ b/include/lldb/Target/TargetList.h
@@ -121,7 +121,7 @@ public:
//------------------------------------------------------------------
/// Delete a Target object from the list.
///
- /// When clients are done with the Target objets, this function
+ /// When clients are done with the Target objects, this function
/// should be called to release the memory associated with a target
/// object.
///
diff --git a/include/lldb/Target/Thread.h b/include/lldb/Target/Thread.h
index 20687e977bff6..cba09e1641056 100644
--- a/include/lldb/Target/Thread.h
+++ b/include/lldb/Target/Thread.h
@@ -14,6 +14,7 @@
#include "lldb/Host/Mutex.h"
#include "lldb/Core/Broadcaster.h"
#include "lldb/Core/Event.h"
+#include "lldb/Core/StructuredData.h"
#include "lldb/Core/UserID.h"
#include "lldb/Core/UserSettingsController.h"
#include "lldb/Target/ExecutionContextScope.h"
@@ -49,6 +50,12 @@ public:
bool
GetTraceEnabledState() const;
+
+ bool
+ GetStepInAvoidsNoDebug () const;
+
+ bool
+ GetStepOutAvoidsNoDebug () const;
};
typedef std::shared_ptr<ThreadProperties> ThreadPropertiesSP;
@@ -153,7 +160,25 @@ public:
static const ThreadPropertiesSP &
GetGlobalProperties();
- Thread (Process &process, lldb::tid_t tid);
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param [in] process
+ ///
+ /// @param [in] tid
+ ///
+ /// @param [in] use_invalid_index_id
+ /// Optional parameter, defaults to false. The only subclass that
+ /// is likely to set use_invalid_index_id == true is the HistoryThread
+ /// class. In that case, the Thread we are constructing represents
+ /// a thread from earlier in the program execution. We may have the
+ /// tid of the original thread that they represent but we don't want
+ /// to reuse the IndexID of that thread, or create a new one. If a
+ /// client wants to know the original thread's IndexID, they should use
+ /// Thread::GetExtendedBacktraceOriginatingIndexID().
+ //------------------------------------------------------------------
+ Thread (Process &process, lldb::tid_t tid, bool use_invalid_index_id = false);
+
virtual ~Thread();
lldb::ProcessSP
@@ -185,10 +210,22 @@ public:
{
return m_resume_state;
}
-
+
+ // This sets the "external resume state" of the thread. If the thread is suspended here, it should never
+ // get scheduled. Note that just because a thread is marked as "running" does not mean we will let it run in
+ // a given bit of process control. For instance "step" tries to stay on the selected thread it was issued on,
+ // which may involve suspending other threads temporarily. This temporary suspension is NOT reflected in the
+ // state set here and reported in GetResumeState.
+ //
+ // If you are just preparing all threads to run, you should not override the threads that are
+ // marked as suspended by the debugger. In that case, pass override_suspend = false. If you want
+ // to force the thread to run (e.g. the "thread continue" command, or are resetting the state
+ // (e.g. in SBThread::Resume()), then pass true to override_suspend.
void
- SetResumeState (lldb::StateType state)
+ SetResumeState (lldb::StateType state, bool override_suspend = false)
{
+ if (m_resume_state == lldb::eStateSuspended && !override_suspend)
+ return;
m_resume_state = state;
}
@@ -270,6 +307,28 @@ public:
return NULL;
}
+ //------------------------------------------------------------------
+ /// Retrieve a dictionary of information about this thread
+ ///
+ /// On Mac OS X systems there may be voucher information.
+ /// The top level dictionary returned will have an "activity" key and the
+ /// value of the activity is a dictionary. Keys in that dictionary will
+ /// be "name" and "id", among others.
+ /// There may also be "trace_messages" (an array) with each entry in that array
+ /// being a dictionary (keys include "message" with the text of the trace
+ /// message).
+ //------------------------------------------------------------------
+ StructuredData::ObjectSP
+ GetExtendedInfo ()
+ {
+ if (m_extended_info_fetched == false)
+ {
+ m_extended_info = FetchThreadExtendedInfo ();
+ m_extended_info_fetched = true;
+ }
+ return m_extended_info;
+ }
+
virtual const char *
GetName ()
{
@@ -281,6 +340,21 @@ public:
{
}
+ //------------------------------------------------------------------
+ /// Retrieve the Queue ID for the queue currently using this Thread
+ ///
+ /// If this Thread is doing work on behalf of a libdispatch/GCD queue,
+ /// retrieve the QueueID.
+ ///
+ /// This is a unique identifier for the libdispatch/GCD queue in a
+ /// process. Often starting at 1 for the initial system-created
+ /// queues and incrementing, a QueueID will not be reused for a
+ /// different queue during the lifetime of a proces.
+ ///
+ /// @return
+ /// A QueueID if the Thread subclass implements this, else
+ /// LLDB_INVALID_QUEUE_ID.
+ //------------------------------------------------------------------
virtual lldb::queue_id_t
GetQueueID ()
{
@@ -292,6 +366,16 @@ public:
{
}
+ //------------------------------------------------------------------
+ /// Retrieve the Queue name for the queue currently using this Thread
+ ///
+ /// If this Thread is doing work on behalf of a libdispatch/GCD queue,
+ /// retrieve the Queue name.
+ ///
+ /// @return
+ /// The Queue name, if the Thread subclass implements this, else
+ /// NULL.
+ //------------------------------------------------------------------
virtual const char *
GetQueueName ()
{
@@ -303,6 +387,44 @@ public:
{
}
+ //------------------------------------------------------------------
+ /// Retrieve the Queue for this thread, if any.
+ ///
+ /// @return
+ /// A QueueSP for the queue that is currently associated with this
+ /// thread.
+ /// An empty shared pointer indicates that this thread is not
+ /// associated with a queue, or libdispatch queues are not
+ /// supported on this target.
+ //------------------------------------------------------------------
+ virtual lldb::QueueSP
+ GetQueue ()
+ {
+ return lldb::QueueSP();
+ }
+
+ //------------------------------------------------------------------
+ /// Retrieve the address of the libdispatch_queue_t struct for queue
+ /// currently using this Thread
+ ///
+ /// If this Thread is doing work on behalf of a libdispatch/GCD queue,
+ /// retrieve the address of the libdispatch_queue_t structure describing
+ /// the queue.
+ ///
+ /// This address may be reused for different queues later in the Process
+ /// lifetime and should not be used to identify a queue uniquely. Use
+ /// the GetQueueID() call for that.
+ ///
+ /// @return
+ /// The Queue's libdispatch_queue_t address if the Thread subclass
+ /// implements this, else LLDB_INVALID_ADDRESS.
+ //------------------------------------------------------------------
+ virtual lldb::addr_t
+ GetQueueLibdispatchQueueAddress ()
+ {
+ return LLDB_INVALID_ADDRESS;
+ }
+
virtual uint32_t
GetStackFrameCount()
{
@@ -412,6 +534,9 @@ public:
void
DumpUsingSettingsFormat (Stream &strm, uint32_t frame_idx);
+ bool
+ GetDescription (Stream &s, lldb::DescriptionLevel level, bool json_output);
+
//------------------------------------------------------------------
/// Default implementation for stepping into.
///
@@ -422,17 +547,22 @@ public:
/// If true and the frame has debug info, then do a source level
/// step in, else do a single instruction step in.
///
- /// @param[in] avoid_code_without_debug_info
+ /// @param[in] step_in_avoids_code_without_debug_info
/// If \a true, then avoid stepping into code that doesn't have
- /// debug info, else step into any code regardless of wether it
+ /// debug info, else step into any code regardless of whether it
/// has debug info.
///
+ /// @param[in] step_out_avoids_code_without_debug_info
+ /// If \a true, then if you step out to code with no debug info, keep
+ /// stepping out till you get to code with debug info.
+ ///
/// @return
/// An error that describes anything that went wrong
//------------------------------------------------------------------
virtual Error
StepIn (bool source_step,
- bool avoid_code_without_debug_info);
+ LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate,
+ LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate);
//------------------------------------------------------------------
/// Default implementation for stepping over.
@@ -448,7 +578,8 @@ public:
/// An error that describes anything that went wrong
//------------------------------------------------------------------
virtual Error
- StepOver (bool source_step);
+ StepOver (bool source_step,
+ LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate);
//------------------------------------------------------------------
/// Default implementation for stepping out.
@@ -487,6 +618,19 @@ public:
virtual lldb::addr_t
GetThreadLocalData (const lldb::ModuleSP module);
+ //------------------------------------------------------------------
+ /// Check whether this thread is safe to run functions
+ ///
+ /// The SystemRuntime may know of certain thread states (functions in
+ /// process of execution, for instance) which can make it unsafe for
+ /// functions to be called.
+ ///
+ /// @return
+ /// True if it is safe to call functions on this thread.
+ /// False if function calls should be avoided on this thread.
+ //------------------------------------------------------------------
+ virtual bool
+ SafeToCallFunctions ();
//------------------------------------------------------------------
// Thread Plan Providers:
@@ -574,14 +718,19 @@ public:
/// @param[in] stop_other_threads
/// \b true if we will stop other threads while we single step this one.
///
+ /// @param[in] step_out_avoids_code_without_debug_info
+ /// If eLazyBoolYes, if the step over steps out it will continue to step out till it comes to a frame with debug info.
+ /// If eLazyBoolCalculate, we will consult the default set in the thread.
+ ///
/// @return
/// A shared pointer to the newly queued thread plan, or NULL if the plan could not be queued.
//------------------------------------------------------------------
virtual lldb::ThreadPlanSP
QueueThreadPlanForStepOverRange (bool abort_other_plans,
- const AddressRange &range,
- const SymbolContext &addr_context,
- lldb::RunMode stop_other_threads);
+ const AddressRange &range,
+ const SymbolContext &addr_context,
+ lldb::RunMode stop_other_threads,
+ LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate);
//------------------------------------------------------------------
/// Queues the plan used to step through an address range, stepping into functions.
@@ -609,19 +758,25 @@ public:
/// @param[in] stop_other_threads
/// \b true if we will stop other threads while we single step this one.
///
- /// @param[in] avoid_code_without_debug_info
- /// If \b true we will step out if we step into code with no debug info.
+ /// @param[in] step_in_avoids_code_without_debug_info
+ /// If eLazyBoolYes we will step out if we step into code with no debug info.
+ /// If eLazyBoolCalculate we will consult the default set in the thread.
+ ///
+ /// @param[in] step_out_avoids_code_without_debug_info
+ /// If eLazyBoolYes, if the step over steps out it will continue to step out till it comes to a frame with debug info.
+ /// If eLazyBoolCalculate, it will consult the default set in the thread.
///
/// @return
/// A shared pointer to the newly queued thread plan, or NULL if the plan could not be queued.
//------------------------------------------------------------------
virtual lldb::ThreadPlanSP
QueueThreadPlanForStepInRange (bool abort_other_plans,
- const AddressRange &range,
- const SymbolContext &addr_context,
- const char *step_in_target,
- lldb::RunMode stop_other_threads,
- bool avoid_code_without_debug_info);
+ const AddressRange &range,
+ const SymbolContext &addr_context,
+ const char *step_in_target,
+ lldb::RunMode stop_other_threads,
+ LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate,
+ LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate);
//------------------------------------------------------------------
/// Queue the plan used to step out of the function at the current PC of
@@ -648,6 +803,10 @@ public:
/// @param[in] run_vote
/// See standard meanings for the stop & run votes in ThreadPlan.h.
///
+ /// @param[in] step_out_avoids_code_without_debug_info
+ /// If eLazyBoolYes, if the step over steps out it will continue to step out till it comes to a frame with debug info.
+ /// If eLazyBoolCalculate, it will consult the default set in the thread.
+ ///
/// @return
/// A shared pointer to the newly queued thread plan, or NULL if the plan could not be queued.
//------------------------------------------------------------------
@@ -658,7 +817,46 @@ public:
bool stop_other_threads,
Vote stop_vote, // = eVoteYes,
Vote run_vote, // = eVoteNoOpinion);
- uint32_t frame_idx);
+ uint32_t frame_idx,
+ LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate);
+
+ //------------------------------------------------------------------
+ /// Queue the plan used to step out of the function at the current PC of
+ /// a thread. This version does not consult the should stop here callback, and should only
+ /// be used by other thread plans when they need to retain control of the step out.
+ ///
+ /// @param[in] abort_other_plans
+ /// \b true if we discard the currently queued plans and replace them with this one.
+ /// Otherwise this plan will go on the end of the plan stack.
+ ///
+ /// @param[in] addr_context
+ /// When dealing with stepping through inlined functions the current PC is not enough information to know
+ /// what "step" means. For instance a series of nested inline functions might start at the same address.
+ // The \a addr_context provides the current symbol context the step
+ /// is supposed to be out of.
+ // FIXME: Currently unused.
+ ///
+ /// @param[in] first_insn
+ /// \b true if this is the first instruction of a function.
+ ///
+ /// @param[in] stop_other_threads
+ /// \b true if we will stop other threads while we single step this one.
+ ///
+ /// @param[in] stop_vote
+ /// @param[in] run_vote
+ /// See standard meanings for the stop & run votes in ThreadPlan.h.
+ ///
+ /// @return
+ /// A shared pointer to the newly queued thread plan, or NULL if the plan could not be queued.
+ //------------------------------------------------------------------
+ virtual lldb::ThreadPlanSP
+ QueueThreadPlanForStepOutNoShouldStop (bool abort_other_plans,
+ SymbolContext *addr_context,
+ bool first_insn,
+ bool stop_other_threads,
+ Vote stop_vote, // = eVoteYes,
+ Vote run_vote, // = eVoteNoOpinion);
+ uint32_t frame_idx);
//------------------------------------------------------------------
/// Gets the plan used to step through the code that steps from a function
@@ -768,6 +966,17 @@ public:
GetReturnValueObject ();
//------------------------------------------------------------------
+ /// Gets the outer-most expression variable from the completed plans
+ ///
+ /// @return
+ /// A ClangExpressionVariableSP, either empty if there is no
+ /// plan completed an expression during the current stop
+ /// or the expression variable that was made for the completed expression.
+ //------------------------------------------------------------------
+ lldb::ClangExpressionVariableSP
+ GetExpressionVariable ();
+
+ //------------------------------------------------------------------
/// Checks whether the given plan is in the completed plans for this
/// stop.
///
@@ -1066,6 +1275,13 @@ protected:
return false;
}
+ // Subclasses that have a way to get an extended info dictionary for this thread should
+ // fill
+ virtual lldb_private::StructuredData::ObjectSP
+ FetchThreadExtendedInfo ()
+ {
+ return StructuredData::ObjectSP();
+ }
lldb::StackFrameListSP
GetStackFrameList ();
@@ -1091,11 +1307,13 @@ protected:
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::ShoudResume.
+ /// It gets set in Thread::ShouldResume.
std::unique_ptr<lldb_private::Unwind> m_unwinder_ap;
bool m_destroy_called; // This is used internally to make sure derived Thread classes call DestroyThread.
LazyBool m_override_should_notify;
private:
+ bool m_extended_info_fetched; // Have we tried to retrieve the m_extended_info for this thread?
+ StructuredData::ObjectSP m_extended_info; // The extended info for this thread
//------------------------------------------------------------------
// For Thread only
//------------------------------------------------------------------
diff --git a/include/lldb/Target/ThreadPlan.h b/include/lldb/Target/ThreadPlan.h
index 3c83fd1b9630d..1f20841906d33 100644
--- a/include/lldb/Target/ThreadPlan.h
+++ b/include/lldb/Target/ThreadPlan.h
@@ -501,11 +501,26 @@ public:
return m_thread.GetStopInfo ();
}
+ // If the completion of the thread plan stepped out of a function, the return value of the function
+ // might have been captured by the thread plan (currently only ThreadPlanStepOut does this.)
+ // If so, the ReturnValueObject can be retrieved from here.
+
virtual lldb::ValueObjectSP
GetReturnValueObject ()
{
return lldb::ValueObjectSP();
}
+
+ // If the thread plan managing the evaluation of a user expression lives longer than the command
+ // that instigated the expression (generally because the expression evaluation hit a breakpoint, and
+ // the user regained control at that point) a subsequent process control command step/continue/etc. might
+ // complete the expression evaluations. If so, the result of the expression evaluation will show up here.
+
+ virtual lldb::ClangExpressionVariableSP
+ GetExpressionVariable ()
+ {
+ return lldb::ClangExpressionVariableSP();
+ }
// If a thread plan stores the state before it was run, then you might
// want to restore the state when it is done. This will do that job.
@@ -524,6 +539,27 @@ public:
return false;
}
+ virtual bool
+ SetIterationCount (size_t count)
+ {
+ if (m_takes_iteration_count)
+ {
+ // Don't tell me to do something 0 times...
+ if (count == 0)
+ return false;
+ m_iteration_count = count;
+ }
+ return m_takes_iteration_count;
+ }
+
+ virtual size_t
+ GetIterationCount ()
+ {
+ if (!m_takes_iteration_count)
+ return 0;
+ else
+ return m_iteration_count;
+ }
protected:
//------------------------------------------------------------------
// Classes that inherit from ThreadPlan can see and modify these
@@ -578,6 +614,8 @@ protected:
Thread &m_thread;
Vote m_stop_vote;
Vote m_run_vote;
+ bool m_takes_iteration_count = false;
+ int32_t m_iteration_count = 1;
private:
//------------------------------------------------------------------
diff --git a/include/lldb/Target/ThreadPlanCallFunction.h b/include/lldb/Target/ThreadPlanCallFunction.h
index 18f1d0facbf6a..12200ab765534 100644
--- a/include/lldb/Target/ThreadPlanCallFunction.h
+++ b/include/lldb/Target/ThreadPlanCallFunction.h
@@ -52,9 +52,6 @@ public:
virtual bool
StopOthers ();
- virtual void
- SetStopOthers (bool new_value);
-
virtual lldb::StateType
GetPlanRunState ();
@@ -128,7 +125,10 @@ public:
m_takedown_done = true;
}
-protected:
+ virtual void
+ SetStopOthers (bool new_value);
+
+protected:
void ReportRegisterState (const char *message);
virtual bool
diff --git a/include/lldb/Target/ThreadPlanCallUserExpression.h b/include/lldb/Target/ThreadPlanCallUserExpression.h
index 5eb7cc1cd4525..67ac642de7bdf 100644
--- a/include/lldb/Target/ThreadPlanCallUserExpression.h
+++ b/include/lldb/Target/ThreadPlanCallUserExpression.h
@@ -40,21 +40,35 @@ public:
GetDescription (Stream *s, lldb::DescriptionLevel level);
virtual void
- WillPop ()
- {
- ThreadPlanCallFunction::WillPop();
- if (m_user_expression_sp)
- m_user_expression_sp.reset();
- }
+ WillPop ();
virtual lldb::StopInfoSP
GetRealStopInfo();
+ virtual bool
+ MischiefManaged ();
+
+ void
+ TransferExpressionOwnership ()
+ {
+ m_manage_materialization = true;
+ }
+
+ virtual lldb::ClangExpressionVariableSP
+ GetExpressionVariable ()
+ {
+ return m_result_var_sp;
+ }
+
protected:
private:
ClangUserExpression::ClangUserExpressionSP m_user_expression_sp; // This is currently just used to ensure the
// User expression the initiated this ThreadPlan
// lives as long as the thread plan does.
+ bool m_manage_materialization = false;
+ lldb::ClangExpressionVariableSP m_result_var_sp; // If we are left to manage the materialization,
+ // then stuff the result expression variable here.
+
DISALLOW_COPY_AND_ASSIGN (ThreadPlanCallUserExpression);
};
diff --git a/include/lldb/Target/ThreadPlanShouldStopHere.h b/include/lldb/Target/ThreadPlanShouldStopHere.h
index 62068b78ae4e2..26e4a1ec4fe77 100644
--- a/include/lldb/Target/ThreadPlanShouldStopHere.h
+++ b/include/lldb/Target/ThreadPlanShouldStopHere.h
@@ -21,8 +21,9 @@ namespace lldb_private {
// This is an interface that ThreadPlans can adopt to allow flexible modifications of the behavior
// when a thread plan comes to a place where it would ordinarily stop. If such modification makes
// sense for your plan, inherit from this class, and when you would be about to stop (in your ShouldStop
-// method), call InvokeShouldStopHereCallback, and if that returns a non-NULL plan, execute that
-// plan instead of stopping.
+// method), call InvokeShouldStopHereCallback, passing in the frame comparison between where the step operation
+// started and where you arrived. If it returns true, then QueueStepOutFromHere will queue the plan
+// to execute instead of stopping.
//
// The classic example of the use of this is ThreadPlanStepInRange not stopping in frames that have
// no debug information.
@@ -34,27 +35,84 @@ namespace lldb_private {
class ThreadPlanShouldStopHere
{
public:
+ struct ThreadPlanShouldStopHereCallbacks
+ {
+ ThreadPlanShouldStopHereCallbacks()
+ {
+ should_stop_here_callback = nullptr;
+ step_from_here_callback = nullptr;
+ }
+
+ ThreadPlanShouldStopHereCallbacks(ThreadPlanShouldStopHereCallback should_stop,
+ ThreadPlanStepFromHereCallback step_from_here)
+ {
+ should_stop_here_callback = should_stop;
+ step_from_here_callback = step_from_here;
+ }
+
+ void
+ Clear()
+ {
+ should_stop_here_callback = nullptr;
+ step_from_here_callback = nullptr;
+ }
+
+ ThreadPlanShouldStopHereCallback should_stop_here_callback;
+ ThreadPlanStepFromHereCallback step_from_here_callback;
+ };
+
enum
{
eNone = 0,
- eAvoidInlines = (1 << 0),
- eAvoidNoDebug = (1 << 1)
+ eAvoidInlines = (1 << 0),
+ eStepInAvoidNoDebug = (1 << 1),
+ eStepOutAvoidNoDebug = (1 << 2)
};
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
+ ThreadPlanShouldStopHere (ThreadPlan *owner);
+
ThreadPlanShouldStopHere (ThreadPlan *owner,
- ThreadPlanShouldStopHereCallback callback = NULL,
+ const ThreadPlanShouldStopHereCallbacks *callbacks,
void *baton = NULL);
virtual
~ThreadPlanShouldStopHere();
-
+
+ // Set the ShouldStopHere callbacks. Pass in null to clear them and have no special behavior (though you
+ // can also call ClearShouldStopHereCallbacks for that purpose. If you pass in a valid pointer, it will
+ // adopt the non-null fields, and any null fields will be set to the default values.
+
void
- SetShouldStopHereCallback (ThreadPlanShouldStopHereCallback callback, void *baton);
+ SetShouldStopHereCallbacks (const ThreadPlanShouldStopHereCallbacks *callbacks, void *baton)
+ {
+ if (callbacks)
+ {
+ m_callbacks = *callbacks;
+ if (!m_callbacks.should_stop_here_callback)
+ m_callbacks.should_stop_here_callback = ThreadPlanShouldStopHere::DefaultShouldStopHereCallback;
+ if (!m_callbacks.step_from_here_callback)
+ m_callbacks.step_from_here_callback = ThreadPlanShouldStopHere::DefaultStepFromHereCallback;
+ }
+ else
+ {
+ ClearShouldStopHereCallbacks ();
+ }
+ m_baton = baton;
+ }
+
+ void
+ ClearShouldStopHereCallbacks()
+ {
+ m_callbacks.Clear();
+ }
+ bool
+ InvokeShouldStopHereCallback (lldb::FrameComparison operation);
+
lldb::ThreadPlanSP
- InvokeShouldStopHereCallback ();
+ CheckShouldStopHereAndQueueStepOut (lldb::FrameComparison operation);
lldb_private::Flags &
GetFlags ()
@@ -69,13 +127,22 @@ public:
}
protected:
+ static bool
+ DefaultShouldStopHereCallback (ThreadPlan *current_plan, Flags &flags, lldb::FrameComparison operation, void *baton);
+
+ static lldb::ThreadPlanSP
+ DefaultStepFromHereCallback (ThreadPlan *current_plan, Flags &flags, lldb::FrameComparison operation, void *baton);
+
+ virtual lldb::ThreadPlanSP
+ QueueStepOutFromHerePlan (Flags &flags, lldb::FrameComparison operation);
+
// Implement this, and call it in the plan's constructor to set the default flags.
virtual void SetFlagsToDefault () = 0;
//------------------------------------------------------------------
// Classes that inherit from ThreadPlanShouldStopHere can see and modify these
//------------------------------------------------------------------
- ThreadPlanShouldStopHereCallback m_callback;
+ ThreadPlanShouldStopHereCallbacks m_callbacks;
void * m_baton;
ThreadPlan *m_owner;
lldb_private::Flags m_flags;
diff --git a/include/lldb/Target/ThreadPlanStepInRange.h b/include/lldb/Target/ThreadPlanStepInRange.h
index 2f741f179bd43..3a22e97e30d0b 100644
--- a/include/lldb/Target/ThreadPlanStepInRange.h
+++ b/include/lldb/Target/ThreadPlanStepInRange.h
@@ -30,13 +30,17 @@ public:
ThreadPlanStepInRange (Thread &thread,
const AddressRange &range,
const SymbolContext &addr_context,
- lldb::RunMode stop_others);
-
+ lldb::RunMode stop_others,
+ LazyBool step_in_avoids_code_without_debug_info,
+ LazyBool step_out_avoids_code_without_debug_info);
+
ThreadPlanStepInRange (Thread &thread,
const AddressRange &range,
const SymbolContext &addr_context,
const char *step_into_function_name,
- lldb::RunMode stop_others);
+ lldb::RunMode stop_others,
+ LazyBool step_in_avoids_code_without_debug_info,
+ LazyBool step_out_avoids_code_without_debug_info);
virtual
~ThreadPlanStepInRange ();
@@ -54,9 +58,6 @@ public:
m_step_into_target.SetCString(target);
}
- static lldb::ThreadPlanSP
- DefaultShouldStopHereCallback (ThreadPlan *current_plan, Flags &flags, void *baton);
-
static void
SetDefaultFlagValue (uint32_t new_value);
@@ -64,13 +65,26 @@ public:
IsVirtualStep();
protected:
+ static bool
+ DefaultShouldStopHereCallback (ThreadPlan *current_plan, Flags &flags, lldb::FrameComparison operation, void *baton);
+
virtual bool DoWillResume (lldb::StateType resume_state, bool current_plan);
virtual bool
DoPlanExplainsStop (Event *event_ptr);
virtual void
- SetFlagsToDefault ();
+ SetFlagsToDefault ()
+ {
+ GetFlags().Set(ThreadPlanStepInRange::s_default_flag_values);
+ }
+
+ void
+ SetCallbacks()
+ {
+ ThreadPlanShouldStopHere::ThreadPlanShouldStopHereCallbacks callbacks(ThreadPlanStepInRange::DefaultShouldStopHereCallback, nullptr);
+ SetShouldStopHereCallbacks (&callbacks, nullptr);
+ }
bool
FrameMatchesAvoidCriteria ();
@@ -81,20 +95,23 @@ private:
Thread::QueueThreadPlanForStepOverRange (bool abort_other_plans,
const AddressRange &range,
const SymbolContext &addr_context,
- lldb::RunMode stop_others);
+ lldb::RunMode stop_others,
+ LazyBool avoid_code_without_debug_info);
friend lldb::ThreadPlanSP
Thread::QueueThreadPlanForStepInRange (bool abort_other_plans,
const AddressRange &range,
const SymbolContext &addr_context,
const char *step_in_target,
lldb::RunMode stop_others,
- bool avoid_code_without_debug_info);
-
+ LazyBool step_in_avoids_code_without_debug_info,
+ LazyBool step_out_avoids_code_without_debug_info);
+ void SetupAvoidNoDebug(LazyBool step_in_avoids_code_without_debug_info,
+ LazyBool step_out_avoids_code_without_debug_info);
// Need an appropriate marker for the current stack so we can tell step out
// from step in.
- static uint32_t s_default_flag_values;
+ static uint32_t s_default_flag_values; // These are the default flag values for the ThreadPlanStepThrough.
lldb::ThreadPlanSP m_sub_plan_sp; // Keep track of the last plan we were running. If it fails, we should stop.
std::unique_ptr<RegularExpression> m_avoid_regexp_ap;
bool m_step_past_prologue; // FIXME: For now hard-coded to true, we could put a switch in for this if there's
diff --git a/include/lldb/Target/ThreadPlanStepInstruction.h b/include/lldb/Target/ThreadPlanStepInstruction.h
index eb4a64bcbc84c..86069ffd9eb5e 100644
--- a/include/lldb/Target/ThreadPlanStepInstruction.h
+++ b/include/lldb/Target/ThreadPlanStepInstruction.h
@@ -32,6 +32,7 @@ public:
virtual lldb::StateType GetPlanRunState ();
virtual bool WillStop ();
virtual bool MischiefManaged ();
+ virtual bool IsPlanStale ();
protected:
virtual bool DoPlanExplainsStop (Event *event_ptr);
@@ -41,6 +42,7 @@ protected:
bool stop_others,
Vote stop_vote,
Vote run_vote);
+ void SetUpState ();
private:
friend lldb::ThreadPlanSP
diff --git a/include/lldb/Target/ThreadPlanStepOut.h b/include/lldb/Target/ThreadPlanStepOut.h
index 2737978a4edc8..8c140dc9d95d1 100644
--- a/include/lldb/Target/ThreadPlanStepOut.h
+++ b/include/lldb/Target/ThreadPlanStepOut.h
@@ -16,10 +16,12 @@
// Project includes
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
+#include "lldb/Target/ThreadPlanShouldStopHere.h"
namespace lldb_private {
-class ThreadPlanStepOut : public ThreadPlan
+class ThreadPlanStepOut : public ThreadPlan,
+ public ThreadPlanShouldStopHere
{
public:
ThreadPlanStepOut (Thread &thread,
@@ -28,7 +30,8 @@ public:
bool stop_others,
Vote stop_vote,
Vote run_vote,
- uint32_t frame_idx);
+ uint32_t frame_idx,
+ LazyBool step_out_avoids_code_without_debug_info);
virtual ~ThreadPlanStepOut ();
@@ -48,21 +51,29 @@ public:
}
protected:
+ virtual void
+ SetFlagsToDefault ()
+ {
+ GetFlags().Set(ThreadPlanStepOut::s_default_flag_values);
+ }
+
virtual bool DoPlanExplainsStop (Event *event_ptr);
virtual bool DoWillResume (lldb::StateType resume_state, bool current_plan);
bool QueueInlinedStepPlan (bool queue_now);
private:
- SymbolContext *m_step_from_context;
+ static uint32_t s_default_flag_values; // These are the default flag values for the ThreadPlanStepThrough.
+
lldb::addr_t m_step_from_insn;
StackID m_step_out_to_id;
StackID m_immediate_step_from_id;
lldb::break_id_t m_return_bp_id;
lldb::addr_t m_return_addr;
- bool m_first_insn;
bool m_stop_others;
- lldb::ThreadPlanSP m_step_through_inline_plan_sp;
- lldb::ThreadPlanSP m_step_out_plan_sp;
+ lldb::ThreadPlanSP m_step_out_to_inline_plan_sp; // This plan implements step out to the real function containing
+ // an inlined frame so we can then step out of that.
+ lldb::ThreadPlanSP m_step_through_inline_plan_sp; // This plan then steps past the inlined frame(s).
+ lldb::ThreadPlanSP m_step_out_further_plan_sp; // This plan keeps stepping out if ShouldStopHere told us to.
Function *m_immediate_step_from_function;
lldb::ValueObjectSP m_return_valobj_sp;
@@ -73,8 +84,10 @@ private:
bool stop_others,
Vote stop_vote,
Vote run_vote,
- uint32_t frame_idx);
+ uint32_t frame_idx,
+ LazyBool step_out_avoids_code_without_debug_info);
+ void SetupAvoidNoDebug(LazyBool step_out_avoids_code_without_debug_info);
// Need an appropriate marker for the current stack so we can tell step out
// from step in.
diff --git a/include/lldb/Target/ThreadPlanStepOverRange.h b/include/lldb/Target/ThreadPlanStepOverRange.h
index 2cb5288272ea4..d47c6c9429d54 100644
--- a/include/lldb/Target/ThreadPlanStepOverRange.h
+++ b/include/lldb/Target/ThreadPlanStepOverRange.h
@@ -21,14 +21,16 @@
namespace lldb_private {
-class ThreadPlanStepOverRange : public ThreadPlanStepRange
+class ThreadPlanStepOverRange : public ThreadPlanStepRange,
+ ThreadPlanShouldStopHere
{
public:
ThreadPlanStepOverRange (Thread &thread,
const AddressRange &range,
const SymbolContext &addr_context,
- lldb::RunMode stop_others);
+ lldb::RunMode stop_others,
+ LazyBool step_out_avoids_no_debug);
virtual ~ThreadPlanStepOverRange ();
@@ -38,9 +40,20 @@ public:
protected:
virtual bool DoPlanExplainsStop (Event *event_ptr);
virtual bool DoWillResume (lldb::StateType resume_state, bool current_plan);
-
+
+ virtual void
+ SetFlagsToDefault ()
+ {
+ GetFlags().Set(ThreadPlanStepOverRange::s_default_flag_values);
+ }
+
+
+
private:
+ static uint32_t s_default_flag_values;
+
+ void SetupAvoidNoDebug(LazyBool step_out_avoids_code_without_debug_info);
bool IsEquivalentContext(const SymbolContext &context);
bool m_first_resume;
diff --git a/include/lldb/Target/ThreadPlanStepRange.h b/include/lldb/Target/ThreadPlanStepRange.h
index 486fd6528390b..3487e9ad66cbe 100644
--- a/include/lldb/Target/ThreadPlanStepRange.h
+++ b/include/lldb/Target/ThreadPlanStepRange.h
@@ -77,6 +77,7 @@ protected:
std::vector<AddressRange> m_address_ranges;
lldb::RunMode m_stop_others;
StackID m_stack_id; // Use the stack ID so we can tell step out from step in.
+ StackID m_parent_stack_id; // Use the parent stack ID so we can identify tail calls and the like.
bool m_no_more_plans; // Need this one so we can tell if we stepped into a call,
// but can't continue, in which case we are done.
bool m_first_run_event; // We want to broadcast only one running event, our first.
diff --git a/include/lldb/Target/UnwindAssembly.h b/include/lldb/Target/UnwindAssembly.h
index 254382ac029d4..963949cf07d56 100644
--- a/include/lldb/Target/UnwindAssembly.h
+++ b/include/lldb/Target/UnwindAssembly.h
@@ -33,6 +33,11 @@ public:
UnwindPlan& unwind_plan) = 0;
virtual bool
+ AugmentUnwindPlanFromCallSite (AddressRange& func,
+ Thread& thread,
+ UnwindPlan& unwind_plan) = 0;
+
+ virtual bool
GetFastUnwindPlan (AddressRange& func,
Thread& thread,
UnwindPlan &unwind_plan) = 0;