mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-07 00:23:43 +00:00
[lldb] Revert ScriptedProcess patches
This patch reverts the following commits: -5a9c34918b
-46796762af
-2cff3dec11
-182f0d1a34
-d62a53aaf1
Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>
This commit is contained in:
parent
a9e68db973
commit
36254f1a0f
@ -135,16 +135,6 @@ public:
|
||||
|
||||
void
|
||||
SetDetachOnError(bool enable);
|
||||
|
||||
const char *
|
||||
GetScriptedProcessClassName() const;
|
||||
|
||||
void SetScriptedProcessClassName(const char *class_name);
|
||||
|
||||
lldb::SBStructuredData
|
||||
GetScriptedProcessDictionary() const;
|
||||
|
||||
void SetScriptedProcessDictionary(lldb::SBStructuredData dict);
|
||||
};
|
||||
|
||||
} // namespace lldb
|
||||
|
@ -104,20 +104,6 @@ function(finish_swig_python swig_target lldb_python_bindings_dir lldb_python_tar
|
||||
FILES "${LLDB_SOURCE_DIR}/examples/python/in_call_stack.py"
|
||||
"${LLDB_SOURCE_DIR}/examples/python/symbolication.py")
|
||||
|
||||
create_python_package(
|
||||
${swig_target}
|
||||
${lldb_python_target_dir}
|
||||
"plugins"
|
||||
FILES
|
||||
"${LLDB_SOURCE_DIR}/examples/python/scripted_process/scripted_process.py")
|
||||
|
||||
create_python_package(
|
||||
${swig_target}
|
||||
${lldb_python_target_dir}
|
||||
"plugins"
|
||||
FILES
|
||||
"${LLDB_SOURCE_DIR}/examples/python/scripted_process/scripted_process.py")
|
||||
|
||||
if(APPLE)
|
||||
create_python_package(
|
||||
${swig_target}
|
||||
|
@ -258,72 +258,6 @@ LLDBSwigPythonCreateCommandObject
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
SWIGEXPORT void*
|
||||
LLDBSwigPythonCreateScriptedProcess
|
||||
(
|
||||
const char *python_class_name,
|
||||
const char *session_dictionary_name,
|
||||
const lldb::TargetSP& target_sp,
|
||||
lldb_private::StructuredDataImpl *args_impl,
|
||||
std::string &error_string
|
||||
)
|
||||
{
|
||||
if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
|
||||
Py_RETURN_NONE;
|
||||
|
||||
|
||||
PyErr_Cleaner py_err_cleaner(true);
|
||||
|
||||
auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
|
||||
auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict);
|
||||
|
||||
if (!pfunc.IsAllocated()) {
|
||||
error_string.append("could not find script class: ");
|
||||
error_string.append(python_class_name);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// I do not want the SBTarget to be deallocated when going out of scope
|
||||
// because python has ownership of it and will manage memory for this
|
||||
// object by itself
|
||||
PythonObject target_arg(PyRefType::Owned, SBTypeToSWIGWrapper(new lldb::SBTarget(target_sp)));
|
||||
|
||||
if (!target_arg.IsAllocated())
|
||||
Py_RETURN_NONE;
|
||||
|
||||
llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
|
||||
if (!arg_info) {
|
||||
llvm::handleAllErrors(
|
||||
arg_info.takeError(),
|
||||
[&](PythonException &E) {
|
||||
error_string.append(E.ReadBacktrace());
|
||||
},
|
||||
[&](const llvm::ErrorInfoBase &E) {
|
||||
error_string.append(E.message());
|
||||
});
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PythonObject result = {};
|
||||
if (arg_info.get().max_positional_args == 2) {
|
||||
if (args_impl != nullptr) {
|
||||
error_string.assign("args passed, but __init__ does not take an args dictionary");
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
result = pfunc(target_arg, dict);
|
||||
} else if (arg_info.get().max_positional_args >= 3) {
|
||||
PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(new lldb::SBStructuredData(args_impl)));
|
||||
result = pfunc(target_arg, args_arg, dict);
|
||||
} else {
|
||||
error_string.assign("wrong number of arguments in __init__, should be 2 or 3 (not including self)");
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
if (result.IsAllocated())
|
||||
return result.release();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
SWIGEXPORT void*
|
||||
LLDBSwigPythonCreateScriptedThreadPlan
|
||||
(
|
||||
@ -851,40 +785,6 @@ LLDBSwigPython_GetValueSynthProviderInstance
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
SWIGEXPORT void*
|
||||
LLDBSWIGPython_CastPyObjectToSBData
|
||||
(
|
||||
PyObject* data
|
||||
)
|
||||
{
|
||||
lldb::SBData* sb_ptr = nullptr;
|
||||
|
||||
int valid_cast = SWIG_ConvertPtr(data, (void**)&sb_ptr, SWIGTYPE_p_lldb__SBData, 0);
|
||||
|
||||
if (valid_cast == -1)
|
||||
return NULL;
|
||||
|
||||
return sb_ptr;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT void*
|
||||
LLDBSWIGPython_CastPyObjectToSBError
|
||||
(
|
||||
PyObject* data
|
||||
)
|
||||
{
|
||||
lldb::SBError* sb_ptr = nullptr;
|
||||
|
||||
int valid_cast = SWIG_ConvertPtr(data, (void**)&sb_ptr, SWIGTYPE_p_lldb__SBError, 0);
|
||||
|
||||
if (valid_cast == -1)
|
||||
return NULL;
|
||||
|
||||
return sb_ptr;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT void*
|
||||
LLDBSWIGPython_CastPyObjectToSBValue
|
||||
(
|
||||
|
@ -1,42 +0,0 @@
|
||||
import os
|
||||
|
||||
import lldb
|
||||
from lldb.plugins.scripted_process import ScriptedProcess
|
||||
|
||||
class MyScriptedProcess(ScriptedProcess):
|
||||
def __init__(self, target: lldb.SBTarget, args : lldb.SBStructuredData):
|
||||
super().__init__(target, args)
|
||||
|
||||
def get_memory_region_containing_address(self, addr: int) -> lldb.SBMemoryRegionInfo:
|
||||
return self.memory_regions[0]
|
||||
|
||||
def get_thread_with_id(self, tid: int):
|
||||
return {}
|
||||
|
||||
def get_registers_for_thread(self, tid: int):
|
||||
return {}
|
||||
|
||||
def read_memory_at_address(self, addr: int, size: int) -> lldb.SBData:
|
||||
data = lldb.SBData().CreateDataFromCString(
|
||||
self.target.GetByteOrder(),
|
||||
self.target.GetCodeByteSize(),
|
||||
"Hello, world!")
|
||||
return data
|
||||
|
||||
def get_loaded_images(self):
|
||||
return self.loaded_images
|
||||
|
||||
def get_process_id(self) -> int:
|
||||
return 42
|
||||
|
||||
def is_alive(self) -> bool:
|
||||
return True
|
||||
|
||||
def __lldb_init_module(debugger, dict):
|
||||
if not 'SKIP_SCRIPTED_PROCESS_LAUNCH' in os.environ:
|
||||
debugger.HandleCommand(
|
||||
"process launch -C %s.%s" % (__name__,
|
||||
MyScriptedProcess.__name__))
|
||||
else:
|
||||
print("Name of the class that will manage the scripted process: '%s.%s'"
|
||||
% (__name__, MyScriptedProcess.__name__))
|
@ -1,147 +0,0 @@
|
||||
from abc import ABCMeta, abstractmethod
|
||||
import six
|
||||
|
||||
import lldb
|
||||
|
||||
@six.add_metaclass(ABCMeta)
|
||||
class ScriptedProcess:
|
||||
|
||||
"""
|
||||
The base class for a scripted process.
|
||||
|
||||
Most of the base class methods are `@abstractmethod` that need to be
|
||||
overwritten by the inheriting class.
|
||||
|
||||
DISCLAIMER: THIS INTERFACE IS STILL UNDER DEVELOPMENT AND NOT STABLE.
|
||||
THE METHODS EXPOSED MIGHT CHANGE IN THE FUTURE.
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def __init__(self, target, args):
|
||||
""" Construct a scripted process.
|
||||
|
||||
Args:
|
||||
target (lldb.SBTarget): The target launching the scripted process.
|
||||
args (lldb.SBStructuredData): A Dictionary holding arbitrary
|
||||
key/value pairs used by the scripted process.
|
||||
"""
|
||||
self.target = None
|
||||
self.args = None
|
||||
if isinstance(target, lldb.SBTarget) and target.IsValid():
|
||||
self.target = target
|
||||
if isinstance(args, lldb.SBStructuredData) and args.IsValid():
|
||||
self.args = args
|
||||
|
||||
@abstractmethod
|
||||
def get_memory_region_containing_address(addr):
|
||||
""" Get the memory region for the scripted process, containing a
|
||||
specific address.
|
||||
|
||||
Args:
|
||||
addr (int): Address to look for in the scripted process memory
|
||||
regions.
|
||||
|
||||
Returns:
|
||||
lldb.SBMemoryRegionInfo: The memory region containing the address.
|
||||
None if out of bounds.
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_thread_with_id(tid):
|
||||
""" Get the scripted process thread with a specific ID.
|
||||
|
||||
Args:
|
||||
tid (int): Thread ID to look for in the scripted process.
|
||||
|
||||
Returns:
|
||||
Dict: The thread represented as a dictionary, withr the
|
||||
tid thread ID. None if tid doesn't match any of the scripted
|
||||
process threads.
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_registers_for_thread(tid):
|
||||
""" Get the register context dictionary for a certain thread of
|
||||
the scripted process.
|
||||
|
||||
Args:
|
||||
tid (int): Thread ID for the thread's register context.
|
||||
|
||||
Returns:
|
||||
Dict: The register context represented as a dictionary, for the
|
||||
tid thread. None if tid doesn't match any of the scripted
|
||||
process threads.
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def read_memory_at_address(addr, size):
|
||||
""" Get a memory buffer from the scripted process at a certain address,
|
||||
of a certain size.
|
||||
|
||||
Args:
|
||||
addr (int): Address from which we should start reading.
|
||||
size (int): Size of the memory to read.
|
||||
|
||||
Returns:
|
||||
lldb.SBData: An `lldb.SBData` buffer with the target byte size and
|
||||
byte order storing the memory read.
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_loaded_images(self):
|
||||
""" Get the list of loaded images for the scripted process.
|
||||
|
||||
```
|
||||
class ScriptedProcessImage:
|
||||
def __init__(name, file_spec, uuid, load_address):
|
||||
self.name = name
|
||||
self.file_spec = file_spec
|
||||
self.uuid = uuid
|
||||
self.load_address = load_address
|
||||
```
|
||||
|
||||
Returns:
|
||||
List[ScriptedProcessImage]: A list of `ScriptedProcessImage`
|
||||
containing for each entry, the name of the library, a UUID,
|
||||
an `lldb.SBFileSpec` and a load address.
|
||||
None if the list is empty.
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_process_id(self):
|
||||
""" Get the scripted process identifier.
|
||||
|
||||
Returns:
|
||||
int: The scripted process identifier.
|
||||
"""
|
||||
return 0
|
||||
|
||||
|
||||
def launch(self):
|
||||
""" Simulate the scripted process launch.
|
||||
|
||||
Returns:
|
||||
lldb.SBError: An `lldb.SBError` with error code 0.
|
||||
"""
|
||||
return lldb.SBError()
|
||||
|
||||
def resume(self):
|
||||
""" Simulate the scripted process resume.
|
||||
|
||||
Returns:
|
||||
lldb.SBError: An `lldb.SBError` with error code 0.
|
||||
"""
|
||||
return lldb.SBError()
|
||||
|
||||
@abstractmethod
|
||||
def is_alive(self):
|
||||
""" Check if the scripted process is alive.
|
||||
|
||||
Returns:
|
||||
bool: True if scripted process is alive. False otherwise.
|
||||
"""
|
||||
pass
|
@ -11,10 +11,6 @@
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
|
||||
namespace lldb_private {
|
||||
class ScriptInterpreter;
|
||||
} // namespace lldb_private
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class LLDB_API SBData {
|
||||
@ -151,8 +147,6 @@ private:
|
||||
friend class SBTarget;
|
||||
friend class SBValue;
|
||||
|
||||
friend class lldb_private::ScriptInterpreter;
|
||||
|
||||
lldb::DataExtractorSP m_opaque_sp;
|
||||
};
|
||||
|
||||
|
@ -11,10 +11,6 @@
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
|
||||
namespace lldb_private {
|
||||
class ScriptInterpreter;
|
||||
} // namespace lldb_private
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class LLDB_API SBError {
|
||||
@ -76,8 +72,6 @@ protected:
|
||||
friend class SBWatchpoint;
|
||||
friend class SBFile;
|
||||
|
||||
friend class lldb_private::ScriptInterpreter;
|
||||
|
||||
lldb_private::Status *get();
|
||||
|
||||
lldb_private::Status *operator->();
|
||||
|
@ -171,14 +171,6 @@ public:
|
||||
|
||||
void SetDetachOnError(bool enable);
|
||||
|
||||
const char *GetScriptedProcessClassName() const;
|
||||
|
||||
void SetScriptedProcessClassName(const char *class_name);
|
||||
|
||||
lldb::SBStructuredData GetScriptedProcessDictionary() const;
|
||||
|
||||
void SetScriptedProcessDictionary(lldb::SBStructuredData dict);
|
||||
|
||||
protected:
|
||||
friend class SBPlatform;
|
||||
friend class SBTarget;
|
||||
|
@ -72,7 +72,6 @@ protected:
|
||||
friend class SBFunction;
|
||||
friend class SBInstruction;
|
||||
friend class SBInstructionList;
|
||||
friend class SBLaunchInfo;
|
||||
friend class SBLineEntry;
|
||||
friend class SBMemoryRegionInfo;
|
||||
friend class SBModule;
|
||||
|
@ -88,7 +88,6 @@ public:
|
||||
size_t GetStringValue(char *dst, size_t dst_len) const;
|
||||
|
||||
protected:
|
||||
friend class SBLaunchInfo;
|
||||
friend class SBTraceOptions;
|
||||
friend class SBDebugger;
|
||||
friend class SBTarget;
|
||||
|
@ -17,6 +17,8 @@ namespace lldb {
|
||||
|
||||
class LLDB_API SBThreadPlan {
|
||||
|
||||
friend class lldb_private::ThreadPlan;
|
||||
|
||||
public:
|
||||
SBThreadPlan();
|
||||
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include "lldb/Host/PseudoTerminal.h"
|
||||
#include "lldb/Utility/FileSpec.h"
|
||||
#include "lldb/Utility/ProcessInfo.h"
|
||||
#include "lldb/Utility/StructuredData.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
@ -147,28 +146,6 @@ public:
|
||||
return m_flags.Test(lldb::eLaunchFlagDetachOnError);
|
||||
}
|
||||
|
||||
bool IsScriptedProcess() const {
|
||||
return !m_scripted_process_class_name.empty();
|
||||
}
|
||||
|
||||
std::string GetScriptedProcessClassName() const {
|
||||
return m_scripted_process_class_name;
|
||||
}
|
||||
|
||||
void SetScriptedProcessClassName(std::string name) {
|
||||
m_scripted_process_class_name = name;
|
||||
}
|
||||
|
||||
lldb_private::StructuredData::DictionarySP
|
||||
GetScriptedProcessDictionarySP() const {
|
||||
return m_scripted_process_dictionary_sp;
|
||||
}
|
||||
|
||||
void SetScriptedProcessDictionarySP(
|
||||
lldb_private::StructuredData::DictionarySP dictionary_sp) {
|
||||
m_scripted_process_dictionary_sp = dictionary_sp;
|
||||
}
|
||||
|
||||
protected:
|
||||
FileSpec m_working_dir;
|
||||
std::string m_plugin_name;
|
||||
@ -184,11 +161,6 @@ protected:
|
||||
// meaning to the upper levels of lldb.
|
||||
lldb::ListenerSP m_listener_sp;
|
||||
lldb::ListenerSP m_hijack_listener_sp;
|
||||
std::string m_scripted_process_class_name; // The name of the class that will
|
||||
// manage a scripted process.
|
||||
StructuredData::DictionarySP
|
||||
m_scripted_process_dictionary_sp; // A dictionary that holds key/value
|
||||
// pairs passed to the scripted process.
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -9,15 +9,12 @@
|
||||
#ifndef LLDB_INTERPRETER_SCRIPTINTERPRETER_H
|
||||
#define LLDB_INTERPRETER_SCRIPTINTERPRETER_H
|
||||
|
||||
#include "lldb/API/SBData.h"
|
||||
#include "lldb/API/SBError.h"
|
||||
#include "lldb/Breakpoint/BreakpointOptions.h"
|
||||
#include "lldb/Core/Communication.h"
|
||||
#include "lldb/Core/PluginInterface.h"
|
||||
#include "lldb/Core/SearchFilter.h"
|
||||
#include "lldb/Core/StreamFile.h"
|
||||
#include "lldb/Host/PseudoTerminal.h"
|
||||
#include "lldb/Interpreter/ScriptedProcessInterface.h"
|
||||
#include "lldb/Utility/Broadcaster.h"
|
||||
#include "lldb/Utility/Status.h"
|
||||
#include "lldb/Utility/StructuredData.h"
|
||||
@ -86,9 +83,7 @@ public:
|
||||
eScriptReturnTypeOpaqueObject
|
||||
};
|
||||
|
||||
ScriptInterpreter(
|
||||
Debugger &debugger, lldb::ScriptLanguage script_lang,
|
||||
lldb::ScriptedProcessInterfaceUP scripted_process_interface_up = {});
|
||||
ScriptInterpreter(Debugger &debugger, lldb::ScriptLanguage script_lang);
|
||||
|
||||
~ScriptInterpreter() override = default;
|
||||
|
||||
@ -533,19 +528,9 @@ public:
|
||||
|
||||
lldb::ScriptLanguage GetLanguage() { return m_script_lang; }
|
||||
|
||||
ScriptedProcessInterface &GetScriptedProcessInterface() {
|
||||
return *m_scripted_process_interface_up;
|
||||
}
|
||||
|
||||
lldb::DataExtractorSP
|
||||
GetDataExtractorFromSBData(const lldb::SBData &data) const;
|
||||
|
||||
Status GetStatusFromSBError(const lldb::SBError &error) const;
|
||||
|
||||
protected:
|
||||
Debugger &m_debugger;
|
||||
lldb::ScriptLanguage m_script_lang;
|
||||
lldb::ScriptedProcessInterfaceUP m_scripted_process_interface_up;
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
@ -1,64 +0,0 @@
|
||||
//===-- ScriptedProcessInterface.h ------------------------------*- C++ -*-===//
|
||||
//
|
||||
// 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_SCRIPTEDPROCESSINTERFACE_H
|
||||
#define LLDB_INTERPRETER_SCRIPTEDPROCESSINTERFACE_H
|
||||
|
||||
#include "lldb/Core/StructuredDataImpl.h"
|
||||
#include "lldb/Interpreter/ScriptInterpreter.h"
|
||||
#include "lldb/lldb-private.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace lldb_private {
|
||||
class ScriptedProcessInterface {
|
||||
public:
|
||||
ScriptedProcessInterface() : m_object_instance_sp(nullptr) {}
|
||||
|
||||
virtual ~ScriptedProcessInterface() = default;
|
||||
|
||||
virtual StructuredData::GenericSP
|
||||
CreatePluginObject(const llvm::StringRef class_name, lldb::TargetSP target_sp,
|
||||
StructuredData::DictionarySP args_sp) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual Status Launch() { return Status("ScriptedProcess did not launch"); }
|
||||
|
||||
virtual Status Resume() { return Status("ScriptedProcess did not resume"); }
|
||||
|
||||
virtual lldb::MemoryRegionInfoSP
|
||||
GetMemoryRegionContainingAddress(lldb::addr_t address) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual StructuredData::DictionarySP GetThreadWithID(lldb::tid_t tid) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual StructuredData::DictionarySP GetRegistersForThread(lldb::tid_t tid) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual lldb::DataExtractorSP
|
||||
ReadMemoryAtAddress(lldb::addr_t address, size_t size, Status &error) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual StructuredData::DictionarySP GetLoadedImages() { return nullptr; }
|
||||
|
||||
virtual lldb::pid_t GetProcessID() { return LLDB_INVALID_PROCESS_ID; }
|
||||
|
||||
virtual bool IsAlive() { return true; }
|
||||
|
||||
private:
|
||||
StructuredData::ObjectSP m_object_instance_sp;
|
||||
};
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // LLDB_INTERPRETER_SCRIPTEDPROCESSINTERFACE_H
|
@ -2561,6 +2561,8 @@ protected:
|
||||
virtual size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
|
||||
Status &error) = 0;
|
||||
|
||||
void SetState(lldb::EventSP &event_sp);
|
||||
|
||||
lldb::StateType GetPrivateState();
|
||||
|
||||
/// The "private" side of resuming a process. This doesn't alter the state
|
||||
|
@ -174,7 +174,6 @@ class RichManglingContext;
|
||||
class Scalar;
|
||||
class ScriptInterpreter;
|
||||
class ScriptInterpreterLocker;
|
||||
class ScriptedProcessInterface;
|
||||
class ScriptedSyntheticChildren;
|
||||
class SearchFilter;
|
||||
class Section;
|
||||
@ -342,7 +341,6 @@ typedef std::shared_ptr<lldb_private::Listener> ListenerSP;
|
||||
typedef std::weak_ptr<lldb_private::Listener> ListenerWP;
|
||||
typedef std::shared_ptr<lldb_private::MemoryHistory> MemoryHistorySP;
|
||||
typedef std::unique_ptr<lldb_private::MemoryRegionInfo> MemoryRegionInfoUP;
|
||||
typedef std::shared_ptr<lldb_private::MemoryRegionInfo> MemoryRegionInfoSP;
|
||||
typedef std::shared_ptr<lldb_private::Module> ModuleSP;
|
||||
typedef std::weak_ptr<lldb_private::Module> ModuleWP;
|
||||
typedef std::shared_ptr<lldb_private::ObjectFile> ObjectFileSP;
|
||||
@ -393,8 +391,6 @@ typedef std::shared_ptr<lldb_private::ScriptSummaryFormat>
|
||||
ScriptSummaryFormatSP;
|
||||
typedef std::shared_ptr<lldb_private::ScriptInterpreter> ScriptInterpreterSP;
|
||||
typedef std::unique_ptr<lldb_private::ScriptInterpreter> ScriptInterpreterUP;
|
||||
typedef std::unique_ptr<lldb_private::ScriptedProcessInterface>
|
||||
ScriptedProcessInterfaceUP;
|
||||
typedef std::shared_ptr<lldb_private::Section> SectionSP;
|
||||
typedef std::unique_ptr<lldb_private::SectionList> SectionListUP;
|
||||
typedef std::weak_ptr<lldb_private::Section> SectionWP;
|
||||
|
@ -10,12 +10,8 @@
|
||||
#include "SBReproducerPrivate.h"
|
||||
|
||||
#include "lldb/API/SBEnvironment.h"
|
||||
#include "lldb/API/SBError.h"
|
||||
#include "lldb/API/SBFileSpec.h"
|
||||
#include "lldb/API/SBListener.h"
|
||||
#include "lldb/API/SBStream.h"
|
||||
#include "lldb/API/SBStructuredData.h"
|
||||
#include "lldb/Core/StructuredDataImpl.h"
|
||||
#include "lldb/Host/ProcessLaunchInfo.h"
|
||||
|
||||
using namespace lldb;
|
||||
@ -347,53 +343,6 @@ bool SBLaunchInfo::GetDetachOnError() const {
|
||||
return m_opaque_sp->GetDetachOnError();
|
||||
}
|
||||
|
||||
const char *SBLaunchInfo::GetScriptedProcessClassName() const {
|
||||
LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBLaunchInfo,
|
||||
GetScriptedProcessClassName);
|
||||
|
||||
// Constify this string so that it is saved in the string pool. Otherwise it
|
||||
// would be freed when this function goes out of scope.
|
||||
ConstString class_name(m_opaque_sp->GetScriptedProcessClassName().c_str());
|
||||
return class_name.AsCString();
|
||||
}
|
||||
|
||||
void SBLaunchInfo::SetScriptedProcessClassName(const char *class_name) {
|
||||
LLDB_RECORD_METHOD(void, SBLaunchInfo, SetScriptedProcessClassName,
|
||||
(const char *), class_name);
|
||||
|
||||
m_opaque_sp->SetScriptedProcessClassName(class_name);
|
||||
}
|
||||
|
||||
lldb::SBStructuredData SBLaunchInfo::GetScriptedProcessDictionary() const {
|
||||
LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBStructuredData, SBLaunchInfo,
|
||||
GetScriptedProcessDictionary);
|
||||
|
||||
lldb_private::StructuredData::DictionarySP dict_sp =
|
||||
m_opaque_sp->GetScriptedProcessDictionarySP();
|
||||
|
||||
SBStructuredData data;
|
||||
data.m_impl_up->SetObjectSP(dict_sp);
|
||||
|
||||
return LLDB_RECORD_RESULT(data);
|
||||
}
|
||||
|
||||
void SBLaunchInfo::SetScriptedProcessDictionary(lldb::SBStructuredData dict) {
|
||||
LLDB_RECORD_METHOD(void, SBLaunchInfo, SetScriptedProcessDictionary,
|
||||
(lldb::SBStructuredData), dict);
|
||||
|
||||
SBStream stream;
|
||||
SBError error = dict.GetAsJSON(stream);
|
||||
|
||||
if (error.Fail())
|
||||
return;
|
||||
|
||||
StructuredData::DictionarySP dict_sp;
|
||||
llvm::json::OStream s(stream.ref().AsRawOstream());
|
||||
dict_sp->Serialize(s);
|
||||
|
||||
m_opaque_sp->SetScriptedProcessDictionarySP(dict_sp);
|
||||
}
|
||||
|
||||
namespace lldb_private {
|
||||
namespace repro {
|
||||
|
||||
@ -454,14 +403,6 @@ void RegisterMethods<SBLaunchInfo>(Registry &R) {
|
||||
());
|
||||
LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetDetachOnError, (bool));
|
||||
LLDB_REGISTER_METHOD_CONST(bool, SBLaunchInfo, GetDetachOnError, ());
|
||||
LLDB_REGISTER_METHOD_CONST(const char *, SBLaunchInfo,
|
||||
GetScriptedProcessClassName, ());
|
||||
LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetScriptedProcessClassName,
|
||||
(const char *));
|
||||
LLDB_REGISTER_METHOD_CONST(lldb::SBStructuredData, SBLaunchInfo,
|
||||
GetScriptedProcessDictionary, ());
|
||||
LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetScriptedProcessDictionary,
|
||||
(lldb::SBStructuredData));
|
||||
LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetEnvironment,
|
||||
(const lldb::SBEnvironment &, bool));
|
||||
LLDB_REGISTER_METHOD(lldb::SBEnvironment, SBLaunchInfo, GetEnvironment, ());
|
||||
|
@ -446,7 +446,6 @@ SBProcess SBTarget::Launch(SBLaunchInfo &sb_launch_info, SBError &error) {
|
||||
if (arch_spec.IsValid())
|
||||
launch_info.GetArchitecture() = arch_spec;
|
||||
|
||||
target_sp->SetProcessLaunchInfo(launch_info);
|
||||
error.SetError(target_sp->Launch(launch_info, nullptr));
|
||||
sb_launch_info.set_ref(launch_info);
|
||||
sb_process.SetSP(target_sp->GetProcessSP());
|
||||
|
@ -1009,14 +1009,11 @@ public:
|
||||
"Launch a new process on a remote platform.",
|
||||
"platform process launch program",
|
||||
eCommandRequiresTarget | eCommandTryTargetAPILock),
|
||||
m_options(), m_all_options() {
|
||||
m_all_options.Append(&m_options);
|
||||
m_all_options.Finalize();
|
||||
}
|
||||
m_options() {}
|
||||
|
||||
~CommandObjectPlatformProcessLaunch() override = default;
|
||||
|
||||
Options *GetOptions() override { return &m_all_options; }
|
||||
Options *GetOptions() override { return &m_options; }
|
||||
|
||||
protected:
|
||||
bool DoExecute(Args &args, CommandReturnObject &result) override {
|
||||
@ -1088,7 +1085,6 @@ protected:
|
||||
}
|
||||
|
||||
CommandOptionsProcessLaunch m_options;
|
||||
OptionGroupOptions m_all_options;
|
||||
};
|
||||
|
||||
// "platform process list"
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "lldb/Interpreter/CommandInterpreter.h"
|
||||
#include "lldb/Interpreter/CommandReturnObject.h"
|
||||
#include "lldb/Interpreter/OptionArgParser.h"
|
||||
#include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
|
||||
#include "lldb/Interpreter/Options.h"
|
||||
#include "lldb/Target/Platform.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
@ -109,12 +108,7 @@ public:
|
||||
interpreter, "process launch",
|
||||
"Launch the executable in the debugger.", nullptr,
|
||||
eCommandRequiresTarget, "restart"),
|
||||
m_options(), m_class_options("scripted process"), m_all_options() {
|
||||
m_all_options.Append(&m_options);
|
||||
m_all_options.Append(&m_class_options, LLDB_OPT_SET_1 | LLDB_OPT_SET_2,
|
||||
LLDB_OPT_SET_1);
|
||||
m_all_options.Finalize();
|
||||
|
||||
m_options() {
|
||||
CommandArgumentEntry arg;
|
||||
CommandArgumentData run_args_arg;
|
||||
|
||||
@ -141,7 +135,7 @@ public:
|
||||
request, nullptr);
|
||||
}
|
||||
|
||||
Options *GetOptions() override { return &m_all_options; }
|
||||
Options *GetOptions() override { return &m_options; }
|
||||
|
||||
const char *GetRepeatCommand(Args ¤t_command_args,
|
||||
uint32_t index) override {
|
||||
@ -186,15 +180,6 @@ protected:
|
||||
disable_aslr = target->GetDisableASLR();
|
||||
}
|
||||
|
||||
if (!m_class_options.GetName().empty()) {
|
||||
m_options.launch_info.SetProcessPluginName("ScriptedProcess");
|
||||
m_options.launch_info.SetScriptedProcessClassName(
|
||||
m_class_options.GetName());
|
||||
m_options.launch_info.SetScriptedProcessDictionarySP(
|
||||
m_class_options.GetStructuredData());
|
||||
target->SetProcessLaunchInfo(m_options.launch_info);
|
||||
}
|
||||
|
||||
if (disable_aslr)
|
||||
m_options.launch_info.GetFlags().Set(eLaunchFlagDisableASLR);
|
||||
else
|
||||
@ -268,8 +253,6 @@ protected:
|
||||
}
|
||||
|
||||
CommandOptionsProcessLaunch m_options;
|
||||
OptionGroupPythonClassWithDict m_class_options;
|
||||
OptionGroupOptions m_all_options;
|
||||
};
|
||||
|
||||
#define LLDB_OPTIONS_process_attach
|
||||
|
@ -30,7 +30,7 @@ Status CommandOptionsProcessLaunch::SetOptionValue(
|
||||
uint32_t option_idx, llvm::StringRef option_arg,
|
||||
ExecutionContext *execution_context) {
|
||||
Status error;
|
||||
const int short_option = g_process_launch_options[option_idx].short_option;
|
||||
const int short_option = m_getopt_table[option_idx].val;
|
||||
|
||||
switch (short_option) {
|
||||
case 's': // Stop at program entry point
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- CommandOptionsProcessLaunch.h ---------------------------*- C++ -*-===//
|
||||
//===-- CommandOptionsProcessLaunch.h -------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
@ -16,9 +16,9 @@ namespace lldb_private {
|
||||
|
||||
// CommandOptionsProcessLaunch
|
||||
|
||||
class CommandOptionsProcessLaunch : public lldb_private::OptionGroup {
|
||||
class CommandOptionsProcessLaunch : public lldb_private::Options {
|
||||
public:
|
||||
CommandOptionsProcessLaunch() : lldb_private::OptionGroup() {
|
||||
CommandOptionsProcessLaunch() : lldb_private::Options() {
|
||||
// Keep default values of all options in one place: OptionParsingStarting
|
||||
// ()
|
||||
OptionParsingStarting(nullptr);
|
||||
|
@ -32,8 +32,7 @@ ProcessLaunchInfo::ProcessLaunchInfo()
|
||||
: ProcessInfo(), m_working_dir(), m_plugin_name(), m_flags(0),
|
||||
m_file_actions(), m_pty(new PseudoTerminal), m_resume_count(0),
|
||||
m_monitor_callback(nullptr), m_monitor_callback_baton(nullptr),
|
||||
m_monitor_signals(false), m_listener_sp(), m_hijack_listener_sp(),
|
||||
m_scripted_process_class_name(), m_scripted_process_dictionary_sp() {}
|
||||
m_monitor_signals(false), m_listener_sp(), m_hijack_listener_sp() {}
|
||||
|
||||
ProcessLaunchInfo::ProcessLaunchInfo(const FileSpec &stdin_file_spec,
|
||||
const FileSpec &stdout_file_spec,
|
||||
@ -43,8 +42,7 @@ ProcessLaunchInfo::ProcessLaunchInfo(const FileSpec &stdin_file_spec,
|
||||
: ProcessInfo(), m_working_dir(), m_plugin_name(), m_flags(launch_flags),
|
||||
m_file_actions(), m_pty(new PseudoTerminal), m_resume_count(0),
|
||||
m_monitor_callback(nullptr), m_monitor_callback_baton(nullptr),
|
||||
m_monitor_signals(false), m_listener_sp(), m_hijack_listener_sp(),
|
||||
m_scripted_process_class_name(), m_scripted_process_dictionary_sp() {
|
||||
m_monitor_signals(false), m_listener_sp(), m_hijack_listener_sp() {
|
||||
if (stdin_file_spec) {
|
||||
FileAction file_action;
|
||||
const bool read = true;
|
||||
@ -173,8 +171,6 @@ void ProcessLaunchInfo::Clear() {
|
||||
m_resume_count = 0;
|
||||
m_listener_sp.reset();
|
||||
m_hijack_listener_sp.reset();
|
||||
m_scripted_process_class_name.clear();
|
||||
m_scripted_process_dictionary_sp.reset();
|
||||
}
|
||||
|
||||
void ProcessLaunchInfo::SetMonitorProcessCallback(
|
||||
|
@ -26,12 +26,9 @@
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
ScriptInterpreter::ScriptInterpreter(
|
||||
Debugger &debugger, lldb::ScriptLanguage script_lang,
|
||||
lldb::ScriptedProcessInterfaceUP scripted_process_interface_up)
|
||||
: m_debugger(debugger), m_script_lang(script_lang),
|
||||
m_scripted_process_interface_up(
|
||||
std::move(scripted_process_interface_up)) {}
|
||||
ScriptInterpreter::ScriptInterpreter(Debugger &debugger,
|
||||
lldb::ScriptLanguage script_lang)
|
||||
: m_debugger(debugger), m_script_lang(script_lang) {}
|
||||
|
||||
void ScriptInterpreter::CollectDataForBreakpointCommandCallback(
|
||||
std::vector<BreakpointOptions *> &bp_options_vec,
|
||||
@ -72,19 +69,6 @@ std::string ScriptInterpreter::LanguageToString(lldb::ScriptLanguage language) {
|
||||
llvm_unreachable("Unhandled ScriptInterpreter!");
|
||||
}
|
||||
|
||||
lldb::DataExtractorSP
|
||||
ScriptInterpreter::GetDataExtractorFromSBData(const lldb::SBData &data) const {
|
||||
return data.m_opaque_sp;
|
||||
}
|
||||
|
||||
Status
|
||||
ScriptInterpreter::GetStatusFromSBError(const lldb::SBError &error) const {
|
||||
if (error.m_opaque_up)
|
||||
return *error.m_opaque_up.get();
|
||||
|
||||
return Status();
|
||||
}
|
||||
|
||||
lldb::ScriptLanguage
|
||||
ScriptInterpreter::StringToLanguage(const llvm::StringRef &language) {
|
||||
if (language.equals_lower(LanguageToString(eScriptLanguageNone)))
|
||||
|
@ -12,7 +12,6 @@ elseif (CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
add_subdirectory(MacOSX-Kernel)
|
||||
endif()
|
||||
add_subdirectory(scripted)
|
||||
add_subdirectory(gdb-remote)
|
||||
add_subdirectory(Utility)
|
||||
add_subdirectory(elf-core)
|
||||
|
@ -1,13 +0,0 @@
|
||||
add_lldb_library(lldbPluginScriptedProcess PLUGIN
|
||||
ScriptedProcess.cpp
|
||||
|
||||
LINK_LIBS
|
||||
lldbCore
|
||||
lldbTarget
|
||||
lldbUtility
|
||||
lldbPluginProcessUtility
|
||||
LINK_COMPONENTS
|
||||
BinaryFormat
|
||||
Object
|
||||
Support
|
||||
)
|
@ -1,242 +0,0 @@
|
||||
//===-- ScriptedProcess.cpp -----------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "ScriptedProcess.h"
|
||||
|
||||
#include "lldb/Core/Debugger.h"
|
||||
#include "lldb/Core/Module.h"
|
||||
#include "lldb/Core/PluginManager.h"
|
||||
|
||||
#include "lldb/Host/OptionParser.h"
|
||||
|
||||
#include "lldb/Interpreter/OptionArgParser.h"
|
||||
#include "lldb/Interpreter/OptionGroupBoolean.h"
|
||||
#include "lldb/Interpreter/ScriptInterpreter.h"
|
||||
#include "lldb/Target/MemoryRegionInfo.h"
|
||||
|
||||
LLDB_PLUGIN_DEFINE(ScriptedProcess)
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
ConstString ScriptedProcess::GetPluginNameStatic() {
|
||||
static ConstString g_name("ScriptedProcess");
|
||||
return g_name;
|
||||
}
|
||||
|
||||
const char *ScriptedProcess::GetPluginDescriptionStatic() {
|
||||
return "Scripted Process plug-in.";
|
||||
}
|
||||
|
||||
lldb::ProcessSP ScriptedProcess::CreateInstance(lldb::TargetSP target_sp,
|
||||
lldb::ListenerSP listener_sp,
|
||||
const FileSpec *file,
|
||||
bool can_connect) {
|
||||
ScriptedProcess::LaunchInfo launch_info(target_sp->GetProcessLaunchInfo());
|
||||
|
||||
auto process_sp =
|
||||
std::make_shared<ScriptedProcess>(target_sp, listener_sp, launch_info);
|
||||
|
||||
if (!process_sp || !process_sp->m_script_object_sp ||
|
||||
!process_sp->m_script_object_sp->IsValid())
|
||||
return nullptr;
|
||||
|
||||
return process_sp;
|
||||
}
|
||||
|
||||
bool ScriptedProcess::CanDebug(lldb::TargetSP target_sp,
|
||||
bool plugin_specified_by_name) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ScriptedProcess::ScriptedProcess(lldb::TargetSP target_sp,
|
||||
lldb::ListenerSP listener_sp,
|
||||
const ScriptedProcess::LaunchInfo &launch_info)
|
||||
: Process(target_sp, listener_sp), m_launch_info(launch_info),
|
||||
m_interpreter(nullptr), m_script_object_sp(nullptr) {
|
||||
if (!target_sp)
|
||||
return;
|
||||
|
||||
m_interpreter = target_sp->GetDebugger().GetScriptInterpreter();
|
||||
|
||||
if (!m_interpreter)
|
||||
return;
|
||||
|
||||
StructuredData::ObjectSP object_sp = GetInterface().CreatePluginObject(
|
||||
m_launch_info.GetClassName().c_str(), target_sp,
|
||||
m_launch_info.GetDictionarySP());
|
||||
|
||||
if (object_sp && object_sp->IsValid())
|
||||
m_script_object_sp = object_sp;
|
||||
}
|
||||
|
||||
ScriptedProcess::~ScriptedProcess() {
|
||||
Clear();
|
||||
// We need to call finalize on the process before destroying ourselves to
|
||||
// make sure all of the broadcaster cleanup goes as planned. If we destruct
|
||||
// this class, then Process::~Process() might have problems trying to fully
|
||||
// destroy the broadcaster.
|
||||
Finalize();
|
||||
}
|
||||
|
||||
void ScriptedProcess::Initialize() {
|
||||
static llvm::once_flag g_once_flag;
|
||||
|
||||
llvm::call_once(g_once_flag, []() {
|
||||
PluginManager::RegisterPlugin(GetPluginNameStatic(),
|
||||
GetPluginDescriptionStatic(), CreateInstance);
|
||||
});
|
||||
}
|
||||
|
||||
void ScriptedProcess::Terminate() {
|
||||
PluginManager::UnregisterPlugin(ScriptedProcess::CreateInstance);
|
||||
}
|
||||
|
||||
ConstString ScriptedProcess::GetPluginName() { return GetPluginNameStatic(); }
|
||||
|
||||
uint32_t ScriptedProcess::GetPluginVersion() { return 1; }
|
||||
|
||||
Status ScriptedProcess::DoLoadCore() {
|
||||
ProcessLaunchInfo launch_info = GetTarget().GetProcessLaunchInfo();
|
||||
|
||||
return DoLaunch(nullptr, launch_info);
|
||||
}
|
||||
|
||||
Status ScriptedProcess::DoLaunch(Module *exe_module,
|
||||
ProcessLaunchInfo &launch_info) {
|
||||
if (!m_interpreter)
|
||||
return Status("No interpreter.");
|
||||
|
||||
if (!m_script_object_sp)
|
||||
return Status("No python object.");
|
||||
|
||||
Status status = GetInterface().Launch();
|
||||
|
||||
if (status.Success()) {
|
||||
SetPrivateState(eStateRunning);
|
||||
SetPrivateState(eStateStopped);
|
||||
}
|
||||
|
||||
return status;
|
||||
};
|
||||
|
||||
void ScriptedProcess::DidLaunch() {
|
||||
if (m_interpreter)
|
||||
m_pid = GetInterface().GetProcessID();
|
||||
}
|
||||
|
||||
Status ScriptedProcess::DoResume() {
|
||||
if (!m_interpreter)
|
||||
return Status("No interpreter.");
|
||||
|
||||
if (!m_script_object_sp)
|
||||
return Status("No python object.");
|
||||
|
||||
Status status = GetInterface().Resume();
|
||||
|
||||
if (status.Success()) {
|
||||
SetPrivateState(eStateRunning);
|
||||
SetPrivateState(eStateStopped);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
Status ScriptedProcess::DoDestroy() { return Status(); }
|
||||
|
||||
bool ScriptedProcess::IsAlive() {
|
||||
if (!m_interpreter)
|
||||
return false;
|
||||
|
||||
return GetInterface().IsAlive();
|
||||
}
|
||||
|
||||
size_t ScriptedProcess::ReadMemory(lldb::addr_t addr, void *buf, size_t size,
|
||||
Status &error) {
|
||||
return DoReadMemory(addr, buf, size, error);
|
||||
}
|
||||
|
||||
size_t ScriptedProcess::DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
|
||||
Status &error) {
|
||||
|
||||
auto error_with_message = [&error](llvm::StringRef message) {
|
||||
error.SetErrorString(message);
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
};
|
||||
|
||||
if (!m_interpreter)
|
||||
return error_with_message("No interpreter.");
|
||||
|
||||
lldb::DataExtractorSP data_extractor_sp =
|
||||
GetInterface().ReadMemoryAtAddress(addr, size, error);
|
||||
|
||||
if (!data_extractor_sp || error.Fail())
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
|
||||
if (data_extractor_sp->GetByteSize() != size)
|
||||
return error_with_message("Failed to read requested memory size.");
|
||||
|
||||
if (data_extractor_sp->CopyData(0, size, buf) <= size)
|
||||
return error_with_message("Failed to copy read memory to buffer.");
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
ArchSpec ScriptedProcess::GetArchitecture() {
|
||||
return GetTarget().GetArchitecture();
|
||||
}
|
||||
|
||||
Status ScriptedProcess::GetMemoryRegionInfo(lldb::addr_t load_addr,
|
||||
MemoryRegionInfo ®ion) {
|
||||
return Status();
|
||||
}
|
||||
|
||||
Status ScriptedProcess::GetMemoryRegions(MemoryRegionInfos ®ion_list) {
|
||||
Status error;
|
||||
|
||||
if (!m_interpreter) {
|
||||
error.SetErrorString("No interpreter.");
|
||||
return error;
|
||||
}
|
||||
|
||||
lldb::addr_t address = 0;
|
||||
lldb::MemoryRegionInfoSP mem_region_sp = nullptr;
|
||||
|
||||
while ((mem_region_sp =
|
||||
GetInterface().GetMemoryRegionContainingAddress(address))) {
|
||||
auto range = mem_region_sp->GetRange();
|
||||
address += range.GetRangeBase() + range.GetByteSize();
|
||||
region_list.push_back(*mem_region_sp.get());
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void ScriptedProcess::Clear() { Process::m_thread_list.Clear(); }
|
||||
|
||||
bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list,
|
||||
ThreadList &new_thread_list) {
|
||||
return new_thread_list.GetSize(false) > 0;
|
||||
}
|
||||
|
||||
bool ScriptedProcess::GetProcessInfo(ProcessInstanceInfo &info) {
|
||||
info.Clear();
|
||||
info.SetProcessID(GetID());
|
||||
info.SetArchitecture(GetArchitecture());
|
||||
lldb::ModuleSP module_sp = GetTarget().GetExecutableModule();
|
||||
if (module_sp) {
|
||||
const bool add_exe_file_as_first_arg = false;
|
||||
info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(),
|
||||
add_exe_file_as_first_arg);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ScriptedProcessInterface &ScriptedProcess::GetInterface() const {
|
||||
return m_interpreter->GetScriptedProcessInterface();
|
||||
}
|
@ -1,113 +0,0 @@
|
||||
//===-- ScriptedProcess.h ------------------------------------- -*- C++ -*-===//
|
||||
//
|
||||
// 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_SOURCE_PLUGINS_SCRIPTED_PROCESS_H
|
||||
#define LLDB_SOURCE_PLUGINS_SCRIPTED_PROCESS_H
|
||||
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Utility/ConstString.h"
|
||||
#include "lldb/Utility/Status.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class ScriptedProcess : public Process {
|
||||
protected:
|
||||
class LaunchInfo {
|
||||
public:
|
||||
LaunchInfo(const ProcessLaunchInfo &launch_info) {
|
||||
m_class_name = launch_info.GetScriptedProcessClassName();
|
||||
m_dictionary_sp = launch_info.GetScriptedProcessDictionarySP();
|
||||
}
|
||||
|
||||
std::string GetClassName() const { return m_class_name; }
|
||||
StructuredData::DictionarySP GetDictionarySP() const {
|
||||
return m_dictionary_sp;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_class_name;
|
||||
StructuredData::DictionarySP m_dictionary_sp;
|
||||
};
|
||||
|
||||
public:
|
||||
static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
|
||||
lldb::ListenerSP listener_sp,
|
||||
const FileSpec *crash_file_path,
|
||||
bool can_connect);
|
||||
|
||||
static void Initialize();
|
||||
|
||||
static void Terminate();
|
||||
|
||||
static ConstString GetPluginNameStatic();
|
||||
|
||||
static const char *GetPluginDescriptionStatic();
|
||||
|
||||
ScriptedProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
|
||||
const ScriptedProcess::LaunchInfo &launch_info);
|
||||
|
||||
~ScriptedProcess() override;
|
||||
|
||||
bool CanDebug(lldb::TargetSP target_sp,
|
||||
bool plugin_specified_by_name) override;
|
||||
|
||||
DynamicLoader *GetDynamicLoader() override { return nullptr; }
|
||||
|
||||
ConstString GetPluginName() override;
|
||||
|
||||
uint32_t GetPluginVersion() override;
|
||||
|
||||
SystemRuntime *GetSystemRuntime() override { return nullptr; }
|
||||
|
||||
Status DoLoadCore() override;
|
||||
|
||||
Status DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) override;
|
||||
|
||||
void DidLaunch() override;
|
||||
|
||||
Status DoResume() override;
|
||||
|
||||
Status DoDestroy() override;
|
||||
|
||||
void RefreshStateAfterStop() override{};
|
||||
|
||||
bool IsAlive() override;
|
||||
|
||||
size_t ReadMemory(lldb::addr_t addr, void *buf, size_t size,
|
||||
Status &error) override;
|
||||
|
||||
size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
|
||||
Status &error) override;
|
||||
|
||||
ArchSpec GetArchitecture();
|
||||
|
||||
Status GetMemoryRegionInfo(lldb::addr_t load_addr,
|
||||
MemoryRegionInfo &range_info) override;
|
||||
|
||||
Status
|
||||
GetMemoryRegions(lldb_private::MemoryRegionInfos ®ion_list) override;
|
||||
|
||||
bool GetProcessInfo(ProcessInstanceInfo &info) override;
|
||||
|
||||
protected:
|
||||
void Clear();
|
||||
|
||||
bool DoUpdateThreadList(ThreadList &old_thread_list,
|
||||
ThreadList &new_thread_list) override;
|
||||
|
||||
private:
|
||||
ScriptedProcessInterface &GetInterface() const;
|
||||
|
||||
const LaunchInfo m_launch_info;
|
||||
lldb_private::ScriptInterpreter *m_interpreter;
|
||||
lldb_private::StructuredData::ObjectSP m_script_object_sp;
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // LLDB_SOURCE_PLUGINS_SCRIPTED_PROCESS_H
|
@ -11,8 +11,6 @@ add_lldb_library(lldbPluginScriptInterpreterPython PLUGIN
|
||||
PythonDataObjects.cpp
|
||||
PythonReadline.cpp
|
||||
ScriptInterpreterPython.cpp
|
||||
ScriptedProcessPythonInterface.cpp
|
||||
SWIGPythonBridge.cpp
|
||||
|
||||
LINK_LIBS
|
||||
lldbBreakpoint
|
||||
|
@ -1,48 +0,0 @@
|
||||
//===-- SWIGPythonBridge.cpp ----------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lldb/Host/Config.h"
|
||||
#include "lldb/lldb-enumerations.h"
|
||||
|
||||
#if LLDB_ENABLE_PYTHON
|
||||
|
||||
// LLDB Python header must be included first
|
||||
#include "lldb-python.h"
|
||||
|
||||
#include "SWIGPythonBridge.h"
|
||||
|
||||
using namespace lldb;
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
template <typename T> const char *GetPythonValueFormatString(T t);
|
||||
template <> const char *GetPythonValueFormatString(char *) { return "s"; }
|
||||
template <> const char *GetPythonValueFormatString(char) { return "b"; }
|
||||
template <> const char *GetPythonValueFormatString(unsigned char) {
|
||||
return "B";
|
||||
}
|
||||
template <> const char *GetPythonValueFormatString(short) { return "h"; }
|
||||
template <> const char *GetPythonValueFormatString(unsigned short) {
|
||||
return "H";
|
||||
}
|
||||
template <> const char *GetPythonValueFormatString(int) { return "i"; }
|
||||
template <> const char *GetPythonValueFormatString(unsigned int) { return "I"; }
|
||||
template <> const char *GetPythonValueFormatString(long) { return "l"; }
|
||||
template <> const char *GetPythonValueFormatString(unsigned long) {
|
||||
return "k";
|
||||
}
|
||||
template <> const char *GetPythonValueFormatString(long long) { return "L"; }
|
||||
template <> const char *GetPythonValueFormatString(unsigned long long) {
|
||||
return "K";
|
||||
}
|
||||
template <> const char *GetPythonValueFormatString(float) { return "f"; }
|
||||
template <> const char *GetPythonValueFormatString(double) { return "d"; }
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // LLDB_ENABLE_PYTHON
|
@ -1,56 +0,0 @@
|
||||
//===-- ScriptInterpreterPython.h -------------------------------*- C++ -*-===//
|
||||
//
|
||||
// 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_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H
|
||||
#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "lldb/Host/Config.h"
|
||||
|
||||
#if LLDB_ENABLE_PYTHON
|
||||
|
||||
#include "lldb/lldb-forward.h"
|
||||
#include "lldb/lldb-types.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
// GetPythonValueFormatString provides a system independent type safe way to
|
||||
// convert a variable's type into a python value format. Python value formats
|
||||
// are defined in terms of builtin C types and could change from system to as
|
||||
// the underlying typedef for uint* types, size_t, off_t and other values
|
||||
// change.
|
||||
|
||||
template <typename T> const char *GetPythonValueFormatString(T t);
|
||||
template <> const char *GetPythonValueFormatString(char *);
|
||||
template <> const char *GetPythonValueFormatString(char);
|
||||
template <> const char *GetPythonValueFormatString(unsigned char);
|
||||
template <> const char *GetPythonValueFormatString(short);
|
||||
template <> const char *GetPythonValueFormatString(unsigned short);
|
||||
template <> const char *GetPythonValueFormatString(int);
|
||||
template <> const char *GetPythonValueFormatString(unsigned int);
|
||||
template <> const char *GetPythonValueFormatString(long);
|
||||
template <> const char *GetPythonValueFormatString(unsigned long);
|
||||
template <> const char *GetPythonValueFormatString(long long);
|
||||
template <> const char *GetPythonValueFormatString(unsigned long long);
|
||||
template <> const char *GetPythonValueFormatString(float t);
|
||||
template <> const char *GetPythonValueFormatString(double t);
|
||||
|
||||
extern "C" void *LLDBSwigPythonCreateScriptedProcess(
|
||||
const char *python_class_name, const char *session_dictionary_name,
|
||||
const lldb::TargetSP &target_sp, StructuredDataImpl *args_impl,
|
||||
std::string &error_string);
|
||||
|
||||
extern "C" void *LLDBSWIGPython_CastPyObjectToSBData(void *data);
|
||||
extern "C" void *LLDBSWIGPython_CastPyObjectToSBError(void *data);
|
||||
extern "C" void *LLDBSWIGPython_CastPyObjectToSBValue(void *data);
|
||||
|
||||
}; // namespace lldb_private
|
||||
|
||||
#endif // LLDB_ENABLE_PYTHON
|
||||
#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H
|
@ -16,11 +16,7 @@
|
||||
|
||||
#include "PythonDataObjects.h"
|
||||
#include "PythonReadline.h"
|
||||
#include "SWIGPythonBridge.h"
|
||||
#include "ScriptInterpreterPythonImpl.h"
|
||||
#include "ScriptedProcessPythonInterface.h"
|
||||
|
||||
#include "lldb/API/SBError.h"
|
||||
#include "lldb/API/SBFrame.h"
|
||||
#include "lldb/API/SBValue.h"
|
||||
#include "lldb/Breakpoint/StoppointCallbackContext.h"
|
||||
@ -152,6 +148,8 @@ extern "C" void *LLDBSwigPython_GetChildAtIndex(void *implementor,
|
||||
extern "C" int LLDBSwigPython_GetIndexOfChildWithName(void *implementor,
|
||||
const char *child_name);
|
||||
|
||||
extern "C" void *LLDBSWIGPython_CastPyObjectToSBValue(void *data);
|
||||
|
||||
extern lldb::ValueObjectSP
|
||||
LLDBSWIGPython_GetValueObjectSPFromSBValue(void *data);
|
||||
|
||||
@ -533,9 +531,6 @@ ScriptInterpreterPythonImpl::ScriptInterpreterPythonImpl(Debugger &debugger)
|
||||
m_command_thread_state(nullptr) {
|
||||
InitializePrivate();
|
||||
|
||||
m_scripted_process_interface_up =
|
||||
std::make_unique<ScriptedProcessPythonInterface>(*this);
|
||||
|
||||
m_dictionary_name.append("_dict");
|
||||
StreamString run_string;
|
||||
run_string.Printf("%s = dict()", m_dictionary_name.c_str());
|
||||
@ -1708,6 +1703,35 @@ StructuredData::ArraySP ScriptInterpreterPythonImpl::OSPlugin_ThreadsInfo(
|
||||
return StructuredData::ArraySP();
|
||||
}
|
||||
|
||||
// GetPythonValueFormatString provides a system independent type safe way to
|
||||
// convert a variable's type into a python value format. Python value formats
|
||||
// are defined in terms of builtin C types and could change from system to as
|
||||
// the underlying typedef for uint* types, size_t, off_t and other values
|
||||
// change.
|
||||
|
||||
template <typename T> const char *GetPythonValueFormatString(T t);
|
||||
template <> const char *GetPythonValueFormatString(char *) { return "s"; }
|
||||
template <> const char *GetPythonValueFormatString(char) { return "b"; }
|
||||
template <> const char *GetPythonValueFormatString(unsigned char) {
|
||||
return "B";
|
||||
}
|
||||
template <> const char *GetPythonValueFormatString(short) { return "h"; }
|
||||
template <> const char *GetPythonValueFormatString(unsigned short) {
|
||||
return "H";
|
||||
}
|
||||
template <> const char *GetPythonValueFormatString(int) { return "i"; }
|
||||
template <> const char *GetPythonValueFormatString(unsigned int) { return "I"; }
|
||||
template <> const char *GetPythonValueFormatString(long) { return "l"; }
|
||||
template <> const char *GetPythonValueFormatString(unsigned long) {
|
||||
return "k";
|
||||
}
|
||||
template <> const char *GetPythonValueFormatString(long long) { return "L"; }
|
||||
template <> const char *GetPythonValueFormatString(unsigned long long) {
|
||||
return "K";
|
||||
}
|
||||
template <> const char *GetPythonValueFormatString(float t) { return "f"; }
|
||||
template <> const char *GetPythonValueFormatString(double t) { return "d"; }
|
||||
|
||||
StructuredData::StringSP
|
||||
ScriptInterpreterPythonImpl::OSPlugin_RegisterContextData(
|
||||
StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid) {
|
||||
|
@ -13,8 +13,6 @@
|
||||
|
||||
#if LLDB_ENABLE_PYTHON
|
||||
|
||||
#include "ScriptedProcessPythonInterface.h"
|
||||
|
||||
#include "lldb/Breakpoint/BreakpointOptions.h"
|
||||
#include "lldb/Core/IOHandler.h"
|
||||
#include "lldb/Core/StructuredDataImpl.h"
|
||||
|
@ -6,9 +6,6 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H
|
||||
#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H
|
||||
|
||||
#include "lldb/Host/Config.h"
|
||||
|
||||
#if LLDB_ENABLE_PYTHON
|
||||
@ -486,5 +483,4 @@ protected:
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // LLDB_ENABLE_PYTHON
|
||||
#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H
|
||||
#endif
|
||||
|
@ -1,287 +0,0 @@
|
||||
//===-- ScriptedProcessPythonInterface.cpp --------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lldb/Host/Config.h"
|
||||
#include "lldb/lldb-enumerations.h"
|
||||
|
||||
#if LLDB_ENABLE_PYTHON
|
||||
|
||||
// LLDB Python header must be included first
|
||||
#include "lldb-python.h"
|
||||
|
||||
#include "SWIGPythonBridge.h"
|
||||
#include "ScriptInterpreterPythonImpl.h"
|
||||
#include "ScriptedProcessPythonInterface.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
using namespace lldb_private::python;
|
||||
using Locker = ScriptInterpreterPythonImpl::Locker;
|
||||
|
||||
StructuredData::GenericSP ScriptedProcessPythonInterface::CreatePluginObject(
|
||||
const llvm::StringRef class_name, lldb::TargetSP target_sp,
|
||||
StructuredData::DictionarySP args_sp) {
|
||||
if (class_name.empty())
|
||||
return {};
|
||||
|
||||
std::string error_string;
|
||||
StructuredDataImpl *args_impl = nullptr;
|
||||
if (args_sp) {
|
||||
args_impl = new StructuredDataImpl();
|
||||
args_impl->SetObjectSP(args_sp);
|
||||
}
|
||||
|
||||
void *ret_val;
|
||||
|
||||
{
|
||||
|
||||
Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
|
||||
Locker::FreeLock);
|
||||
|
||||
ret_val = LLDBSwigPythonCreateScriptedProcess(
|
||||
class_name.str().c_str(), m_interpreter.GetDictionaryName(), target_sp,
|
||||
args_impl, error_string);
|
||||
}
|
||||
|
||||
m_object_instance_sp =
|
||||
StructuredData::GenericSP(new StructuredPythonObject(ret_val));
|
||||
|
||||
return m_object_instance_sp;
|
||||
}
|
||||
|
||||
Status ScriptedProcessPythonInterface::Launch() {
|
||||
return LaunchOrResume("launch");
|
||||
}
|
||||
|
||||
Status ScriptedProcessPythonInterface::Resume() {
|
||||
return LaunchOrResume("resume");
|
||||
}
|
||||
|
||||
Status
|
||||
ScriptedProcessPythonInterface::LaunchOrResume(llvm::StringRef method_name) {
|
||||
Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
|
||||
Locker::FreeLock);
|
||||
|
||||
if (!m_object_instance_sp)
|
||||
return Status("Python object ill-formed.");
|
||||
|
||||
if (!m_object_instance_sp)
|
||||
return Status("Cannot convert Python object to StructuredData::Generic.");
|
||||
PythonObject implementor(PyRefType::Borrowed,
|
||||
(PyObject *)m_object_instance_sp->GetValue());
|
||||
|
||||
if (!implementor.IsAllocated())
|
||||
return Status("Python implementor not allocated.");
|
||||
|
||||
PythonObject pmeth(
|
||||
PyRefType::Owned,
|
||||
PyObject_GetAttrString(implementor.get(), method_name.str().c_str()));
|
||||
|
||||
if (PyErr_Occurred())
|
||||
PyErr_Clear();
|
||||
|
||||
if (!pmeth.IsAllocated())
|
||||
return Status("Python method not allocated.");
|
||||
|
||||
if (PyCallable_Check(pmeth.get()) == 0) {
|
||||
if (PyErr_Occurred())
|
||||
PyErr_Clear();
|
||||
return Status("Python method not callable.");
|
||||
}
|
||||
|
||||
if (PyErr_Occurred())
|
||||
PyErr_Clear();
|
||||
|
||||
PythonObject py_return(PyRefType::Owned,
|
||||
PyObject_CallMethod(implementor.get(),
|
||||
method_name.str().c_str(),
|
||||
nullptr));
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
return Status("Python method could not be called.");
|
||||
}
|
||||
|
||||
if (PyObject *py_ret_ptr = py_return.get()) {
|
||||
lldb::SBError *sb_error =
|
||||
(lldb::SBError *)LLDBSWIGPython_CastPyObjectToSBError(py_ret_ptr);
|
||||
|
||||
if (!sb_error)
|
||||
return Status("Couldn't cast lldb::SBError to lldb::Status.");
|
||||
|
||||
Status status = m_interpreter.GetStatusFromSBError(*sb_error);
|
||||
|
||||
if (status.Fail())
|
||||
return Status("error: %s", status.AsCString());
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
return Status("Returned object is null.");
|
||||
}
|
||||
|
||||
size_t
|
||||
ScriptedProcessPythonInterface::GetGenericInteger(llvm::StringRef method_name) {
|
||||
Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
|
||||
Locker::FreeLock);
|
||||
|
||||
if (!m_object_instance_sp)
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
|
||||
if (!m_object_instance_sp)
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
PythonObject implementor(PyRefType::Borrowed,
|
||||
(PyObject *)m_object_instance_sp->GetValue());
|
||||
|
||||
if (!implementor.IsAllocated())
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
|
||||
PythonObject pmeth(
|
||||
PyRefType::Owned,
|
||||
PyObject_GetAttrString(implementor.get(), method_name.str().c_str()));
|
||||
|
||||
if (PyErr_Occurred())
|
||||
PyErr_Clear();
|
||||
|
||||
if (!pmeth.IsAllocated())
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
|
||||
if (PyCallable_Check(pmeth.get()) == 0) {
|
||||
if (PyErr_Occurred())
|
||||
PyErr_Clear();
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
if (PyErr_Occurred())
|
||||
PyErr_Clear();
|
||||
|
||||
PythonObject py_return(PyRefType::Owned,
|
||||
PyObject_CallMethod(implementor.get(),
|
||||
method_name.str().c_str(),
|
||||
nullptr));
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
||||
if (py_return.get()) {
|
||||
auto size = py_return.AsUnsignedLongLong();
|
||||
return (size) ? *size : LLDB_INVALID_ADDRESS;
|
||||
}
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
lldb::MemoryRegionInfoSP
|
||||
ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress(
|
||||
lldb::addr_t address) {
|
||||
// TODO: Implement
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
StructuredData::DictionarySP
|
||||
ScriptedProcessPythonInterface::GetThreadWithID(lldb::tid_t tid) {
|
||||
// TODO: Implement
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
StructuredData::DictionarySP
|
||||
ScriptedProcessPythonInterface::GetRegistersForThread(lldb::tid_t tid) {
|
||||
// TODO: Implement
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
lldb::DataExtractorSP ScriptedProcessPythonInterface::ReadMemoryAtAddress(
|
||||
lldb::addr_t address, size_t size, Status &error) {
|
||||
Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
|
||||
Locker::FreeLock);
|
||||
|
||||
auto error_with_message = [&error](llvm::StringRef message) {
|
||||
error.SetErrorString(message);
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
static char callee_name[] = "read_memory_at_address";
|
||||
std::string param_format = GetPythonValueFormatString(address);
|
||||
param_format += GetPythonValueFormatString(size);
|
||||
|
||||
if (!m_object_instance_sp)
|
||||
return error_with_message("Python object ill-formed.");
|
||||
|
||||
if (!m_object_instance_sp)
|
||||
return error_with_message("Python method not callable.");
|
||||
|
||||
PythonObject implementor(PyRefType::Borrowed,
|
||||
(PyObject *)m_object_instance_sp->GetValue());
|
||||
|
||||
if (!implementor.IsAllocated())
|
||||
return error_with_message("Python implementor not allocated.");
|
||||
|
||||
PythonObject pmeth(PyRefType::Owned,
|
||||
PyObject_GetAttrString(implementor.get(), callee_name));
|
||||
|
||||
if (PyErr_Occurred())
|
||||
PyErr_Clear();
|
||||
|
||||
if (!pmeth.IsAllocated())
|
||||
return error_with_message("Python method not allocated.");
|
||||
|
||||
if (PyCallable_Check(pmeth.get()) == 0) {
|
||||
if (PyErr_Occurred())
|
||||
PyErr_Clear();
|
||||
return error_with_message("Python method not callable.");
|
||||
}
|
||||
|
||||
if (PyErr_Occurred())
|
||||
PyErr_Clear();
|
||||
|
||||
PythonObject py_return(PyRefType::Owned,
|
||||
PyObject_CallMethod(implementor.get(), callee_name,
|
||||
param_format.c_str(), address,
|
||||
size));
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
return error_with_message("Python method could not be called.");
|
||||
}
|
||||
|
||||
if (PyObject *py_ret_ptr = py_return.get()) {
|
||||
lldb::SBData *sb_data =
|
||||
(lldb::SBData *)LLDBSWIGPython_CastPyObjectToSBData(py_ret_ptr);
|
||||
|
||||
if (!sb_data)
|
||||
return error_with_message(
|
||||
"Couldn't cast lldb::SBData to lldb::DataExtractor.");
|
||||
|
||||
return m_interpreter.GetDataExtractorFromSBData(*sb_data);
|
||||
}
|
||||
|
||||
return error_with_message("Returned object is null.");
|
||||
}
|
||||
|
||||
StructuredData::DictionarySP ScriptedProcessPythonInterface::GetLoadedImages() {
|
||||
// TODO: Implement
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() {
|
||||
size_t pid = GetGenericInteger("get_process_id");
|
||||
|
||||
return (pid >= std::numeric_limits<lldb::pid_t>::max())
|
||||
? LLDB_INVALID_PROCESS_ID
|
||||
: pid;
|
||||
}
|
||||
|
||||
bool ScriptedProcessPythonInterface::IsAlive() {
|
||||
return GetGenericInteger("is_alive");
|
||||
;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,61 +0,0 @@
|
||||
//===-- ScriptedProcessPythonInterface.h ------------------------*- C++ -*-===//
|
||||
//
|
||||
// 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_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPROCESSPYTHONINTERFACE_H
|
||||
#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPROCESSPYTHONINTERFACE_H
|
||||
|
||||
#include "lldb/Host/Config.h"
|
||||
|
||||
#if LLDB_ENABLE_PYTHON
|
||||
|
||||
#include "lldb/Interpreter/ScriptedProcessInterface.h"
|
||||
|
||||
namespace lldb_private {
|
||||
class ScriptInterpreterPythonImpl;
|
||||
class ScriptedProcessPythonInterface : public ScriptedProcessInterface {
|
||||
public:
|
||||
ScriptedProcessPythonInterface(ScriptInterpreterPythonImpl &interpreter)
|
||||
: ScriptedProcessInterface(), m_interpreter(interpreter) {}
|
||||
|
||||
StructuredData::GenericSP
|
||||
CreatePluginObject(const llvm::StringRef class_name, lldb::TargetSP target_sp,
|
||||
StructuredData::DictionarySP args_sp) override;
|
||||
|
||||
Status Launch() override;
|
||||
|
||||
Status Resume() override;
|
||||
|
||||
lldb::MemoryRegionInfoSP
|
||||
GetMemoryRegionContainingAddress(lldb::addr_t address) override;
|
||||
|
||||
StructuredData::DictionarySP GetThreadWithID(lldb::tid_t tid) override;
|
||||
|
||||
StructuredData::DictionarySP GetRegistersForThread(lldb::tid_t tid) override;
|
||||
|
||||
lldb::DataExtractorSP ReadMemoryAtAddress(lldb::addr_t address, size_t size,
|
||||
Status &error) override;
|
||||
|
||||
StructuredData::DictionarySP GetLoadedImages() override;
|
||||
|
||||
lldb::pid_t GetProcessID() override;
|
||||
|
||||
bool IsAlive() override;
|
||||
|
||||
protected:
|
||||
size_t GetGenericInteger(llvm::StringRef method_name);
|
||||
Status LaunchOrResume(llvm::StringRef method_name);
|
||||
|
||||
private:
|
||||
// The lifetime is managed by the ScriptInterpreter
|
||||
ScriptInterpreterPythonImpl &m_interpreter;
|
||||
StructuredData::GenericSP m_object_instance_sp;
|
||||
};
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // LLDB_ENABLE_PYTHON
|
||||
#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPROCESSPYTHONINTERFACE_H
|
@ -2950,7 +2950,7 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) {
|
||||
// If we're not already connected to the process, and if we have a platform
|
||||
// that can launch a process for debugging, go ahead and do that here.
|
||||
if (state != eStateConnected && platform_sp &&
|
||||
platform_sp->CanDebugProcess() && !launch_info.IsScriptedProcess()) {
|
||||
platform_sp->CanDebugProcess()) {
|
||||
LLDB_LOGF(log, "Target::%s asking the platform to debug the process",
|
||||
__FUNCTION__);
|
||||
|
||||
|
@ -1,4 +0,0 @@
|
||||
C_SOURCES := main.c
|
||||
|
||||
include Makefile.rules
|
||||
|
@ -1,97 +0,0 @@
|
||||
"""
|
||||
Test python scripted process in lldb
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
import lldb
|
||||
from lldbsuite.test.decorators import *
|
||||
from lldbsuite.test.lldbtest import *
|
||||
from lldbsuite.test import lldbutil
|
||||
from lldbsuite.test import lldbtest
|
||||
|
||||
|
||||
class ScriptedProcesTestCase(TestBase):
|
||||
|
||||
mydir = TestBase.compute_mydir(__file__)
|
||||
|
||||
def setUp(self):
|
||||
TestBase.setUp(self)
|
||||
self.source = "main.c"
|
||||
|
||||
def tearDown(self):
|
||||
TestBase.tearDown(self)
|
||||
|
||||
def test_python_plugin_package(self):
|
||||
"""Test that the lldb python module has a `plugins.scripted_process`
|
||||
package."""
|
||||
self.expect('script import lldb.plugins',
|
||||
substrs=["ModuleNotFoundError"], matching=False)
|
||||
|
||||
self.expect('script dir(lldb.plugins)',
|
||||
substrs=["scripted_process"])
|
||||
|
||||
self.expect('script import lldb.plugins.scripted_process',
|
||||
substrs=["ModuleNotFoundError"], matching=False)
|
||||
|
||||
self.expect('script dir(lldb.plugins.scripted_process)',
|
||||
substrs=["ScriptedProcess"])
|
||||
|
||||
self.expect('script from lldb.plugins.scripted_process import ScriptedProcess',
|
||||
substrs=["ImportError"], matching=False)
|
||||
|
||||
self.expect('script dir(ScriptedProcess)',
|
||||
substrs=["launch"])
|
||||
|
||||
def test_launch_scripted_process_sbapi(self):
|
||||
"""Test that we can launch an lldb scripted process using the SBAPI,
|
||||
check its process ID and read string from memory."""
|
||||
self.build()
|
||||
target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
|
||||
self.assertTrue(target, VALID_TARGET)
|
||||
|
||||
scripted_process_example_relpath = ['..','..','..','..','examples','python','scripted_process','my_scripted_process.py']
|
||||
os.environ['SKIP_SCRIPTED_PROCESS_LAUNCH'] = '1'
|
||||
self.runCmd("command script import " + os.path.join(self.getSourceDir(),
|
||||
*scripted_process_example_relpath))
|
||||
|
||||
launch_info = lldb.SBLaunchInfo(None)
|
||||
launch_info.SetProcessPluginName('ScriptedProcess')
|
||||
launch_info.SetScriptedProcessClassName('my_scripted_process.MyScriptedProcess')
|
||||
|
||||
error = lldb.SBError()
|
||||
process = target.Launch(launch_info, error)
|
||||
self.assertTrue(process, PROCESS_IS_VALID)
|
||||
self.assertEqual(process.GetProcessID(), 42)
|
||||
|
||||
hello_world = 'Hello, world!'
|
||||
memory_read = process.ReadCStringFromMemory(0x50000000000,
|
||||
len(hello_world) + 1, # NULL byte
|
||||
error)
|
||||
|
||||
self.assertTrue(error.Success(), "Failed to read memory from scripted process.")
|
||||
self.assertEqual(hello_world, memory_read)
|
||||
|
||||
def test_launch_scripted_process_cli(self):
|
||||
"""Test that we can launch an lldb scripted process from the command
|
||||
line, check its process ID and read string from memory."""
|
||||
self.build()
|
||||
target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
|
||||
self.assertTrue(target, VALID_TARGET)
|
||||
|
||||
scripted_process_example_relpath = ['..','..','..','..','examples','python','scripted_process','my_scripted_process.py']
|
||||
self.runCmd("command script import " + os.path.join(self.getSourceDir(),
|
||||
*scripted_process_example_relpath))
|
||||
|
||||
process = target.GetProcess()
|
||||
self.assertTrue(process, PROCESS_IS_VALID)
|
||||
self.assertEqual(process.GetProcessID(), 42)
|
||||
|
||||
error = lldb.SBError()
|
||||
hello_world = 'Hello, world!'
|
||||
memory_read = process.ReadCStringFromMemory(0x50000000000,
|
||||
len(hello_world) + 1, # NULL byte
|
||||
error)
|
||||
|
||||
self.assertTrue(error.Success(), "Failed to read memory from scripted process.")
|
||||
self.assertEqual(hello_world, memory_read)
|
@ -1,5 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
int main() {
|
||||
return 0; // break here
|
||||
}
|
@ -12,7 +12,6 @@
|
||||
|
||||
#include "Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h"
|
||||
#include "Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h"
|
||||
#include "lldb/API/SBError.h"
|
||||
#include "lldb/Host/FileSystem.h"
|
||||
#include "lldb/Host/HostInfo.h"
|
||||
|
||||
@ -154,14 +153,6 @@ extern "C" int LLDBSwigPython_GetIndexOfChildWithName(void *implementor,
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" void *LLDBSWIGPython_CastPyObjectToSBData(void *data) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
extern "C" void *LLDBSWIGPython_CastPyObjectToSBError(void *data) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
extern "C" void *LLDBSWIGPython_CastPyObjectToSBValue(void *data) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -216,13 +207,6 @@ LLDBSWIGPythonCreateOSPlugin(const char *python_class_name,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
extern "C" void *LLDBSwigPythonCreateScriptedProcess(
|
||||
const char *python_class_name, const char *session_dictionary_name,
|
||||
const lldb::TargetSP &target_sp, StructuredDataImpl *args_impl,
|
||||
std::string &error_string) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
extern "C" void *
|
||||
LLDBSWIGPython_CreateFrameRecognizer(const char *python_class_name,
|
||||
const char *session_dictionary_name) {
|
||||
|
Loading…
Reference in New Issue
Block a user