#include "PythonDataObjects.h"
#include "PythonExceptionState.h"
-#include "ScriptInterpreterPython.h"
+#include "ScriptInterpreterPythonImpl.h"
-#include "lldb/API/SBValue.h"
#include "lldb/API/SBFrame.h"
+#include "lldb/API/SBValue.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Breakpoint/WatchpointOptions.h"
#include "lldb/Core/Communication.h"
using namespace lldb;
using namespace lldb_private;
-#ifndef LLDB_DISABLE_PYTHON
-
// Defined in the SWIG source file
#if PY_MAJOR_VERSION >= 3
extern "C" PyObject *PyInit__lldb(void);
LLDBSWIGPython_GetDynamicSetting(void *module, const char *setting,
const lldb::TargetSP &target_sp);
-#endif
-
static bool g_initialized = false;
namespace {
Py_SetPythonHome(g_python_home);
#else
#if defined(__APPLE__) && PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION == 7
- // For Darwin, the only Python version supported is the one shipped in the OS
- // OS and linked with lldb. Other installation of Python may have higher
+ // For Darwin, the only Python version supported is the one shipped in the
+ // OS OS and linked with lldb. Other installation of Python may have higher
// priorities in the path, overriding PYTHONHOME and causing
// problems/incompatibilities. In order to avoid confusion, always hardcode
// the PythonHome to be right, as it's not going to change.
- static char path[] = "/System/Library/Frameworks/Python.framework/Versions/2.7";
+ static char path[] =
+ "/System/Library/Frameworks/Python.framework/Versions/2.7";
Py_SetPythonHome(path);
#endif
#endif
// executed instead of unlocking GIL with `PyEval_SaveThread`. When
// an another thread calls `PyGILState_Ensure` it would get stuck in deadlock.
#if (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 7) || (PY_MAJOR_VERSION > 3)
-// The only case we should go further and acquire the GIL: it is unlocked.
+ // The only case we should go further and acquire the GIL: it is unlocked.
if (PyGILState_Check())
return;
#endif
PyGILState_STATE m_gil_state;
bool m_was_already_initialized;
};
+} // namespace
+
+void ScriptInterpreterPython::ComputePythonDirForApple(
+ llvm::SmallVectorImpl<char> &path) {
+ auto style = llvm::sys::path::Style::posix;
+
+ llvm::StringRef path_ref(path.begin(), path.size());
+ auto rbegin = llvm::sys::path::rbegin(path_ref, style);
+ auto rend = llvm::sys::path::rend(path_ref);
+ auto framework = std::find(rbegin, rend, "LLDB.framework");
+ if (framework == rend) {
+ ComputePythonDirForPosix(path);
+ return;
+ }
+ path.resize(framework - rend);
+ llvm::sys::path::append(path, style, "LLDB.framework", "Resources", "Python");
+}
+
+void ScriptInterpreterPython::ComputePythonDirForPosix(
+ llvm::SmallVectorImpl<char> &path) {
+ auto style = llvm::sys::path::Style::posix;
+#if defined(LLDB_PYTHON_RELATIVE_LIBDIR)
+ // Build the path by backing out of the lib dir, then building with whatever
+ // the real python interpreter uses. (e.g. lib for most, lib64 on RHEL
+ // x86_64).
+ llvm::sys::path::remove_filename(path, style);
+ llvm::sys::path::append(path, style, LLDB_PYTHON_RELATIVE_LIBDIR);
+#else
+ llvm::sys::path::append(path, style,
+ "python" + llvm::Twine(PY_MAJOR_VERSION) + "." +
+ llvm::Twine(PY_MINOR_VERSION),
+ "site-packages");
+#endif
+}
+
+void ScriptInterpreterPython::ComputePythonDirForWindows(
+ llvm::SmallVectorImpl<char> &path) {
+ auto style = llvm::sys::path::Style::windows;
+ llvm::sys::path::remove_filename(path, style);
+ llvm::sys::path::append(path, style, "lib", "site-packages");
+
+ // This will be injected directly through FileSpec.GetDirectory().SetString(),
+ // so we need to normalize manually.
+ std::replace(path.begin(), path.end(), '\\', '/');
+}
+
+FileSpec ScriptInterpreterPython::GetPythonDir() {
+ static FileSpec g_spec = []() {
+ FileSpec spec = HostInfo::GetShlibDir();
+ if (!spec)
+ return FileSpec();
+ llvm::SmallString<64> path;
+ spec.GetPath(path);
+
+#if defined(__APPLE__)
+ ComputePythonDirForApple(path);
+#elif defined(_WIN32)
+ ComputePythonDirForWindows(path);
+#else
+ ComputePythonDirForPosix(path);
+#endif
+ spec.GetDirectory().SetString(path);
+ return spec;
+ }();
+ return g_spec;
}
-ScriptInterpreterPython::Locker::Locker(ScriptInterpreterPython *py_interpreter,
- uint16_t on_entry, uint16_t on_leave,
- FILE *in, FILE *out, FILE *err)
+lldb_private::ConstString ScriptInterpreterPython::GetPluginNameStatic() {
+ static ConstString g_name("script-python");
+ return g_name;
+}
+
+const char *ScriptInterpreterPython::GetPluginDescriptionStatic() {
+ return "Embedded Python interpreter";
+}
+
+void ScriptInterpreterPython::Initialize() {
+ static llvm::once_flag g_once_flag;
+
+ llvm::call_once(g_once_flag, []() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(),
+ lldb::eScriptLanguagePython,
+ ScriptInterpreterPythonImpl::CreateInstance);
+ });
+}
+
+void ScriptInterpreterPython::Terminate() {}
+
+ScriptInterpreterPythonImpl::Locker::Locker(
+ ScriptInterpreterPythonImpl *py_interpreter, uint16_t on_entry,
+ uint16_t on_leave, FILE *in, FILE *out, FILE *err)
: ScriptInterpreterLocker(),
m_teardown_session((on_leave & TearDownSession) == TearDownSession),
m_python_interpreter(py_interpreter) {
}
}
-bool ScriptInterpreterPython::Locker::DoAcquireLock() {
+bool ScriptInterpreterPythonImpl::Locker::DoAcquireLock() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT));
m_GILState = PyGILState_Ensure();
LLDB_LOGV(log, "Ensured PyGILState. Previous state = {0}locked",
return true;
}
-bool ScriptInterpreterPython::Locker::DoInitSession(uint16_t on_entry_flags,
- FILE *in, FILE *out,
- FILE *err) {
+bool ScriptInterpreterPythonImpl::Locker::DoInitSession(uint16_t on_entry_flags,
+ FILE *in, FILE *out,
+ FILE *err) {
if (!m_python_interpreter)
return false;
return m_python_interpreter->EnterSession(on_entry_flags, in, out, err);
}
-bool ScriptInterpreterPython::Locker::DoFreeLock() {
+bool ScriptInterpreterPythonImpl::Locker::DoFreeLock() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT));
LLDB_LOGV(log, "Releasing PyGILState. Returning to state = {0}locked",
m_GILState == PyGILState_UNLOCKED ? "un" : "");
return true;
}
-bool ScriptInterpreterPython::Locker::DoTearDownSession() {
+bool ScriptInterpreterPythonImpl::Locker::DoTearDownSession() {
if (!m_python_interpreter)
return false;
m_python_interpreter->LeaveSession();
return true;
}
-ScriptInterpreterPython::Locker::~Locker() {
+ScriptInterpreterPythonImpl::Locker::~Locker() {
if (m_teardown_session)
DoTearDownSession();
DoFreeLock();
}
-ScriptInterpreterPython::ScriptInterpreterPython(
+ScriptInterpreterPythonImpl::ScriptInterpreterPythonImpl(
CommandInterpreter &interpreter)
- : ScriptInterpreter(interpreter, eScriptLanguagePython),
- IOHandlerDelegateMultiline("DONE"), m_saved_stdin(), m_saved_stdout(),
+ : ScriptInterpreterPython(interpreter), m_saved_stdin(), m_saved_stdout(),
m_saved_stderr(), m_main_module(),
m_session_dict(PyInitialValue::Invalid),
m_sys_module_dict(PyInitialValue::Invalid), m_run_one_line_function(),
StreamString run_string;
run_string.Printf("%s = dict()", m_dictionary_name.c_str());
- Locker locker(this, ScriptInterpreterPython::Locker::AcquireLock,
- ScriptInterpreterPython::Locker::FreeAcquiredLock);
+ Locker locker(this, Locker::AcquireLock, Locker::FreeAcquiredLock);
PyRun_SimpleString(run_string.GetData());
run_string.Clear();
PyRun_SimpleString(run_string.GetData());
}
-ScriptInterpreterPython::~ScriptInterpreterPython() {
+ScriptInterpreterPythonImpl::~ScriptInterpreterPythonImpl() {
// the session dictionary may hold objects with complex state which means
// that they may need to be torn down with some level of smarts and that, in
// turn, requires a valid thread state force Python to procure itself such a
PyGILState_Release(gil_state);
}
-void ScriptInterpreterPython::Initialize() {
- static llvm::once_flag g_once_flag;
-
- llvm::call_once(g_once_flag, []() {
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- lldb::eScriptLanguagePython, CreateInstance);
- });
-}
-
-void ScriptInterpreterPython::Terminate() {}
-
-lldb::ScriptInterpreterSP
-ScriptInterpreterPython::CreateInstance(CommandInterpreter &interpreter) {
- return std::make_shared<ScriptInterpreterPython>(interpreter);
-}
-
-lldb_private::ConstString ScriptInterpreterPython::GetPluginNameStatic() {
- static ConstString g_name("script-python");
- return g_name;
-}
-
-const char *ScriptInterpreterPython::GetPluginDescriptionStatic() {
- return "Embedded Python interpreter";
-}
-
-void ScriptInterpreterPython::ComputePythonDirForApple(
- llvm::SmallVectorImpl<char> &path) {
- auto style = llvm::sys::path::Style::posix;
-
- llvm::StringRef path_ref(path.begin(), path.size());
- auto rbegin = llvm::sys::path::rbegin(path_ref, style);
- auto rend = llvm::sys::path::rend(path_ref);
- auto framework = std::find(rbegin, rend, "LLDB.framework");
- if (framework == rend) {
- ComputePythonDirForPosix(path);
- return;
- }
- path.resize(framework - rend);
- llvm::sys::path::append(path, style, "LLDB.framework", "Resources", "Python");
-}
-
-void ScriptInterpreterPython::ComputePythonDirForPosix(
- llvm::SmallVectorImpl<char> &path) {
- auto style = llvm::sys::path::Style::posix;
-#if defined(LLDB_PYTHON_RELATIVE_LIBDIR)
- // Build the path by backing out of the lib dir, then building with whatever
- // the real python interpreter uses. (e.g. lib for most, lib64 on RHEL
- // x86_64).
- llvm::sys::path::remove_filename(path, style);
- llvm::sys::path::append(path, style, LLDB_PYTHON_RELATIVE_LIBDIR);
-#else
- llvm::sys::path::append(path, style,
- "python" + llvm::Twine(PY_MAJOR_VERSION) + "." +
- llvm::Twine(PY_MINOR_VERSION),
- "site-packages");
-#endif
-}
-
-void ScriptInterpreterPython::ComputePythonDirForWindows(
- llvm::SmallVectorImpl<char> &path) {
- auto style = llvm::sys::path::Style::windows;
- llvm::sys::path::remove_filename(path, style);
- llvm::sys::path::append(path, style, "lib", "site-packages");
-
- // This will be injected directly through FileSpec.GetDirectory().SetString(),
- // so we need to normalize manually.
- std::replace(path.begin(), path.end(), '\\', '/');
-}
-
-FileSpec ScriptInterpreterPython::GetPythonDir() {
- static FileSpec g_spec = []() {
- FileSpec spec = HostInfo::GetShlibDir();
- if (!spec)
- return FileSpec();
- llvm::SmallString<64> path;
- spec.GetPath(path);
-
-#if defined(__APPLE__)
- ComputePythonDirForApple(path);
-#elif defined(_WIN32)
- ComputePythonDirForWindows(path);
-#else
- ComputePythonDirForPosix(path);
-#endif
- spec.GetDirectory().SetString(path);
- return spec;
- }();
- return g_spec;
-}
-
-lldb_private::ConstString ScriptInterpreterPython::GetPluginName() {
+lldb_private::ConstString ScriptInterpreterPythonImpl::GetPluginName() {
return GetPluginNameStatic();
}
-uint32_t ScriptInterpreterPython::GetPluginVersion() { return 1; }
+uint32_t ScriptInterpreterPythonImpl::GetPluginVersion() { return 1; }
-void ScriptInterpreterPython::IOHandlerActivated(IOHandler &io_handler, bool interactive) {
+void ScriptInterpreterPythonImpl::IOHandlerActivated(IOHandler &io_handler,
+ bool interactive) {
const char *instructions = nullptr;
switch (m_active_io_handler) {
}
}
-void ScriptInterpreterPython::IOHandlerInputComplete(IOHandler &io_handler,
- std::string &data) {
+void ScriptInterpreterPythonImpl::IOHandlerInputComplete(IOHandler &io_handler,
+ std::string &data) {
io_handler.SetIsDone(true);
bool batch_mode = m_interpreter.GetBatchCommandMode();
auto baton_sp = std::make_shared<BreakpointOptions::CommandBaton>(
std::move(data_up));
bp_options->SetCallback(
- ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp);
+ ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp);
} else if (!batch_mode) {
StreamFileSP error_sp = io_handler.GetErrorStreamFile();
if (error_sp) {
auto baton_sp =
std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up));
wp_options->SetCallback(
- ScriptInterpreterPython::WatchpointCallbackFunction, baton_sp);
+ ScriptInterpreterPythonImpl::WatchpointCallbackFunction, baton_sp);
} else if (!batch_mode) {
StreamFileSP error_sp = io_handler.GetErrorStreamFile();
if (error_sp) {
}
}
-void ScriptInterpreterPython::ResetOutputFileHandle(FILE *fh) {}
+lldb::ScriptInterpreterSP
+ScriptInterpreterPythonImpl::CreateInstance(CommandInterpreter &interpreter) {
+ return std::make_shared<ScriptInterpreterPythonImpl>(interpreter);
+}
-void ScriptInterpreterPython::SaveTerminalState(int fd) {
+void ScriptInterpreterPythonImpl::ResetOutputFileHandle(FILE *fh) {}
+
+void ScriptInterpreterPythonImpl::SaveTerminalState(int fd) {
// Python mucks with the terminal state of STDIN. If we can possibly avoid
// this by setting the file handles up correctly prior to entering the
// interpreter we should. For now we save and restore the terminal state on
m_terminal_state.Save(fd, false);
}
-void ScriptInterpreterPython::RestoreTerminalState() {
+void ScriptInterpreterPythonImpl::RestoreTerminalState() {
// Python mucks with the terminal state of STDIN. If we can possibly avoid
// this by setting the file handles up correctly prior to entering the
// interpreter we should. For now we save and restore the terminal state on
m_terminal_state.Restore();
}
-void ScriptInterpreterPython::LeaveSession() {
+void ScriptInterpreterPythonImpl::LeaveSession() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT));
if (log)
- log->PutCString("ScriptInterpreterPython::LeaveSession()");
+ log->PutCString("ScriptInterpreterPythonImpl::LeaveSession()");
// checking that we have a valid thread state - since we use our own
// threading and locking in some (rare) cases during cleanup Python may end
m_session_is_active = false;
}
-bool ScriptInterpreterPython::SetStdHandle(File &file, const char *py_name,
- PythonFile &save_file,
- const char *mode) {
+bool ScriptInterpreterPythonImpl::SetStdHandle(File &file, const char *py_name,
+ PythonFile &save_file,
+ const char *mode) {
if (file.IsValid()) {
// Flush the file before giving it to python to avoid interleaved output.
file.Flush();
return false;
}
-bool ScriptInterpreterPython::EnterSession(uint16_t on_entry_flags, FILE *in,
- FILE *out, FILE *err) {
+bool ScriptInterpreterPythonImpl::EnterSession(uint16_t on_entry_flags,
+ FILE *in, FILE *out, FILE *err) {
// If we have already entered the session, without having officially 'left'
// it, then there is no need to 'enter' it again.
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT));
if (m_session_is_active) {
if (log)
log->Printf(
- "ScriptInterpreterPython::EnterSession(on_entry_flags=0x%" PRIx16
+ "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16
") session is already active, returning without doing anything",
on_entry_flags);
return false;
if (log)
log->Printf(
- "ScriptInterpreterPython::EnterSession(on_entry_flags=0x%" PRIx16 ")",
+ "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16
+ ")",
on_entry_flags);
m_session_is_active = true;
return true;
}
-PythonObject &ScriptInterpreterPython::GetMainModule() {
+PythonObject &ScriptInterpreterPythonImpl::GetMainModule() {
if (!m_main_module.IsValid())
m_main_module.Reset(PyRefType::Borrowed, PyImport_AddModule("__main__"));
return m_main_module;
}
-PythonDictionary &ScriptInterpreterPython::GetSessionDictionary() {
+PythonDictionary &ScriptInterpreterPythonImpl::GetSessionDictionary() {
if (m_session_dict.IsValid())
return m_session_dict;
return m_session_dict;
}
-PythonDictionary &ScriptInterpreterPython::GetSysModuleDictionary() {
+PythonDictionary &ScriptInterpreterPythonImpl::GetSysModuleDictionary() {
if (m_sys_module_dict.IsValid())
return m_sys_module_dict;
return sstr.GetString();
}
-bool ScriptInterpreterPython::GetEmbeddedInterpreterModuleObjects() {
+bool ScriptInterpreterPythonImpl::GetEmbeddedInterpreterModuleObjects() {
if (m_run_one_line_function.IsValid())
return true;
}
}
-bool ScriptInterpreterPython::ExecuteOneLine(
+bool ScriptInterpreterPythonImpl::ExecuteOneLine(
llvm::StringRef command, CommandReturnObject *result,
const ExecuteScriptOptions &options) {
std::string command_str = command.str();
StreamFileSP output_file_sp;
StreamFileSP error_file_sp;
Communication output_comm(
- "lldb.ScriptInterpreterPython.ExecuteOneLine.comm");
+ "lldb.ScriptInterpreterPythonImpl.ExecuteOneLine.comm");
bool join_read_thread = false;
if (options.GetEnableIO()) {
if (result) {
// happen.
Locker locker(
this,
- ScriptInterpreterPython::Locker::AcquireLock |
- ScriptInterpreterPython::Locker::InitSession |
- (options.GetSetLLDBGlobals()
- ? ScriptInterpreterPython::Locker::InitGlobals
- : 0) |
+ Locker::AcquireLock | Locker::InitSession |
+ (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) |
((result && result->GetInteractive()) ? 0 : Locker::NoSTDIN),
- ScriptInterpreterPython::Locker::FreeAcquiredLock |
- ScriptInterpreterPython::Locker::TearDownSession,
- in_file, out_file, err_file);
+ Locker::FreeAcquiredLock | Locker::TearDownSession, in_file, out_file,
+ err_file);
// Find the correct script interpreter dictionary in the main module.
PythonDictionary &session_dict = GetSessionDictionary();
return false;
}
-class IOHandlerPythonInterpreter : public IOHandler {
-public:
- IOHandlerPythonInterpreter(Debugger &debugger,
- ScriptInterpreterPython *python)
- : IOHandler(debugger, IOHandler::Type::PythonInterpreter),
- m_python(python) {}
-
- ~IOHandlerPythonInterpreter() override {}
-
- ConstString GetControlSequence(char ch) override {
- if (ch == 'd')
- return ConstString("quit()\n");
- return ConstString();
- }
-
- void Run() override {
- if (m_python) {
- int stdin_fd = GetInputFD();
- if (stdin_fd >= 0) {
- Terminal terminal(stdin_fd);
- TerminalState terminal_state;
- const bool is_a_tty = terminal.IsATerminal();
-
- if (is_a_tty) {
- terminal_state.Save(stdin_fd, false);
- terminal.SetCanonical(false);
- terminal.SetEcho(true);
- }
-
- ScriptInterpreterPython::Locker locker(
- m_python, ScriptInterpreterPython::Locker::AcquireLock |
- ScriptInterpreterPython::Locker::InitSession |
- ScriptInterpreterPython::Locker::InitGlobals,
- ScriptInterpreterPython::Locker::FreeAcquiredLock |
- ScriptInterpreterPython::Locker::TearDownSession);
-
- // The following call drops into the embedded interpreter loop and
- // stays there until the user chooses to exit from the Python
- // interpreter. This embedded interpreter will, as any Python code that
- // performs I/O, unlock the GIL before a system call that can hang, and
- // lock it when the syscall has returned.
-
- // We need to surround the call to the embedded interpreter with calls
- // to PyGILState_Ensure and PyGILState_Release (using the Locker
- // above). This is because Python has a global lock which must be held
- // whenever we want to touch any Python objects. Otherwise, if the user
- // calls Python code, the interpreter state will be off, and things
- // could hang (it's happened before).
-
- StreamString run_string;
- run_string.Printf("run_python_interpreter (%s)",
- m_python->GetDictionaryName());
- PyRun_SimpleString(run_string.GetData());
-
- if (is_a_tty)
- terminal_state.Restore();
- }
- }
- SetIsDone(true);
- }
-
- void Cancel() override {}
-
- bool Interrupt() override { return m_python->Interrupt(); }
-
- void GotEOF() override {}
-
-protected:
- ScriptInterpreterPython *m_python;
-};
-
-void ScriptInterpreterPython::ExecuteInterpreterLoop() {
+void ScriptInterpreterPythonImpl::ExecuteInterpreterLoop() {
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
}
}
-bool ScriptInterpreterPython::Interrupt() {
+bool ScriptInterpreterPythonImpl::Interrupt() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT));
if (IsExecutingPython()) {
PyThreadState_Swap(state);
int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt);
if (log)
- log->Printf("ScriptInterpreterPython::Interrupt() sending "
+ log->Printf("ScriptInterpreterPythonImpl::Interrupt() sending "
"PyExc_KeyboardInterrupt (tid = %li, num_threads = %i)...",
tid, num_threads);
return true;
}
}
if (log)
- log->Printf("ScriptInterpreterPython::Interrupt() python code not running, "
- "can't interrupt");
+ log->Printf(
+ "ScriptInterpreterPythonImpl::Interrupt() python code not running, "
+ "can't interrupt");
return false;
}
-bool ScriptInterpreterPython::ExecuteOneLineWithReturn(
+bool ScriptInterpreterPythonImpl::ExecuteOneLineWithReturn(
llvm::StringRef in_string, ScriptInterpreter::ScriptReturnType return_type,
void *ret_value, const ExecuteScriptOptions &options) {
- Locker locker(this, ScriptInterpreterPython::Locker::AcquireLock |
- ScriptInterpreterPython::Locker::InitSession |
- (options.GetSetLLDBGlobals()
- ? ScriptInterpreterPython::Locker::InitGlobals
- : 0) |
- Locker::NoSTDIN,
- ScriptInterpreterPython::Locker::FreeAcquiredLock |
- ScriptInterpreterPython::Locker::TearDownSession);
+ Locker locker(this,
+ Locker::AcquireLock | Locker::InitSession |
+ (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) |
+ Locker::NoSTDIN,
+ Locker::FreeAcquiredLock | Locker::TearDownSession);
PythonObject py_return;
PythonObject &main_module = GetMainModule();
return ret_success;
}
-Status ScriptInterpreterPython::ExecuteMultipleLines(
+Status ScriptInterpreterPythonImpl::ExecuteMultipleLines(
const char *in_string, const ExecuteScriptOptions &options) {
Status error;
- Locker locker(this, ScriptInterpreterPython::Locker::AcquireLock |
- ScriptInterpreterPython::Locker::InitSession |
- (options.GetSetLLDBGlobals()
- ? ScriptInterpreterPython::Locker::InitGlobals
- : 0) |
- Locker::NoSTDIN,
- ScriptInterpreterPython::Locker::FreeAcquiredLock |
- ScriptInterpreterPython::Locker::TearDownSession);
+ Locker locker(this,
+ Locker::AcquireLock | Locker::InitSession |
+ (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) |
+ Locker::NoSTDIN,
+ Locker::FreeAcquiredLock | Locker::TearDownSession);
PythonObject return_value;
PythonObject &main_module = GetMainModule();
return error;
}
-void ScriptInterpreterPython::CollectDataForBreakpointCommandCallback(
+void ScriptInterpreterPythonImpl::CollectDataForBreakpointCommandCallback(
std::vector<BreakpointOptions *> &bp_options_vec,
CommandReturnObject &result) {
m_active_io_handler = eIOHandlerBreakpoint;
&bp_options_vec);
}
-void ScriptInterpreterPython::CollectDataForWatchpointCommandCallback(
+void ScriptInterpreterPythonImpl::CollectDataForWatchpointCommandCallback(
WatchpointOptions *wp_options, CommandReturnObject &result) {
m_active_io_handler = eIOHandlerWatchpoint;
m_interpreter.GetPythonCommandsFromIOHandler(" ", *this, true, wp_options);
}
-void ScriptInterpreterPython::SetBreakpointCommandCallbackFunction(
+void ScriptInterpreterPythonImpl::SetBreakpointCommandCallbackFunction(
BreakpointOptions *bp_options, const char *function_name) {
// For now just cons up a oneliner that calls the provided function.
std::string oneliner("return ");
bp_options, oneliner.c_str());
}
-Status ScriptInterpreterPython::SetBreakpointCommandCallback(
+Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback(
BreakpointOptions *bp_options,
std::unique_ptr<BreakpointOptions::CommandData> &cmd_data_up) {
Status error;
}
auto baton_sp =
std::make_shared<BreakpointOptions::CommandBaton>(std::move(cmd_data_up));
- bp_options->SetCallback(ScriptInterpreterPython::BreakpointCallbackFunction,
- baton_sp);
+ bp_options->SetCallback(
+ ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp);
return error;
}
// Set a Python one-liner as the callback for the breakpoint.
-Status ScriptInterpreterPython::SetBreakpointCommandCallback(
+Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback(
BreakpointOptions *bp_options, const char *command_body_text) {
auto data_up = llvm::make_unique<CommandDataPython>();
if (error.Success()) {
auto baton_sp =
std::make_shared<BreakpointOptions::CommandBaton>(std::move(data_up));
- bp_options->SetCallback(ScriptInterpreterPython::BreakpointCallbackFunction,
- baton_sp);
+ bp_options->SetCallback(
+ ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp);
return error;
} else
return error;
}
// Set a Python one-liner as the callback for the watchpoint.
-void ScriptInterpreterPython::SetWatchpointCommandCallback(
+void ScriptInterpreterPythonImpl::SetWatchpointCommandCallback(
WatchpointOptions *wp_options, const char *oneliner) {
auto data_up = llvm::make_unique<WatchpointOptions::CommandData>();
data_up->script_source)) {
auto baton_sp =
std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up));
- wp_options->SetCallback(ScriptInterpreterPython::WatchpointCallbackFunction,
- baton_sp);
+ wp_options->SetCallback(
+ ScriptInterpreterPythonImpl::WatchpointCallbackFunction, baton_sp);
}
return;
}
-Status ScriptInterpreterPython::ExportFunctionDefinitionToInterpreter(
+Status ScriptInterpreterPythonImpl::ExportFunctionDefinitionToInterpreter(
StringList &function_def) {
// Convert StringList to one long, newline delimited, const char *.
std::string function_def_string(function_def.CopyList());
return error;
}
-Status ScriptInterpreterPython::GenerateFunction(const char *signature,
- const StringList &input) {
+Status ScriptInterpreterPythonImpl::GenerateFunction(const char *signature,
+ const StringList &input) {
Status error;
int num_lines = input.GetSize();
if (num_lines == 0) {
return error;
}
-bool ScriptInterpreterPython::GenerateTypeScriptFunction(
+bool ScriptInterpreterPythonImpl::GenerateTypeScriptFunction(
StringList &user_input, std::string &output, const void *name_token) {
static uint32_t num_created_functions = 0;
user_input.RemoveBlankLines();
return true;
}
-bool ScriptInterpreterPython::GenerateScriptAliasFunction(
+bool ScriptInterpreterPythonImpl::GenerateScriptAliasFunction(
StringList &user_input, std::string &output) {
static uint32_t num_created_functions = 0;
user_input.RemoveBlankLines();
return true;
}
-bool ScriptInterpreterPython::GenerateTypeSynthClass(StringList &user_input,
- std::string &output,
- const void *name_token) {
+bool ScriptInterpreterPythonImpl::GenerateTypeSynthClass(
+ StringList &user_input, std::string &output, const void *name_token) {
static uint32_t num_created_classes = 0;
user_input.RemoveBlankLines();
int num_lines = user_input.GetSize();
return true;
}
-StructuredData::GenericSP ScriptInterpreterPython::CreateFrameRecognizer(
- const char *class_name) {
+StructuredData::GenericSP
+ScriptInterpreterPythonImpl::CreateFrameRecognizer(const char *class_name) {
if (class_name == nullptr || class_name[0] == '\0')
return StructuredData::GenericSP();
return StructuredData::GenericSP(new StructuredPythonObject(ret_val));
}
-lldb::ValueObjectListSP ScriptInterpreterPython::GetRecognizedArguments(
+lldb::ValueObjectListSP ScriptInterpreterPythonImpl::GetRecognizedArguments(
const StructuredData::ObjectSP &os_plugin_object_sp,
lldb::StackFrameSP frame_sp) {
Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
- if (!os_plugin_object_sp) return ValueObjectListSP();
+ if (!os_plugin_object_sp)
+ return ValueObjectListSP();
StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
- if (!generic) return nullptr;
+ if (!generic)
+ return nullptr;
PythonObject implementor(PyRefType::Borrowed,
(PyObject *)generic->GetValue());
- if (!implementor.IsAllocated()) return ValueObjectListSP();
+ if (!implementor.IsAllocated())
+ return ValueObjectListSP();
PythonObject py_return(PyRefType::Owned,
(PyObject *)LLDBSwigPython_GetRecognizedArguments(
lldb::SBValue *sb_value_ptr =
(lldb::SBValue *)LLDBSWIGPython_CastPyObjectToSBValue(item);
auto valobj_sp = LLDBSWIGPython_GetValueObjectSPFromSBValue(sb_value_ptr);
- if (valobj_sp) result->Append(valobj_sp);
+ if (valobj_sp)
+ result->Append(valobj_sp);
}
return result;
}
return ValueObjectListSP();
}
-StructuredData::GenericSP ScriptInterpreterPython::OSPlugin_CreatePluginObject(
+StructuredData::GenericSP
+ScriptInterpreterPythonImpl::OSPlugin_CreatePluginObject(
const char *class_name, lldb::ProcessSP process_sp) {
if (class_name == nullptr || class_name[0] == '\0')
return StructuredData::GenericSP();
return StructuredData::GenericSP(new StructuredPythonObject(ret_val));
}
-StructuredData::DictionarySP ScriptInterpreterPython::OSPlugin_RegisterInfo(
+StructuredData::DictionarySP ScriptInterpreterPythonImpl::OSPlugin_RegisterInfo(
StructuredData::ObjectSP os_plugin_object_sp) {
Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
return StructuredData::DictionarySP();
}
-StructuredData::ArraySP ScriptInterpreterPython::OSPlugin_ThreadsInfo(
+StructuredData::ArraySP ScriptInterpreterPythonImpl::OSPlugin_ThreadsInfo(
StructuredData::ObjectSP os_plugin_object_sp) {
Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
template <> const char *GetPythonValueFormatString(float t) { return "f"; }
template <> const char *GetPythonValueFormatString(double t) { return "d"; }
-StructuredData::StringSP ScriptInterpreterPython::OSPlugin_RegisterContextData(
+StructuredData::StringSP
+ScriptInterpreterPythonImpl::OSPlugin_RegisterContextData(
StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid) {
Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
return StructuredData::StringSP();
}
-StructuredData::DictionarySP ScriptInterpreterPython::OSPlugin_CreateThread(
+StructuredData::DictionarySP ScriptInterpreterPythonImpl::OSPlugin_CreateThread(
StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid,
lldb::addr_t context) {
Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
return StructuredData::DictionarySP();
}
-StructuredData::ObjectSP ScriptInterpreterPython::CreateScriptedThreadPlan(
+StructuredData::ObjectSP ScriptInterpreterPythonImpl::CreateScriptedThreadPlan(
const char *class_name, lldb::ThreadPlanSP thread_plan_sp) {
if (class_name == nullptr || class_name[0] == '\0')
return StructuredData::ObjectSP();
Debugger &debugger = thread_plan_sp->GetTarget().GetDebugger();
ScriptInterpreter *script_interpreter =
debugger.GetCommandInterpreter().GetScriptInterpreter();
- ScriptInterpreterPython *python_interpreter =
- static_cast<ScriptInterpreterPython *>(script_interpreter);
+ ScriptInterpreterPythonImpl *python_interpreter =
+ static_cast<ScriptInterpreterPythonImpl *>(script_interpreter);
if (!script_interpreter)
return StructuredData::ObjectSP();
return StructuredData::ObjectSP(new StructuredPythonObject(ret_val));
}
-bool ScriptInterpreterPython::ScriptedThreadPlanExplainsStop(
+bool ScriptInterpreterPythonImpl::ScriptedThreadPlanExplainsStop(
StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) {
bool explains_stop = true;
StructuredData::Generic *generic = nullptr;
return explains_stop;
}
-bool ScriptInterpreterPython::ScriptedThreadPlanShouldStop(
+bool ScriptInterpreterPythonImpl::ScriptedThreadPlanShouldStop(
StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) {
bool should_stop = true;
StructuredData::Generic *generic = nullptr;
return should_stop;
}
-bool ScriptInterpreterPython::ScriptedThreadPlanIsStale(
+bool ScriptInterpreterPythonImpl::ScriptedThreadPlanIsStale(
StructuredData::ObjectSP implementor_sp, bool &script_error) {
bool is_stale = true;
StructuredData::Generic *generic = nullptr;
return is_stale;
}
-lldb::StateType ScriptInterpreterPython::ScriptedThreadPlanGetRunState(
+lldb::StateType ScriptInterpreterPythonImpl::ScriptedThreadPlanGetRunState(
StructuredData::ObjectSP implementor_sp, bool &script_error) {
bool should_step = false;
StructuredData::Generic *generic = nullptr;
}
StructuredData::GenericSP
-ScriptInterpreterPython::CreateScriptedBreakpointResolver(
- const char *class_name,
- StructuredDataImpl *args_data,
+ScriptInterpreterPythonImpl::CreateScriptedBreakpointResolver(
+ const char *class_name, StructuredDataImpl *args_data,
lldb::BreakpointSP &bkpt_sp) {
if (class_name == nullptr || class_name[0] == '\0')
Debugger &debugger = bkpt_sp->GetTarget().GetDebugger();
ScriptInterpreter *script_interpreter =
debugger.GetCommandInterpreter().GetScriptInterpreter();
- ScriptInterpreterPython *python_interpreter =
- static_cast<ScriptInterpreterPython *>(script_interpreter);
+ ScriptInterpreterPythonImpl *python_interpreter =
+ static_cast<ScriptInterpreterPythonImpl *>(script_interpreter);
if (!script_interpreter)
return StructuredData::GenericSP();
return StructuredData::GenericSP(new StructuredPythonObject(ret_val));
}
-bool
-ScriptInterpreterPython::ScriptedBreakpointResolverSearchCallback(
- StructuredData::GenericSP implementor_sp,
- SymbolContext *sym_ctx) {
+bool ScriptInterpreterPythonImpl::ScriptedBreakpointResolverSearchCallback(
+ StructuredData::GenericSP implementor_sp, SymbolContext *sym_ctx) {
bool should_continue = false;
if (implementor_sp) {
}
lldb::SearchDepth
-ScriptInterpreterPython::ScriptedBreakpointResolverSearchDepth(
+ScriptInterpreterPythonImpl::ScriptedBreakpointResolverSearchDepth(
StructuredData::GenericSP implementor_sp) {
int depth_as_int = lldb::eSearchDepthModule;
if (implementor_sp) {
return lldb::eSearchDepthModule;
if (depth_as_int <= lldb::kLastSearchDepthKind)
- return (lldb::SearchDepth) depth_as_int;
+ return (lldb::SearchDepth)depth_as_int;
else
return lldb::eSearchDepthModule;
}
StructuredData::ObjectSP
-ScriptInterpreterPython::LoadPluginModule(const FileSpec &file_spec,
- lldb_private::Status &error) {
+ScriptInterpreterPythonImpl::LoadPluginModule(const FileSpec &file_spec,
+ lldb_private::Status &error) {
if (!FileSystem::Instance().Exists(file_spec)) {
error.SetErrorString("no such file");
return StructuredData::ObjectSP();
return StructuredData::ObjectSP();
}
-StructuredData::DictionarySP ScriptInterpreterPython::GetDynamicSettings(
+StructuredData::DictionarySP ScriptInterpreterPythonImpl::GetDynamicSettings(
StructuredData::ObjectSP plugin_module_sp, Target *target,
const char *setting_name, lldb_private::Status &error) {
if (!plugin_module_sp || !target || !setting_name || !setting_name[0])
}
StructuredData::ObjectSP
-ScriptInterpreterPython::CreateSyntheticScriptedProvider(
+ScriptInterpreterPythonImpl::CreateSyntheticScriptedProvider(
const char *class_name, lldb::ValueObjectSP valobj) {
if (class_name == nullptr || class_name[0] == '\0')
return StructuredData::ObjectSP();
Debugger &debugger = target->GetDebugger();
ScriptInterpreter *script_interpreter =
debugger.GetCommandInterpreter().GetScriptInterpreter();
- ScriptInterpreterPython *python_interpreter =
- (ScriptInterpreterPython *)script_interpreter;
+ ScriptInterpreterPythonImpl *python_interpreter =
+ (ScriptInterpreterPythonImpl *)script_interpreter;
if (!script_interpreter)
return StructuredData::ObjectSP();
}
StructuredData::GenericSP
-ScriptInterpreterPython::CreateScriptCommandObject(const char *class_name) {
+ScriptInterpreterPythonImpl::CreateScriptCommandObject(const char *class_name) {
DebuggerSP debugger_sp(
GetCommandInterpreter().GetDebugger().shared_from_this());
return StructuredData::GenericSP(new StructuredPythonObject(ret_val));
}
-bool ScriptInterpreterPython::GenerateTypeScriptFunction(
+bool ScriptInterpreterPythonImpl::GenerateTypeScriptFunction(
const char *oneliner, std::string &output, const void *name_token) {
StringList input;
input.SplitIntoLines(oneliner, strlen(oneliner));
return GenerateTypeScriptFunction(input, output, name_token);
}
-bool ScriptInterpreterPython::GenerateTypeSynthClass(const char *oneliner,
- std::string &output,
- const void *name_token) {
+bool ScriptInterpreterPythonImpl::GenerateTypeSynthClass(
+ const char *oneliner, std::string &output, const void *name_token) {
StringList input;
input.SplitIntoLines(oneliner, strlen(oneliner));
return GenerateTypeSynthClass(input, output, name_token);
}
-Status ScriptInterpreterPython::GenerateBreakpointCommandCallbackData(
+Status ScriptInterpreterPythonImpl::GenerateBreakpointCommandCallbackData(
StringList &user_input, std::string &output) {
static uint32_t num_created_functions = 0;
user_input.RemoveBlankLines();
return error;
}
-bool ScriptInterpreterPython::GenerateWatchpointCommandCallbackData(
+bool ScriptInterpreterPythonImpl::GenerateWatchpointCommandCallbackData(
StringList &user_input, std::string &output) {
static uint32_t num_created_functions = 0;
user_input.RemoveBlankLines();
return true;
}
-bool ScriptInterpreterPython::GetScriptedSummary(
+bool ScriptInterpreterPythonImpl::GetScriptedSummary(
const char *python_function_name, lldb::ValueObjectSP valobj,
StructuredData::ObjectSP &callee_wrapper_sp,
const TypeSummaryOptions &options, std::string &retval) {
return ret_val;
}
-void ScriptInterpreterPython::Clear() {
+void ScriptInterpreterPythonImpl::Clear() {
// Release any global variables that might have strong references to
// LLDB objects when clearing the python script interpreter.
- Locker locker(this, ScriptInterpreterPython::Locker::AcquireLock,
- ScriptInterpreterPython::Locker::FreeAcquiredLock);
+ Locker locker(this, Locker::AcquireLock, Locker::FreeAcquiredLock);
// This may be called as part of Py_Finalize. In that case the modules are
// destroyed in random order and we can't guarantee that we can access these.
"= None; lldb.thread = None; lldb.frame = None");
}
-bool ScriptInterpreterPython::BreakpointCallbackFunction(
+bool ScriptInterpreterPythonImpl::BreakpointCallbackFunction(
void *baton, StoppointCallbackContext *context, user_id_t break_id,
user_id_t break_loc_id) {
CommandDataPython *bp_option_data = (CommandDataPython *)baton;
Debugger &debugger = target->GetDebugger();
ScriptInterpreter *script_interpreter =
debugger.GetCommandInterpreter().GetScriptInterpreter();
- ScriptInterpreterPython *python_interpreter =
- (ScriptInterpreterPython *)script_interpreter;
+ ScriptInterpreterPythonImpl *python_interpreter =
+ (ScriptInterpreterPythonImpl *)script_interpreter;
if (!script_interpreter)
return true;
return true;
}
-bool ScriptInterpreterPython::WatchpointCallbackFunction(
+bool ScriptInterpreterPythonImpl::WatchpointCallbackFunction(
void *baton, StoppointCallbackContext *context, user_id_t watch_id) {
WatchpointOptions::CommandData *wp_option_data =
(WatchpointOptions::CommandData *)baton;
Debugger &debugger = target->GetDebugger();
ScriptInterpreter *script_interpreter =
debugger.GetCommandInterpreter().GetScriptInterpreter();
- ScriptInterpreterPython *python_interpreter =
- (ScriptInterpreterPython *)script_interpreter;
+ ScriptInterpreterPythonImpl *python_interpreter =
+ (ScriptInterpreterPythonImpl *)script_interpreter;
if (!script_interpreter)
return true;
return true;
}
-size_t ScriptInterpreterPython::CalculateNumChildren(
+size_t ScriptInterpreterPythonImpl::CalculateNumChildren(
const StructuredData::ObjectSP &implementor_sp, uint32_t max) {
if (!implementor_sp)
return 0;
return ret_val;
}
-lldb::ValueObjectSP ScriptInterpreterPython::GetChildAtIndex(
+lldb::ValueObjectSP ScriptInterpreterPythonImpl::GetChildAtIndex(
const StructuredData::ObjectSP &implementor_sp, uint32_t idx) {
if (!implementor_sp)
return lldb::ValueObjectSP();
if (!implementor)
return lldb::ValueObjectSP();
-
lldb::ValueObjectSP ret_val;
{
Locker py_lock(this,
return ret_val;
}
-int ScriptInterpreterPython::GetIndexOfChildWithName(
+int ScriptInterpreterPythonImpl::GetIndexOfChildWithName(
const StructuredData::ObjectSP &implementor_sp, const char *child_name) {
if (!implementor_sp)
return UINT32_MAX;
return ret_val;
}
-bool ScriptInterpreterPython::UpdateSynthProviderInstance(
+bool ScriptInterpreterPythonImpl::UpdateSynthProviderInstance(
const StructuredData::ObjectSP &implementor_sp) {
bool ret_val = false;
return ret_val;
}
-bool ScriptInterpreterPython::MightHaveChildrenSynthProviderInstance(
+bool ScriptInterpreterPythonImpl::MightHaveChildrenSynthProviderInstance(
const StructuredData::ObjectSP &implementor_sp) {
bool ret_val = false;
if (!implementor)
return ret_val;
-
{
Locker py_lock(this,
Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
return ret_val;
}
-lldb::ValueObjectSP ScriptInterpreterPython::GetSyntheticValue(
+lldb::ValueObjectSP ScriptInterpreterPythonImpl::GetSyntheticValue(
const StructuredData::ObjectSP &implementor_sp) {
lldb::ValueObjectSP ret_val(nullptr);
return ret_val;
}
-ConstString ScriptInterpreterPython::GetSyntheticTypeName(
+ConstString ScriptInterpreterPythonImpl::GetSyntheticTypeName(
const StructuredData::ObjectSP &implementor_sp) {
Locker py_lock(this,
Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
return ret_val;
}
-bool ScriptInterpreterPython::RunScriptFormatKeyword(const char *impl_function,
- Process *process,
- std::string &output,
- Status &error) {
+bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
+ const char *impl_function, Process *process, std::string &output,
+ Status &error) {
bool ret_val;
if (!process) {
error.SetErrorString("no process");
return ret_val;
}
-bool ScriptInterpreterPython::RunScriptFormatKeyword(const char *impl_function,
- Thread *thread,
- std::string &output,
- Status &error) {
+bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
+ const char *impl_function, Thread *thread, std::string &output,
+ Status &error) {
bool ret_val;
if (!thread) {
error.SetErrorString("no thread");
return ret_val;
}
-bool ScriptInterpreterPython::RunScriptFormatKeyword(const char *impl_function,
- Target *target,
- std::string &output,
- Status &error) {
+bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
+ const char *impl_function, Target *target, std::string &output,
+ Status &error) {
bool ret_val;
if (!target) {
error.SetErrorString("no thread");
return ret_val;
}
-bool ScriptInterpreterPython::RunScriptFormatKeyword(const char *impl_function,
- StackFrame *frame,
- std::string &output,
- Status &error) {
+bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
+ const char *impl_function, StackFrame *frame, std::string &output,
+ Status &error) {
bool ret_val;
if (!frame) {
error.SetErrorString("no frame");
return ret_val;
}
-bool ScriptInterpreterPython::RunScriptFormatKeyword(const char *impl_function,
- ValueObject *value,
- std::string &output,
- Status &error) {
+bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
+ const char *impl_function, ValueObject *value, std::string &output,
+ Status &error) {
bool ret_val;
if (!value) {
error.SetErrorString("no value");
return matches;
}
-bool ScriptInterpreterPython::LoadScriptingModule(
+bool ScriptInterpreterPythonImpl::LoadScriptingModule(
const char *pathname, bool can_reload, bool init_session,
lldb_private::Status &error, StructuredData::ObjectSP *module_sp) {
if (!pathname || !pathname[0]) {
StreamString command_stream;
// Before executing Python code, lock the GIL.
- Locker py_lock(this, Locker::AcquireLock |
- (init_session ? Locker::InitSession : 0) |
- Locker::NoSTDIN,
+ 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;
bool was_imported_globally =
(ExecuteOneLineWithReturn(
command_stream.GetData(),
- ScriptInterpreterPython::eScriptReturnTypeBool, &does_contain,
+ ScriptInterpreterPythonImpl::eScriptReturnTypeBool, &does_contain,
ScriptInterpreter::ExecuteScriptOptions()
.SetEnableIO(false)
.SetSetLLDBGlobals(false)) &&
}
}
-bool ScriptInterpreterPython::IsReservedWord(const char *word) {
+bool ScriptInterpreterPythonImpl::IsReservedWord(const char *word) {
if (!word || !word[0])
return false;
return false;
}
-ScriptInterpreterPython::SynchronicityHandler::SynchronicityHandler(
+ScriptInterpreterPythonImpl::SynchronicityHandler::SynchronicityHandler(
lldb::DebuggerSP debugger_sp, ScriptedCommandSynchronicity synchro)
: m_debugger_sp(debugger_sp), m_synch_wanted(synchro),
m_old_asynch(debugger_sp->GetAsyncExecution()) {
m_debugger_sp->SetAsyncExecution(true);
}
-ScriptInterpreterPython::SynchronicityHandler::~SynchronicityHandler() {
+ScriptInterpreterPythonImpl::SynchronicityHandler::~SynchronicityHandler() {
if (m_synch_wanted != eScriptedCommandSynchronicityCurrentValue)
m_debugger_sp->SetAsyncExecution(m_old_asynch);
}
-bool ScriptInterpreterPython::RunScriptBasedCommand(
+bool ScriptInterpreterPythonImpl::RunScriptBasedCommand(
const char *impl_function, llvm::StringRef args,
ScriptedCommandSynchronicity synchronicity,
lldb_private::CommandReturnObject &cmd_retobj, Status &error,
return ret_val;
}
-bool ScriptInterpreterPython::RunScriptBasedCommand(
+bool ScriptInterpreterPythonImpl::RunScriptBasedCommand(
StructuredData::GenericSP impl_obj_sp, llvm::StringRef args,
ScriptedCommandSynchronicity synchronicity,
lldb_private::CommandReturnObject &cmd_retobj, Status &error,
// in Python, a special attribute __doc__ contains the docstring for an object
// (function, method, class, ...) if any is defined Otherwise, the attribute's
// value is None
-bool ScriptInterpreterPython::GetDocumentationForItem(const char *item,
- std::string &dest) {
+bool ScriptInterpreterPythonImpl::GetDocumentationForItem(const char *item,
+ std::string &dest) {
dest.clear();
if (!item || !*item)
return false;
}
}
-bool ScriptInterpreterPython::GetShortHelpForCommandObject(
+bool ScriptInterpreterPythonImpl::GetShortHelpForCommandObject(
StructuredData::GenericSP cmd_obj_sp, std::string &dest) {
bool got_string = false;
dest.clear();
return got_string;
}
-uint32_t ScriptInterpreterPython::GetFlagsForCommandObject(
+uint32_t ScriptInterpreterPythonImpl::GetFlagsForCommandObject(
StructuredData::GenericSP cmd_obj_sp) {
uint32_t result = 0;
return result;
}
-bool ScriptInterpreterPython::GetLongHelpForCommandObject(
+bool ScriptInterpreterPythonImpl::GetLongHelpForCommandObject(
StructuredData::GenericSP cmd_obj_sp, std::string &dest) {
bool got_string = false;
dest.clear();
}
std::unique_ptr<ScriptInterpreterLocker>
-ScriptInterpreterPython::AcquireInterpreterLock() {
+ScriptInterpreterPythonImpl::AcquireInterpreterLock() {
std::unique_ptr<ScriptInterpreterLocker> py_lock(new Locker(
this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN,
Locker::FreeLock | Locker::TearDownSession));
return py_lock;
}
-void ScriptInterpreterPython::InitializePrivate() {
+void ScriptInterpreterPythonImpl::InitializePrivate() {
if (g_initialized)
return;
"from lldb.embedded_interpreter import run_one_line");
}
-void ScriptInterpreterPython::AddToSysPath(AddLocation location,
- std::string path) {
+void ScriptInterpreterPythonImpl::AddToSysPath(AddLocation location,
+ std::string path) {
std::string path_copy;
std::string statement;
// calls Py_Finalize, which calls all the 'at_exit' registered functions.
// SBDebugger::Terminate calls Debugger::Terminate, which calls lldb::Terminate,
// which calls ScriptInterpreter::Terminate, which calls
-// ScriptInterpreterPython::Terminate. So if we call Py_Finalize here, we end
-// up with Py_Finalize being called from within Py_Finalize, which results in a
-// seg fault. Since this function only gets called when lldb is shutting down
-// and going away anyway, the fact that we don't actually call Py_Finalize
+// ScriptInterpreterPythonImpl::Terminate. So if we call Py_Finalize here, we
+// end up with Py_Finalize being called from within Py_Finalize, which results
+// in a seg fault. Since this function only gets called when lldb is shutting
+// down and going away anyway, the fact that we don't actually call Py_Finalize
// should not cause any problems (everything should shut down/go away anyway
// when the process exits).
//
-// void ScriptInterpreterPython::Terminate() { Py_Finalize (); }
+// void ScriptInterpreterPythonImpl::Terminate() { Py_Finalize (); }
#endif // LLDB_DISABLE_PYTHON
#else
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "PythonDataObjects.h"
#include "lldb/Breakpoint/BreakpointOptions.h"
#include "lldb/Core/IOHandler.h"
-#include "lldb/Host/Terminal.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
#include "lldb/lldb-private.h"
-class IOHandlerPythonInterpreter;
+#include <memory>
+#include <string>
+#include <vector>
namespace lldb_private {
-
+/// Abstract interface for the Python script interpreter.
class ScriptInterpreterPython : public ScriptInterpreter,
public IOHandlerDelegateMultiline {
public:
}
};
- friend class ::IOHandlerPythonInterpreter;
-
- ScriptInterpreterPython(CommandInterpreter &interpreter);
-
- ~ScriptInterpreterPython() override;
-
- bool Interrupt() override;
-
- bool ExecuteOneLine(
- llvm::StringRef command, CommandReturnObject *result,
- const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
-
- void ExecuteInterpreterLoop() override;
-
- bool ExecuteOneLineWithReturn(
- llvm::StringRef in_string,
- ScriptInterpreter::ScriptReturnType return_type, void *ret_value,
- const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
-
- lldb_private::Status ExecuteMultipleLines(
- const char *in_string,
- const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
-
- Status
- ExportFunctionDefinitionToInterpreter(StringList &function_def) override;
-
- bool GenerateTypeScriptFunction(StringList &input, std::string &output,
- const void *name_token = nullptr) override;
-
- bool GenerateTypeSynthClass(StringList &input, std::string &output,
- const void *name_token = nullptr) override;
-
- bool GenerateTypeSynthClass(const char *oneliner, std::string &output,
- const void *name_token = nullptr) override;
-
- // use this if the function code is just a one-liner script
- bool GenerateTypeScriptFunction(const char *oneliner, std::string &output,
- const void *name_token = nullptr) override;
-
- bool GenerateScriptAliasFunction(StringList &input,
- std::string &output) override;
-
- StructuredData::ObjectSP
- CreateSyntheticScriptedProvider(const char *class_name,
- lldb::ValueObjectSP valobj) override;
-
- StructuredData::GenericSP
- CreateScriptCommandObject(const char *class_name) override;
-
- StructuredData::ObjectSP
- CreateScriptedThreadPlan(const char *class_name,
- lldb::ThreadPlanSP thread_plan) override;
-
- bool ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp,
- Event *event,
- bool &script_error) override;
-
- bool ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp,
- Event *event, bool &script_error) override;
-
- bool ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp,
- bool &script_error) override;
-
- lldb::StateType
- ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp,
- bool &script_error) override;
-
- StructuredData::GenericSP
- CreateScriptedBreakpointResolver(const char *class_name,
- StructuredDataImpl *args_data,
- lldb::BreakpointSP &bkpt_sp) override;
- bool
- ScriptedBreakpointResolverSearchCallback(StructuredData::GenericSP
- implementor_sp,
- SymbolContext *sym_ctx) override;
-
- lldb::SearchDepth
- ScriptedBreakpointResolverSearchDepth(StructuredData::GenericSP
- implementor_sp) override;
-
- StructuredData::GenericSP
- CreateFrameRecognizer(const char *class_name) override;
-
- lldb::ValueObjectListSP
- GetRecognizedArguments(const StructuredData::ObjectSP &implementor,
- lldb::StackFrameSP frame_sp) override;
-
- StructuredData::GenericSP
- OSPlugin_CreatePluginObject(const char *class_name,
- lldb::ProcessSP process_sp) override;
-
- StructuredData::DictionarySP
- OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) override;
-
- StructuredData::ArraySP
- OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp) override;
-
- StructuredData::StringSP
- OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp,
- lldb::tid_t thread_id) override;
-
- StructuredData::DictionarySP
- OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp,
- lldb::tid_t tid, lldb::addr_t context) override;
-
- StructuredData::ObjectSP
- LoadPluginModule(const FileSpec &file_spec,
- lldb_private::Status &error) override;
-
- StructuredData::DictionarySP
- GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target,
- const char *setting_name,
- lldb_private::Status &error) override;
-
- size_t CalculateNumChildren(const StructuredData::ObjectSP &implementor,
- uint32_t max) override;
-
- lldb::ValueObjectSP
- GetChildAtIndex(const StructuredData::ObjectSP &implementor,
- uint32_t idx) override;
-
- int GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor,
- const char *child_name) override;
-
- bool UpdateSynthProviderInstance(
- const StructuredData::ObjectSP &implementor) override;
-
- bool MightHaveChildrenSynthProviderInstance(
- const StructuredData::ObjectSP &implementor) override;
-
- lldb::ValueObjectSP
- GetSyntheticValue(const StructuredData::ObjectSP &implementor) override;
-
- ConstString
- GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) override;
-
- bool
- RunScriptBasedCommand(const char *impl_function, llvm::StringRef args,
- ScriptedCommandSynchronicity synchronicity,
- lldb_private::CommandReturnObject &cmd_retobj,
- Status &error,
- const lldb_private::ExecutionContext &exe_ctx) override;
-
- bool RunScriptBasedCommand(
- StructuredData::GenericSP impl_obj_sp, llvm::StringRef args,
- ScriptedCommandSynchronicity synchronicity,
- lldb_private::CommandReturnObject &cmd_retobj, Status &error,
- const lldb_private::ExecutionContext &exe_ctx) override;
-
- Status GenerateFunction(const char *signature,
- const StringList &input) override;
-
- Status GenerateBreakpointCommandCallbackData(StringList &input,
- std::string &output) override;
-
- bool GenerateWatchpointCommandCallbackData(StringList &input,
- std::string &output) override;
-
- static bool BreakpointCallbackFunction(void *baton,
- StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id);
-
- static bool WatchpointCallbackFunction(void *baton,
- StoppointCallbackContext *context,
- lldb::user_id_t watch_id);
-
- bool GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj,
- StructuredData::ObjectSP &callee_wrapper_sp,
- const TypeSummaryOptions &options,
- std::string &retval) override;
-
- void Clear() override;
-
- bool GetDocumentationForItem(const char *item, std::string &dest) override;
-
- bool GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,
- std::string &dest) override;
-
- uint32_t
- GetFlagsForCommandObject(StructuredData::GenericSP cmd_obj_sp) override;
-
- bool GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,
- std::string &dest) override;
-
- bool CheckObjectExists(const char *name) override {
- if (!name || !name[0])
- return false;
- std::string temp;
- return GetDocumentationForItem(name, temp);
- }
-
- bool RunScriptFormatKeyword(const char *impl_function, Process *process,
- std::string &output, Status &error) override;
-
- bool RunScriptFormatKeyword(const char *impl_function, Thread *thread,
- std::string &output, Status &error) override;
-
- bool RunScriptFormatKeyword(const char *impl_function, Target *target,
- std::string &output, Status &error) override;
+ ScriptInterpreterPython(CommandInterpreter &interpreter)
+ : ScriptInterpreter(interpreter, lldb::eScriptLanguagePython),
+ IOHandlerDelegateMultiline("DONE") {}
- bool RunScriptFormatKeyword(const char *impl_function, StackFrame *frame,
- std::string &output, Status &error) override;
-
- bool RunScriptFormatKeyword(const char *impl_function, ValueObject *value,
- std::string &output, Status &error) override;
-
- bool
- LoadScriptingModule(const char *filename, bool can_reload, bool init_session,
- lldb_private::Status &error,
- StructuredData::ObjectSP *module_sp = nullptr) override;
-
- bool IsReservedWord(const char *word) override;
-
- std::unique_ptr<ScriptInterpreterLocker> AcquireInterpreterLock() override;
-
- void CollectDataForBreakpointCommandCallback(
- std::vector<BreakpointOptions *> &bp_options_vec,
- CommandReturnObject &result) override;
-
- void
- CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options,
- CommandReturnObject &result) override;
-
- /// Set the callback body text into the callback for the breakpoint.
- Status SetBreakpointCommandCallback(BreakpointOptions *bp_options,
- const char *callback_body) override;
-
- void SetBreakpointCommandCallbackFunction(BreakpointOptions *bp_options,
- const char *function_name) override;
-
- /// This one is for deserialization:
- Status SetBreakpointCommandCallback(
- BreakpointOptions *bp_options,
- std::unique_ptr<BreakpointOptions::CommandData> &data_up) override;
-
- /// Set a one-liner as the callback for the watchpoint.
- void SetWatchpointCommandCallback(WatchpointOptions *wp_options,
- const char *oneliner) override;
-
- StringList ReadCommandInputFromUser(FILE *in_file);
-
- void ResetOutputFileHandle(FILE *new_fh) override;
-
- const char *GetDictionaryName() { return m_dictionary_name.c_str(); }
-
- PyThreadState *GetThreadState() { return m_command_thread_state; }
-
- void SetThreadState(PyThreadState *s) {
- if (s)
- m_command_thread_state = s;
- }
-
- //----------------------------------------------------------------------
- // IOHandlerDelegate
- //----------------------------------------------------------------------
- void IOHandlerActivated(IOHandler &io_handler, bool interactive) override;
-
- void IOHandlerInputComplete(IOHandler &io_handler,
- std::string &data) override;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
static void Initialize();
-
static void Terminate();
-
- static lldb::ScriptInterpreterSP
- CreateInstance(CommandInterpreter &interpreter);
-
static lldb_private::ConstString GetPluginNameStatic();
-
static const char *GetPluginDescriptionStatic();
-
static FileSpec GetPythonDir();
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString GetPluginName() override;
-
- uint32_t GetPluginVersion() override;
-
- class Locker : public ScriptInterpreterLocker {
- public:
- enum OnEntry {
- AcquireLock = 0x0001,
- InitSession = 0x0002,
- InitGlobals = 0x0004,
- NoSTDIN = 0x0008
- };
-
- enum OnLeave {
- FreeLock = 0x0001,
- FreeAcquiredLock = 0x0002, // do not free the lock if we already held it
- // when calling constructor
- TearDownSession = 0x0004
- };
-
- Locker(ScriptInterpreterPython *py_interpreter = nullptr,
- uint16_t on_entry = AcquireLock | InitSession,
- uint16_t on_leave = FreeLock | TearDownSession, FILE *in = nullptr,
- FILE *out = nullptr, FILE *err = nullptr);
-
- ~Locker() override;
-
- private:
- bool DoAcquireLock();
-
- bool DoInitSession(uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err);
-
- bool DoFreeLock();
-
- bool DoTearDownSession();
-
- static void ReleasePythonLock();
-
- bool m_teardown_session;
- ScriptInterpreterPython *m_python_interpreter;
- // FILE* m_tmp_fh;
- PyGILState_STATE m_GILState;
- };
-
protected:
- static void InitializePrivate();
-
- class SynchronicityHandler {
- private:
- lldb::DebuggerSP m_debugger_sp;
- ScriptedCommandSynchronicity m_synch_wanted;
- bool m_old_asynch;
-
- public:
- SynchronicityHandler(lldb::DebuggerSP, ScriptedCommandSynchronicity);
-
- ~SynchronicityHandler();
- };
-
- enum class AddLocation { Beginning, End };
-
- static void AddToSysPath(AddLocation location, std::string path);
-
static void ComputePythonDirForApple(llvm::SmallVectorImpl<char> &path);
static void ComputePythonDirForPosix(llvm::SmallVectorImpl<char> &path);
static void ComputePythonDirForWindows(llvm::SmallVectorImpl<char> &path);
-
- bool EnterSession(uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err);
-
- void LeaveSession();
-
- void SaveTerminalState(int fd);
-
- void RestoreTerminalState();
-
- uint32_t IsExecutingPython() const { return m_lock_count > 0; }
-
- uint32_t IncrementLockCount() { return ++m_lock_count; }
-
- uint32_t DecrementLockCount() {
- if (m_lock_count > 0)
- --m_lock_count;
- return m_lock_count;
- }
-
- enum ActiveIOHandler {
- eIOHandlerNone,
- eIOHandlerBreakpoint,
- eIOHandlerWatchpoint
- };
-
- PythonObject &GetMainModule();
-
- PythonDictionary &GetSessionDictionary();
-
- PythonDictionary &GetSysModuleDictionary();
-
- bool GetEmbeddedInterpreterModuleObjects();
-
- bool SetStdHandle(File &file, const char *py_name, PythonFile &save_file,
- const char *mode);
-
- PythonFile m_saved_stdin;
- PythonFile m_saved_stdout;
- PythonFile m_saved_stderr;
- PythonObject m_main_module;
- PythonDictionary m_session_dict;
- PythonDictionary m_sys_module_dict;
- PythonObject m_run_one_line_function;
- PythonObject m_run_one_line_str_global;
- std::string m_dictionary_name;
- TerminalState m_terminal_state;
- ActiveIOHandler m_active_io_handler;
- bool m_session_is_active;
- bool m_pty_slave_is_open;
- bool m_valid_session;
- uint32_t m_lock_count;
- PyThreadState *m_command_thread_state;
};
-
} // namespace lldb_private
#endif // LLDB_DISABLE_PYTHON
-
#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHON_H
--- /dev/null
+//===-- ScriptInterpreterPythonImpl.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
+//
+//===----------------------------------------------------------------------===//
+
+#ifdef LLDB_DISABLE_PYTHON
+
+// Python is disabled in this build
+
+#else
+
+#include "lldb-python.h"
+
+#include "PythonDataObjects.h"
+#include "ScriptInterpreterPython.h"
+
+#include "lldb/Host/Terminal.h"
+#include "lldb/Utility/StreamString.h"
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace lldb_private {
+class IOHandlerPythonInterpreter;
+class ScriptInterpreterPythonImpl : public ScriptInterpreterPython {
+public:
+ friend class IOHandlerPythonInterpreter;
+
+ ScriptInterpreterPythonImpl(CommandInterpreter &interpreter);
+
+ ~ScriptInterpreterPythonImpl() override;
+
+ bool Interrupt() override;
+
+ bool ExecuteOneLine(
+ llvm::StringRef command, CommandReturnObject *result,
+ const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
+
+ void ExecuteInterpreterLoop() override;
+
+ bool ExecuteOneLineWithReturn(
+ llvm::StringRef in_string,
+ ScriptInterpreter::ScriptReturnType return_type, void *ret_value,
+ const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
+
+ lldb_private::Status ExecuteMultipleLines(
+ const char *in_string,
+ const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
+
+ Status
+ ExportFunctionDefinitionToInterpreter(StringList &function_def) override;
+
+ bool GenerateTypeScriptFunction(StringList &input, std::string &output,
+ const void *name_token = nullptr) override;
+
+ bool GenerateTypeSynthClass(StringList &input, std::string &output,
+ const void *name_token = nullptr) override;
+
+ bool GenerateTypeSynthClass(const char *oneliner, std::string &output,
+ const void *name_token = nullptr) override;
+
+ // use this if the function code is just a one-liner script
+ bool GenerateTypeScriptFunction(const char *oneliner, std::string &output,
+ const void *name_token = nullptr) override;
+
+ bool GenerateScriptAliasFunction(StringList &input,
+ std::string &output) override;
+
+ StructuredData::ObjectSP
+ CreateSyntheticScriptedProvider(const char *class_name,
+ lldb::ValueObjectSP valobj) override;
+
+ StructuredData::GenericSP
+ CreateScriptCommandObject(const char *class_name) override;
+
+ StructuredData::ObjectSP
+ CreateScriptedThreadPlan(const char *class_name,
+ lldb::ThreadPlanSP thread_plan) override;
+
+ bool ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp,
+ Event *event,
+ bool &script_error) override;
+
+ bool ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp,
+ Event *event, bool &script_error) override;
+
+ bool ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp,
+ bool &script_error) override;
+
+ lldb::StateType
+ ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp,
+ bool &script_error) override;
+
+ StructuredData::GenericSP
+ CreateScriptedBreakpointResolver(const char *class_name,
+ StructuredDataImpl *args_data,
+ lldb::BreakpointSP &bkpt_sp) override;
+ bool ScriptedBreakpointResolverSearchCallback(
+ StructuredData::GenericSP implementor_sp,
+ SymbolContext *sym_ctx) override;
+
+ lldb::SearchDepth ScriptedBreakpointResolverSearchDepth(
+ StructuredData::GenericSP implementor_sp) override;
+
+ StructuredData::GenericSP
+ CreateFrameRecognizer(const char *class_name) override;
+
+ lldb::ValueObjectListSP
+ GetRecognizedArguments(const StructuredData::ObjectSP &implementor,
+ lldb::StackFrameSP frame_sp) override;
+
+ StructuredData::GenericSP
+ OSPlugin_CreatePluginObject(const char *class_name,
+ lldb::ProcessSP process_sp) override;
+
+ StructuredData::DictionarySP
+ OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) override;
+
+ StructuredData::ArraySP
+ OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp) override;
+
+ StructuredData::StringSP
+ OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp,
+ lldb::tid_t thread_id) override;
+
+ StructuredData::DictionarySP
+ OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp,
+ lldb::tid_t tid, lldb::addr_t context) override;
+
+ StructuredData::ObjectSP
+ LoadPluginModule(const FileSpec &file_spec,
+ lldb_private::Status &error) override;
+
+ StructuredData::DictionarySP
+ GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target,
+ const char *setting_name,
+ lldb_private::Status &error) override;
+
+ size_t CalculateNumChildren(const StructuredData::ObjectSP &implementor,
+ uint32_t max) override;
+
+ lldb::ValueObjectSP
+ GetChildAtIndex(const StructuredData::ObjectSP &implementor,
+ uint32_t idx) override;
+
+ int GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor,
+ const char *child_name) override;
+
+ bool UpdateSynthProviderInstance(
+ const StructuredData::ObjectSP &implementor) override;
+
+ bool MightHaveChildrenSynthProviderInstance(
+ const StructuredData::ObjectSP &implementor) override;
+
+ lldb::ValueObjectSP
+ GetSyntheticValue(const StructuredData::ObjectSP &implementor) override;
+
+ ConstString
+ GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) override;
+
+ bool
+ RunScriptBasedCommand(const char *impl_function, llvm::StringRef args,
+ ScriptedCommandSynchronicity synchronicity,
+ lldb_private::CommandReturnObject &cmd_retobj,
+ Status &error,
+ const lldb_private::ExecutionContext &exe_ctx) override;
+
+ bool RunScriptBasedCommand(
+ StructuredData::GenericSP impl_obj_sp, llvm::StringRef args,
+ ScriptedCommandSynchronicity synchronicity,
+ lldb_private::CommandReturnObject &cmd_retobj, Status &error,
+ const lldb_private::ExecutionContext &exe_ctx) override;
+
+ Status GenerateFunction(const char *signature,
+ const StringList &input) override;
+
+ Status GenerateBreakpointCommandCallbackData(StringList &input,
+ std::string &output) override;
+
+ bool GenerateWatchpointCommandCallbackData(StringList &input,
+ std::string &output) override;
+
+ bool GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj,
+ StructuredData::ObjectSP &callee_wrapper_sp,
+ const TypeSummaryOptions &options,
+ std::string &retval) override;
+
+ void Clear() override;
+
+ bool GetDocumentationForItem(const char *item, std::string &dest) override;
+
+ bool GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,
+ std::string &dest) override;
+
+ uint32_t
+ GetFlagsForCommandObject(StructuredData::GenericSP cmd_obj_sp) override;
+
+ bool GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,
+ std::string &dest) override;
+
+ bool CheckObjectExists(const char *name) override {
+ if (!name || !name[0])
+ return false;
+ std::string temp;
+ return GetDocumentationForItem(name, temp);
+ }
+
+ bool RunScriptFormatKeyword(const char *impl_function, Process *process,
+ std::string &output, Status &error) override;
+
+ bool RunScriptFormatKeyword(const char *impl_function, Thread *thread,
+ std::string &output, Status &error) override;
+
+ bool RunScriptFormatKeyword(const char *impl_function, Target *target,
+ std::string &output, Status &error) override;
+
+ bool RunScriptFormatKeyword(const char *impl_function, StackFrame *frame,
+ std::string &output, Status &error) override;
+
+ bool RunScriptFormatKeyword(const char *impl_function, ValueObject *value,
+ std::string &output, Status &error) override;
+
+ bool
+ LoadScriptingModule(const char *filename, bool can_reload, bool init_session,
+ lldb_private::Status &error,
+ StructuredData::ObjectSP *module_sp = nullptr) override;
+
+ bool IsReservedWord(const char *word) override;
+
+ std::unique_ptr<ScriptInterpreterLocker> AcquireInterpreterLock() override;
+
+ void CollectDataForBreakpointCommandCallback(
+ std::vector<BreakpointOptions *> &bp_options_vec,
+ CommandReturnObject &result) override;
+
+ void
+ CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options,
+ CommandReturnObject &result) override;
+
+ /// Set the callback body text into the callback for the breakpoint.
+ Status SetBreakpointCommandCallback(BreakpointOptions *bp_options,
+ const char *callback_body) override;
+
+ void SetBreakpointCommandCallbackFunction(BreakpointOptions *bp_options,
+ const char *function_name) override;
+
+ /// This one is for deserialization:
+ Status SetBreakpointCommandCallback(
+ BreakpointOptions *bp_options,
+ std::unique_ptr<BreakpointOptions::CommandData> &data_up) override;
+
+ /// Set a one-liner as the callback for the watchpoint.
+ void SetWatchpointCommandCallback(WatchpointOptions *wp_options,
+ const char *oneliner) override;
+
+ void ResetOutputFileHandle(FILE *new_fh) override;
+
+ const char *GetDictionaryName() { return m_dictionary_name.c_str(); }
+
+ PyThreadState *GetThreadState() { return m_command_thread_state; }
+
+ void SetThreadState(PyThreadState *s) {
+ if (s)
+ m_command_thread_state = s;
+ }
+
+ //----------------------------------------------------------------------
+ // IOHandlerDelegate
+ //----------------------------------------------------------------------
+ void IOHandlerActivated(IOHandler &io_handler, bool interactive) override;
+
+ void IOHandlerInputComplete(IOHandler &io_handler,
+ std::string &data) override;
+
+ static lldb::ScriptInterpreterSP
+ CreateInstance(CommandInterpreter &interpreter);
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
+ class Locker : public ScriptInterpreterLocker {
+ public:
+ enum OnEntry {
+ AcquireLock = 0x0001,
+ InitSession = 0x0002,
+ InitGlobals = 0x0004,
+ NoSTDIN = 0x0008
+ };
+
+ enum OnLeave {
+ FreeLock = 0x0001,
+ FreeAcquiredLock = 0x0002, // do not free the lock if we already held it
+ // when calling constructor
+ TearDownSession = 0x0004
+ };
+
+ Locker(ScriptInterpreterPythonImpl *py_interpreter = nullptr,
+ uint16_t on_entry = AcquireLock | InitSession,
+ uint16_t on_leave = FreeLock | TearDownSession, FILE *in = nullptr,
+ FILE *out = nullptr, FILE *err = nullptr);
+
+ ~Locker() override;
+
+ private:
+ bool DoAcquireLock();
+
+ bool DoInitSession(uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err);
+
+ bool DoFreeLock();
+
+ bool DoTearDownSession();
+
+ bool m_teardown_session;
+ ScriptInterpreterPythonImpl *m_python_interpreter;
+ // FILE* m_tmp_fh;
+ PyGILState_STATE m_GILState;
+ };
+
+ static bool BreakpointCallbackFunction(void *baton,
+ StoppointCallbackContext *context,
+ lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id);
+ static bool WatchpointCallbackFunction(void *baton,
+ StoppointCallbackContext *context,
+ lldb::user_id_t watch_id);
+ static void InitializePrivate();
+
+ class SynchronicityHandler {
+ private:
+ lldb::DebuggerSP m_debugger_sp;
+ ScriptedCommandSynchronicity m_synch_wanted;
+ bool m_old_asynch;
+
+ public:
+ SynchronicityHandler(lldb::DebuggerSP, ScriptedCommandSynchronicity);
+
+ ~SynchronicityHandler();
+ };
+
+ enum class AddLocation { Beginning, End };
+
+ static void AddToSysPath(AddLocation location, std::string path);
+
+ bool EnterSession(uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err);
+
+ void LeaveSession();
+
+ void SaveTerminalState(int fd);
+
+ void RestoreTerminalState();
+
+ uint32_t IsExecutingPython() const { return m_lock_count > 0; }
+
+ uint32_t IncrementLockCount() { return ++m_lock_count; }
+
+ uint32_t DecrementLockCount() {
+ if (m_lock_count > 0)
+ --m_lock_count;
+ return m_lock_count;
+ }
+
+ enum ActiveIOHandler {
+ eIOHandlerNone,
+ eIOHandlerBreakpoint,
+ eIOHandlerWatchpoint
+ };
+
+ PythonObject &GetMainModule();
+
+ PythonDictionary &GetSessionDictionary();
+
+ PythonDictionary &GetSysModuleDictionary();
+
+ bool GetEmbeddedInterpreterModuleObjects();
+
+ bool SetStdHandle(File &file, const char *py_name, PythonFile &save_file,
+ const char *mode);
+
+ PythonFile m_saved_stdin;
+ PythonFile m_saved_stdout;
+ PythonFile m_saved_stderr;
+ PythonObject m_main_module;
+ PythonDictionary m_session_dict;
+ PythonDictionary m_sys_module_dict;
+ PythonObject m_run_one_line_function;
+ PythonObject m_run_one_line_str_global;
+ std::string m_dictionary_name;
+ TerminalState m_terminal_state;
+ ActiveIOHandler m_active_io_handler;
+ bool m_session_is_active;
+ bool m_pty_slave_is_open;
+ bool m_valid_session;
+ uint32_t m_lock_count;
+ PyThreadState *m_command_thread_state;
+};
+
+class IOHandlerPythonInterpreter : public IOHandler {
+public:
+ IOHandlerPythonInterpreter(Debugger &debugger,
+ ScriptInterpreterPythonImpl *python)
+ : IOHandler(debugger, IOHandler::Type::PythonInterpreter),
+ m_python(python) {}
+
+ ~IOHandlerPythonInterpreter() override {}
+
+ ConstString GetControlSequence(char ch) override {
+ if (ch == 'd')
+ return ConstString("quit()\n");
+ return ConstString();
+ }
+
+ void Run() override {
+ if (m_python) {
+ int stdin_fd = GetInputFD();
+ if (stdin_fd >= 0) {
+ Terminal terminal(stdin_fd);
+ TerminalState terminal_state;
+ const bool is_a_tty = terminal.IsATerminal();
+
+ if (is_a_tty) {
+ terminal_state.Save(stdin_fd, false);
+ terminal.SetCanonical(false);
+ terminal.SetEcho(true);
+ }
+
+ ScriptInterpreterPythonImpl::Locker locker(
+ m_python,
+ ScriptInterpreterPythonImpl::Locker::AcquireLock |
+ ScriptInterpreterPythonImpl::Locker::InitSession |
+ ScriptInterpreterPythonImpl::Locker::InitGlobals,
+ ScriptInterpreterPythonImpl::Locker::FreeAcquiredLock |
+ ScriptInterpreterPythonImpl::Locker::TearDownSession);
+
+ // The following call drops into the embedded interpreter loop and
+ // stays there until the user chooses to exit from the Python
+ // interpreter. This embedded interpreter will, as any Python code that
+ // performs I/O, unlock the GIL before a system call that can hang, and
+ // lock it when the syscall has returned.
+
+ // We need to surround the call to the embedded interpreter with calls
+ // to PyGILState_Ensure and PyGILState_Release (using the Locker
+ // above). This is because Python has a global lock which must be held
+ // whenever we want to touch any Python objects. Otherwise, if the user
+ // calls Python code, the interpreter state will be off, and things
+ // could hang (it's happened before).
+
+ StreamString run_string;
+ run_string.Printf("run_python_interpreter (%s)",
+ m_python->GetDictionaryName());
+ PyRun_SimpleString(run_string.GetData());
+
+ if (is_a_tty)
+ terminal_state.Restore();
+ }
+ }
+ SetIsDone(true);
+ }
+
+ void Cancel() override {}
+
+ bool Interrupt() override { return m_python->Interrupt(); }
+
+ void GotEOF() override {}
+
+protected:
+ ScriptInterpreterPythonImpl *m_python;
+};
+
+} // namespace lldb_private
+
+#endif