aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-06-13 19:31:46 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-06-13 19:37:19 +0000
commite8d8bef961a50d4dc22501cde4fb9fb0be1b2532 (patch)
tree94f04805f47bb7c59ae29690d8952b6074fff602 /contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python
parentbb130ff39747b94592cb26d71b7cb097b9a4ea6b (diff)
parentb60736ec1405bb0a8dd40989f67ef4c93da068ab (diff)
Diffstat (limited to 'contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python')
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp339
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h16
3 files changed, 227 insertions, 132 deletions
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
index 6f040fdef09b..7c49502f1b57 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -451,7 +451,11 @@ Expected<llvm::StringRef> PythonString::AsUTF8() const {
size_t PythonString::GetSize() const {
if (IsValid()) {
#if PY_MAJOR_VERSION >= 3
+#if PY_MINOR_VERSION >= 3
+ return PyUnicode_GetLength(m_py_obj);
+#else
return PyUnicode_GetSize(m_py_obj);
+#endif
#else
return PyString_Size(m_py_obj);
#endif
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index 9f56b4fa60a5..6b53bd3a2edc 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/Config.h"
+#include "lldb/lldb-enumerations.h"
#if LLDB_ENABLE_PYTHON
@@ -32,6 +33,7 @@
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
+#include "lldb/Utility/ReproducerInstrumentation.h"
#include "lldb/Utility/Timer.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
@@ -127,6 +129,16 @@ extern "C" unsigned int
LLDBSwigPythonCallBreakpointResolver(void *implementor, const char *method_name,
lldb_private::SymbolContext *sym_ctx);
+extern "C" void *LLDBSwigPythonCreateScriptedStopHook(
+ TargetSP target_sp, const char *python_class_name,
+ const char *session_dictionary_name, lldb_private::StructuredDataImpl *args,
+ lldb_private::Status &error);
+
+extern "C" bool
+LLDBSwigPythonStopHookCallHandleStop(void *implementor,
+ lldb::ExecutionContextRefSP exc_ctx,
+ lldb::StreamSP stream);
+
extern "C" size_t LLDBSwigPython_CalculateNumChildren(void *implementor,
uint32_t max);
@@ -204,6 +216,12 @@ extern "C" void *
LLDBSWIGPython_GetDynamicSetting(void *module, const char *setting,
const lldb::TargetSP &target_sp);
+static ScriptInterpreterPythonImpl *GetPythonInterpreter(Debugger &debugger) {
+ ScriptInterpreter *script_interpreter =
+ debugger.GetScriptInterpreter(true, lldb::eScriptLanguagePython);
+ return static_cast<ScriptInterpreterPythonImpl *>(script_interpreter);
+}
+
static bool g_initialized = false;
namespace {
@@ -420,6 +438,7 @@ ScriptInterpreterPythonImpl::Locker::Locker(
: ScriptInterpreterLocker(),
m_teardown_session((on_leave & TearDownSession) == TearDownSession),
m_python_interpreter(py_interpreter) {
+ repro::Recorder::PrivateThread();
DoAcquireLock();
if ((on_entry & InitSession) == InitSession) {
if (!DoInitSession(on_entry, in, out, err)) {
@@ -982,8 +1001,7 @@ bool ScriptInterpreterPythonImpl::ExecuteOneLine(
}
void ScriptInterpreterPythonImpl::ExecuteInterpreterLoop() {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
+ LLDB_SCOPED_TIMER();
Debugger &debugger = m_debugger;
@@ -1815,11 +1833,10 @@ StructuredData::ObjectSP ScriptInterpreterPythonImpl::CreateScriptedThreadPlan(
return {};
Debugger &debugger = thread_plan_sp->GetTarget().GetDebugger();
- ScriptInterpreter *script_interpreter = debugger.GetScriptInterpreter();
ScriptInterpreterPythonImpl *python_interpreter =
- static_cast<ScriptInterpreterPythonImpl *>(script_interpreter);
+ GetPythonInterpreter(debugger);
- if (!script_interpreter)
+ if (!python_interpreter)
return {};
void *ret_val;
@@ -1919,11 +1936,10 @@ ScriptInterpreterPythonImpl::CreateScriptedBreakpointResolver(
return StructuredData::GenericSP();
Debugger &debugger = bkpt_sp->GetTarget().GetDebugger();
- ScriptInterpreter *script_interpreter = debugger.GetScriptInterpreter();
ScriptInterpreterPythonImpl *python_interpreter =
- static_cast<ScriptInterpreterPythonImpl *>(script_interpreter);
+ GetPythonInterpreter(debugger);
- if (!script_interpreter)
+ if (!python_interpreter)
return StructuredData::GenericSP();
void *ret_val;
@@ -1979,6 +1995,59 @@ ScriptInterpreterPythonImpl::ScriptedBreakpointResolverSearchDepth(
return lldb::eSearchDepthModule;
}
+StructuredData::GenericSP ScriptInterpreterPythonImpl::CreateScriptedStopHook(
+ TargetSP target_sp, const char *class_name, StructuredDataImpl *args_data,
+ Status &error) {
+
+ if (!target_sp) {
+ error.SetErrorString("No target for scripted stop-hook.");
+ return StructuredData::GenericSP();
+ }
+
+ if (class_name == nullptr || class_name[0] == '\0') {
+ error.SetErrorString("No class name for scripted stop-hook.");
+ return StructuredData::GenericSP();
+ }
+
+ ScriptInterpreterPythonImpl *python_interpreter =
+ GetPythonInterpreter(m_debugger);
+
+ if (!python_interpreter) {
+ error.SetErrorString("No script interpreter for scripted stop-hook.");
+ return StructuredData::GenericSP();
+ }
+
+ void *ret_val;
+
+ {
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+
+ ret_val = LLDBSwigPythonCreateScriptedStopHook(
+ target_sp, class_name, python_interpreter->m_dictionary_name.c_str(),
+ args_data, error);
+ }
+
+ return StructuredData::GenericSP(new StructuredPythonObject(ret_val));
+}
+
+bool ScriptInterpreterPythonImpl::ScriptedStopHookHandleStop(
+ StructuredData::GenericSP implementor_sp, ExecutionContext &exc_ctx,
+ lldb::StreamSP stream_sp) {
+ assert(implementor_sp &&
+ "can't call a stop hook with an invalid implementor");
+ assert(stream_sp && "can't call a stop hook with an invalid stream");
+
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+
+ lldb::ExecutionContextRefSP exc_ctx_ref_sp(new ExecutionContextRef(exc_ctx));
+
+ bool ret_val = LLDBSwigPythonStopHookCallHandleStop(
+ implementor_sp->GetValue(), exc_ctx_ref_sp, stream_sp);
+ return ret_val;
+}
+
StructuredData::ObjectSP
ScriptInterpreterPythonImpl::LoadPluginModule(const FileSpec &file_spec,
lldb_private::Status &error) {
@@ -2039,11 +2108,10 @@ ScriptInterpreterPythonImpl::CreateSyntheticScriptedProvider(
return StructuredData::ObjectSP();
Debugger &debugger = target->GetDebugger();
- ScriptInterpreter *script_interpreter = debugger.GetScriptInterpreter();
ScriptInterpreterPythonImpl *python_interpreter =
- (ScriptInterpreterPythonImpl *)script_interpreter;
+ GetPythonInterpreter(debugger);
- if (!script_interpreter)
+ if (!python_interpreter)
return StructuredData::ObjectSP();
void *ret_val = nullptr;
@@ -2151,8 +2219,7 @@ bool ScriptInterpreterPythonImpl::GetScriptedSummary(
StructuredData::ObjectSP &callee_wrapper_sp,
const TypeSummaryOptions &options, std::string &retval) {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
+ LLDB_SCOPED_TIMER();
if (!valobj.get()) {
retval.assign("<no object>");
@@ -2210,11 +2277,10 @@ bool ScriptInterpreterPythonImpl::BreakpointCallbackFunction(
return true;
Debugger &debugger = target->GetDebugger();
- ScriptInterpreter *script_interpreter = debugger.GetScriptInterpreter();
ScriptInterpreterPythonImpl *python_interpreter =
- (ScriptInterpreterPythonImpl *)script_interpreter;
+ GetPythonInterpreter(debugger);
- if (!script_interpreter)
+ if (!python_interpreter)
return true;
if (python_function_name && python_function_name[0]) {
@@ -2276,11 +2342,10 @@ bool ScriptInterpreterPythonImpl::WatchpointCallbackFunction(
return true;
Debugger &debugger = target->GetDebugger();
- ScriptInterpreter *script_interpreter = debugger.GetScriptInterpreter();
ScriptInterpreterPythonImpl *python_interpreter =
- (ScriptInterpreterPythonImpl *)script_interpreter;
+ GetPythonInterpreter(debugger);
- if (!script_interpreter)
+ if (!python_interpreter)
return true;
if (python_function_name && python_function_name[0]) {
@@ -2669,7 +2734,10 @@ uint64_t replace_all(std::string &str, const std::string &oldStr,
bool ScriptInterpreterPythonImpl::LoadScriptingModule(
const char *pathname, bool init_session, lldb_private::Status &error,
- StructuredData::ObjectSP *module_sp) {
+ StructuredData::ObjectSP *module_sp, FileSpec extra_search_dir) {
+ namespace fs = llvm::sys::fs;
+ namespace path = llvm::sys::path;
+
if (!pathname || !pathname[0]) {
error.SetErrorString("invalid pathname");
return false;
@@ -2677,24 +2745,55 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule(
lldb::DebuggerSP debugger_sp = m_debugger.shared_from_this();
- {
- FileSpec target_file(pathname);
- FileSystem::Instance().Resolve(target_file);
- FileSystem::Instance().Collect(target_file);
- std::string basename(target_file.GetFilename().GetCString());
+ // Before executing Python code, lock the GIL.
+ Locker py_lock(this,
+ Locker::AcquireLock |
+ (init_session ? Locker::InitSession : 0) | Locker::NoSTDIN,
+ Locker::FreeAcquiredLock |
+ (init_session ? Locker::TearDownSession : 0));
+
+ auto ExtendSysPath = [this](std::string directory) -> llvm::Error {
+ if (directory.empty()) {
+ return llvm::make_error<llvm::StringError>(
+ "invalid directory name", llvm::inconvertibleErrorCode());
+ }
+
+ replace_all(directory, "\\", "\\\\");
+ replace_all(directory, "'", "\\'");
+ // Make sure that Python has "directory" in the search path.
StreamString command_stream;
+ command_stream.Printf("if not (sys.path.__contains__('%s')):\n "
+ "sys.path.insert(1,'%s');\n\n",
+ directory.c_str(), directory.c_str());
+ bool syspath_retval =
+ ExecuteMultipleLines(command_stream.GetData(),
+ ScriptInterpreter::ExecuteScriptOptions()
+ .SetEnableIO(false)
+ .SetSetLLDBGlobals(false))
+ .Success();
+ if (!syspath_retval) {
+ return llvm::make_error<llvm::StringError>(
+ "Python sys.path handling failed", llvm::inconvertibleErrorCode());
+ }
+
+ return llvm::Error::success();
+ };
+
+ std::string module_name(pathname);
+
+ if (extra_search_dir) {
+ if (llvm::Error e = ExtendSysPath(extra_search_dir.GetPath())) {
+ error = std::move(e);
+ return false;
+ }
+ } else {
+ FileSpec module_file(pathname);
+ FileSystem::Instance().Resolve(module_file);
+ FileSystem::Instance().Collect(module_file);
- // Before executing Python code, lock the GIL.
- Locker py_lock(this,
- Locker::AcquireLock |
- (init_session ? Locker::InitSession : 0) |
- Locker::NoSTDIN,
- Locker::FreeAcquiredLock |
- (init_session ? Locker::TearDownSession : 0));
- namespace fs = llvm::sys::fs;
fs::file_status st;
- std::error_code ec = status(target_file.GetPath(), st);
+ std::error_code ec = status(module_file.GetPath(), st);
if (ec || st.type() == fs::file_type::status_error ||
st.type() == fs::file_type::type_unknown ||
@@ -2705,113 +2804,98 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule(
error.SetErrorString("invalid pathname");
return false;
}
- basename = pathname; // not a filename, probably a package of some sort,
- // let it go through
+ // Not a filename, probably a package of some sort, let it go through.
} else if (is_directory(st) || is_regular_file(st)) {
- if (target_file.GetDirectory().IsEmpty()) {
+ if (module_file.GetDirectory().IsEmpty()) {
error.SetErrorString("invalid directory name");
return false;
}
-
- std::string directory = target_file.GetDirectory().GetCString();
- replace_all(directory, "\\", "\\\\");
- replace_all(directory, "'", "\\'");
-
- // now make sure that Python has "directory" in the search path
- StreamString command_stream;
- command_stream.Printf("if not (sys.path.__contains__('%s')):\n "
- "sys.path.insert(1,'%s');\n\n",
- directory.c_str(), directory.c_str());
- bool syspath_retval =
- ExecuteMultipleLines(command_stream.GetData(),
- ScriptInterpreter::ExecuteScriptOptions()
- .SetEnableIO(false)
- .SetSetLLDBGlobals(false))
- .Success();
- if (!syspath_retval) {
- error.SetErrorString("Python sys.path handling failed");
+ if (llvm::Error e =
+ ExtendSysPath(module_file.GetDirectory().GetCString())) {
+ error = std::move(e);
return false;
}
-
- // strip .py or .pyc extension
- ConstString extension = target_file.GetFileNameExtension();
- if (extension) {
- if (llvm::StringRef(extension.GetCString()) == ".py")
- basename.resize(basename.length() - 3);
- else if (llvm::StringRef(extension.GetCString()) == ".pyc")
- basename.resize(basename.length() - 4);
- }
+ module_name = module_file.GetFilename().GetCString();
} else {
error.SetErrorString("no known way to import this module specification");
return false;
}
+ }
- // check if the module is already import-ed
- command_stream.Clear();
- command_stream.Printf("sys.modules.__contains__('%s')", basename.c_str());
- bool does_contain = false;
- // this call will succeed if the module was ever imported in any Debugger
- // in the lifetime of the process in which this LLDB framework is living
- bool was_imported_globally =
- (ExecuteOneLineWithReturn(
- command_stream.GetData(),
- ScriptInterpreterPythonImpl::eScriptReturnTypeBool, &does_contain,
- ScriptInterpreter::ExecuteScriptOptions()
- .SetEnableIO(false)
- .SetSetLLDBGlobals(false)) &&
- does_contain);
- // this call will fail if the module was not imported in this Debugger
- // before
- command_stream.Clear();
- command_stream.Printf("sys.getrefcount(%s)", basename.c_str());
- bool was_imported_locally = GetSessionDictionary()
- .GetItemForKey(PythonString(basename))
- .IsAllocated();
-
- bool was_imported = (was_imported_globally || was_imported_locally);
-
- // now actually do the import
- command_stream.Clear();
-
- if (was_imported) {
- if (!was_imported_locally)
- command_stream.Printf("import %s ; reload_module(%s)", basename.c_str(),
- basename.c_str());
- else
- command_stream.Printf("reload_module(%s)", basename.c_str());
- } else
- command_stream.Printf("import %s", basename.c_str());
-
- error = ExecuteMultipleLines(command_stream.GetData(),
- ScriptInterpreter::ExecuteScriptOptions()
- .SetEnableIO(false)
- .SetSetLLDBGlobals(false));
- if (error.Fail())
- return false;
+ // Strip .py or .pyc extension
+ llvm::StringRef extension = llvm::sys::path::extension(module_name);
+ if (!extension.empty()) {
+ if (extension == ".py")
+ module_name.resize(module_name.length() - 3);
+ else if (extension == ".pyc")
+ module_name.resize(module_name.length() - 4);
+ }
- // if we are here, everything worked
- // call __lldb_init_module(debugger,dict)
- if (!LLDBSwigPythonCallModuleInit(basename.c_str(),
- m_dictionary_name.c_str(), debugger_sp)) {
- error.SetErrorString("calling __lldb_init_module failed");
- return false;
- }
+ // check if the module is already import-ed
+ StreamString command_stream;
+ command_stream.Clear();
+ command_stream.Printf("sys.modules.__contains__('%s')", module_name.c_str());
+ bool does_contain = false;
+ // this call will succeed if the module was ever imported in any Debugger
+ // in the lifetime of the process in which this LLDB framework is living
+ bool was_imported_globally =
+ (ExecuteOneLineWithReturn(
+ command_stream.GetData(),
+ ScriptInterpreterPythonImpl::eScriptReturnTypeBool, &does_contain,
+ ScriptInterpreter::ExecuteScriptOptions()
+ .SetEnableIO(false)
+ .SetSetLLDBGlobals(false)) &&
+ does_contain);
+ // this call will fail if the module was not imported in this Debugger
+ // before
+ command_stream.Clear();
+ command_stream.Printf("sys.getrefcount(%s)", module_name.c_str());
+ bool was_imported_locally = GetSessionDictionary()
+ .GetItemForKey(PythonString(module_name))
+ .IsAllocated();
+
+ bool was_imported = (was_imported_globally || was_imported_locally);
+
+ // now actually do the import
+ command_stream.Clear();
+
+ if (was_imported) {
+ if (!was_imported_locally)
+ command_stream.Printf("import %s ; reload_module(%s)",
+ module_name.c_str(), module_name.c_str());
+ else
+ command_stream.Printf("reload_module(%s)", module_name.c_str());
+ } else
+ command_stream.Printf("import %s", module_name.c_str());
+
+ error = ExecuteMultipleLines(command_stream.GetData(),
+ ScriptInterpreter::ExecuteScriptOptions()
+ .SetEnableIO(false)
+ .SetSetLLDBGlobals(false));
+ if (error.Fail())
+ return false;
- if (module_sp) {
- // everything went just great, now set the module object
- command_stream.Clear();
- command_stream.Printf("%s", basename.c_str());
- void *module_pyobj = nullptr;
- if (ExecuteOneLineWithReturn(
- command_stream.GetData(),
- ScriptInterpreter::eScriptReturnTypeOpaqueObject,
- &module_pyobj) &&
- module_pyobj)
- *module_sp = std::make_shared<StructuredPythonObject>(module_pyobj);
- }
+ // if we are here, everything worked
+ // call __lldb_init_module(debugger,dict)
+ if (!LLDBSwigPythonCallModuleInit(module_name.c_str(),
+ m_dictionary_name.c_str(), debugger_sp)) {
+ error.SetErrorString("calling __lldb_init_module failed");
+ return false;
+ }
- return true;
+ if (module_sp) {
+ // everything went just great, now set the module object
+ command_stream.Clear();
+ command_stream.Printf("%s", module_name.c_str());
+ void *module_pyobj = nullptr;
+ if (ExecuteOneLineWithReturn(
+ command_stream.GetData(),
+ ScriptInterpreter::eScriptReturnTypeOpaqueObject, &module_pyobj) &&
+ module_pyobj)
+ *module_sp = std::make_shared<StructuredPythonObject>(module_pyobj);
}
+
+ return true;
}
bool ScriptInterpreterPythonImpl::IsReservedWord(const char *word) {
@@ -3154,8 +3238,7 @@ void ScriptInterpreterPythonImpl::InitializePrivate() {
g_initialized = true;
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
+ LLDB_SCOPED_TIMER();
// RAII-based initialization which correctly handles multiple-initialization,
// version- specific differences among Python 2 and Python 3, and saving and
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
index 22b2c8152eac..45dad4217005 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
@@ -106,6 +106,14 @@ public:
StructuredData::GenericSP implementor_sp) override;
StructuredData::GenericSP
+ CreateScriptedStopHook(lldb::TargetSP target_sp, const char *class_name,
+ StructuredDataImpl *args_data, Status &error) override;
+
+ bool ScriptedStopHookHandleStop(StructuredData::GenericSP implementor_sp,
+ ExecutionContext &exc_ctx,
+ lldb::StreamSP stream_sp) override;
+
+ StructuredData::GenericSP
CreateFrameRecognizer(const char *class_name) override;
lldb::ValueObjectListSP
@@ -223,10 +231,10 @@ public:
bool RunScriptFormatKeyword(const char *impl_function, ValueObject *value,
std::string &output, Status &error) override;
- bool
- LoadScriptingModule(const char *filename, bool init_session,
- lldb_private::Status &error,
- StructuredData::ObjectSP *module_sp = nullptr) override;
+ bool LoadScriptingModule(const char *filename, bool init_session,
+ lldb_private::Status &error,
+ StructuredData::ObjectSP *module_sp = nullptr,
+ FileSpec extra_search_dir = {}) override;
bool IsReservedWord(const char *word) override;