27#include "lldb/Host/Config.h"
45#include "llvm/ADT/STLExtras.h"
46#include "llvm/ADT/StringExtras.h"
47#include "llvm/ADT/StringRef.h"
48#include "llvm/Support/Error.h"
49#include "llvm/Support/ErrorExtras.h"
50#include "llvm/Support/FileSystem.h"
51#include "llvm/Support/FormatAdapters.h"
74#define LLDBSwigPyInit PyInit__lldb
78#define LLDB_USE_PYTHON_SET_INTERRUPT 0
80#define LLDB_USE_PYTHON_SET_INTERRUPT 1
97struct InitializePythonRAII {
99 llvm::Error DoInitialize() {
100 const bool was_initialized = Py_IsInitialized();
104 if (!was_initialized) {
105#ifdef LLDB_USE_LIBEDIT_READLINE_COMPAT_MODULE
108 PyImport_AppendInittab(
"readline", initlldb_readline);
115#if LLDB_EMBED_PYTHON_HOME
116 if (!was_initialized) {
118 PyConfig_InitPythonConfig(&config);
120 static std::string g_python_home = []() -> std::string {
121 if (llvm::sys::path::is_absolute(LLDB_PYTHON_HOME))
122 return LLDB_PYTHON_HOME;
124 FileSpec spec = HostInfo::GetShlibDir();
130 if (!g_python_home.empty()) {
131 PyStatus status = PyConfig_SetBytesString(&config, &config.home,
132 g_python_home.c_str());
133 if (PyStatus_Exception(status)) {
134 PyConfig_Clear(&config);
135 return llvm::createStringError(
136 "failed to set the Python config: '%s'", status.err_msg);
140 config.install_signal_handlers = 0;
141 PyStatus status = Py_InitializeFromConfig(&config);
142 PyConfig_Clear(&config);
143 if (PyStatus_Exception(status))
144 return llvm::createStringError(
"Python failed to initialize: '%s'",
148 if (!was_initialized)
150 if (!Py_IsInitialized())
151 return llvm::createStringError(
"Python failed to initialize");
154 m_python_initialized =
true;
157 PyGILState_STATE gil_state = PyGILState_Ensure();
158 if (gil_state != PyGILState_UNLOCKED)
159 return llvm::Error::success();
161 m_was_already_initialized =
true;
162 m_gil_state = gil_state;
164 GetLog(LLDBLog::Script),
"Ensured PyGILState. Previous state = {0}",
165 m_gil_state == PyGILState_UNLOCKED ?
"unlocked" :
"locked");
166 return llvm::Error::success();
169 ~InitializePythonRAII() {
170 if (!m_python_initialized)
173 if (m_was_already_initialized) {
175 "Releasing PyGILState. Returning to state = {0}",
176 m_gil_state == PyGILState_UNLOCKED ?
"unlocked"
178 PyGILState_Release(m_gil_state);
186 PyGILState_STATE m_gil_state = PyGILState_UNLOCKED;
187 bool m_was_already_initialized =
false;
188 bool m_python_initialized =
false;
191#if LLDB_USE_PYTHON_SET_INTERRUPT
194struct RestoreSignalHandlerScope {
196 struct sigaction m_prev_handler;
198 RestoreSignalHandlerScope(
int signal_code) : m_signal_code(signal_code) {
200 std::memset(&m_prev_handler, 0,
sizeof(m_prev_handler));
202 struct sigaction *new_handler =
nullptr;
203 int signal_err = ::sigaction(m_signal_code, new_handler, &m_prev_handler);
204 lldbassert(signal_err == 0 &&
"sigaction failed to read handler");
206 ~RestoreSignalHandlerScope() {
207 int signal_err = ::sigaction(m_signal_code, &m_prev_handler,
nullptr);
208 lldbassert(signal_err == 0 &&
"sigaction failed to restore old handler");
216 auto style = llvm::sys::path::Style::posix;
218 llvm::StringRef path_ref(path.begin(), path.size());
219 auto rbegin = llvm::sys::path::rbegin(path_ref, style);
220 auto rend = llvm::sys::path::rend(path_ref);
221 auto framework = std::find(rbegin, rend,
"LLDB.framework");
222 if (framework == rend) {
226 path.resize(framework - rend);
227 llvm::sys::path::append(path, style,
"LLDB.framework",
"Resources",
"Python");
235 llvm::sys::path::remove_filename(path);
236 llvm::sys::path::append(path, LLDB_PYTHON_RELATIVE_LIBDIR);
241 std::replace(path.begin(), path.end(),
'\\',
'/');
247 FileSpec spec = HostInfo::GetShlibDir();
250 llvm::SmallString<64> path;
253#if defined(__APPLE__)
268def main(lldb_python_dir, python_exe_relative_path):
270 "lldb-pythonpath": lldb_python_dir,
271 "language": "python",
272 "prefix": sys.prefix,
273 "executable": os.path.join(sys.prefix, python_exe_relative_path)
283 if (!python_dir_spec)
291 return info_json.CreateStructuredDictionary();
298 return "lldb.plugins.operating_system";
300 return "lldb.plugins.scripted_platform";
302 return "lldb.plugins.scripted_process";
304 return "lldb.plugins.scripted_hook";
306 return "lldb.plugins.scripted_breakpoint";
308 return "lldb.plugins.scripted_thread_plan";
310 return "lldb.plugins.scripted_frame_provider";
313 return "lldb.plugins.scripted_process";
315 return "lldb.plugins.scripted_stackframe_recognizer";
318 return "lldb.plugins.scripted_command";
320 return "lldb.plugins.scripted_string_summary";
322 return "lldb.plugins.scripted_synthetic_children";
324 return llvm::createStringError(
"invalid extension name");
326 return llvm::createStringError(
"invalid extension name");
329llvm::Expected<StructuredData::ObjectSP>
331 const llvm::SmallVector<llvm::StringRef> &extension_path) {
335 if (!import_path_or_err)
336 return import_path_or_err.takeError();
345 command_stream.
Printf(
"lldb.embedded_interpreter.generate_extension_schema("
346 "__import__('%s', fromlist=['']).%s)",
347 import_path_or_err->c_str(),
356 void *result_obj =
nullptr;
361 return llvm::createStringError(
"invalid extension schema format");
367 std::string schema_str;
369 PyGILState_STATE gil_state = PyGILState_Ensure();
372 static_cast<PyObject *
>(result_obj));
376 PyGILState_Release(gil_state);
379 if (schema_str.empty())
380 return llvm::createStringError(
"empty extension schema");
385 Stream &s, llvm::StringRef output_script_prefix,
386 const llvm::SmallVector<llvm::StringRef> &extension_path,
387 bool generate_non_abstract_methods, std::set<std::string> &typing_imports) {
390 return schema_or_err.takeError();
394 return llvm::createStringError(
"empty extension schema");
397 return llvm::createStringError(
"extension schema is not a JSON object");
405 typing_imports.insert(str->GetValue().str());
409 llvm::StringRef base_class, import_path;
411 return llvm::createStringError(
412 llvm::formatv(
"extension schema dictionary is missing 'class' key")
415 return llvm::createStringError(
416 llvm::formatv(
"extension schema dictionary is missing 'module' key")
420 s.
Printf(
"from %s import %s\n", import_path.data(), base_class.data());
424 s.
Printf(
"class %s%s(%s):\n", output_script_prefix.data(), base_class.data(),
431 bool has_body =
false;
438 s.
Printf(
"Attributes inherited from %s:\n", base_class.data());
439 for (
size_t i = 0; i < attributes->
GetSize(); i++) {
444 llvm::StringRef attr_name;
447 llvm::StringRef attr_type;
450 s.
Printf(
"- %s", attr_name.data());
452 s.
Printf(
": %s", attr_type.data());
463 return llvm::createStringError(
"missing 'members' key in extension schema");
469 bool any_abstract =
false;
470 for (
size_t i = 0; i < members->
GetSize(); i++) {
474 bool is_abstract =
false;
475 if ((*maybe_dict)->GetValueForKeyAsBoolean(
"is_abstract", is_abstract) &&
481 bool emit_all_methods = generate_non_abstract_methods || !any_abstract;
483 for (
size_t i = 0; i < members->
GetSize(); i++) {
486 return llvm::createStringError(
488 "member at index {0} in extension schema isn't a dictionary")
492 llvm::StringRef symbol, args;
494 return llvm::createStringError(
496 "member at index {0} in extension schema is missing 'name' key")
499 return llvm::createStringError(
500 llvm::formatv(
"member at index {0} in extension schema is missing "
504 bool is_abstract =
false;
505 bool has_is_abstract =
507 if (!emit_all_methods)
508 if (!has_is_abstract || !is_abstract)
512 s.
Printf(
"def %s%s:\n", symbol.data(), args.data());
515 llvm::StringRef documentation;
520 llvm::SmallVector<llvm::StringRef> lines;
521 documentation.split(lines,
"\n");
523 for (llvm::StringRef line : lines) {
534 if (symbol ==
"__init__") {
540 llvm::StringRef params = args.trim(
"()");
541 std::vector<std::string> forwarded_args;
544 auto flush = [&](
size_t end) {
545 llvm::StringRef param = params.slice(start, end);
546 param = param.split(
':').first.split(
'=').first.trim();
547 if (!param.empty() && param !=
"self")
548 forwarded_args.push_back(param.str());
550 for (
size_t i = 0; i < params.size(); ++i) {
552 if (c ==
'[' || c ==
'(' || c ==
'{')
554 else if (c ==
']' || c ==
')' || c ==
'}')
556 else if (c ==
',' && depth == 0) {
561 flush(params.size());
563 s.
Printf(
"super().__init__(%s)\n",
564 llvm::join(forwarded_args,
", ").c_str());
583 return llvm::Error::success();
587 const std::string &name, std::vector<ExtensionTemplateRequest> &extensions,
588 bool generate_non_abstract_methods, std::string output_file) {
594 std::set<std::string> typing_imports;
597 if (llvm::Error err =
599 generate_non_abstract_methods, typing_imports))
600 return std::move(err);
605 generated_file_stream.
PutCString(
"import lldb\n");
606 if (!typing_imports.empty()) {
607 std::vector<std::string> sorted_imports(typing_imports.begin(),
608 typing_imports.end());
609 generated_file_stream.
Format(
"from typing import {0}\n",
610 llvm::join(sorted_imports,
", "));
616 if (output_file.empty()) {
621 std::string sanitized;
622 sanitized.reserve(name.size());
624 sanitized.push_back(llvm::isAlnum(c) ?
static_cast<char>(llvm::toLower(c))
626 if (sanitized.find_first_not_of(
'_') == std::string::npos)
627 sanitized =
"extension";
628 const std::string file_name =
"lldb_" + sanitized +
"_extension.py";
629 save_location = HostInfo::GetGlobalTempDir();
633 save_location =
FileSpec(output_file);
644 return opened_file.takeError();
646 FileUP file = std::move(opened_file.get());
648 size_t byte_size = generated_file_stream.
GetSize();
652 if (
error.Fail() || byte_size != generated_file_stream.
GetSize())
653 return llvm::createStringError(
"Unable to write to destination file. Bytes "
654 "written do not match generated file size.");
655 return save_location;
670 llvm::StringRef libdir = LLDB_PYTHON_RELATIVE_LIBDIR;
671 for (
auto it = llvm::sys::path::begin(libdir),
672 end = llvm::sys::path::end(libdir);
686 return "Embedded Python interpreter";
690 llvm::Expected<ScriptInterpreterRuntimeLoader &> loader =
697 if (llvm::Error
error = loader->Load()) {
707 setenv(
"PYTHONMALLOC",
"malloc",
true);
713#if !LLDB_ENABLE_DYNAMIC_SCRIPTINTERPRETERS
714 HostInfo::SetSharedLibraryDirectoryHelper(
758 "Ensured PyGILState. Previous state = {0}",
759 m_GILState == PyGILState_UNLOCKED ?
"unlocked" :
"locked");
781 "Releasing PyGILState. Returning to state = {0}",
782 m_GILState == PyGILState_UNLOCKED ?
"unlocked" :
"locked");
820 run_string.
Printf(
"run_one_line (%s, 'import copy, keyword, os, re, sys, "
821 "uuid, lldb, importlib')",
831 "run_one_line (%s, 'import lldb.formatters, lldb.formatters.cpp')",
836 run_string.
Printf(
"run_one_line (%s, 'import lldb.embedded_interpreter; from "
837 "lldb.embedded_interpreter import run_python_interpreter; "
838 "from lldb.embedded_interpreter import run_one_line')",
845 run_string.
Printf(
"run_one_line (%s, 'import pydoc; pydoc.pager = "
846 "pydoc.plainpager')",
851 run_string.
Printf(
"run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64
871 std::unique_ptr<SessionIORedirect> redirect(
877 std::unique_ptr<Connection> conn =
878 std::make_unique<ConnectionGenericFile>(read_handle,
true);
880 std::unique_ptr<Connection> conn =
881 std::make_unique<ConnectionFileDescriptor>(
884 if (!conn->IsConnected())
887 redirect->m_communication.SetConnection(std::move(conn));
888 redirect->m_communication.SetReadThreadBytesReceivedCallback(
890 if (!redirect->m_communication.StartReadThread())
892 redirect->m_connected =
true;
895 redirect->m_write_file_sp = std::make_shared<NativeFile>(
923 if (!src || !src_len)
928 debugger_sp->PrintAsync(
static_cast<const char *
>(src), src_len,
945 auto gil_state = PyGILState_Ensure();
947 PyGILState_Release(gil_state);
952 const char *instructions =
nullptr;
958 instructions = R
"(Enter your Python command(s). Type 'DONE' to end.
959def function (frame, bp_loc, internal_dict):
960 """frame: the lldb.SBFrame for the location at which you stopped
961 bp_loc: an lldb.SBBreakpointLocation for the breakpoint location information
962 internal_dict: an LLDB support object not to be used"""
966 instructions =
"Enter your Python command(s). Type 'DONE' to end.\n";
970 if (instructions && interactive) {
982 bool batch_mode =
m_debugger.GetCommandInterpreter().GetBatchCommandMode();
988 std::vector<std::reference_wrapper<BreakpointOptions>> *bp_options_vec =
989 (std::vector<std::reference_wrapper<BreakpointOptions>> *)
991 for (BreakpointOptions &bp_options : *bp_options_vec) {
993 auto data_up = std::make_unique<CommandDataPython>();
996 data_up->user_source.SplitIntoLines(data);
999 data_up->script_source,
1003 auto baton_sp = std::make_shared<BreakpointOptions::CommandBaton>(
1004 std::move(data_up));
1005 bp_options.SetCallback(
1007 }
else if (!batch_mode) {
1009 LockedStreamFile locked_stream = error_sp->Lock();
1010 locked_stream.
Printf(
"Warning: No command attached to breakpoint.\n");
1017 WatchpointOptions *wp_options =
1019 auto data_up = std::make_unique<WatchpointOptions::CommandData>();
1020 data_up->user_source.SplitIntoLines(data);
1023 data_up->user_source, data_up->script_source,
1026 LockedStreamFile locked_stream = error_sp->Lock();
1027 locked_stream <<
"error: " << llvm::toString(std::move(
error)) <<
"\n";
1029 llvm::consumeError(std::move(
error));
1033 std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up));
1045 return std::make_shared<ScriptInterpreterPythonImpl>(debugger);
1051 log->
PutCString(
"ScriptInterpreterPythonImpl::LeaveSession()");
1054 RunSimpleString(
"lldb.debugger = None; lldb.target = None; lldb.process "
1055 "= None; lldb.thread = None; lldb.frame = None");
1062 if (PyThreadState_GetDict()) {
1064 if (sys_module_dict.
IsValid()) {
1069 auto flush_redirect = [&](
const char *py_name,
1070 std::unique_ptr<SessionIORedirect> &redirect) {
1077 if (llvm::Expected<PythonObject> result = file.
CallMethod(
"flush"))
1080 llvm::consumeError(result.takeError());
1109 const char *py_name,
PythonObject &save_file,
const char *mode,
1111 const bool is_stdout = ::strcmp(py_name,
"stdout") == 0;
1112 if (!is_stdout && ::strcmp(py_name,
"stderr") != 0)
1127 fd != debugger_file->GetDescriptor())
1130 std::unique_ptr<SessionIORedirect> &redirect =
1139 PyObject *pipe_file = PyFile_FromFd(
1149 "failed to wrap sys.{0} on a synchronized pipe; falling back to "
1150 "the unsynchronized terminal descriptor",
1165 const char *py_name,
1168 bool serialize_terminal_output) {
1169 if (!file_sp || !*file_sp) {
1173 File &file = *file_sp;
1178 if (serialize_terminal_output &&
1190 "ScriptInterpreterPythonImpl::SetStdHandle failed to wrap "
1196 save_file = sys_module_dict.
GetItemForKey(PythonString(py_name));
1211 "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16
1212 ") session is already active, returning without doing anything",
1219 "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16
")",
1227 run_string.
Printf(
"run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64,
1230 "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64
")",
1232 run_string.
PutCString(
"; lldb.target = lldb.debugger.GetSelectedTarget()");
1233 run_string.
PutCString(
"; lldb.process = lldb.target.GetProcess()");
1234 run_string.
PutCString(
"; lldb.thread = lldb.process.GetSelectedThread ()");
1235 run_string.
PutCString(
"; lldb.frame = lldb.thread.GetSelectedFrame ()");
1240 run_string.
Printf(
"run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64,
1243 "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64
")",
1252 if (sys_module_dict.
IsValid()) {
1255 if (!in_sp || !out_sp || !err_sp || !*in_sp || !*out_sp || !*err_sp)
1256 m_debugger.AdoptTopIOHandlerFilesIfInvalid(top_in_sp, top_out_sp,
1272 const bool serialize_terminal_output =
1276 serialize_terminal_output)) {
1279 "w", serialize_terminal_output);
1283 serialize_terminal_output)) {
1286 "w", serialize_terminal_output);
1290 if (PyErr_Occurred())
1311 PyModule_GetDict(main_module.
get()));
1312 if (!main_dict.IsValid())
1328llvm::Expected<unsigned>
1330 const llvm::StringRef &callable_name) {
1331 if (callable_name.empty()) {
1332 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1333 "called with empty callable name.");
1340 callable_name, dict);
1342 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1343 "can't find callable: %s",
1344 callable_name.str().c_str());
1346 llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
1350 "GetArgInfo failed for callable {1}, falling back to "
1351 "inspect.signature: {0}",
1356 return arg_info.takeError();
1357 return arg_info.
get().max_positional_args;
1361 uint32_t &functions_counter,
1362 const void *name_token =
nullptr) {
1365 if (!base_name_wanted)
1366 return std::string();
1369 sstr.
Printf(
"%s_%d", base_name_wanted, functions_counter++);
1371 sstr.
Printf(
"%s_%p", base_name_wanted, name_token);
1381 PyImport_AddModule(
"lldb.embedded_interpreter"));
1382 if (!module.IsValid())
1386 PyModule_GetDict(module.get()));
1387 if (!module_dict.IsValid())
1391 module_dict.GetItemForKey(
PythonString(
"run_one_line"));
1393 module_dict.GetItemForKey(
PythonString(
"g_run_one_line_str"));
1400 std::string command_str = command.str();
1405 if (!command.empty()) {
1412 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
1415 if (!io_redirect_or_error) {
1418 "failed to redirect I/O: {0}\n",
1419 llvm::fmt_consume(io_redirect_or_error.takeError()));
1421 llvm::consumeError(io_redirect_or_error.takeError());
1427 bool success =
false;
1453 Py_BuildValue(
"(Os)", session_dict.
get(), command_str.c_str()));
1470 io_redirect.
Flush();
1479 command_str.c_str());
1485 result->
AppendError(
"empty command passed to python\n");
1501 return llvm::Error::success();
1504 if (io_handler_sp) {
1507 return llvm::Error::success();
1511#if LLDB_USE_PYTHON_SET_INTERRUPT
1519 PyErr_SetInterrupt();
1530 PyThreadState *state = PyThreadState_Get();
1534 long tid = PyThread_get_thread_ident();
1535 PyThreadState_Swap(state);
1536 int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt);
1538 "ScriptInterpreterPythonImpl::Interrupt() sending "
1539 "PyExc_KeyboardInterrupt (tid = %li, num_threads = %i)...",
1545 "ScriptInterpreterPythonImpl::Interrupt() python code not running, "
1555 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
1559 if (!io_redirect_or_error) {
1560 llvm::consumeError(io_redirect_or_error.takeError());
1584 Expected<PythonObject> maybe_py_return =
1587 if (!maybe_py_return) {
1588 llvm::handleAllErrors(
1589 maybe_py_return.takeError(),
1592 if (options.GetMaskoutErrors()) {
1593 if (E.Matches(PyExc_SyntaxError)) {
1599 [](
const llvm::ErrorInfoBase &E) {});
1603 PythonObject py_return = std::move(maybe_py_return.get());
1606 switch (return_type) {
1607 case eScriptReturnTypeCharPtr:
1609 const char format[3] =
"s#";
1610 return PyArg_Parse(py_return.
get(), format, (
char **)ret_value);
1612 case eScriptReturnTypeCharStrOrNone:
1615 const char format[3] =
"z";
1616 return PyArg_Parse(py_return.
get(), format, (
char **)ret_value);
1618 case eScriptReturnTypeBool: {
1619 const char format[2] =
"b";
1620 return PyArg_Parse(py_return.
get(), format, (
bool *)ret_value);
1622 case eScriptReturnTypeShortInt: {
1623 const char format[2] =
"h";
1624 return PyArg_Parse(py_return.
get(), format, (
short *)ret_value);
1626 case eScriptReturnTypeShortIntUnsigned: {
1627 const char format[2] =
"H";
1628 return PyArg_Parse(py_return.
get(), format, (
unsigned short *)ret_value);
1630 case eScriptReturnTypeInt: {
1631 const char format[2] =
"i";
1632 return PyArg_Parse(py_return.
get(), format, (
int *)ret_value);
1634 case eScriptReturnTypeIntUnsigned: {
1635 const char format[2] =
"I";
1636 return PyArg_Parse(py_return.
get(), format, (
unsigned int *)ret_value);
1638 case eScriptReturnTypeLongInt: {
1639 const char format[2] =
"l";
1640 return PyArg_Parse(py_return.
get(), format, (
long *)ret_value);
1642 case eScriptReturnTypeLongIntUnsigned: {
1643 const char format[2] =
"k";
1644 return PyArg_Parse(py_return.
get(), format, (
unsigned long *)ret_value);
1646 case eScriptReturnTypeLongLong: {
1647 const char format[2] =
"L";
1648 return PyArg_Parse(py_return.
get(), format, (
long long *)ret_value);
1650 case eScriptReturnTypeLongLongUnsigned: {
1651 const char format[2] =
"K";
1652 return PyArg_Parse(py_return.
get(), format,
1653 (
unsigned long long *)ret_value);
1655 case eScriptReturnTypeFloat: {
1656 const char format[2] =
"f";
1657 return PyArg_Parse(py_return.
get(), format, (
float *)ret_value);
1659 case eScriptReturnTypeDouble: {
1660 const char format[2] =
"d";
1661 return PyArg_Parse(py_return.
get(), format, (
double *)ret_value);
1663 case eScriptReturnTypeChar: {
1664 const char format[2] =
"c";
1665 return PyArg_Parse(py_return.
get(), format, (
char *)ret_value);
1667 case eScriptReturnTypeOpaqueObject: {
1668 *((PyObject **)ret_value) = py_return.
release();
1672 llvm_unreachable(
"Fully covered switch!");
1678 if (in_string ==
nullptr)
1681 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
1685 if (!io_redirect_or_error)
1688 ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
1708 Expected<PythonObject> return_value =
1711 if (!return_value) {
1713 llvm::handleErrors(return_value.takeError(), [&](PythonException &E) {
1714 llvm::Error error = llvm::createStringError(
1715 llvm::inconvertibleErrorCode(), E.ReadBacktrace());
1716 if (!options.GetMaskoutErrors())
1727 std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
1730 m_debugger.GetCommandInterpreter().GetPythonCommandsFromIOHandler(
1731 " ", *
this, &bp_options_vec);
1737 m_debugger.GetCommandInterpreter().GetPythonCommandsFromIOHandler(
1738 " ", *
this, wp_options);
1745 std::string function_signature = function_name;
1747 llvm::Expected<unsigned> maybe_args =
1750 return llvm::createStringErrorV(
"could not get num args: {0}",
1751 llvm::fmt_consume(maybe_args.takeError()));
1752 size_t max_args = *maybe_args;
1754 bool uses_extra_args =
false;
1755 if (max_args >= 4) {
1756 uses_extra_args =
true;
1757 function_signature +=
"(frame, bp_loc, extra_args, internal_dict)";
1758 }
else if (max_args >= 3) {
1760 return llvm::createStringError(
1761 "cannot pass extra_args to a three argument callback");
1762 uses_extra_args =
false;
1763 function_signature +=
"(frame, bp_loc, internal_dict)";
1765 return llvm::createStringErrorV(
1766 "expected 3 or 4 argument function, {0} can only take {1}",
1767 function_name, max_args);
1771 extra_args_sp, uses_extra_args,
1777 std::unique_ptr<BreakpointOptions::CommandData> &cmd_data_up) {
1779 cmd_data_up->user_source, cmd_data_up->script_source,
1783 return error.takeError();
1785 std::make_shared<BreakpointOptions::CommandBaton>(std::move(cmd_data_up));
1788 return llvm::Error::success();
1795 false, is_callback);
1803 auto data_up = std::make_unique<CommandDataPython>(extra_args_sp);
1809 data_up->user_source.SplitIntoLines(command_body_text);
1811 data_up->user_source, data_up->script_source, uses_extra_args,
1814 return error.takeError();
1816 std::make_shared<BreakpointOptions::CommandBaton>(std::move(data_up));
1819 return llvm::Error::success();
1825 auto data_up = std::make_unique<WatchpointOptions::CommandData>();
1832 data_up->user_source.AppendString(user_input);
1833 data_up->script_source.assign(user_input);
1836 data_up->user_source, data_up->script_source, is_callback))
1840 std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up));
1843 return llvm::Error::success();
1849 std::string function_def_string(function_def.
CopyList());
1851 function_def_string.c_str());
1862 int num_lines = input.
GetSize();
1863 if (num_lines == 0) {
1868 if (!signature || *signature == 0) {
1874 StringList auto_generated_function;
1877 " global_dict = globals()");
1879 " new_keys = internal_dict.keys()");
1882 " old_keys = global_dict.keys()");
1884 " global_dict.update(internal_dict)");
1891 if (num_lines == 1) {
1897 "ScriptInterpreterPythonImpl::GenerateFunction(is_callback="
1898 "true) = ERROR: python function is multiline.");
1902 " __return_val = None");
1904 " def __user_code():");
1908 for (
int i = 0; i < num_lines; ++i) {
1914 " __return_val = __user_code()");
1918 " for key in new_keys:");
1921 " if key in old_keys:");
1924 " internal_dict[key] = global_dict[key]");
1926 " elif key in global_dict:");
1929 " del global_dict[key]");
1932 " return __return_val");
1941 StringList &user_input, std::string &output,
const void *name_token) {
1942 static uint32_t num_created_functions = 0;
1947 if (user_input.
GetSize() == 0)
1953 std::string auto_generated_function_name(
1955 num_created_functions, name_token));
1956 sstr.
Printf(
"def %s (valobj, internal_dict):",
1957 auto_generated_function_name.c_str());
1964 output.assign(auto_generated_function_name);
1969 StringList &user_input, std::string &output) {
1970 static uint32_t num_created_functions = 0;
1975 if (user_input.
GetSize() == 0)
1979 "lldb_autogen_python_cmd_alias_func", num_created_functions));
1981 sstr.
Printf(
"def %s (debugger, args, exe_ctx, result, internal_dict):",
1982 auto_generated_function_name.c_str());
1989 output.assign(auto_generated_function_name);
1994 StringList &user_input, std::string &output,
const void *name_token) {
1995 static uint32_t num_created_classes = 0;
1997 int num_lines = user_input.
GetSize();
2001 if (user_input.
GetSize() == 0)
2007 "lldb_autogen_python_type_synth_class", num_created_classes, name_token));
2013 sstr.
Printf(
"class %s:", auto_generated_class_name.c_str());
2019 for (
int i = 0; i < num_lines; ++i) {
2033 output.assign(auto_generated_class_name);
2039 return std::make_unique<ScriptedProcessPythonInterface>(*
this);
2044 return std::make_shared<ScriptedHookPythonInterface>(*
this);
2049 return std::make_shared<ScriptedBreakpointPythonInterface>(*
this);
2054 return std::make_shared<ScriptedStackFrameRecognizerPythonInterface>(*
this);
2059 return std::make_shared<ScriptedCommandPythonInterface>(*
this);
2064 return std::make_shared<ScriptedStringSummaryPythonInterface>(*
this);
2069 return std::make_shared<ScriptedSyntheticChildrenPythonInterface>(*
this);
2074 return std::make_shared<ScriptedThreadPythonInterface>(*
this);
2079 return std::make_shared<ScriptedFramePythonInterface>(*
this);
2084 return std::make_shared<ScriptedFrameProviderPythonInterface>(*
this);
2089 return std::make_shared<ScriptedThreadPlanPythonInterface>(*
this);
2094 return std::make_shared<OperatingSystemPythonInterface>(*
this);
2100 void *ptr =
const_cast<void *
>(obj.
GetPointer());
2103 if (!py_obj.IsValid() || py_obj.IsNone())
2105 return py_obj.CreateStructuredObject();
2118 LoadScriptOptions load_script_options =
2119 LoadScriptOptions().SetInitSession(
true).SetSilent(
false);
2130 if (!plugin_module_sp || !target || !setting_name || !setting_name[0])
2138 TargetSP target_sp(target->shared_from_this());
2141 generic->GetValue(), setting_name, target_sp);
2156 const char *oneliner, std::string &output,
const void *name_token) {
2163 const char *oneliner, std::string &output,
const void *name_token) {
2170 StringList &user_input, std::string &output,
bool has_extra_args,
2172 static uint32_t num_created_functions = 0;
2176 if (user_input.
GetSize() == 0) {
2182 "lldb_autogen_python_bp_callback_func_", num_created_functions));
2184 sstr.
Printf(
"def %s (frame, bp_loc, extra_args, internal_dict):",
2185 auto_generated_function_name.c_str());
2187 sstr.
Printf(
"def %s (frame, bp_loc, internal_dict):",
2188 auto_generated_function_name.c_str());
2191 if (!
error.Success())
2195 output.assign(auto_generated_function_name);
2200 StringList &user_input, std::string &output,
bool is_callback) {
2201 static uint32_t num_created_functions = 0;
2205 if (user_input.
GetSize() == 0)
2206 return llvm::createStringError(
"No input data.");
2209 "lldb_autogen_python_wp_callback_func_", num_created_functions));
2210 sstr.
Printf(
"def %s (frame, wp, internal_dict):",
2211 auto_generated_function_name.c_str());
2215 return error.takeError();
2218 output.assign(auto_generated_function_name);
2219 return llvm::Error::success();
2229 if (!valobj.get()) {
2230 retval.assign(
"<no object>");
2234 void *old_callee =
nullptr;
2236 if (callee_wrapper_sp) {
2237 generic = callee_wrapper_sp->GetAsGeneric();
2239 old_callee =
generic->GetValue();
2241 void *new_callee = old_callee;
2244 if (python_function_name && *python_function_name) {
2251 static Timer::Category func_cat(
"LLDBSwigPythonCallTypeScript");
2252 Timer scoped_timer(func_cat,
"LLDBSwigPythonCallTypeScript");
2255 &new_callee, options_sp, retval);
2259 retval.assign(
"<no function name>");
2263 if (new_callee && old_callee != new_callee) {
2266 callee_wrapper_sp = std::make_shared<StructuredPythonObject>(
2267 PythonObject(PyRefType::Borrowed,
static_cast<PyObject *
>(new_callee)));
2274 const char *python_function_name,
TypeImplSP type_impl_sp) {
2284 CommandDataPython *bp_option_data = (CommandDataPython *)baton;
2285 const char *python_function_name = bp_option_data->script_source.c_str();
2291 Target *target = exe_ctx.GetTargetPtr();
2300 if (!python_interpreter)
2303 if (python_function_name && python_function_name[0]) {
2304 const StackFrameSP stop_frame_sp(exe_ctx.GetFrameSP());
2306 if (breakpoint_sp) {
2308 breakpoint_sp->FindLocationByID(break_loc_id));
2310 if (stop_frame_sp && bp_loc_sp) {
2311 bool ret_val =
true;
2316 Expected<bool> maybe_ret_val =
2318 python_function_name,
2320 bp_loc_sp, bp_option_data->m_extra_args);
2322 if (!maybe_ret_val) {
2324 llvm::handleAllErrors(
2325 maybe_ret_val.takeError(),
2327 *debugger.GetAsyncErrorStream() << E.ReadBacktrace();
2329 [&](
const llvm::ErrorInfoBase &E) {
2330 *debugger.GetAsyncErrorStream() << E.message();
2334 ret_val = maybe_ret_val.get();
2350 const char *python_function_name = wp_option_data->
script_source.c_str();
2365 if (!python_interpreter)
2368 if (python_function_name && python_function_name[0]) {
2372 if (stop_frame_sp && wp_sp) {
2373 bool ret_val =
true;
2379 python_function_name,
2393 const char *impl_function,
Process *process, std::string &output,
2400 if (!impl_function || !impl_function[0]) {
2418 const char *impl_function,
Thread *thread, std::string &output,
2424 if (!impl_function || !impl_function[0]) {
2431 if (std::optional<std::string> result =
2434 thread->shared_from_this())) {
2435 output = std::move(*result);
2443 const char *impl_function,
Target *target, std::string &output,
2450 if (!impl_function || !impl_function[0]) {
2456 TargetSP target_sp(target->shared_from_this());
2468 const char *impl_function,
StackFrame *frame, std::string &output,
2474 if (!impl_function || !impl_function[0]) {
2481 if (std::optional<std::string> result =
2484 frame->shared_from_this())) {
2485 output = std::move(*result);
2493 const char *impl_function,
ValueObject *value, std::string &output,
2500 if (!impl_function || !impl_function[0]) {
2516uint64_t
replace_all(std::string &str,
const std::string &oldStr,
2517 const std::string &newStr) {
2519 uint64_t matches = 0;
2520 while ((pos = str.find(oldStr, pos)) != std::string::npos) {
2522 str.replace(pos, oldStr.length(), newStr);
2523 pos += newStr.length();
2532 namespace fs = llvm::sys::fs;
2533 namespace path = llvm::sys::path;
2539 if (!pathname || !pathname[0]) {
2544 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
2548 if (!io_redirect_or_error) {
2553 ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
2565 auto ExtendSysPath = [&](std::string directory) -> llvm::Error {
2566 if (directory.empty()) {
2567 return llvm::createStringError(
"invalid directory name");
2574 StreamString command_stream;
2575 command_stream.
Printf(
"if not (sys.path.__contains__('%s')):\n "
2576 "sys.path.insert(1,'%s');\n\n",
2577 directory.c_str(), directory.c_str());
2578 bool syspath_retval =
2580 if (!syspath_retval)
2581 return llvm::createStringError(
"Python sys.path handling failed");
2583 return llvm::Error::success();
2586 std::string module_name(pathname);
2587 bool possible_package =
false;
2589 if (extra_search_dir) {
2590 if (llvm::Error e = ExtendSysPath(extra_search_dir.
GetPath())) {
2595 FileSpec module_file(pathname);
2599 std::error_code ec = status(module_file.GetPath(), st);
2601 if (ec || st.type() == fs::file_type::status_error ||
2602 st.type() == fs::file_type::type_unknown ||
2603 st.type() == fs::file_type::file_not_found) {
2606 if (strchr(pathname,
'\\') || strchr(pathname,
'/')) {
2612 possible_package =
true;
2613 }
else if (is_directory(st) || is_regular_file(st)) {
2614 if (module_file.GetDirectory().empty()) {
2616 "invalid directory name '{0}'", pathname);
2619 if (llvm::Error e = ExtendSysPath(module_file.GetDirectory().str())) {
2623 module_name = module_file.GetFilename().str();
2626 "no known way to import this module specification");
2632 llvm::StringRef extension = llvm::sys::path::extension(module_name);
2633 if (!extension.empty()) {
2634 if (extension ==
".py")
2635 module_name.resize(module_name.length() - 3);
2636 else if (extension ==
".pyc")
2637 module_name.resize(module_name.length() - 4);
2640 if (!possible_package && module_name.find(
'.') != llvm::StringRef::npos) {
2642 "Python does not allow dots in module names: %s", module_name.c_str());
2646 if (module_name.find(
'-') != llvm::StringRef::npos) {
2648 "Python discourages dashes in module names: %s", module_name.c_str());
2653 StreamString command_stream;
2654 command_stream.
Clear();
2655 command_stream.
Printf(
"sys.modules.__contains__('%s')", module_name.c_str());
2656 bool does_contain =
false;
2664 const bool was_imported_globally = does_contain_executed && does_contain;
2665 const bool was_imported_locally =
2671 command_stream.
Clear();
2673 if (was_imported_globally || was_imported_locally) {
2674 if (!was_imported_locally)
2675 command_stream.
Printf(
"import %s ; importlib.reload(%s)",
2676 module_name.c_str(), module_name.c_str());
2678 command_stream.
Printf(
"importlib.reload(%s)", module_name.c_str());
2680 command_stream.
Printf(
"import %s", module_name.c_str());
2697 command_stream.
Clear();
2698 command_stream.
Printf(
"%s", module_name.c_str());
2699 void *module_pyobj =
nullptr;
2705 *module_sp = std::make_shared<StructuredPythonObject>(PythonObject(
2706 PyRefType::Owned,
static_cast<PyObject *
>(module_pyobj)));
2719 if (!word || !word[0])
2722 llvm::StringRef word_sr(word);
2726 if (word_sr.find(
'"') != llvm::StringRef::npos ||
2727 word_sr.find(
'\'') != llvm::StringRef::npos)
2731 command_stream.
Printf(
"keyword.iskeyword('%s')", word);
2746 : m_debugger_sp(debugger_sp), m_synch_wanted(synchro),
2747 m_old_asynch(debugger_sp->GetAsyncExecution()) {
2756 m_debugger_sp->SetAsyncExecution(m_old_asynch);
2760 const char *impl_function, llvm::StringRef args,
2764 if (!impl_function) {
2772 if (!debugger_sp.get()) {
2777 bool ret_val =
false;
2787 std::string args_str = args.str();
2790 cmd_retobj, exe_ctx_ref_sp);
2808 std::string &dest) {
2811 if (!item || !*item)
2814 std::string command(item);
2815 command +=
".__doc__";
2819 char *result_ptr =
nullptr;
2825 dest.assign(result_ptr);
2830 str_stream <<
"Function " << item
2831 <<
" was not found. Containing module might be missing.";
2832 dest = std::string(str_stream.
GetString());
2837std::unique_ptr<ScriptInterpreterLocker>
2839 std::unique_ptr<ScriptInterpreterLocker> py_lock(
new Locker(
2852 InitializePythonRAII initialize_guard;
2853 if (llvm::Error
error = initialize_guard.DoInitialize())
2870 if (
FileSpec file_spec = HostInfo::GetShlibDir())
2874 "lldb.embedded_interpreter; from "
2875 "lldb.embedded_interpreter import run_python_interpreter; "
2876 "from lldb.embedded_interpreter import run_one_line");
2878#if LLDB_USE_PYTHON_SET_INTERRUPT
2882 RestoreSignalHandlerScope save_sigint(SIGINT);
2890 " def signal_handler(sig, frame):\n"
2891 " raise KeyboardInterrupt()\n"
2892 " signal.signal(signal.SIGINT, signal_handler);\n"
2893 "lldb_setup_sigint_handler();\n"
2894 "del lldb_setup_sigint_handler\n");
2896 return llvm::Error::success();
2901 std::string statement;
2903 statement.assign(
"sys.path.insert(0,\"");
2904 statement.append(path);
2905 statement.append(
"\")");
2907 statement.assign(
"sys.path.append(\"");
2908 statement.append(path);
2909 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 void SetScriptInterpreterError(lldb::ScriptLanguage script_lang, llvm::Error error)
Records why no script interpreter for script_lang could be registered, for the fallback interpreter t...
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
llvm::Error SetBreakpointCommandCallbackFunction(BreakpointOptions &bp_options, const char *function_name, StructuredData::ObjectSP extra_args_sp) override
Set a script function as the callback for the breakpoint.
python::PythonObject m_run_one_line_function
python::PythonObject m_saved_stderr
friend class IOHandlerPythonInterpreter
bool Interrupt() override
ScriptInterpreterPythonImpl(Debugger &debugger)
llvm::Error GenerateWatchpointCommandCallbackData(StringList &input, std::string &output, bool is_callback) override
lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() override
llvm::Error SetBreakpointCommandCallback(BreakpointOptions &bp_options, const char *callback_body, bool is_callback) override
Set the callback body text into the callback for the breakpoint.
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
llvm::Error SetWatchpointCommandCallback(WatchpointOptions *wp_options, const char *user_input, bool is_callback) override
Set a one-liner as the callback for the watchpoint.
python::PythonObject m_saved_stdin
PyThreadState * GetThreadState()
lldb::ScriptedStackFrameRecognizerInterfaceSP CreateScriptedStackFrameRecognizerInterface() override
bool EnterSession(uint16_t on_entry_flags, lldb::FileSP in, lldb::FileSP out, lldb::FileSP err)
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
static lldb::ScriptInterpreterSP CreateInstance(Debugger &debugger, lldb::ScriptLanguage)
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
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
llvm::Error ExecuteInterpreterLoop() override
python::PythonObject m_run_one_line_str_global
static bool WatchpointCallbackFunction(void *baton, StoppointCallbackContext *context, lldb::user_id_t watch_id)
~ScriptInterpreterPythonImpl() override
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
static llvm::Expected< ScriptInterpreterRuntimeLoader & > Get(lldb::ScriptLanguage language)
Returns the loader for language.
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
ScriptLanguage
Script interpreter types.
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