27#include "lldb/Host/Config.h"
44#include "llvm/ADT/STLExtras.h"
45#include "llvm/ADT/StringExtras.h"
46#include "llvm/ADT/StringRef.h"
47#include "llvm/Support/Error.h"
48#include "llvm/Support/ErrorExtras.h"
49#include "llvm/Support/FileSystem.h"
50#include "llvm/Support/FormatAdapters.h"
73#define LLDBSwigPyInit PyInit__lldb
77#define LLDB_USE_PYTHON_SET_INTERRUPT 0
79#define LLDB_USE_PYTHON_SET_INTERRUPT 1
96struct InitializePythonRAII {
98 llvm::Error DoInitialize() {
99 const bool was_initialized = Py_IsInitialized();
103 if (!was_initialized) {
104#ifdef LLDB_USE_LIBEDIT_READLINE_COMPAT_MODULE
107 PyImport_AppendInittab(
"readline", initlldb_readline);
114#if LLDB_EMBED_PYTHON_HOME
115 if (!was_initialized) {
117 PyConfig_InitPythonConfig(&config);
119 static std::string g_python_home = []() -> std::string {
120 if (llvm::sys::path::is_absolute(LLDB_PYTHON_HOME))
121 return LLDB_PYTHON_HOME;
123 FileSpec spec = HostInfo::GetShlibDir();
129 if (!g_python_home.empty()) {
130 PyStatus status = PyConfig_SetBytesString(&config, &config.home,
131 g_python_home.c_str());
132 if (PyStatus_Exception(status)) {
133 PyConfig_Clear(&config);
134 return llvm::createStringError(
135 "failed to set the Python config: '%s'", status.err_msg);
139 config.install_signal_handlers = 0;
140 PyStatus status = Py_InitializeFromConfig(&config);
141 PyConfig_Clear(&config);
142 if (PyStatus_Exception(status))
143 return llvm::createStringError(
"Python failed to initialize: '%s'",
147 if (!was_initialized)
149 if (!Py_IsInitialized())
150 return llvm::createStringError(
"Python failed to initialize");
153 m_python_initialized =
true;
156 PyGILState_STATE gil_state = PyGILState_Ensure();
157 if (gil_state != PyGILState_UNLOCKED)
158 return llvm::Error::success();
160 m_was_already_initialized =
true;
161 m_gil_state = gil_state;
163 GetLog(LLDBLog::Script),
"Ensured PyGILState. Previous state = {0}",
164 m_gil_state == PyGILState_UNLOCKED ?
"unlocked" :
"locked");
165 return llvm::Error::success();
168 ~InitializePythonRAII() {
169 if (!m_python_initialized)
172 if (m_was_already_initialized) {
174 "Releasing PyGILState. Returning to state = {0}",
175 m_gil_state == PyGILState_UNLOCKED ?
"unlocked"
177 PyGILState_Release(m_gil_state);
185 PyGILState_STATE m_gil_state = PyGILState_UNLOCKED;
186 bool m_was_already_initialized =
false;
187 bool m_python_initialized =
false;
190#if LLDB_USE_PYTHON_SET_INTERRUPT
193struct RestoreSignalHandlerScope {
195 struct sigaction m_prev_handler;
197 RestoreSignalHandlerScope(
int signal_code) : m_signal_code(signal_code) {
199 std::memset(&m_prev_handler, 0,
sizeof(m_prev_handler));
201 struct sigaction *new_handler =
nullptr;
202 int signal_err = ::sigaction(m_signal_code, new_handler, &m_prev_handler);
203 lldbassert(signal_err == 0 &&
"sigaction failed to read handler");
205 ~RestoreSignalHandlerScope() {
206 int signal_err = ::sigaction(m_signal_code, &m_prev_handler,
nullptr);
207 lldbassert(signal_err == 0 &&
"sigaction failed to restore old handler");
215 auto style = llvm::sys::path::Style::posix;
217 llvm::StringRef path_ref(path.begin(), path.size());
218 auto rbegin = llvm::sys::path::rbegin(path_ref, style);
219 auto rend = llvm::sys::path::rend(path_ref);
220 auto framework = std::find(rbegin, rend,
"LLDB.framework");
221 if (framework == rend) {
225 path.resize(framework - rend);
226 llvm::sys::path::append(path, style,
"LLDB.framework",
"Resources",
"Python");
234 llvm::sys::path::remove_filename(path);
235 llvm::sys::path::append(path, LLDB_PYTHON_RELATIVE_LIBDIR);
240 std::replace(path.begin(), path.end(),
'\\',
'/');
246 FileSpec spec = HostInfo::GetShlibDir();
249 llvm::SmallString<64> path;
252#if defined(__APPLE__)
267def main(lldb_python_dir, python_exe_relative_path):
269 "lldb-pythonpath": lldb_python_dir,
270 "language": "python",
271 "prefix": sys.prefix,
272 "executable": os.path.join(sys.prefix, python_exe_relative_path)
282 if (!python_dir_spec)
290 return info_json.CreateStructuredDictionary();
297 return "lldb.plugins.operating_system";
299 return "lldb.plugins.scripted_platform";
301 return "lldb.plugins.scripted_process";
303 return "lldb.plugins.scripted_hook";
305 return "lldb.plugins.scripted_breakpoint";
307 return "lldb.plugins.scripted_thread_plan";
309 return "lldb.plugins.scripted_frame_provider";
312 return "lldb.plugins.scripted_process";
314 return "lldb.plugins.scripted_stackframe_recognizer";
317 return "lldb.plugins.scripted_command";
319 return "lldb.plugins.scripted_string_summary";
321 return "lldb.plugins.scripted_synthetic_children";
323 return llvm::createStringError(
"invalid extension name");
325 return llvm::createStringError(
"invalid extension name");
328llvm::Expected<StructuredData::ObjectSP>
330 const llvm::SmallVector<llvm::StringRef> &extension_path) {
334 if (!import_path_or_err)
335 return import_path_or_err.takeError();
344 command_stream.
Printf(
"lldb.embedded_interpreter.generate_extension_schema("
345 "__import__('%s', fromlist=['']).%s)",
346 import_path_or_err->c_str(),
355 void *result_obj =
nullptr;
360 return llvm::createStringError(
"invalid extension schema format");
366 std::string schema_str;
368 PyGILState_STATE gil_state = PyGILState_Ensure();
371 static_cast<PyObject *
>(result_obj));
375 PyGILState_Release(gil_state);
378 if (schema_str.empty())
379 return llvm::createStringError(
"empty extension schema");
384 Stream &s, llvm::StringRef output_script_prefix,
385 const llvm::SmallVector<llvm::StringRef> &extension_path,
386 bool generate_non_abstract_methods, std::set<std::string> &typing_imports) {
389 return schema_or_err.takeError();
393 return llvm::createStringError(
"empty extension schema");
396 return llvm::createStringError(
"extension schema is not a JSON object");
404 typing_imports.insert(str->GetValue().str());
408 llvm::StringRef base_class, import_path;
410 return llvm::createStringError(
411 llvm::formatv(
"extension schema dictionary is missing 'class' key")
414 return llvm::createStringError(
415 llvm::formatv(
"extension schema dictionary is missing 'module' key")
419 s.
Printf(
"from %s import %s\n", import_path.data(), base_class.data());
423 s.
Printf(
"class %s%s(%s):\n", output_script_prefix.data(), base_class.data(),
430 bool has_body =
false;
437 s.
Printf(
"Attributes inherited from %s:\n", base_class.data());
438 for (
size_t i = 0; i < attributes->
GetSize(); i++) {
443 llvm::StringRef attr_name;
446 llvm::StringRef attr_type;
449 s.
Printf(
"- %s", attr_name.data());
451 s.
Printf(
": %s", attr_type.data());
462 return llvm::createStringError(
"missing 'members' key in extension schema");
468 bool any_abstract =
false;
469 for (
size_t i = 0; i < members->
GetSize(); i++) {
473 bool is_abstract =
false;
474 if ((*maybe_dict)->GetValueForKeyAsBoolean(
"is_abstract", is_abstract) &&
480 bool emit_all_methods = generate_non_abstract_methods || !any_abstract;
482 for (
size_t i = 0; i < members->
GetSize(); i++) {
485 return llvm::createStringError(
487 "member at index {0} in extension schema isn't a dictionary")
491 llvm::StringRef symbol, args;
493 return llvm::createStringError(
495 "member at index {0} in extension schema is missing 'name' key")
498 return llvm::createStringError(
499 llvm::formatv(
"member at index {0} in extension schema is missing "
503 bool is_abstract =
false;
504 bool has_is_abstract =
506 if (!emit_all_methods)
507 if (!has_is_abstract || !is_abstract)
511 s.
Printf(
"def %s%s:\n", symbol.data(), args.data());
514 llvm::StringRef documentation;
519 llvm::SmallVector<llvm::StringRef> lines;
520 documentation.split(lines,
"\n");
522 for (llvm::StringRef line : lines) {
533 if (symbol ==
"__init__") {
539 llvm::StringRef params = args.trim(
"()");
540 std::vector<std::string> forwarded_args;
543 auto flush = [&](
size_t end) {
544 llvm::StringRef param = params.slice(start, end);
545 param = param.split(
':').first.split(
'=').first.trim();
546 if (!param.empty() && param !=
"self")
547 forwarded_args.push_back(param.str());
549 for (
size_t i = 0; i < params.size(); ++i) {
551 if (c ==
'[' || c ==
'(' || c ==
'{')
553 else if (c ==
']' || c ==
')' || c ==
'}')
555 else if (c ==
',' && depth == 0) {
560 flush(params.size());
562 s.
Printf(
"super().__init__(%s)\n",
563 llvm::join(forwarded_args,
", ").c_str());
582 return llvm::Error::success();
586 const std::string &name, std::vector<ExtensionTemplateRequest> &extensions,
587 bool generate_non_abstract_methods, std::string output_file) {
593 std::set<std::string> typing_imports;
596 if (llvm::Error err =
598 generate_non_abstract_methods, typing_imports))
599 return std::move(err);
604 generated_file_stream.
PutCString(
"import lldb\n");
605 if (!typing_imports.empty()) {
606 std::vector<std::string> sorted_imports(typing_imports.begin(),
607 typing_imports.end());
608 generated_file_stream.
Format(
"from typing import {0}\n",
609 llvm::join(sorted_imports,
", "));
615 if (output_file.empty()) {
620 std::string sanitized;
621 sanitized.reserve(name.size());
623 sanitized.push_back(llvm::isAlnum(c) ?
static_cast<char>(llvm::toLower(c))
625 if (sanitized.find_first_not_of(
'_') == std::string::npos)
626 sanitized =
"extension";
627 const std::string file_name =
"lldb_" + sanitized +
"_extension.py";
628 save_location = HostInfo::GetGlobalTempDir();
632 save_location =
FileSpec(output_file);
643 return opened_file.takeError();
645 FileUP file = std::move(opened_file.get());
647 size_t byte_size = generated_file_stream.
GetSize();
651 if (
error.Fail() || byte_size != generated_file_stream.
GetSize())
652 return llvm::createStringError(
"Unable to write to destination file. Bytes "
653 "written do not match generated file size.");
654 return save_location;
669 llvm::StringRef libdir = LLDB_PYTHON_RELATIVE_LIBDIR;
670 for (
auto it = llvm::sys::path::begin(libdir),
671 end = llvm::sys::path::end(libdir);
685 return "Embedded Python interpreter";
693 setenv(
"PYTHONMALLOC",
"malloc",
true);
699#if !LLDB_ENABLE_DYNAMIC_SCRIPTINTERPRETERS
700 HostInfo::SetSharedLibraryDirectoryHelper(
743 "Ensured PyGILState. Previous state = {0}",
744 m_GILState == PyGILState_UNLOCKED ?
"unlocked" :
"locked");
766 "Releasing PyGILState. Returning to state = {0}",
767 m_GILState == PyGILState_UNLOCKED ?
"unlocked" :
"locked");
805 run_string.
Printf(
"run_one_line (%s, 'import copy, keyword, os, re, sys, "
806 "uuid, lldb, importlib')",
816 "run_one_line (%s, 'import lldb.formatters, lldb.formatters.cpp')",
821 run_string.
Printf(
"run_one_line (%s, 'import lldb.embedded_interpreter; from "
822 "lldb.embedded_interpreter import run_python_interpreter; "
823 "from lldb.embedded_interpreter import run_one_line')",
830 run_string.
Printf(
"run_one_line (%s, 'import pydoc; pydoc.pager = "
831 "pydoc.plainpager')",
836 run_string.
Printf(
"run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64
856 std::unique_ptr<SessionIORedirect> redirect(
862 std::unique_ptr<Connection> conn =
863 std::make_unique<ConnectionGenericFile>(read_handle,
true);
865 std::unique_ptr<Connection> conn =
866 std::make_unique<ConnectionFileDescriptor>(
869 if (!conn->IsConnected())
872 redirect->m_communication.SetConnection(std::move(conn));
873 redirect->m_communication.SetReadThreadBytesReceivedCallback(
875 if (!redirect->m_communication.StartReadThread())
877 redirect->m_connected =
true;
880 redirect->m_write_file_sp = std::make_shared<NativeFile>(
908 if (!src || !src_len)
913 debugger_sp->PrintAsync(
static_cast<const char *
>(src), src_len,
930 auto gil_state = PyGILState_Ensure();
932 PyGILState_Release(gil_state);
937 const char *instructions =
nullptr;
943 instructions = R
"(Enter your Python command(s). Type 'DONE' to end.
944def function (frame, bp_loc, internal_dict):
945 """frame: the lldb.SBFrame for the location at which you stopped
946 bp_loc: an lldb.SBBreakpointLocation for the breakpoint location information
947 internal_dict: an LLDB support object not to be used"""
951 instructions =
"Enter your Python command(s). Type 'DONE' to end.\n";
955 if (instructions && interactive) {
967 bool batch_mode =
m_debugger.GetCommandInterpreter().GetBatchCommandMode();
973 std::vector<std::reference_wrapper<BreakpointOptions>> *bp_options_vec =
974 (std::vector<std::reference_wrapper<BreakpointOptions>> *)
976 for (BreakpointOptions &bp_options : *bp_options_vec) {
978 auto data_up = std::make_unique<CommandDataPython>();
981 data_up->user_source.SplitIntoLines(data);
984 data_up->script_source,
988 auto baton_sp = std::make_shared<BreakpointOptions::CommandBaton>(
990 bp_options.SetCallback(
992 }
else if (!batch_mode) {
994 LockedStreamFile locked_stream = error_sp->Lock();
995 locked_stream.
Printf(
"Warning: No command attached to breakpoint.\n");
1002 WatchpointOptions *wp_options =
1004 auto data_up = std::make_unique<WatchpointOptions::CommandData>();
1005 data_up->user_source.SplitIntoLines(data);
1008 data_up->script_source,
1011 std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up));
1014 }
else if (!batch_mode) {
1016 LockedStreamFile locked_stream = error_sp->Lock();
1017 locked_stream.
Printf(
"Warning: No command attached to breakpoint.\n");
1027 return std::make_shared<ScriptInterpreterPythonImpl>(debugger);
1033 log->
PutCString(
"ScriptInterpreterPythonImpl::LeaveSession()");
1036 RunSimpleString(
"lldb.debugger = None; lldb.target = None; lldb.process "
1037 "= None; lldb.thread = None; lldb.frame = None");
1044 if (PyThreadState_GetDict()) {
1046 if (sys_module_dict.
IsValid()) {
1051 auto flush_redirect = [&](
const char *py_name,
1052 std::unique_ptr<SessionIORedirect> &redirect) {
1059 if (llvm::Expected<PythonObject> result = file.
CallMethod(
"flush"))
1062 llvm::consumeError(result.takeError());
1091 const char *py_name,
PythonObject &save_file,
const char *mode,
1093 const bool is_stdout = ::strcmp(py_name,
"stdout") == 0;
1094 if (!is_stdout && ::strcmp(py_name,
"stderr") != 0)
1109 fd != debugger_file->GetDescriptor())
1112 std::unique_ptr<SessionIORedirect> &redirect =
1121 PyObject *pipe_file = PyFile_FromFd(
1131 "failed to wrap sys.{0} on a synchronized pipe; falling back to "
1132 "the unsynchronized terminal descriptor",
1147 const char *py_name,
1150 bool serialize_terminal_output) {
1151 if (!file_sp || !*file_sp) {
1155 File &file = *file_sp;
1160 if (serialize_terminal_output &&
1172 "ScriptInterpreterPythonImpl::SetStdHandle failed to wrap "
1178 save_file = sys_module_dict.
GetItemForKey(PythonString(py_name));
1193 "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16
1194 ") session is already active, returning without doing anything",
1201 "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16
")",
1209 run_string.
Printf(
"run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64,
1212 "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64
")",
1214 run_string.
PutCString(
"; lldb.target = lldb.debugger.GetSelectedTarget()");
1215 run_string.
PutCString(
"; lldb.process = lldb.target.GetProcess()");
1216 run_string.
PutCString(
"; lldb.thread = lldb.process.GetSelectedThread ()");
1217 run_string.
PutCString(
"; lldb.frame = lldb.thread.GetSelectedFrame ()");
1222 run_string.
Printf(
"run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64,
1225 "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64
")",
1234 if (sys_module_dict.
IsValid()) {
1237 if (!in_sp || !out_sp || !err_sp || !*in_sp || !*out_sp || !*err_sp)
1238 m_debugger.AdoptTopIOHandlerFilesIfInvalid(top_in_sp, top_out_sp,
1254 const bool serialize_terminal_output =
1258 serialize_terminal_output)) {
1261 "w", serialize_terminal_output);
1265 serialize_terminal_output)) {
1268 "w", serialize_terminal_output);
1272 if (PyErr_Occurred())
1293 PyModule_GetDict(main_module.
get()));
1294 if (!main_dict.IsValid())
1310llvm::Expected<unsigned>
1312 const llvm::StringRef &callable_name) {
1313 if (callable_name.empty()) {
1314 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1315 "called with empty callable name.");
1322 callable_name, dict);
1324 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1325 "can't find callable: %s",
1326 callable_name.str().c_str());
1328 llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
1332 "GetArgInfo failed for callable {1}, falling back to "
1333 "inspect.signature: {0}",
1338 return arg_info.takeError();
1339 return arg_info.
get().max_positional_args;
1343 uint32_t &functions_counter,
1344 const void *name_token =
nullptr) {
1347 if (!base_name_wanted)
1348 return std::string();
1351 sstr.
Printf(
"%s_%d", base_name_wanted, functions_counter++);
1353 sstr.
Printf(
"%s_%p", base_name_wanted, name_token);
1363 PyImport_AddModule(
"lldb.embedded_interpreter"));
1364 if (!module.IsValid())
1368 PyModule_GetDict(module.get()));
1369 if (!module_dict.IsValid())
1373 module_dict.GetItemForKey(
PythonString(
"run_one_line"));
1375 module_dict.GetItemForKey(
PythonString(
"g_run_one_line_str"));
1382 std::string command_str = command.str();
1387 if (!command.empty()) {
1394 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
1397 if (!io_redirect_or_error) {
1400 "failed to redirect I/O: {0}\n",
1401 llvm::fmt_consume(io_redirect_or_error.takeError()));
1403 llvm::consumeError(io_redirect_or_error.takeError());
1409 bool success =
false;
1435 Py_BuildValue(
"(Os)", session_dict.
get(), command_str.c_str()));
1452 io_redirect.
Flush();
1461 command_str.c_str());
1467 result->
AppendError(
"empty command passed to python\n");
1486 if (io_handler_sp) {
1492#if LLDB_USE_PYTHON_SET_INTERRUPT
1500 PyErr_SetInterrupt();
1511 PyThreadState *state = PyThreadState_Get();
1515 long tid = PyThread_get_thread_ident();
1516 PyThreadState_Swap(state);
1517 int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt);
1519 "ScriptInterpreterPythonImpl::Interrupt() sending "
1520 "PyExc_KeyboardInterrupt (tid = %li, num_threads = %i)...",
1526 "ScriptInterpreterPythonImpl::Interrupt() python code not running, "
1536 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
1540 if (!io_redirect_or_error) {
1541 llvm::consumeError(io_redirect_or_error.takeError());
1565 Expected<PythonObject> maybe_py_return =
1568 if (!maybe_py_return) {
1569 llvm::handleAllErrors(
1570 maybe_py_return.takeError(),
1573 if (options.GetMaskoutErrors()) {
1574 if (E.Matches(PyExc_SyntaxError)) {
1580 [](
const llvm::ErrorInfoBase &E) {});
1584 PythonObject py_return = std::move(maybe_py_return.get());
1587 switch (return_type) {
1588 case eScriptReturnTypeCharPtr:
1590 const char format[3] =
"s#";
1591 return PyArg_Parse(py_return.
get(), format, (
char **)ret_value);
1593 case eScriptReturnTypeCharStrOrNone:
1596 const char format[3] =
"z";
1597 return PyArg_Parse(py_return.
get(), format, (
char **)ret_value);
1599 case eScriptReturnTypeBool: {
1600 const char format[2] =
"b";
1601 return PyArg_Parse(py_return.
get(), format, (
bool *)ret_value);
1603 case eScriptReturnTypeShortInt: {
1604 const char format[2] =
"h";
1605 return PyArg_Parse(py_return.
get(), format, (
short *)ret_value);
1607 case eScriptReturnTypeShortIntUnsigned: {
1608 const char format[2] =
"H";
1609 return PyArg_Parse(py_return.
get(), format, (
unsigned short *)ret_value);
1611 case eScriptReturnTypeInt: {
1612 const char format[2] =
"i";
1613 return PyArg_Parse(py_return.
get(), format, (
int *)ret_value);
1615 case eScriptReturnTypeIntUnsigned: {
1616 const char format[2] =
"I";
1617 return PyArg_Parse(py_return.
get(), format, (
unsigned int *)ret_value);
1619 case eScriptReturnTypeLongInt: {
1620 const char format[2] =
"l";
1621 return PyArg_Parse(py_return.
get(), format, (
long *)ret_value);
1623 case eScriptReturnTypeLongIntUnsigned: {
1624 const char format[2] =
"k";
1625 return PyArg_Parse(py_return.
get(), format, (
unsigned long *)ret_value);
1627 case eScriptReturnTypeLongLong: {
1628 const char format[2] =
"L";
1629 return PyArg_Parse(py_return.
get(), format, (
long long *)ret_value);
1631 case eScriptReturnTypeLongLongUnsigned: {
1632 const char format[2] =
"K";
1633 return PyArg_Parse(py_return.
get(), format,
1634 (
unsigned long long *)ret_value);
1636 case eScriptReturnTypeFloat: {
1637 const char format[2] =
"f";
1638 return PyArg_Parse(py_return.
get(), format, (
float *)ret_value);
1640 case eScriptReturnTypeDouble: {
1641 const char format[2] =
"d";
1642 return PyArg_Parse(py_return.
get(), format, (
double *)ret_value);
1644 case eScriptReturnTypeChar: {
1645 const char format[2] =
"c";
1646 return PyArg_Parse(py_return.
get(), format, (
char *)ret_value);
1648 case eScriptReturnTypeOpaqueObject: {
1649 *((PyObject **)ret_value) = py_return.
release();
1653 llvm_unreachable(
"Fully covered switch!");
1659 if (in_string ==
nullptr)
1662 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
1666 if (!io_redirect_or_error)
1669 ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
1689 Expected<PythonObject> return_value =
1692 if (!return_value) {
1694 llvm::handleErrors(return_value.takeError(), [&](PythonException &E) {
1695 llvm::Error error = llvm::createStringError(
1696 llvm::inconvertibleErrorCode(), E.ReadBacktrace());
1697 if (!options.GetMaskoutErrors())
1708 std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
1711 m_debugger.GetCommandInterpreter().GetPythonCommandsFromIOHandler(
1712 " ", *
this, &bp_options_vec);
1718 m_debugger.GetCommandInterpreter().GetPythonCommandsFromIOHandler(
1719 " ", *
this, wp_options);
1727 std::string function_signature = function_name;
1729 llvm::Expected<unsigned> maybe_args =
1733 "could not get num args: %s",
1734 llvm::toString(maybe_args.takeError()).c_str());
1737 size_t max_args = *maybe_args;
1739 bool uses_extra_args =
false;
1740 if (max_args >= 4) {
1741 uses_extra_args =
true;
1742 function_signature +=
"(frame, bp_loc, extra_args, internal_dict)";
1743 }
else if (max_args >= 3) {
1744 if (extra_args_sp) {
1746 "cannot pass extra_args to a three argument callback");
1749 uses_extra_args =
false;
1750 function_signature +=
"(frame, bp_loc, internal_dict)";
1753 "function, %s can only take %zu",
1754 function_name, max_args);
1759 extra_args_sp, uses_extra_args,
1766 std::unique_ptr<BreakpointOptions::CommandData> &cmd_data_up) {
1769 cmd_data_up->script_source,
1776 std::make_shared<BreakpointOptions::CommandBaton>(std::move(cmd_data_up));
1786 false, is_callback);
1794 auto data_up = std::make_unique<CommandDataPython>(extra_args_sp);
1800 data_up->user_source.SplitIntoLines(command_body_text);
1802 data_up->user_source, data_up->script_source, uses_extra_args,
1804 if (
error.Success()) {
1806 std::make_shared<BreakpointOptions::CommandBaton>(std::move(data_up));
1817 auto data_up = std::make_unique<WatchpointOptions::CommandData>();
1824 data_up->user_source.AppendString(user_input);
1825 data_up->script_source.assign(user_input);
1828 data_up->user_source, data_up->script_source, is_callback)) {
1830 std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up));
1839 std::string function_def_string(function_def.
CopyList());
1841 function_def_string.c_str());
1852 int num_lines = input.
GetSize();
1853 if (num_lines == 0) {
1858 if (!signature || *signature == 0) {
1864 StringList auto_generated_function;
1867 " global_dict = globals()");
1869 " new_keys = internal_dict.keys()");
1872 " old_keys = global_dict.keys()");
1874 " global_dict.update(internal_dict)");
1881 if (num_lines == 1) {
1887 "ScriptInterpreterPythonImpl::GenerateFunction(is_callback="
1888 "true) = ERROR: python function is multiline.");
1892 " __return_val = None");
1894 " def __user_code():");
1898 for (
int i = 0; i < num_lines; ++i) {
1904 " __return_val = __user_code()");
1908 " for key in new_keys:");
1911 " if key in old_keys:");
1914 " internal_dict[key] = global_dict[key]");
1916 " elif key in global_dict:");
1919 " del global_dict[key]");
1922 " return __return_val");
1931 StringList &user_input, std::string &output,
const void *name_token) {
1932 static uint32_t num_created_functions = 0;
1937 if (user_input.
GetSize() == 0)
1943 std::string auto_generated_function_name(
1945 num_created_functions, name_token));
1946 sstr.
Printf(
"def %s (valobj, internal_dict):",
1947 auto_generated_function_name.c_str());
1954 output.assign(auto_generated_function_name);
1959 StringList &user_input, std::string &output) {
1960 static uint32_t num_created_functions = 0;
1965 if (user_input.
GetSize() == 0)
1969 "lldb_autogen_python_cmd_alias_func", num_created_functions));
1971 sstr.
Printf(
"def %s (debugger, args, exe_ctx, result, internal_dict):",
1972 auto_generated_function_name.c_str());
1979 output.assign(auto_generated_function_name);
1984 StringList &user_input, std::string &output,
const void *name_token) {
1985 static uint32_t num_created_classes = 0;
1987 int num_lines = user_input.
GetSize();
1991 if (user_input.
GetSize() == 0)
1997 "lldb_autogen_python_type_synth_class", num_created_classes, name_token));
2003 sstr.
Printf(
"class %s:", auto_generated_class_name.c_str());
2009 for (
int i = 0; i < num_lines; ++i) {
2023 output.assign(auto_generated_class_name);
2029 return std::make_unique<ScriptedProcessPythonInterface>(*
this);
2034 return std::make_shared<ScriptedHookPythonInterface>(*
this);
2039 return std::make_shared<ScriptedBreakpointPythonInterface>(*
this);
2044 return std::make_shared<ScriptedStackFrameRecognizerPythonInterface>(*
this);
2049 return std::make_shared<ScriptedCommandPythonInterface>(*
this);
2054 return std::make_shared<ScriptedStringSummaryPythonInterface>(*
this);
2059 return std::make_shared<ScriptedSyntheticChildrenPythonInterface>(*
this);
2064 return std::make_shared<ScriptedThreadPythonInterface>(*
this);
2069 return std::make_shared<ScriptedFramePythonInterface>(*
this);
2074 return std::make_shared<ScriptedFrameProviderPythonInterface>(*
this);
2079 return std::make_shared<ScriptedThreadPlanPythonInterface>(*
this);
2084 return std::make_shared<OperatingSystemPythonInterface>(*
this);
2090 void *ptr =
const_cast<void *
>(obj.
GetPointer());
2093 if (!py_obj.IsValid() || py_obj.IsNone())
2095 return py_obj.CreateStructuredObject();
2108 LoadScriptOptions load_script_options =
2109 LoadScriptOptions().SetInitSession(
true).SetSilent(
false);
2120 if (!plugin_module_sp || !target || !setting_name || !setting_name[0])
2128 TargetSP target_sp(target->shared_from_this());
2131 generic->GetValue(), setting_name, target_sp);
2146 const char *oneliner, std::string &output,
const void *name_token) {
2153 const char *oneliner, std::string &output,
const void *name_token) {
2160 StringList &user_input, std::string &output,
bool has_extra_args,
2162 static uint32_t num_created_functions = 0;
2166 if (user_input.
GetSize() == 0) {
2172 "lldb_autogen_python_bp_callback_func_", num_created_functions));
2174 sstr.
Printf(
"def %s (frame, bp_loc, extra_args, internal_dict):",
2175 auto_generated_function_name.c_str());
2177 sstr.
Printf(
"def %s (frame, bp_loc, internal_dict):",
2178 auto_generated_function_name.c_str());
2181 if (!
error.Success())
2185 output.assign(auto_generated_function_name);
2190 StringList &user_input, std::string &output,
bool is_callback) {
2191 static uint32_t num_created_functions = 0;
2195 if (user_input.
GetSize() == 0)
2199 "lldb_autogen_python_wp_callback_func_", num_created_functions));
2200 sstr.
Printf(
"def %s (frame, wp, internal_dict):",
2201 auto_generated_function_name.c_str());
2207 output.assign(auto_generated_function_name);
2218 if (!valobj.get()) {
2219 retval.assign(
"<no object>");
2223 void *old_callee =
nullptr;
2225 if (callee_wrapper_sp) {
2226 generic = callee_wrapper_sp->GetAsGeneric();
2228 old_callee =
generic->GetValue();
2230 void *new_callee = old_callee;
2233 if (python_function_name && *python_function_name) {
2240 static Timer::Category func_cat(
"LLDBSwigPythonCallTypeScript");
2241 Timer scoped_timer(func_cat,
"LLDBSwigPythonCallTypeScript");
2244 &new_callee, options_sp, retval);
2248 retval.assign(
"<no function name>");
2252 if (new_callee && old_callee != new_callee) {
2255 callee_wrapper_sp = std::make_shared<StructuredPythonObject>(
2256 PythonObject(PyRefType::Borrowed,
static_cast<PyObject *
>(new_callee)));
2263 const char *python_function_name,
TypeImplSP type_impl_sp) {
2273 CommandDataPython *bp_option_data = (CommandDataPython *)baton;
2274 const char *python_function_name = bp_option_data->script_source.c_str();
2280 Target *target = exe_ctx.GetTargetPtr();
2289 if (!python_interpreter)
2292 if (python_function_name && python_function_name[0]) {
2293 const StackFrameSP stop_frame_sp(exe_ctx.GetFrameSP());
2295 if (breakpoint_sp) {
2297 breakpoint_sp->FindLocationByID(break_loc_id));
2299 if (stop_frame_sp && bp_loc_sp) {
2300 bool ret_val =
true;
2305 Expected<bool> maybe_ret_val =
2307 python_function_name,
2309 bp_loc_sp, bp_option_data->m_extra_args);
2311 if (!maybe_ret_val) {
2313 llvm::handleAllErrors(
2314 maybe_ret_val.takeError(),
2316 *debugger.GetAsyncErrorStream() << E.ReadBacktrace();
2318 [&](
const llvm::ErrorInfoBase &E) {
2319 *debugger.GetAsyncErrorStream() << E.message();
2323 ret_val = maybe_ret_val.get();
2339 const char *python_function_name = wp_option_data->
script_source.c_str();
2354 if (!python_interpreter)
2357 if (python_function_name && python_function_name[0]) {
2361 if (stop_frame_sp && wp_sp) {
2362 bool ret_val =
true;
2368 python_function_name,
2382 const char *impl_function,
Process *process, std::string &output,
2389 if (!impl_function || !impl_function[0]) {
2407 const char *impl_function,
Thread *thread, std::string &output,
2413 if (!impl_function || !impl_function[0]) {
2420 if (std::optional<std::string> result =
2423 thread->shared_from_this())) {
2424 output = std::move(*result);
2432 const char *impl_function,
Target *target, std::string &output,
2439 if (!impl_function || !impl_function[0]) {
2445 TargetSP target_sp(target->shared_from_this());
2457 const char *impl_function,
StackFrame *frame, std::string &output,
2463 if (!impl_function || !impl_function[0]) {
2470 if (std::optional<std::string> result =
2473 frame->shared_from_this())) {
2474 output = std::move(*result);
2482 const char *impl_function,
ValueObject *value, std::string &output,
2489 if (!impl_function || !impl_function[0]) {
2505uint64_t
replace_all(std::string &str,
const std::string &oldStr,
2506 const std::string &newStr) {
2508 uint64_t matches = 0;
2509 while ((pos = str.find(oldStr, pos)) != std::string::npos) {
2511 str.replace(pos, oldStr.length(), newStr);
2512 pos += newStr.length();
2521 namespace fs = llvm::sys::fs;
2522 namespace path = llvm::sys::path;
2528 if (!pathname || !pathname[0]) {
2533 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
2537 if (!io_redirect_or_error) {
2542 ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
2554 auto ExtendSysPath = [&](std::string directory) -> llvm::Error {
2555 if (directory.empty()) {
2556 return llvm::createStringError(
"invalid directory name");
2563 StreamString command_stream;
2564 command_stream.
Printf(
"if not (sys.path.__contains__('%s')):\n "
2565 "sys.path.insert(1,'%s');\n\n",
2566 directory.c_str(), directory.c_str());
2567 bool syspath_retval =
2569 if (!syspath_retval)
2570 return llvm::createStringError(
"Python sys.path handling failed");
2572 return llvm::Error::success();
2575 std::string module_name(pathname);
2576 bool possible_package =
false;
2578 if (extra_search_dir) {
2579 if (llvm::Error e = ExtendSysPath(extra_search_dir.
GetPath())) {
2584 FileSpec module_file(pathname);
2588 std::error_code ec = status(module_file.GetPath(), st);
2590 if (ec || st.type() == fs::file_type::status_error ||
2591 st.type() == fs::file_type::type_unknown ||
2592 st.type() == fs::file_type::file_not_found) {
2595 if (strchr(pathname,
'\\') || strchr(pathname,
'/')) {
2601 possible_package =
true;
2602 }
else if (is_directory(st) || is_regular_file(st)) {
2603 if (module_file.GetDirectory().empty()) {
2605 "invalid directory name '{0}'", pathname);
2608 if (llvm::Error e = ExtendSysPath(module_file.GetDirectory().str())) {
2612 module_name = module_file.GetFilename().str();
2615 "no known way to import this module specification");
2621 llvm::StringRef extension = llvm::sys::path::extension(module_name);
2622 if (!extension.empty()) {
2623 if (extension ==
".py")
2624 module_name.resize(module_name.length() - 3);
2625 else if (extension ==
".pyc")
2626 module_name.resize(module_name.length() - 4);
2629 if (!possible_package && module_name.find(
'.') != llvm::StringRef::npos) {
2631 "Python does not allow dots in module names: %s", module_name.c_str());
2635 if (module_name.find(
'-') != llvm::StringRef::npos) {
2637 "Python discourages dashes in module names: %s", module_name.c_str());
2642 StreamString command_stream;
2643 command_stream.
Clear();
2644 command_stream.
Printf(
"sys.modules.__contains__('%s')", module_name.c_str());
2645 bool does_contain =
false;
2653 const bool was_imported_globally = does_contain_executed && does_contain;
2654 const bool was_imported_locally =
2660 command_stream.
Clear();
2662 if (was_imported_globally || was_imported_locally) {
2663 if (!was_imported_locally)
2664 command_stream.
Printf(
"import %s ; importlib.reload(%s)",
2665 module_name.c_str(), module_name.c_str());
2667 command_stream.
Printf(
"importlib.reload(%s)", module_name.c_str());
2669 command_stream.
Printf(
"import %s", module_name.c_str());
2686 command_stream.
Clear();
2687 command_stream.
Printf(
"%s", module_name.c_str());
2688 void *module_pyobj =
nullptr;
2694 *module_sp = std::make_shared<StructuredPythonObject>(PythonObject(
2695 PyRefType::Owned,
static_cast<PyObject *
>(module_pyobj)));
2708 if (!word || !word[0])
2711 llvm::StringRef word_sr(word);
2715 if (word_sr.find(
'"') != llvm::StringRef::npos ||
2716 word_sr.find(
'\'') != llvm::StringRef::npos)
2720 command_stream.
Printf(
"keyword.iskeyword('%s')", word);
2735 : m_debugger_sp(debugger_sp), m_synch_wanted(synchro),
2736 m_old_asynch(debugger_sp->GetAsyncExecution()) {
2745 m_debugger_sp->SetAsyncExecution(m_old_asynch);
2749 const char *impl_function, llvm::StringRef args,
2753 if (!impl_function) {
2761 if (!debugger_sp.get()) {
2766 bool ret_val =
false;
2776 std::string args_str = args.str();
2779 cmd_retobj, exe_ctx_ref_sp);
2797 std::string &dest) {
2800 if (!item || !*item)
2803 std::string command(item);
2804 command +=
".__doc__";
2808 char *result_ptr =
nullptr;
2814 dest.assign(result_ptr);
2819 str_stream <<
"Function " << item
2820 <<
" was not found. Containing module might be missing.";
2821 dest = std::string(str_stream.
GetString());
2826std::unique_ptr<ScriptInterpreterLocker>
2828 std::unique_ptr<ScriptInterpreterLocker> py_lock(
new Locker(
2841 InitializePythonRAII initialize_guard;
2842 if (llvm::Error
error = initialize_guard.DoInitialize())
2859 if (
FileSpec file_spec = HostInfo::GetShlibDir())
2863 "lldb.embedded_interpreter; from "
2864 "lldb.embedded_interpreter import run_python_interpreter; "
2865 "from lldb.embedded_interpreter import run_one_line");
2867#if LLDB_USE_PYTHON_SET_INTERRUPT
2871 RestoreSignalHandlerScope save_sigint(SIGINT);
2879 " def signal_handler(sig, frame):\n"
2880 " raise KeyboardInterrupt()\n"
2881 " signal.signal(signal.SIGINT, signal_handler);\n"
2882 "lldb_setup_sigint_handler();\n"
2883 "del lldb_setup_sigint_handler\n");
2885 return llvm::Error::success();
2890 std::string statement;
2892 statement.assign(
"sys.path.insert(0,\"");
2893 statement.append(path);
2894 statement.append(
"\")");
2896 statement.assign(
"sys.path.append(\"");
2897 statement.append(path);
2898 statement.append(
"\")");
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF(log,...)
#define LLDB_LOG_ERROR(log, error,...)
#define LLDB_LOG_VERBOSE(log,...)
ScriptInterpreterPythonImpl::Locker Locker
#define LLDB_PLUGIN_DEFINE(PluginName)
PyObject * PyInit__lldb(void)
static std::string GenerateUniqueName(const char *base_name_wanted, uint32_t &functions_counter, const void *name_token=nullptr)
static ScriptInterpreterPythonImpl * GetPythonInterpreter(Debugger &debugger)
static const char python_exe_relative_path[]
uint64_t replace_all(std::string &str, const std::string &oldStr, const std::string &newStr)
static const char GetInterpreterInfoScript[]
#define LLDB_SCOPED_TIMER()
A Python sys.stdout/stderr file backed by a pipe whose read end is drained by a reader thread that wr...
lldb::user_id_t m_debugger_id
int GetWriteDescriptor() const
ThreadedCommunication m_communication
static void ReadThreadBytesReceived(void *baton, const void *src, size_t src_len)
lldb::FileSP m_write_file_sp
static std::unique_ptr< SessionIORedirect > Create(lldb::user_id_t debugger_id, bool is_stdout)
SessionIORedirect(lldb::user_id_t debugger_id, bool is_stdout)
"lldb/Breakpoint/BreakpointOptions.h" Class that manages the options on a breakpoint or breakpoint lo...
void SetCallback(BreakpointHitCallback callback, const lldb::BatonSP &baton_sp, bool synchronous=false)
Adds a callback to the breakpoint option set.
bool GetInteractive() const
void AppendError(llvm::StringRef in_string)
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
lldb::ReturnStatus GetStatus() const
void AppendErrorWithFormatv(const char *format, Args &&...args)
A class to manage flag bits.
lldb::FileSP GetErrorFileSP()
lldb::FileSP GetOutputFileSP()
void RunIOHandlerAsync(const lldb::IOHandlerSP &reader_sp, bool cancel_top_handler=true)
Run the given IO handler and return immediately.
bool StatuslineSupported()
Whether the statusline can be drawn: show-statusline is enabled and the output is an escape-code-capa...
static lldb::DebuggerSP FindDebuggerWithID(lldb::user_id_t id)
ScriptInterpreter * GetScriptInterpreter(bool can_create=true, std::optional< lldb::ScriptLanguage > language={})
bool GetSetLLDBGlobals() const
bool GetMaskoutErrors() const
ExecuteScriptOptions & SetMaskoutErrors(bool maskout)
ExecuteScriptOptions & SetSetLLDBGlobals(bool set)
ExecuteScriptOptions & SetEnableIO(bool enable)
Execution context objects refer to objects in the execution of the program that is being debugged.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
const lldb::StackFrameSP & GetFrameSP() const
Get accessor to get the frame shared pointer.
Target * GetTargetPtr() const
Returns a pointer to the target object.
void AppendPathComponent(llvm::StringRef component)
bool RemoveLastPathComponent()
Removes the last path component by replacing the current path with its parent.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
void SetDirectory(llvm::StringRef directory)
Directory string set accessor.
llvm::StringRef GetFileNameExtension() const
Extract the extension of the file.
Status ResolveSymbolicLink(const FileSpec &src, FileSpec &dst)
int Open(const char *path, int flags, int mode=0600)
Wraps open in a platform-independent way.
static FileSystem & Instance()
void Resolve(llvm::SmallVectorImpl< char > &path, bool force_make_absolute=false)
Resolve path to make it canonical.
An abstract base class for files.
static int kInvalidDescriptor
virtual int GetDescriptor() const
Get underlying OS file descriptor for this file, or kInvalidDescriptor.
bool IsValid() const override
IsValid.
virtual Status Flush()
Flush the current stream.
lldb::LockableStreamFileSP GetErrorStreamFileSP()
lldb::LockableStreamFileSP GetOutputStreamFileSP()
bool GetInitSession() const
void PutCString(const char *cstr)
Status CreateNew() override
int ReleaseReadFileDescriptor() override
int ReleaseWriteFileDescriptor() override
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
A plug-in interface definition class for debugging a process.
lldb::FileSP GetOutputFile() const
lldb::FileSP GetErrorFile() const
void Flush()
Flush our output and error file handles.
lldb::FileSP GetInputFile() const
static llvm::Expected< std::unique_ptr< ScriptInterpreterIORedirect > > Create(bool enable_io, Debugger &debugger, CommandReturnObject *result)
Create an IO redirect.
ScriptInterpreterLocker()=default
bool DoInitSession(uint16_t on_entry_flags, lldb::FileSP in, lldb::FileSP out, lldb::FileSP err)
Locker(ScriptInterpreterPythonImpl *py_interpreter, uint16_t on_entry=AcquireLock|InitSession, uint16_t on_leave=FreeLock|TearDownSession, lldb::FileSP in=nullptr, lldb::FileSP out=nullptr, lldb::FileSP err=nullptr)
PyGILState_STATE m_GILState
ScriptInterpreterPythonImpl * m_python_interpreter
ScriptedCommandSynchronicity m_synch_wanted
SynchronicityHandler(lldb::DebuggerSP, ScriptedCommandSynchronicity)
lldb::DebuggerSP m_debugger_sp
bool GenerateTypeScriptFunction(StringList &input, std::string &output, const void *name_token=nullptr) override
Status GenerateFunction(const char *signature, const StringList &input, bool is_callback) override
bool GenerateScriptAliasFunction(StringList &input, std::string &output) override
lldb_private::Status ExecuteMultipleLines(const char *in_string, const ExecuteScriptOptions &options=ExecuteScriptOptions()) override
static llvm::Error Initialize()
bool IsReservedWord(const char *word) override
python::PythonObject m_run_one_line_function
python::PythonObject m_saved_stderr
bool GenerateWatchpointCommandCallbackData(StringList &input, std::string &output, bool is_callback) override
friend class IOHandlerPythonInterpreter
bool Interrupt() override
ScriptInterpreterPythonImpl(Debugger &debugger)
Status SetBreakpointCommandCallbackFunction(BreakpointOptions &bp_options, const char *function_name, StructuredData::ObjectSP extra_args_sp) override
Set a script function as the callback for the breakpoint.
lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() override
std::unique_ptr< SessionIORedirect > m_stderr_redirect
static bool BreakpointCallbackFunction(void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
std::string m_dictionary_name
StructuredData::DictionarySP GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target, const char *setting_name, lldb_private::Status &error) override
void CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options, CommandReturnObject &result) override
lldb::ScriptedCommandInterfaceSP CreateScriptedCommandInterface() 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
python::PythonModule & GetMainModule()
lldb::ScriptedFrameProviderInterfaceSP CreateScriptedFrameProviderInterface() override
python::PythonObject m_saved_stdin
Status SetBreakpointCommandCallback(BreakpointOptions &bp_options, const char *callback_body, bool is_callback) override
Set the callback body text into the callback for the breakpoint.
PyThreadState * GetThreadState()
lldb::ScriptedStackFrameRecognizerInterfaceSP CreateScriptedStackFrameRecognizerInterface() override
bool EnterSession(uint16_t on_entry_flags, lldb::FileSP in, lldb::FileSP out, lldb::FileSP err)
void SetWatchpointCommandCallback(WatchpointOptions *wp_options, const char *user_input, bool is_callback) override
Set a one-liner as the callback for the watchpoint.
bool RedirectTerminalHandleThroughLock(const char *py_name, python::PythonObject &save_file, const char *mode, File &file)
If file is the debugger's own terminal, point sys.
std::unique_ptr< ScriptInterpreterLocker > AcquireInterpreterLock() override
void CollectDataForBreakpointCommandCallback(std::vector< std::reference_wrapper< BreakpointOptions > > &bp_options_vec, CommandReturnObject &result) override
python::PythonDictionary m_session_dict
uint32_t IsExecutingPython()
static void AddToSysPath(AddLocation location, std::string path)
lldb::ScriptedStringSummaryInterfaceSP CreateScriptedStringSummaryInterface() override
python::PythonDictionary & GetSessionDictionary()
bool LoadScriptingModule(const char *filename, const LoadScriptOptions &options, lldb_private::Status &error, StructuredData::ObjectSP *module_sp=nullptr, FileSpec extra_search_dir={}, lldb::TargetSP loaded_into_target_sp={}) override
Status GenerateBreakpointCommandCallbackData(StringList &input, std::string &output, bool has_extra_args, bool is_callback) override
PyThreadState * m_command_thread_state
lldb::OperatingSystemInterfaceSP CreateOperatingSystemInterface() override
python::PythonObject m_saved_stdout
bool FormatterCallbackFunction(const char *function_name, lldb::TypeImplSP type_impl_sp) override
void ExecuteInterpreterLoop() override
Status ExportFunctionDefinitionToInterpreter(StringList &function_def) override
bool ExecuteOneLine(llvm::StringRef command, CommandReturnObject *result, const ExecuteScriptOptions &options=ExecuteScriptOptions()) override
bool GetDocumentationForItem(const char *item, std::string &dest) override
In Python, a special attribute doc contains the docstring for an object (function,...
lldb::ScriptedSyntheticChildrenInterfaceSP CreateScriptedSyntheticChildrenInterface() override
lldb::ScriptedHookInterfaceSP CreateScriptedHookInterface() override
void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override
Called when a line or lines have been retrieved.
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
bool GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj, StructuredData::ObjectSP &callee_wrapper_sp, const TypeSummaryOptions &options, std::string &retval) override
lldb::ScriptedFrameInterfaceSP CreateScriptedFrameInterface() override
lldb::ScriptedProcessInterfaceUP CreateScriptedProcessInterface() override
bool m_pty_secondary_is_open
python::PythonDictionary m_sys_module_dict
bool ExecuteOneLineWithReturn(llvm::StringRef in_string, ScriptInterpreter::ScriptReturnType return_type, void *ret_value, const ExecuteScriptOptions &options=ExecuteScriptOptions()) override
lldb::ScriptedBreakpointInterfaceSP CreateScriptedBreakpointInterface() override
bool RunScriptFormatKeyword(const char *impl_function, Process *process, std::string &output, Status &error) override
python::PythonDictionary & GetSysModuleDictionary()
bool SetStdHandle(lldb::FileSP file, const char *py_name, python::PythonObject &save_file, const char *mode, bool serialize_terminal_output)
Point sys.
bool GetEmbeddedInterpreterModuleObjects()
bool GenerateTypeSynthClass(StringList &input, std::string &output, const void *name_token=nullptr) override
StructuredData::ObjectSP CreateStructuredDataFromScriptObject(ScriptObject obj) override
StructuredData::ObjectSP LoadPluginModule(const FileSpec &file_spec, lldb_private::Status &error) override
python::PythonModule m_main_module
llvm::Expected< unsigned > GetMaxPositionalArgumentsForCallable(const llvm::StringRef &callable_name) override
python::PythonObject m_run_one_line_str_global
static bool WatchpointCallbackFunction(void *baton, StoppointCallbackContext *context, lldb::user_id_t watch_id)
~ScriptInterpreterPythonImpl() override
static lldb::ScriptInterpreterSP CreateInstance(Debugger &debugger)
lldb::ScriptedThreadPlanInterfaceSP CreateScriptedThreadPlanInterface() override
ActiveIOHandler m_active_io_handler
std::unique_ptr< SessionIORedirect > m_stdout_redirect
Abstract interface for the Python script interpreter.
static void ComputePythonDir(llvm::SmallVectorImpl< char > &path)
static llvm::StringRef GetPluginNameStatic()
static void ComputePythonDirForApple(llvm::SmallVectorImpl< char > &path)
llvm::Expected< StructuredData::ObjectSP > GetExtensionSchema(const llvm::SmallVector< llvm::StringRef > &extension_path)
ScriptInterpreterPython(Debugger &debugger)
static llvm::StringRef GetPluginDescriptionStatic()
StructuredData::DictionarySP GetInterpreterInfo() override
llvm::Error ParseExtensionSchema(Stream &s, llvm::StringRef output_script_prefix, const llvm::SmallVector< llvm::StringRef > &extension_path, bool generate_non_abstract_methods, std::set< std::string > &typing_imports)
static FileSpec GetPythonDir()
static void SharedLibraryDirectoryHelper(FileSpec &this_file)
llvm::Expected< std::string > ExtensionToImportPath(lldb::ScriptedExtension extension) override
llvm::Expected< FileSpec > GenerateExtensionTemplate(const std::string &name, std::vector< ExtensionTemplateRequest > &extensions, bool generate_non_abstract_methods, std::string output_file) override
virtual bool ExecuteOneLineWithReturn(llvm::StringRef in_string, ScriptReturnType return_type, void *ret_value, const ExecuteScriptOptions &options=ExecuteScriptOptions())
static llvm::StringLiteral ExtensionToString(lldb::ScriptedExtension extension)
static lldb::ScriptedExtension StringToExtension(llvm::StringRef string)
@ eScriptReturnTypeOpaqueObject
@ eScriptReturnTypeCharStrOrNone
const void * GetPointer() const
This base class provides an interface to stack frames.
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
bool Fail() const
Test for error condition.
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
bool Success() const
Test for success condition.
General Outline: When we hit a breakpoint we need to package up whatever information is needed to eva...
ExecutionContextRef exe_ctx_ref
void Flush() override
Flush the stream.
const char * GetData() const
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
void Format(const char *format, Args &&... args)
Forwards the arguments to llvm::formatv and writes to the stream.
size_t Indent(llvm::StringRef s="")
Indent the current line in the stream.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
size_t EOL()
Output and End of Line character to the stream.
void IndentLess(unsigned amount=2)
Decrement the current indentation level.
void IndentMore(unsigned amount=2)
Increment the current indentation level.
std::string CopyList(const char *item_preamble=nullptr, const char *items_sep="\n") const
size_t SplitIntoLines(const std::string &lines)
void AppendString(const std::string &s)
const char * GetStringAtIndex(size_t idx) const
bool ForEach(std::function< bool(Object *object)> const &foreach_callback) const
std::optional< Dictionary * > GetItemAtIndexAsDictionary(size_t idx) const
Retrieves the element at index idx from a StructuredData::Array if it is a Dictionary.
bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result) const
bool GetValueForKeyAsBoolean(llvm::StringRef key, bool &result) const
bool GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const
std::shared_ptr< Dictionary > DictionarySP
std::shared_ptr< Object > ObjectSP
static ObjectSP ParseJSON(llvm::StringRef json_text)
lldb::BreakpointSP GetBreakpointByID(lldb::break_id_t break_id)
Debugger & GetDebugger() const
WatchpointList & GetWatchpointList()
"lldb/Core/ThreadedCommunication.h" Variation of Communication that supports threaded reads.
lldb::ValueObjectSP GetSP()
lldb::WatchpointSP FindByID(lldb::watch_id_t watchID) const
Returns a shared pointer to the watchpoint with id watchID, const version.
"lldb/Breakpoint/WatchpointOptions.h" Class that manages the options on a watchpoint.
void SetCallback(WatchpointHitCallback callback, const lldb::BatonSP &baton_sp, bool synchronous=false)
Adds a callback to the watchpoint option set.
static llvm::Expected< ArgInfo > GetArgInfoFromInspectSignature(const PythonCallable &callable)
StructuredData::DictionarySP CreateStructuredDictionary() const
PythonObject GetItemForKey(const PythonObject &key) const
void SetItemForKey(const PythonObject &key, const PythonObject &value)
static int TranslateFdToPython(int our_fd)
static llvm::Expected< PythonFile > FromFile(File &file, const char *mode=nullptr)
static PythonModule MainModule()
PythonDictionary GetDictionary() const
static llvm::Expected< PythonModule > Import(const llvm::Twine &name)
PythonObject ResolveName(llvm::StringRef name) const
static PythonObject ResolveNameWithDictionary(llvm::StringRef name, const PythonDictionary &dict)
llvm::Expected< PythonObject > GetAttribute(const llvm::Twine &name) const
llvm::Expected< PythonObject > CallMethod(const char *name, const T &... t) const
llvm::StringRef GetString() const
static bool LLDBSWIGPythonRunScriptKeywordValue(const char *python_function_name, const char *session_dictionary_name, const lldb::ValueObjectSP &value, std::string &output)
static bool LLDBSwigPythonCallTypeScript(const char *python_function_name, const void *session_dictionary, const lldb::ValueObjectSP &valobj_sp, void **pyfunct_wrapper, const lldb::TypeSummaryOptionsSP &options_sp, std::string &retval)
static void * LLDBSWIGPython_GetDynamicSetting(void *module, const char *setting, const lldb::TargetSP &target_sp)
static std::optional< std::string > LLDBSWIGPythonRunScriptKeywordThread(const char *python_function_name, const char *session_dictionary_name, lldb::ThreadSP thread)
static bool LLDBSwigPythonCallCommand(const char *python_function_name, const char *session_dictionary_name, lldb::DebuggerSP debugger, const char *args, lldb_private::CommandReturnObject &cmd_retobj, lldb::ExecutionContextRefSP exe_ctx_ref_sp)
static bool LLDBSWIGPythonRunScriptKeywordTarget(const char *python_function_name, const char *session_dictionary_name, const lldb::TargetSP &target, std::string &output)
static std::optional< std::string > LLDBSWIGPythonRunScriptKeywordFrame(const char *python_function_name, const char *session_dictionary_name, lldb::StackFrameSP frame)
static bool LLDBSWIGPythonRunScriptKeywordProcess(const char *python_function_name, const char *session_dictionary_name, const lldb::ProcessSP &process, std::string &output)
static bool LLDBSwigPythonFormatterCallbackFunction(const char *python_function_name, const char *session_dictionary_name, lldb::TypeImplSP type_impl_sp)
static bool LLDBSwigPythonCallModuleInit(const char *python_module_name, const char *session_dictionary_name, lldb::DebuggerSP debugger)
static bool LLDBSwigPythonWatchpointCallbackFunction(const char *python_function_name, const char *session_dictionary_name, const lldb::StackFrameSP &sb_frame, const lldb::WatchpointSP &sb_wp)
static bool LLDBSwigPythonCallModuleNewTarget(const char *python_module_name, const char *session_dictionary_name, lldb::TargetSP target)
static llvm::Expected< bool > LLDBSwigPythonBreakpointCallbackFunction(const char *python_function_name, const char *session_dictionary_name, const lldb::StackFrameSP &sb_frame, const lldb::BreakpointLocationSP &sb_bp_loc, const lldb_private::StructuredDataImpl &args_impl)
llvm::Expected< T > As(llvm::Expected< PythonObject > &&obj)
T unwrapIgnoringErrors(llvm::Expected< T > expected)
llvm::Expected< PythonObject > runStringMultiLine(const llvm::Twine &string, const PythonDictionary &globals, const PythonDictionary &locals)
int RunSimpleString(const char *str)
llvm::Expected< PythonObject > runStringOneLine(const llvm::Twine &string, const PythonDictionary &globals, const PythonDictionary &locals)
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
ScriptedCommandSynchronicity
@ eScriptedCommandSynchronicityAsynchronous
@ eScriptedCommandSynchronicitySynchronous
@ eScriptedCommandSynchronicityCurrentValue
ScriptedExtension
Scripting extension types.
@ eScriptedExtensionOperatingSystem
@ eScriptedExtensionScriptedHook
@ eScriptedExtensionParsedCommand
@ eScriptedExtensionScriptedPlatform
@ eScriptedExtensionScriptedCommand
@ eScriptedExtensionScriptedProcess
@ eScriptedExtensionScriptedFrame
@ eScriptedExtensionScriptedBreakpointResolver
@ eScriptedExtensionScriptedThreadPlan
@ eScriptedExtensionScriptedStringSummary
@ eScriptedExtensionScriptedFrameProvider
@ eScriptedExtensionScriptedThread
@ eScriptedExtensionScriptedStackFrameRecognizer
@ eScriptedExtensionScriptedSyntheticChildren
@ eScriptedExtensionInvalid
std::shared_ptr< lldb_private::ScriptedSyntheticChildrenInterface > ScriptedSyntheticChildrenInterfaceSP
std::shared_ptr< lldb_private::ScriptedHookInterface > ScriptedHookInterfaceSP
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
std::shared_ptr< lldb_private::ScriptedStringSummaryInterface > ScriptedStringSummaryInterfaceSP
std::shared_ptr< lldb_private::BreakpointLocation > BreakpointLocationSP
std::shared_ptr< lldb_private::IOHandler > IOHandlerSP
std::shared_ptr< lldb_private::ScriptInterpreter > ScriptInterpreterSP
std::shared_ptr< lldb_private::ScriptedThreadPlanInterface > ScriptedThreadPlanInterfaceSP
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
std::unique_ptr< lldb_private::File > FileUP
std::shared_ptr< lldb_private::TypeSummaryOptions > TypeSummaryOptionsSP
std::shared_ptr< lldb_private::OperatingSystemInterface > OperatingSystemInterfaceSP
std::shared_ptr< lldb_private::Breakpoint > BreakpointSP
std::shared_ptr< lldb_private::ScriptedBreakpointInterface > ScriptedBreakpointInterfaceSP
std::shared_ptr< lldb_private::ScriptedThreadInterface > ScriptedThreadInterfaceSP
std::shared_ptr< lldb_private::Debugger > DebuggerSP
std::shared_ptr< lldb_private::Watchpoint > WatchpointSP
std::shared_ptr< lldb_private::ScriptedFrameProviderInterface > ScriptedFrameProviderInterfaceSP
std::shared_ptr< lldb_private::ScriptedCommandInterface > ScriptedCommandInterfaceSP
std::shared_ptr< lldb_private::LockableStreamFile > LockableStreamFileSP
std::shared_ptr< lldb_private::TypeImpl > TypeImplSP
std::shared_ptr< lldb_private::Target > TargetSP
std::shared_ptr< lldb_private::File > FileSP
std::shared_ptr< lldb_private::ScriptedStackFrameRecognizerInterface > ScriptedStackFrameRecognizerInterfaceSP
std::unique_ptr< lldb_private::ScriptedProcessInterface > ScriptedProcessInterfaceUP
std::shared_ptr< lldb_private::ScriptedFrameInterface > ScriptedFrameInterfaceSP
std::shared_ptr< lldb_private::ExecutionContextRef > ExecutionContextRefSP
Describes one extension to emit into the generated template file.
lldb::user_id_t GetID() const
Get accessor for the user ID.
std::string script_source