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
136 changes: 136 additions & 0 deletions lldb/examples/python/templates/scripted_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,142 @@ def get_extended_info(self):
"""
return self.extended_info

def get_scripted_frame_plugin(self):
"""Get scripted frame plugin name.

Returns:
str: Name of the scripted frame plugin.
"""
return None


class ScriptedFrame(metaclass=ABCMeta):
"""
The base class for a scripted frame.

Most of the base class methods are `@abstractmethod` that need to be
overwritten by the inheriting class.
"""

@abstractmethod
def __init__(self, thread, args):
"""Construct a scripted frame.

Args:
thread (ScriptedThread): The thread owning this frame.
args (lldb.SBStructuredData): A Dictionary holding arbitrary
key/value pairs used by the scripted frame.
"""
self.target = None
self.originating_thread = None
self.thread = None
self.args = None
self.id = None
self.name = None
self.register_info = None
self.register_ctx = {}
self.variables = []

if (
isinstance(thread, ScriptedThread)
or isinstance(thread, lldb.SBThread)
and thread.IsValid()
):
self.target = thread.target
self.process = thread.process
self.originating_thread = thread
self.thread = self.process.GetThreadByIndexID(thread.tid)
self.get_register_info()

@abstractmethod
def get_id(self):
"""Get the scripted frame identifier.

Returns:
int: The identifier of the scripted frame in the scripted thread.
"""
pass

def get_pc(self):
"""Get the scripted frame address.

Returns:
int: The optional address of the scripted frame in the scripted thread.
"""
return None

def get_symbol_context(self):
"""Get the scripted frame symbol context.

Returns:
lldb.SBSymbolContext: The symbol context of the scripted frame in the scripted thread.
"""
return None

def is_inlined(self):
"""Check if the scripted frame is inlined.

Returns:
bool: True if scripted frame is inlined. False otherwise.
"""
return False

def is_artificial(self):
"""Check if the scripted frame is artificial.

Returns:
bool: True if scripted frame is artificial. False otherwise.
"""
return True

def is_hidden(self):
"""Check if the scripted frame is hidden.

Returns:
bool: True if scripted frame is hidden. False otherwise.
"""
return False

def get_function_name(self):
"""Get the scripted frame function name.

Returns:
str: The function name of the scripted frame.
"""
return self.name

def get_display_function_name(self):
"""Get the scripted frame display function name.

Returns:
str: The display function name of the scripted frame.
"""
return self.get_function_name()

def get_variables(self, filters):
"""Get the scripted thread state type.

Args:
filter (lldb.SBVariablesOptions): The filter used to resolve the variables
Returns:
lldb.SBValueList: The SBValueList containing the SBValue for each resolved variable.
Returns None by default.
"""
return None

def get_register_info(self):
if self.register_info is None:
self.register_info = self.originating_thread.get_register_info()
return self.register_info

@abstractmethod
def get_register_context(self):
"""Get the scripted thread register context

