Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions lldb/bindings/python/python-wrapper.swig
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,18 @@ void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBValue(PyObject * data
return sb_ptr;
}

void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBValueList(PyObject * data) {
lldb::SBValueList *sb_ptr = NULL;

int valid_cast =
SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBValueList, 0);

if (valid_cast == -1)
return NULL;

return sb_ptr;
}

void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *
data) {
lldb::SBMemoryRegionInfo *sb_ptr = NULL;
Expand Down
10 changes: 6 additions & 4 deletions lldb/include/lldb/API/SBValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@
#include "lldb/API/SBDefines.h"
#include "lldb/API/SBType.h"

namespace lldb_private {
class ValueImpl;
class ValueLocker;

namespace lldb_private {
namespace python {
class SWIGBridge;
}
Expand Down Expand Up @@ -490,7 +489,7 @@ class LLDB_API SBValue {
/// \return
/// A ValueObjectSP of the best kind (static, dynamic or synthetic) we
/// can cons up, in accordance with the SBValue's settings.
lldb::ValueObjectSP GetSP(ValueLocker &value_locker) const;
lldb::ValueObjectSP GetSP(lldb_private::ValueLocker &value_locker) const;

// these calls do the right thing WRT adjusting their settings according to
// the target's preferences
Expand All @@ -506,8 +505,11 @@ class LLDB_API SBValue {
void SetSP(const lldb::ValueObjectSP &sp, lldb::DynamicValueType use_dynamic,
bool use_synthetic, const char *name);

protected:
friend class lldb_private::ScriptInterpreter;

private:
typedef std::shared_ptr<ValueImpl> ValueImplSP;
typedef std::shared_ptr<lldb_private::ValueImpl> ValueImplSP;
ValueImplSP m_opaque_sp;

void SetSP(ValueImplSP impl_sp);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#define LLDB_INTERPRETER_INTERFACES_SCRIPTEDFRAMEINTERFACE_H

#include "ScriptedInterface.h"
#include "lldb/API/SBValueList.h"
#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/lldb-private.h"
Expand Down Expand Up @@ -49,6 +50,14 @@ class ScriptedFrameInterface : virtual public ScriptedInterface {
virtual std::optional<std::string> GetRegisterContext() {
return std::nullopt;
}

virtual lldb::ValueObjectListSP GetVariables() { return nullptr; }

virtual lldb::ValueObjectSP
GetValueObjectForVariableExpression(llvm::StringRef expr, uint32_t options,
Status &error) {
return nullptr;
}
};
} // namespace lldb_private

Expand Down
3 changes: 3 additions & 0 deletions lldb/include/lldb/Interpreter/ScriptInterpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,9 @@ class ScriptInterpreter : public PluginInterface {
lldb::StackFrameListSP
GetOpaqueTypeFromSBFrameList(const lldb::SBFrameList &exe_ctx) const;

lldb::ValueObjectSP
GetOpaqueTypeFromSBValue(const lldb::SBValue &value) const;

protected:
Debugger &m_debugger;
lldb::ScriptLanguage m_script_lang;
Expand Down
19 changes: 11 additions & 8 deletions lldb/include/lldb/Target/ExecutionContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@

#include "lldb/Host/ProcessRunLock.h"
#include "lldb/Target/StackID.h"
#include "lldb/Target/SyntheticFrameProvider.h"
#include "lldb/lldb-private.h"

namespace lldb_private {

struct StoppedExecutionContext;

//===----------------------------------------------------------------------===//
/// Execution context objects refer to objects in the execution of the program
/// that is being debugged. The consist of one or more of the following
Expand Down Expand Up @@ -270,9 +273,12 @@ class ExecutionContextRef {

void ClearFrame() {
m_stack_id.Clear();
m_frame_list_wp.reset();
m_frame_list_id.reset();
}

friend llvm::Expected<StoppedExecutionContext>
GetStoppedExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr);

protected:
// Member variables
lldb::TargetWP m_target_wp; ///< A weak reference to a target
Expand All @@ -283,13 +289,10 @@ class ExecutionContextRef {
/// backing object changes
StackID m_stack_id; ///< The stack ID that this object refers to in case the
///< backing object changes
mutable lldb::StackFrameListWP
m_frame_list_wp; ///< Weak reference to the
///< frame list that contains
///< this frame. If we can create a valid
///< StackFrameListSP from it, we must use it to resolve
///< the StackID, otherwise, we should ask the Thread's
///< StackFrameList.
/// A map of identifiers to scripted frame providers used in this thread.
mutable std::optional<
std::pair<ScriptedFrameProviderDescriptor, lldb::frame_list_id_t>>
m_frame_list_id;
};

/// \class ExecutionContext ExecutionContext.h
Expand Down
12 changes: 6 additions & 6 deletions lldb/include/lldb/Target/StackFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -542,17 +542,17 @@ class StackFrame : public ExecutionContextScope,

virtual lldb::RecognizedStackFrameSP GetRecognizedFrame();

/// Get the StackFrameList that contains this frame.
/// Get the identifier of the StackFrameList that contains this frame.
///
/// Returns the StackFrameList that contains this frame, allowing
/// Returns the StackFrameList identifier that contains this frame, allowing
/// frames to resolve execution contexts without calling
/// Thread::GetStackFrameList(), which can cause circular dependencies
/// during frame provider initialization.
///
/// \return
/// The StackFrameList that contains this frame, or nullptr if not set.
virtual lldb::StackFrameListSP GetContainingStackFrameList() const {
return m_frame_list_wp.lock();
/// The identifier of the containing StackFrameList
lldb::frame_list_id_t GetContainingStackFrameListIdentifier() const {
return m_frame_list_id;
}

protected:
Expand Down Expand Up @@ -598,8 +598,8 @@ class StackFrame : public ExecutionContextScope,
/// be the first address of its function). True for actual frame zero as
/// well as any other frame with the same trait.
bool m_behaves_like_zeroth_frame;
lldb::frame_list_id_t m_frame_list_id = 0;
lldb::VariableListSP m_variable_list_sp;
lldb::StackFrameListWP m_frame_list_wp;
/// Value objects for each variable in m_variable_list_sp.
ValueObjectList m_variable_list_value_objects;
std::optional<lldb::RecognizedStackFrameSP> m_recognized_frame_sp;
Expand Down
16 changes: 14 additions & 2 deletions lldb/include/lldb/Target/StackFrameList.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ class StackFrameList : public std::enable_shared_from_this<StackFrameList> {
public:
// Constructors and Destructors
StackFrameList(Thread &thread, const lldb::StackFrameListSP &prev_frames_sp,
bool show_inline_frames);
bool show_inline_frames,
lldb::frame_list_id_t provider_id = 0);

virtual ~StackFrameList();

Expand Down Expand Up @@ -104,6 +105,9 @@ class StackFrameList : public std::enable_shared_from_this<StackFrameList> {
/// Get the thread associated with this frame list.
Thread &GetThread() const { return m_thread; }

/// Get the unique identifier for this frame list.
lldb::frame_list_id_t GetIdentifier() const { return m_identifier; }

protected:
friend class Thread;
friend class ScriptedFrameProvider;
Expand Down Expand Up @@ -212,6 +216,9 @@ class StackFrameList : public std::enable_shared_from_this<StackFrameList> {
/// Whether or not to show synthetic (inline) frames. Immutable.
const bool m_show_inlined_frames;

/// Unique identifier for this frame list instance.
lldb::frame_list_id_t m_identifier = 0;

/// Returns true if fetching frames was interrupted, false otherwise.
virtual bool FetchFramesUpTo(uint32_t end_idx,
InterruptionControl allow_interrupt);
Expand Down Expand Up @@ -243,7 +250,9 @@ class SyntheticStackFrameList : public StackFrameList {
public:
SyntheticStackFrameList(Thread &thread, lldb::StackFrameListSP input_frames,
const lldb::StackFrameListSP &prev_frames_sp,
bool show_inline_frames);
bool show_inline_frames,
lldb::SyntheticFrameProviderSP provider_sp,
uint64_t provider_id);

protected:
/// Override FetchFramesUpTo to lazily return frames from the provider
Expand All @@ -255,6 +264,9 @@ class SyntheticStackFrameList : public StackFrameList {
/// The input stack frame list that the provider transforms.
/// This could be a real StackFrameList or another SyntheticStackFrameList.
lldb::StackFrameListSP m_input_frames;

/// The provider that transforms the input frames.
lldb::SyntheticFrameProviderSP m_provider;
};

} // namespace lldb_private
Expand Down
6 changes: 6 additions & 0 deletions lldb/include/lldb/Target/Target.h
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,12 @@ class Target : public std::enable_shared_from_this<Target>,
const llvm::DenseMap<uint32_t, ScriptedFrameProviderDescriptor> &
GetScriptedFrameProviderDescriptors() const;

protected:
/// Invalidate all potentially cached frame providers for all threads
/// and trigger a stack changed event for all threads.
void InvalidateThreadFrameProviders();

public:
// This part handles the breakpoints.

BreakpointList &GetBreakpointList(bool internal = false);
Expand Down
34 changes: 30 additions & 4 deletions lldb/include/lldb/Target/Thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@
#include "lldb/Target/ExecutionContextScope.h"
#include "lldb/Target/RegisterCheckpoint.h"
#include "lldb/Target/StackFrameList.h"
#include "lldb/Target/SyntheticFrameProvider.h"
#include "lldb/Utility/Broadcaster.h"
#include "lldb/Utility/CompletionRequest.h"
#include "lldb/Utility/Event.h"
#include "lldb/Utility/StructuredData.h"
#include "lldb/Utility/UnimplementedError.h"
#include "lldb/Utility/UserID.h"
#include "lldb/lldb-private.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/MemoryBuffer.h"

#define LLDB_THREAD_MAX_STOP_EXC_DATA 8
Expand Down Expand Up @@ -1297,13 +1299,20 @@ class Thread : public std::enable_shared_from_this<Thread>,

lldb::StackFrameListSP GetStackFrameList();

/// Get a frame list by its unique identifier.
lldb::StackFrameListSP GetFrameListByIdentifier(lldb::frame_list_id_t id);

llvm::Error
LoadScriptedFrameProvider(const ScriptedFrameProviderDescriptor &descriptor);

llvm::Expected<ScriptedFrameProviderDescriptor>
GetScriptedFrameProviderDescriptorForID(lldb::frame_list_id_t id) const;

void ClearScriptedFrameProvider();

lldb::SyntheticFrameProviderSP GetFrameProvider() const {
return m_frame_provider_sp;
const llvm::DenseMap<lldb::frame_list_id_t, lldb::SyntheticFrameProviderSP> &
GetFrameProviders() const {
return m_frame_providers;
}

protected:
Expand Down Expand Up @@ -1383,6 +1392,8 @@ class Thread : public std::enable_shared_from_this<Thread>,
m_state_mutex; ///< Multithreaded protection for m_state.
mutable std::recursive_mutex
m_frame_mutex; ///< Multithreaded protection for m_state.
lldb::StackFrameListSP
m_unwinder_frames_sp; ///< The unwinder frame list (ID 0).
lldb::StackFrameListSP m_curr_frames_sp; ///< The stack frames that get lazily
///populated after a thread stops.
lldb::StackFrameListSP m_prev_frames_sp; ///< The previous stack frames from
Expand All @@ -1409,8 +1420,23 @@ class Thread : public std::enable_shared_from_this<Thread>,
/// The Thread backed by this thread, if any.
lldb::ThreadWP m_backed_thread;

/// The Scripted Frame Provider, if any.
lldb::SyntheticFrameProviderSP m_frame_provider_sp;
/// Map from frame list ID to its frame provider.
/// Cleared in ClearStackFrames(), repopulated in GetStackFrameList().
llvm::DenseMap<lldb::frame_list_id_t, lldb::SyntheticFrameProviderSP>
m_frame_providers;

/// Ordered chain of provider IDs.
/// Persists across ClearStackFrames() to maintain stable provider IDs.
std::vector<std::pair<ScriptedFrameProviderDescriptor, lldb::frame_list_id_t>>
m_provider_chain_ids;

/// Map from frame list identifier to frame list weak pointer.
mutable llvm::DenseMap<lldb::frame_list_id_t, lldb::StackFrameListWP>
m_frame_lists_by_id;

/// Counter for assigning unique provider IDs. Starts at 1 since 0 is
/// reserved for normal unwinder frames. Persists across ClearStackFrames.
lldb::frame_list_id_t m_next_provider_id = 1;

private:
bool m_extended_info_fetched; // Have we tried to retrieve the m_extended_info
Expand Down
78 changes: 78 additions & 0 deletions lldb/include/lldb/ValueObject/ValueObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -1121,6 +1121,84 @@ class ValueObject {
const ValueObject &operator=(const ValueObject &) = delete;
};

// The two classes below are used by the public SBValue API implementation. This
// is useful here because we need them in order to access the underlying
// ValueObject from SBValue without introducing a back-dependency from the API
// library to the more core libs.

class ValueImpl {
public:
ValueImpl() = default;

ValueImpl(lldb::ValueObjectSP in_valobj_sp,
lldb::DynamicValueType use_dynamic, bool use_synthetic,
const char *name = nullptr);

ValueImpl(const ValueImpl &rhs) = default;

ValueImpl &operator=(const ValueImpl &rhs);

bool IsValid();

lldb::ValueObjectSP GetRootSP() { return m_valobj_sp; }

lldb::ValueObjectSP GetSP(Process::StopLocker &stop_locker,
std::unique_lock<std::recursive_mutex> &lock,
Status &error);

void SetUseDynamic(lldb::DynamicValueType use_dynamic) {
m_use_dynamic = use_dynamic;
}

void SetUseSynthetic(bool use_synthetic) { m_use_synthetic = use_synthetic; }

lldb::DynamicValueType GetUseDynamic() { return m_use_dynamic; }

bool GetUseSynthetic() { return m_use_synthetic; }

// All the derived values that we would make from the m_valobj_sp will share
// the ExecutionContext with m_valobj_sp, so we don't need to do the
// calculations in GetSP to return the Target, Process, Thread or Frame. It
// is convenient to provide simple accessors for these, which I do here.
lldb::TargetSP GetTargetSP() {
return m_valobj_sp ? m_valobj_sp->GetTargetSP() : lldb::TargetSP{};
}

lldb::ProcessSP GetProcessSP() {
return m_valobj_sp ? m_valobj_sp->GetProcessSP() : lldb::ProcessSP{};
}

lldb::ThreadSP GetThreadSP() {
return m_valobj_sp ? m_valobj_sp->GetThreadSP() : lldb::ThreadSP{};
}

lldb::StackFrameSP GetFrameSP() {
return m_valobj_sp ? m_valobj_sp->GetFrameSP() : lldb::StackFrameSP{};
}

private:
lldb::ValueObjectSP m_valobj_sp;
lldb::DynamicValueType m_use_dynamic;
bool m_use_synthetic;
ConstString m_name;
};

class ValueLocker {
public:
ValueLocker() = default;

lldb::ValueObjectSP GetLockedSP(ValueImpl &in_value) {
return in_value.GetSP(m_stop_locker, m_lock, m_lock_error);
}

Status &GetError() { return m_lock_error; }

private:
Process::StopLocker m_stop_locker;
std::unique_lock<std::recursive_mutex> m_lock;
Status m_lock_error;
};

} // namespace lldb_private

#endif // LLDB_VALUEOBJECT_VALUEOBJECT_H
1 change: 1 addition & 0 deletions lldb/include/lldb/lldb-defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
#define LLDB_INVALID_PROCESS_ID 0
#define LLDB_INVALID_THREAD_ID 0
#define LLDB_INVALID_FRAME_ID UINT32_MAX
#define LLDB_UNWINDER_FRAME_LIST_ID 0
#define LLDB_INVALID_SIGNAL_NUMBER INT32_MAX
#define LLDB_INVALID_SYMBOL_ID UINT32_MAX
#define LLDB_INVALID_OFFSET UINT64_MAX // Must match max of lldb::offset_t
Expand Down
Loading
Loading