Returns:
str: A byte representing all register's value.
"""
pass

class PassthroughScriptedProcess(ScriptedProcess):
driving_target = None
Expand Down
1 change: 1 addition & 0 deletions lldb/include/lldb/API/SBSymbolContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class LLDB_API SBSymbolContext {
friend class SBTarget;
friend class SBSymbolContextList;

friend class lldb_private::ScriptInterpreter;
friend class lldb_private::python::SWIGBridge;

SBSymbolContext(const lldb_private::SymbolContext &sc_ptr);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_INTERPRETER_INTERFACES_SCRIPTEDFRAMEINTERFACE_H
#define LLDB_INTERPRETER_INTERFACES_SCRIPTEDFRAMEINTERFACE_H

#include "ScriptedInterface.h"
#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/lldb-private.h"
#include <optional>
#include <string>

namespace lldb_private {
class ScriptedFrameInterface : virtual public ScriptedInterface {
public:
virtual llvm::Expected<StructuredData::GenericSP>
CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx,
StructuredData::DictionarySP args_sp,
StructuredData::Generic *script_obj = nullptr) = 0;

virtual lldb::user_id_t GetID() { return LLDB_INVALID_FRAME_ID; }

virtual lldb::addr_t GetPC() { return LLDB_INVALID_ADDRESS; }

virtual std::optional<SymbolContext> GetSymbolContext() {
return std::nullopt;
}

virtual std::optional<std::string> GetFunctionName() { return std::nullopt; }

virtual std::optional<std::string> GetDisplayFunctionName() {
return std::nullopt;
}

virtual bool IsInlined() { return false; }

virtual bool IsArtificial() { return false; }

virtual bool IsHidden() { return false; }

virtual StructuredData::DictionarySP GetRegisterInfo() { return {}; }

virtual std::optional<std::string> GetRegisterContext() {
return std::nullopt;
}
};
} // namespace lldb_private

#endif // LLDB_INTERPRETER_INTERFACES_SCRIPTEDFRAMEINTERFACE_H
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@ class ScriptedThreadInterface : virtual public ScriptedInterface {
}

virtual StructuredData::ArraySP GetExtendedInfo() { return {}; }

virtual std::optional<std::string> GetScriptedFramePluginName() {
return std::nullopt;
}

protected:
friend class ScriptedFrame;
virtual lldb::ScriptedFrameInterfaceSP CreateScriptedFrameInterface() {
return {};
}
};
} // namespace lldb_private

Expand Down
5 changes: 5 additions & 0 deletions lldb/include/lldb/Interpreter/ScriptInterpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "lldb/Host/PseudoTerminal.h"
#include "lldb/Host/StreamFile.h"
#include "lldb/Interpreter/Interfaces/OperatingSystemInterface.h"
#include "lldb/Interpreter/Interfaces/ScriptedFrameInterface.h"
#include "lldb/Interpreter/Interfaces/ScriptedPlatformInterface.h"
#include "lldb/Interpreter/Interfaces/ScriptedProcessInterface.h"
#include "lldb/Interpreter/Interfaces/ScriptedThreadInterface.h"
Expand Down Expand Up @@ -531,6 +532,10 @@ class ScriptInterpreter : public PluginInterface {
return {};
}

virtual lldb::ScriptedFrameInterfaceSP CreateScriptedFrameInterface() {
return {};
}

virtual lldb::ScriptedThreadPlanInterfaceSP
CreateScriptedThreadPlanInterface() {
return {};
Expand Down
34 changes: 17 additions & 17 deletions lldb/include/lldb/Target/StackFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ class StackFrame : public ExecutionContextScope,
///
/// \return
/// true if this is an inlined frame.
bool IsInlined();
virtual bool IsInlined();

/// Query whether this frame is synthetic.
bool IsSynthetic() const;
Expand All @@ -409,12 +409,12 @@ class StackFrame : public ExecutionContextScope,
/// Query whether this frame is artificial (e.g a synthesized result of
/// inferring missing tail call frames from a backtrace). Artificial frames
/// may have limited support for inspecting variables.
bool IsArtificial() const;
virtual bool IsArtificial() const;

/// Query whether this frame should be hidden from backtraces. Frame
/// recognizers can customize this behavior and hide distracting
/// system implementation details this way.
bool IsHidden();
virtual bool IsHidden();

/// Language plugins can use this API to report language-specific
/// runtime information about this compile unit, such as additional
Expand All @@ -425,13 +425,13 @@ class StackFrame : public ExecutionContextScope,
///
/// /// \return
/// A C-String containing the function demangled name. Can be null.
const char *GetFunctionName();
virtual const char *GetFunctionName();

/// Get the frame's demangled display name.
///
/// /// \return
/// A C-String containing the function demangled display name. Can be null.
const char *GetDisplayFunctionName();
virtual const char *GetDisplayFunctionName();

/// Query this frame to find what frame it is in this Thread's
/// StackFrameList.
Expand Down Expand Up @@ -543,18 +543,7 @@ class StackFrame : public ExecutionContextScope,

bool HasCachedData() const;

private:
/// Private methods, called from GetValueForVariableExpressionPath.
/// See that method for documentation of parameters and return value.
lldb::ValueObjectSP LegacyGetValueForVariableExpressionPath(
llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic,
uint32_t options, lldb::VariableSP &var_sp, Status &error);

lldb::ValueObjectSP DILGetValueForVariableExpressionPath(
llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic,
uint32_t options, lldb::VariableSP &var_sp, Status &error);

/// For StackFrame only.
/// For StackFrame and derived classes only.
/// \{
lldb::ThreadWP m_thread_wp;
uint32_t m_frame_index;
Expand Down Expand Up @@ -591,6 +580,17 @@ class StackFrame : public ExecutionContextScope,
StreamString m_disassembly;
std::recursive_mutex m_mutex;

private:
/// Private methods, called from GetValueForVariableExpressionPath.
/// See that method for documentation of parameters and return value.
lldb::ValueObjectSP LegacyGetValueForVariableExpressionPath(
llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic,
uint32_t options, lldb::VariableSP &var_sp, Status &error);

lldb::ValueObjectSP DILGetValueForVariableExpressionPath(
llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic,
uint32_t options, lldb::VariableSP &var_sp, Status &error);

StackFrame(const StackFrame &) = delete;
const StackFrame &operator=(const StackFrame &) = delete;
};
Expand Down
3 changes: 3 additions & 0 deletions lldb/include/lldb/lldb-forward.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ class SaveCoreOptions;
class Scalar;
class ScriptInterpreter;
class ScriptInterpreterLocker;
class ScriptedFrameInterface;
class ScriptedMetadata;
class ScriptedBreakpointInterface;
class ScriptedPlatformInterface;
Expand Down Expand Up @@ -408,6 +409,8 @@ typedef std::shared_ptr<lldb_private::RecognizedStackFrame>
typedef std::shared_ptr<lldb_private::ScriptSummaryFormat>
ScriptSummaryFormatSP;
typedef std::shared_ptr<lldb_private::ScriptInterpreter> ScriptInterpreterSP;
typedef std::shared_ptr<lldb_private::ScriptedFrameInterface>
ScriptedFrameInterfaceSP;
typedef std::shared_ptr<lldb_private::ScriptedMetadata> ScriptedMetadataSP;
typedef std::unique_ptr<lldb_private::ScriptedPlatformInterface>
ScriptedPlatformInterfaceUP;
Expand Down
2 changes: 1 addition & 1 deletion lldb/source/Core/FormatEntity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1681,7 +1681,7 @@ bool FormatEntity::Format(const Entry &entry, Stream &s,
StackFrame *frame = exe_ctx->GetFramePtr();
if (frame) {
const Address &pc_addr = frame->GetFrameCodeAddress();
if (pc_addr.IsValid()) {
if (pc_addr.IsValid() || frame->IsSynthetic()) {
if (DumpAddressAndContent(s, sc, exe_ctx, pc_addr, false))
return true;
}
Expand Down
1 change: 1 addition & 0 deletions lldb/source/Plugins/Process/scripted/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
add_lldb_library(lldbPluginScriptedProcess PLUGIN
ScriptedProcess.cpp
ScriptedThread.cpp
ScriptedFrame.cpp

LINK_COMPONENTS
BinaryFormat
Expand Down
Loading
Loading