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 InitializePythonRAII() {
101 if (!Py_IsInitialized()) {
102#ifdef LLDB_USE_LIBEDIT_READLINE_COMPAT_MODULE
105 PyImport_AppendInittab(
"readline", initlldb_readline);
112#if LLDB_EMBED_PYTHON_HOME
114 PyConfig_InitPythonConfig(&config);
116 static std::string g_python_home = []() -> std::string {
117 if (llvm::sys::path::is_absolute(LLDB_PYTHON_HOME))
118 return LLDB_PYTHON_HOME;
120 FileSpec spec = HostInfo::GetShlibDir();
126 if (!g_python_home.empty()) {
127 PyConfig_SetBytesString(&config, &config.home, g_python_home.c_str());
130 config.install_signal_handlers = 0;
131 Py_InitializeFromConfig(&config);
132 PyConfig_Clear(&config);
138 PyGILState_STATE gil_state = PyGILState_Ensure();
139 if (gil_state != PyGILState_UNLOCKED)
142 m_was_already_initialized =
true;
143 m_gil_state = gil_state;
145 GetLog(LLDBLog::Script),
"Ensured PyGILState. Previous state = {0}",
146 m_gil_state == PyGILState_UNLOCKED ?
"unlocked" :
"locked");
149 ~InitializePythonRAII() {
150 if (m_was_already_initialized) {
152 "Releasing PyGILState. Returning to state = {0}",
153 m_gil_state == PyGILState_UNLOCKED ?
"unlocked"
155 PyGILState_Release(m_gil_state);
163 PyGILState_STATE m_gil_state = PyGILState_UNLOCKED;
164 bool m_was_already_initialized =
false;
167#if LLDB_USE_PYTHON_SET_INTERRUPT
170struct RestoreSignalHandlerScope {
172 struct sigaction m_prev_handler;
174 RestoreSignalHandlerScope(
int signal_code) : m_signal_code(signal_code) {
176 std::memset(&m_prev_handler, 0,
sizeof(m_prev_handler));
178 struct sigaction *new_handler =
nullptr;
179 int signal_err = ::sigaction(m_signal_code, new_handler, &m_prev_handler);
180 lldbassert(signal_err == 0 &&
"sigaction failed to read handler");
182 ~RestoreSignalHandlerScope() {
183 int signal_err = ::sigaction(m_signal_code, &m_prev_handler,
nullptr);
184 lldbassert(signal_err == 0 &&
"sigaction failed to restore old handler");
192 auto style = llvm::sys::path::Style::posix;
194 llvm::StringRef path_ref(path.begin(), path.size());
195 auto rbegin = llvm::sys::path::rbegin(path_ref, style);
196 auto rend = llvm::sys::path::rend(path_ref);
197 auto framework = std::find(rbegin, rend,
"LLDB.framework");
198 if (framework == rend) {
202 path.resize(framework - rend);
203 llvm::sys::path::append(path, style,
"LLDB.framework",
"Resources",
"Python");
211 llvm::sys::path::remove_filename(path);
212 llvm::sys::path::append(path, LLDB_PYTHON_RELATIVE_LIBDIR);
217 std::replace(path.begin(), path.end(),
'\\',
'/');
223 FileSpec spec = HostInfo::GetShlibDir();
226 llvm::SmallString<64> path;
229#if defined(__APPLE__)
244def main(lldb_python_dir, python_exe_relative_path):
246 "lldb-pythonpath": lldb_python_dir,
247 "language": "python",
248 "prefix": sys.prefix,
249 "executable": os.path.join(sys.prefix, python_exe_relative_path)
259 if (!python_dir_spec)
267 return info_json.CreateStructuredDictionary();
274 return "lldb.plugins.operating_system";
276 return "lldb.plugins.scripted_platform";
278 return "lldb.plugins.scripted_process";
280 return "lldb.plugins.scripted_hook";
282 return "lldb.plugins.scripted_breakpoint";
284 return "lldb.plugins.scripted_thread_plan";
286 return "lldb.plugins.scripted_frame_provider";
289 return "lldb.plugins.scripted_process";
291 return "lldb.plugins.scripted_stackframe_recognizer";
294 return "lldb.plugins.scripted_command";
296 return "lldb.plugins.scripted_string_summary";
298 return "lldb.plugins.scripted_synthetic_children";
300 return llvm::createStringError(
"invalid extension name");
302 return llvm::createStringError(
"invalid extension name");
305llvm::Expected<StructuredData::ObjectSP>
307 const llvm::SmallVector<llvm::StringRef> &extension_path) {
311 if (!import_path_or_err)
312 return import_path_or_err.takeError();
321 command_stream.
Printf(
"lldb.embedded_interpreter.generate_extension_schema("
322 "__import__('%s', fromlist=['']).%s)",
323 import_path_or_err->c_str(),
332 void *result_obj =
nullptr;
337 return llvm::createStringError(
"invalid extension schema format");
343 std::string schema_str;
345 PyGILState_STATE gil_state = PyGILState_Ensure();
348 static_cast<PyObject *
>(result_obj));
352 PyGILState_Release(gil_state);
355 if (schema_str.empty())
356 return llvm::createStringError(
"empty extension schema");
361 Stream &s, llvm::StringRef output_script_prefix,
362 const llvm::SmallVector<llvm::StringRef> &extension_path,
363 bool generate_non_abstract_methods, std::set<std::string> &typing_imports) {
366 return schema_or_err.takeError();
370 return llvm::createStringError(
"empty extension schema");
373 return llvm::createStringError(
"extension schema is not a JSON object");
381 typing_imports.insert(str->GetValue().str());
385 llvm::StringRef base_class, import_path;
387 return llvm::createStringError(
388 llvm::formatv(
"extension schema dictionary is missing 'class' key")
391 return llvm::createStringError(
392 llvm::formatv(
"extension schema dictionary is missing 'module' key")
396 s.
Printf(
"from %s import %s\n", import_path.data(), base_class.data());
400 s.
Printf(
"class %s%s(%s):\n", output_script_prefix.data(), base_class.data(),
407 bool has_body =
false;
414 s.
Printf(
"Attributes inherited from %s:\n", base_class.data());
415 for (
size_t i = 0; i < attributes->
GetSize(); i++) {
420 llvm::StringRef attr_name;
423 llvm::StringRef attr_type;
426 s.
Printf(
"- %s", attr_name.data());
428 s.
Printf(
": %s", attr_type.data());
439 return llvm::createStringError(
"missing 'members' key in extension schema");
445 bool any_abstract =
false;
446 for (
size_t i = 0; i < members->
GetSize(); i++) {
450 bool is_abstract =
false;
451 if ((*maybe_dict)->GetValueForKeyAsBoolean(
"is_abstract", is_abstract) &&
457 bool emit_all_methods = generate_non_abstract_methods || !any_abstract;
459 for (
size_t i = 0; i < members->
GetSize(); i++) {
462 return llvm::createStringError(
464 "member at index {0} in extension schema isn't a dictionary")
468 llvm::StringRef symbol, args;
470 return llvm::createStringError(
472 "member at index {0} in extension schema is missing 'name' key")
475 return llvm::createStringError(
476 llvm::formatv(
"member at index {0} in extension schema is missing "
480 bool is_abstract =
false;
481 bool has_is_abstract =
483 if (!emit_all_methods)
484 if (!has_is_abstract || !is_abstract)
488 s.
Printf(
"def %s%s:\n", symbol.data(), args.data());
491 llvm::StringRef documentation;
496 llvm::SmallVector<llvm::StringRef> lines;
497 documentation.split(lines,
"\n");
499 for (llvm::StringRef line : lines) {
510 if (symbol ==
"__init__") {
516 llvm::StringRef params = args.trim(
"()");
517 std::vector<std::string> forwarded_args;
520 auto flush = [&](
size_t end) {
521 llvm::StringRef param = params.slice(start, end);
522 param = param.split(
':').first.split(
'=').first.trim();
523 if (!param.empty() && param !=
"self")
524 forwarded_args.push_back(param.str());
526 for (
size_t i = 0; i < params.size(); ++i) {
528 if (c ==
'[' || c ==
'(' || c ==
'{')
530 else if (c ==
']' || c ==
')' || c ==
'}')
532 else if (c ==
',' && depth == 0) {
537 flush(params.size());
539 s.
Printf(
"super().__init__(%s)\n",
540 llvm::join(forwarded_args,
", ").c_str());
559 return llvm::Error::success();
563 const std::string &name, std::vector<ExtensionTemplateRequest> &extensions,
564 bool generate_non_abstract_methods, std::string output_file) {
570 std::set<std::string> typing_imports;
573 if (llvm::Error err =
575 generate_non_abstract_methods, typing_imports))
576 return std::move(err);
581 generated_file_stream.
PutCString(
"import lldb\n");
582 if (!typing_imports.empty()) {
583 std::vector<std::string> sorted_imports(typing_imports.begin(),
584 typing_imports.end());
585 generated_file_stream.
Format(
"from typing import {0}\n",
586 llvm::join(sorted_imports,
", "));
592 if (output_file.empty()) {
597 std::string sanitized;
598 sanitized.reserve(name.size());
600 sanitized.push_back(llvm::isAlnum(c) ?
static_cast<char>(llvm::toLower(c))
602 if (sanitized.find_first_not_of(
'_') == std::string::npos)
603 sanitized =
"extension";
604 const std::string file_name =
"lldb_" + sanitized +
"_extension.py";
605 save_location = HostInfo::GetGlobalTempDir();
609 save_location =
FileSpec(output_file);
620 return opened_file.takeError();
622 FileUP file = std::move(opened_file.get());
624 size_t byte_size = generated_file_stream.
GetSize();
628 if (
error.Fail() || byte_size != generated_file_stream.
GetSize())
629 return llvm::createStringError(
"Unable to write to destination file. Bytes "
630 "written do not match generated file size.");
631 return save_location;
646 llvm::StringRef libdir = LLDB_PYTHON_RELATIVE_LIBDIR;
647 for (
auto it = llvm::sys::path::begin(libdir),
648 end = llvm::sys::path::end(libdir);
662 return "Embedded Python interpreter";
670 setenv(
"PYTHONMALLOC",
"malloc",
true);
676#if !LLDB_ENABLE_DYNAMIC_SCRIPTINTERPRETERS
677 HostInfo::SetSharedLibraryDirectoryHelper(
711 "Ensured PyGILState. Previous state = {0}",
712 m_GILState == PyGILState_UNLOCKED ?
"unlocked" :
"locked");
734 "Releasing PyGILState. Returning to state = {0}",
735 m_GILState == PyGILState_UNLOCKED ?
"unlocked" :
"locked");
773 run_string.
Printf(
"run_one_line (%s, 'import copy, keyword, os, re, sys, "
774 "uuid, lldb, importlib')",
784 "run_one_line (%s, 'import lldb.formatters, lldb.formatters.cpp')",
789 run_string.
Printf(
"run_one_line (%s, 'import lldb.embedded_interpreter; from "
790 "lldb.embedded_interpreter import run_python_interpreter; "
791 "from lldb.embedded_interpreter import run_one_line')",
798 run_string.
Printf(
"run_one_line (%s, 'import pydoc; pydoc.pager = "
799 "pydoc.plainpager')",
804 run_string.
Printf(
"run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64
824 std::unique_ptr<SessionIORedirect> redirect(
830 std::unique_ptr<Connection> conn =
831 std::make_unique<ConnectionGenericFile>(read_handle,
true);
833 std::unique_ptr<Connection> conn =
834 std::make_unique<ConnectionFileDescriptor>(
837 if (!conn->IsConnected())
840 redirect->m_communication.SetConnection(std::move(conn));
841 redirect->m_communication.SetReadThreadBytesReceivedCallback(
843 if (!redirect->m_communication.StartReadThread())
845 redirect->m_connected =
true;
848 redirect->m_write_file_sp = std::make_shared<NativeFile>(
876 if (!src || !src_len)
881 debugger_sp->PrintAsync(
static_cast<const char *
>(src), src_len,
898 auto gil_state = PyGILState_Ensure();
900 PyGILState_Release(gil_state);
905 const char *instructions =
nullptr;
911 instructions = R
"(Enter your Python command(s). Type 'DONE' to end.
912def function (frame, bp_loc, internal_dict):
913 """frame: the lldb.SBFrame for the location at which you stopped
914 bp_loc: an lldb.SBBreakpointLocation for the breakpoint location information
915 internal_dict: an LLDB support object not to be used"""
919 instructions =
"Enter your Python command(s). Type 'DONE' to end.\n";
923 if (instructions && interactive) {
935 bool batch_mode =
m_debugger.GetCommandInterpreter().GetBatchCommandMode();
941 std::vector<std::reference_wrapper<BreakpointOptions>> *bp_options_vec =
942 (std::vector<std::reference_wrapper<BreakpointOptions>> *)
944 for (BreakpointOptions &bp_options : *bp_options_vec) {
946 auto data_up = std::make_unique<CommandDataPython>();
949 data_up->user_source.SplitIntoLines(data);
952 data_up->script_source,
956 auto baton_sp = std::make_shared<BreakpointOptions::CommandBaton>(
958 bp_options.SetCallback(
960 }
else if (!batch_mode) {
962 LockedStreamFile locked_stream = error_sp->Lock();
963 locked_stream.
Printf(
"Warning: No command attached to breakpoint.\n");
970 WatchpointOptions *wp_options =
972 auto data_up = std::make_unique<WatchpointOptions::CommandData>();
973 data_up->user_source.SplitIntoLines(data);
976 data_up->script_source,
979 std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up));
982 }
else if (!batch_mode) {
984 LockedStreamFile locked_stream = error_sp->Lock();
985 locked_stream.
Printf(
"Warning: No command attached to breakpoint.\n");
995 return std::make_shared<ScriptInterpreterPythonImpl>(debugger);
1001 log->
PutCString(
"ScriptInterpreterPythonImpl::LeaveSession()");
1004 RunSimpleString(
"lldb.debugger = None; lldb.target = None; lldb.process "
1005 "= None; lldb.thread = None; lldb.frame = None");
1012 if (PyThreadState_GetDict()) {
1014 if (sys_module_dict.
IsValid()) {
1019 auto flush_redirect = [&](
const char *py_name,
1020 std::unique_ptr<SessionIORedirect> &redirect) {
1027 if (llvm::Expected<PythonObject> result = file.
CallMethod(
"flush"))
1030 llvm::consumeError(result.takeError());
1059 const char *py_name,
PythonObject &save_file,
const char *mode,
1061 const bool is_stdout = ::strcmp(py_name,
"stdout") == 0;
1062 if (!is_stdout && ::strcmp(py_name,
"stderr") != 0)
1077 fd != debugger_file->GetDescriptor())
1080 std::unique_ptr<SessionIORedirect> &redirect =
1089 PyObject *pipe_file = PyFile_FromFd(
1090 redirect->GetWriteDescriptor(),
nullptr, mode, 1,
1091 nullptr,
"ignore",
nullptr,
1097 "failed to wrap sys.{0} on a synchronized pipe; falling back to "
1098 "the unsynchronized terminal descriptor",
1113 const char *py_name,
1116 bool serialize_terminal_output) {
1117 if (!file_sp || !*file_sp) {
1121 File &file = *file_sp;
1126 if (serialize_terminal_output &&
1138 "ScriptInterpreterPythonImpl::SetStdHandle failed to wrap "
1144 save_file = sys_module_dict.
GetItemForKey(PythonString(py_name));
1159 "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16
1160 ") session is already active, returning without doing anything",
1167 "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16
")",
1175 run_string.
Printf(
"run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64,
1178 "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64
")",
1180 run_string.
PutCString(
"; lldb.target = lldb.debugger.GetSelectedTarget()");
1181 run_string.
PutCString(
"; lldb.process = lldb.target.GetProcess()");
1182 run_string.
PutCString(
"; lldb.thread = lldb.process.GetSelectedThread ()");
1183 run_string.
PutCString(
"; lldb.frame = lldb.thread.GetSelectedFrame ()");
1188 run_string.
Printf(
"run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64,
1191 "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64
")",
1200 if (sys_module_dict.
IsValid()) {
1203 if (!in_sp || !out_sp || !err_sp || !*in_sp || !*out_sp || !*err_sp)
1204 m_debugger.AdoptTopIOHandlerFilesIfInvalid(top_in_sp, top_out_sp,
1220 const bool serialize_terminal_output =
1224 serialize_terminal_output)) {
1227 "w", serialize_terminal_output);
1231 serialize_terminal_output)) {
1234 "w", serialize_terminal_output);
1238 if (PyErr_Occurred())
1259 PyModule_GetDict(main_module.
get()));
1260 if (!main_dict.IsValid())
1276llvm::Expected<unsigned>
1278 const llvm::StringRef &callable_name) {
1279 if (callable_name.empty()) {
1280 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1281 "called with empty callable name.");
1288 callable_name, dict);
1290 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1291 "can't find callable: %s",
1292 callable_name.str().c_str());
1294 llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
1298 "GetArgInfo failed for callable {1}, falling back to "
1299 "inspect.signature: {0}",
1304 return arg_info.takeError();
1305 return arg_info.
get().max_positional_args;
1309 uint32_t &functions_counter,
1310 const void *name_token =
nullptr) {
1313 if (!base_name_wanted)
1314 return std::string();
1317 sstr.
Printf(
"%s_%d", base_name_wanted, functions_counter++);
1319 sstr.
Printf(
"%s_%p", base_name_wanted, name_token);
1329 PyImport_AddModule(
"lldb.embedded_interpreter"));
1330 if (!module.IsValid())
1334 PyModule_GetDict(module.get()));
1335 if (!module_dict.IsValid())
1339 module_dict.GetItemForKey(
PythonString(
"run_one_line"));
1341 module_dict.GetItemForKey(
PythonString(
"g_run_one_line_str"));
1348 std::string command_str = command.str();
1353 if (!command.empty()) {
1360 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
1363 if (!io_redirect_or_error) {
1366 "failed to redirect I/O: {0}\n",
1367 llvm::fmt_consume(io_redirect_or_error.takeError()));
1369 llvm::consumeError(io_redirect_or_error.takeError());
1375 bool success =
false;
1401 Py_BuildValue(
"(Os)", session_dict.
get(), command_str.c_str()));
1418 io_redirect.
Flush();
1427 command_str.c_str());
1433 result->
AppendError(
"empty command passed to python\n");
1452 if (io_handler_sp) {
1458#if LLDB_USE_PYTHON_SET_INTERRUPT
1466 PyErr_SetInterrupt();
1477 PyThreadState *state = PyThreadState_Get();
1481 long tid = PyThread_get_thread_ident();
1482 PyThreadState_Swap(state);
1483 int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt);
1485 "ScriptInterpreterPythonImpl::Interrupt() sending "
1486 "PyExc_KeyboardInterrupt (tid = %li, num_threads = %i)...",
1492 "ScriptInterpreterPythonImpl::Interrupt() python code not running, "
1502 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
1506 if (!io_redirect_or_error) {
1507 llvm::consumeError(io_redirect_or_error.takeError());
1531 Expected<PythonObject> maybe_py_return =
1534 if (!maybe_py_return) {
1535 llvm::handleAllErrors(
1536 maybe_py_return.takeError(),
1539 if (options.GetMaskoutErrors()) {
1540 if (E.Matches(PyExc_SyntaxError)) {
1546 [](
const llvm::ErrorInfoBase &E) {});
1550 PythonObject py_return = std::move(maybe_py_return.get());
1553 switch (return_type) {
1554 case eScriptReturnTypeCharPtr:
1556 const char format[3] =
"s#";
1557 return PyArg_Parse(py_return.
get(), format, (
char **)ret_value);
1559 case eScriptReturnTypeCharStrOrNone:
1562 const char format[3] =
"z";
1563 return PyArg_Parse(py_return.
get(), format, (
char **)ret_value);
1565 case eScriptReturnTypeBool: {
1566 const char format[2] =
"b";
1567 return PyArg_Parse(py_return.
get(), format, (
bool *)ret_value);
1569 case eScriptReturnTypeShortInt: {
1570 const char format[2] =
"h";
1571 return PyArg_Parse(py_return.
get(), format, (
short *)ret_value);
1573 case eScriptReturnTypeShortIntUnsigned: {
1574 const char format[2] =
"H";
1575 return PyArg_Parse(py_return.
get(), format, (
unsigned short *)ret_value);
1577 case eScriptReturnTypeInt: {
1578 const char format[2] =
"i";
1579 return PyArg_Parse(py_return.
get(), format, (
int *)ret_value);
1581 case eScriptReturnTypeIntUnsigned: {
1582 const char format[2] =
"I";
1583 return PyArg_Parse(py_return.
get(), format, (
unsigned int *)ret_value);
1585 case eScriptReturnTypeLongInt: {
1586 const char format[2] =
"l";
1587 return PyArg_Parse(py_return.
get(), format, (
long *)ret_value);
1589 case eScriptReturnTypeLongIntUnsigned: {
1590 const char format[2] =
"k";
1591 return PyArg_Parse(py_return.
get(), format, (
unsigned long *)ret_value);
1593 case eScriptReturnTypeLongLong: {
1594 const char format[2] =
"L";
1595 return PyArg_Parse(py_return.
get(), format, (
long long *)ret_value);
1597 case eScriptReturnTypeLongLongUnsigned: {
1598 const char format[2] =
"K";
1599 return PyArg_Parse(py_return.
get(), format,
1600 (
unsigned long long *)ret_value);
1602 case eScriptReturnTypeFloat: {
1603 const char format[2] =
"f";
1604 return PyArg_Parse(py_return.
get(), format, (
float *)ret_value);
1606 case eScriptReturnTypeDouble: {
1607 const char format[2] =
"d";
1608 return PyArg_Parse(py_return.
get(), format, (
double *)ret_value);
1610 case eScriptReturnTypeChar: {
1611 const char format[2] =
"c";
1612 return PyArg_Parse(py_return.
get(), format, (
char *)ret_value);
1614 case eScriptReturnTypeOpaqueObject: {
1615 *((PyObject **)ret_value) = py_return.
release();
1619 llvm_unreachable(
"Fully covered switch!");
1625 if (in_string ==
nullptr)
1628 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
1632 if (!io_redirect_or_error)
1635 ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
1655 Expected<PythonObject> return_value =
1658 if (!return_value) {
1660 llvm::handleErrors(return_value.takeError(), [&](PythonException &E) {
1661 llvm::Error error = llvm::createStringError(
1662 llvm::inconvertibleErrorCode(), E.ReadBacktrace());
1663 if (!options.GetMaskoutErrors())
1674 std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
1677 m_debugger.GetCommandInterpreter().GetPythonCommandsFromIOHandler(
1678 " ", *
this, &bp_options_vec);
1684 m_debugger.GetCommandInterpreter().GetPythonCommandsFromIOHandler(
1685 " ", *
this, wp_options);
1693 std::string function_signature = function_name;
1695 llvm::Expected<unsigned> maybe_args =
1699 "could not get num args: %s",
1700 llvm::toString(maybe_args.takeError()).c_str());
1703 size_t max_args = *maybe_args;
1705 bool uses_extra_args =
false;
1706 if (max_args >= 4) {
1707 uses_extra_args =
true;
1708 function_signature +=
"(frame, bp_loc, extra_args, internal_dict)";
1709 }
else if (max_args >= 3) {
1710 if (extra_args_sp) {
1712 "cannot pass extra_args to a three argument callback");
1715 uses_extra_args =
false;
1716 function_signature +=
"(frame, bp_loc, internal_dict)";
1719 "function, %s can only take %zu",
1720 function_name, max_args);
1725 extra_args_sp, uses_extra_args,
1732 std::unique_ptr<BreakpointOptions::CommandData> &cmd_data_up) {
1735 cmd_data_up->script_source,
1742 std::make_shared<BreakpointOptions::CommandBaton>(std::move(cmd_data_up));
1752 false, is_callback);
1760 auto data_up = std::make_unique<CommandDataPython>(extra_args_sp);
1766 data_up->user_source.SplitIntoLines(command_body_text);
1768 data_up->user_source, data_up->script_source, uses_extra_args,
1770 if (
error.Success()) {
1772 std::make_shared<BreakpointOptions::CommandBaton>(std::move(data_up));
1783 auto data_up = std::make_unique<WatchpointOptions::CommandData>();
1790 data_up->user_source.AppendString(user_input);
1791 data_up->script_source.assign(user_input);
1794 data_up->user_source, data_up->script_source, is_callback)) {
1796 std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up));
1805 std::string function_def_string(function_def.
CopyList());
1807 function_def_string.c_str());
1818 int num_lines = input.
GetSize();
1819 if (num_lines == 0) {
1824 if (!signature || *signature == 0) {
1830 StringList auto_generated_function;
1833 " global_dict = globals()");
1835 " new_keys = internal_dict.keys()");
1838 " old_keys = global_dict.keys()");
1840 " global_dict.update(internal_dict)");
1847 if (num_lines == 1) {
1853 "ScriptInterpreterPythonImpl::GenerateFunction(is_callback="
1854 "true) = ERROR: python function is multiline.");
1858 " __return_val = None");
1860 " def __user_code():");
1864 for (
int i = 0; i < num_lines; ++i) {
1870 " __return_val = __user_code()");
1874 " for key in new_keys:");
1877 " if key in old_keys:");
1880 " internal_dict[key] = global_dict[key]");
1882 " elif key in global_dict:");
1885 " del global_dict[key]");
1888 " return __return_val");
1897 StringList &user_input, std::string &output,
const void *name_token) {
1898 static uint32_t num_created_functions = 0;
1903 if (user_input.
GetSize() == 0)
1909 std::string auto_generated_function_name(
1911 num_created_functions, name_token));
1912 sstr.
Printf(
"def %s (valobj, internal_dict):",
1913 auto_generated_function_name.c_str());
1920 output.assign(auto_generated_function_name);
1925 StringList &user_input, std::string &output) {
1926 static uint32_t num_created_functions = 0;
1931 if (user_input.
GetSize() == 0)
1935 "lldb_autogen_python_cmd_alias_func", num_created_functions));
1937 sstr.
Printf(
"def %s (debugger, args, exe_ctx, result, internal_dict):",
1938 auto_generated_function_name.c_str());
1945 output.assign(auto_generated_function_name);
1950 StringList &user_input, std::string &output,
const void *name_token) {
1951 static uint32_t num_created_classes = 0;
1953 int num_lines = user_input.
GetSize();
1957 if (user_input.
GetSize() == 0)
1963 "lldb_autogen_python_type_synth_class", num_created_classes, name_token));
1969 sstr.
Printf(
"class %s:", auto_generated_class_name.c_str());
1975 for (
int i = 0; i < num_lines; ++i) {
1989 output.assign(auto_generated_class_name);
1995 return std::make_unique<ScriptedProcessPythonInterface>(*
this);
2000 return std::make_shared<ScriptedHookPythonInterface>(*
this);
2005 return std::make_shared<ScriptedBreakpointPythonInterface>(*
this);
2010 return std::make_shared<ScriptedStackFrameRecognizerPythonInterface>(*
this);
2015 return std::make_shared<ScriptedCommandPythonInterface>(*
this);
2020 return std::make_shared<ScriptedStringSummaryPythonInterface>(*
this);
2025 return std::make_shared<ScriptedSyntheticChildrenPythonInterface>(*
this);
2030 return std::make_shared<ScriptedThreadPythonInterface>(*
this);
2035 return std::make_shared<ScriptedFramePythonInterface>(*
this);
2040 return std::make_shared<ScriptedFrameProviderPythonInterface>(*
this);
2045 return std::make_shared<ScriptedThreadPlanPythonInterface>(*
this);
2050 return std::make_shared<OperatingSystemPythonInterface>(*
this);
2056 void *ptr =
const_cast<void *
>(obj.
GetPointer());
2059 if (!py_obj.IsValid() || py_obj.IsNone())
2061 return py_obj.CreateStructuredObject();
2074 LoadScriptOptions load_script_options =
2075 LoadScriptOptions().SetInitSession(
true).SetSilent(
false);
2086 if (!plugin_module_sp || !target || !setting_name || !setting_name[0])
2094 TargetSP target_sp(target->shared_from_this());
2097 generic->GetValue(), setting_name, target_sp);
2112 const char *oneliner, std::string &output,
const void *name_token) {
2119 const char *oneliner, std::string &output,
const void *name_token) {
2126 StringList &user_input, std::string &output,
bool has_extra_args,
2128 static uint32_t num_created_functions = 0;
2132 if (user_input.
GetSize() == 0) {
2138 "lldb_autogen_python_bp_callback_func_", num_created_functions));
2140 sstr.
Printf(
"def %s (frame, bp_loc, extra_args, internal_dict):",
2141 auto_generated_function_name.c_str());
2143 sstr.
Printf(
"def %s (frame, bp_loc, internal_dict):",
2144 auto_generated_function_name.c_str());
2147 if (!
error.Success())
2151 output.assign(auto_generated_function_name);
2156 StringList &user_input, std::string &output,
bool is_callback) {
2157 static uint32_t num_created_functions = 0;
2161 if (user_input.
GetSize() == 0)
2165 "lldb_autogen_python_wp_callback_func_", num_created_functions));
2166 sstr.
Printf(
"def %s (frame, wp, internal_dict):",
2167 auto_generated_function_name.c_str());
2173 output.assign(auto_generated_function_name);
2184 if (!valobj.get()) {
2185 retval.assign(
"<no object>");
2189 void *old_callee =
nullptr;
2191 if (callee_wrapper_sp) {
2192 generic = callee_wrapper_sp->GetAsGeneric();
2194 old_callee =
generic->GetValue();
2196 void *new_callee = old_callee;
2199 if (python_function_name && *python_function_name) {
2206 static Timer::Category func_cat(
"LLDBSwigPythonCallTypeScript");
2207 Timer scoped_timer(func_cat,
"LLDBSwigPythonCallTypeScript");
2210 &new_callee, options_sp, retval);
2214 retval.assign(
"<no function name>");
2218 if (new_callee && old_callee != new_callee) {
2221 callee_wrapper_sp = std::make_shared<StructuredPythonObject>(
2222 PythonObject(PyRefType::Borrowed,
static_cast<PyObject *
>(new_callee)));
2229 const char *python_function_name,
TypeImplSP type_impl_sp) {
2239 CommandDataPython *bp_option_data = (CommandDataPython *)baton;
2240 const char *python_function_name = bp_option_data->script_source.c_str();
2246 Target *target = exe_ctx.GetTargetPtr();
2255 if (!python_interpreter)
2258 if (python_function_name && python_function_name[0]) {
2259 const StackFrameSP stop_frame_sp(exe_ctx.GetFrameSP());
2261 if (breakpoint_sp) {
2263 breakpoint_sp->FindLocationByID(break_loc_id));
2265 if (stop_frame_sp && bp_loc_sp) {
2266 bool ret_val =
true;
2271 Expected<bool> maybe_ret_val =
2273 python_function_name,
2275 bp_loc_sp, bp_option_data->m_extra_args);
2277 if (!maybe_ret_val) {
2279 llvm::handleAllErrors(
2280 maybe_ret_val.takeError(),
2282 *debugger.GetAsyncErrorStream() << E.ReadBacktrace();
2284 [&](
const llvm::ErrorInfoBase &E) {
2285 *debugger.GetAsyncErrorStream() << E.message();
2289 ret_val = maybe_ret_val.get();
2305 const char *python_function_name = wp_option_data->
script_source.c_str();
2320 if (!python_interpreter)
2323 if (python_function_name && python_function_name[0]) {
2327 if (stop_frame_sp && wp_sp) {
2328 bool ret_val =
true;
2334 python_function_name,
2348 const char *impl_function,
Process *process, std::string &output,
2355 if (!impl_function || !impl_function[0]) {
2373 const char *impl_function,
Thread *thread, std::string &output,
2379 if (!impl_function || !impl_function[0]) {
2386 if (std::optional<std::string> result =
2389 thread->shared_from_this())) {
2390 output = std::move(*result);
2398 const char *impl_function,
Target *target, std::string &output,
2405 if (!impl_function || !impl_function[0]) {
2411 TargetSP target_sp(target->shared_from_this());
2423 const char *impl_function,
StackFrame *frame, std::string &output,
2429 if (!impl_function || !impl_function[0]) {
2436 if (std::optional<std::string> result =
2439 frame->shared_from_this())) {
2440 output = std::move(*result);
2448 const char *impl_function,
ValueObject *value, std::string &output,
2455 if (!impl_function || !impl_function[0]) {
2471uint64_t
replace_all(std::string &str,
const std::string &oldStr,
2472 const std::string &newStr) {
2474 uint64_t matches = 0;
2475 while ((pos = str.find(oldStr, pos)) != std::string::npos) {
2477 str.replace(pos, oldStr.length(), newStr);
2478 pos += newStr.length();
2487 namespace fs = llvm::sys::fs;
2488 namespace path = llvm::sys::path;
2494 if (!pathname || !pathname[0]) {
2499 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
2503 if (!io_redirect_or_error) {
2508 ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
2520 auto ExtendSysPath = [&](std::string directory) -> llvm::Error {
2521 if (directory.empty()) {
2522 return llvm::createStringError(
"invalid directory name");
2529 StreamString command_stream;
2530 command_stream.
Printf(
"if not (sys.path.__contains__('%s')):\n "
2531 "sys.path.insert(1,'%s');\n\n",
2532 directory.c_str(), directory.c_str());
2533 bool syspath_retval =
2535 if (!syspath_retval)
2536 return llvm::createStringError(
"Python sys.path handling failed");
2538 return llvm::Error::success();
2541 std::string module_name(pathname);
2542 bool possible_package =
false;
2544 if (extra_search_dir) {
2545 if (llvm::Error e = ExtendSysPath(extra_search_dir.
GetPath())) {
2550 FileSpec module_file(pathname);
2554 std::error_code ec = status(module_file.GetPath(), st);
2556 if (ec || st.type() == fs::file_type::status_error ||
2557 st.type() == fs::file_type::type_unknown ||
2558 st.type() == fs::file_type::file_not_found) {
2561 if (strchr(pathname,
'\\') || strchr(pathname,
'/')) {
2567 possible_package =
true;
2568 }
else if (is_directory(st) || is_regular_file(st)) {
2569 if (module_file.GetDirectory().empty()) {
2571 "invalid directory name '{0}'", pathname);
2574 if (llvm::Error e = ExtendSysPath(module_file.GetDirectory().str())) {
2578 module_name = module_file.GetFilename().str();
2581 "no known way to import this module specification");
2587 llvm::StringRef extension = llvm::sys::path::extension(module_name);
2588 if (!extension.empty()) {
2589 if (extension ==
".py")
2590 module_name.resize(module_name.length() - 3);
2591 else if (extension ==
".pyc")
2592 module_name.resize(module_name.length() - 4);
2595 if (!possible_package && module_name.find(
'.') != llvm::StringRef::npos) {
2597 "Python does not allow dots in module names: %s", module_name.c_str());
2601 if (module_name.find(
'-') != llvm::StringRef::npos) {
2603 "Python discourages dashes in module names: %s", module_name.c_str());
2608 StreamString command_stream;
2609 command_stream.
Clear();
2610 command_stream.
Printf(
"sys.modules.__contains__('%s')", module_name.c_str());
2611 bool does_contain =
false;
2619 const bool was_imported_globally = does_contain_executed && does_contain;
2620 const bool was_imported_locally =
2626 command_stream.
Clear();
2628 if (was_imported_globally || was_imported_locally) {
2629 if (!was_imported_locally)
2630 command_stream.
Printf(
"import %s ; importlib.reload(%s)",
2631 module_name.c_str(), module_name.c_str());
2633 command_stream.
Printf(
"importlib.reload(%s)", module_name.c_str());
2635 command_stream.
Printf(
"import %s", module_name.c_str());
2652 command_stream.
Clear();
2653 command_stream.
Printf(
"%s", module_name.c_str());
2654 void *module_pyobj =
nullptr;
2660 *module_sp = std::make_shared<StructuredPythonObject>(PythonObject(
2661 PyRefType::Owned,
static_cast<PyObject *
>(module_pyobj)));
2674 if (!word || !word[0])
2677 llvm::StringRef word_sr(word);
2681 if (word_sr.find(
'"') != llvm::StringRef::npos ||
2682 word_sr.find(
'\'') != llvm::StringRef::npos)
2686 command_stream.
Printf(
"keyword.iskeyword('%s')", word);
2701 : m_debugger_sp(debugger_sp), m_synch_wanted(synchro),
2702 m_old_asynch(debugger_sp->GetAsyncExecution()) {
2711 m_debugger_sp->SetAsyncExecution(m_old_asynch);
2715 const char *impl_function, llvm::StringRef args,
2719 if (!impl_function) {
2727 if (!debugger_sp.get()) {
2732 bool ret_val =
false;
2742 std::string args_str = args.str();
2745 cmd_retobj, exe_ctx_ref_sp);
2763 std::string &dest) {
2766 if (!item || !*item)
2769 std::string command(item);
2770 command +=
".__doc__";
2774 char *result_ptr =
nullptr;
2780 dest.assign(result_ptr);
2785 str_stream <<
"Function " << item
2786 <<
" was not found. Containing module might be missing.";
2787 dest = std::string(str_stream.
GetString());
2792std::unique_ptr<ScriptInterpreterLocker>
2794 std::unique_ptr<ScriptInterpreterLocker> py_lock(
new Locker(
2807 InitializePythonRAII initialize_guard;
2823 if (
FileSpec file_spec = HostInfo::GetShlibDir())
2827 "lldb.embedded_interpreter; from "
2828 "lldb.embedded_interpreter import run_python_interpreter; "
2829 "from lldb.embedded_interpreter import run_one_line");
2831#if LLDB_USE_PYTHON_SET_INTERRUPT
2835 RestoreSignalHandlerScope save_sigint(SIGINT);
2843 " def signal_handler(sig, frame):\n"
2844 " raise KeyboardInterrupt()\n"
2845 " signal.signal(signal.SIGINT, signal_handler);\n"
2846 "lldb_setup_sigint_handler();\n"
2847 "del lldb_setup_sigint_handler\n");
2853 std::string statement;
2855 statement.assign(
"sys.path.insert(0,\"");
2856 statement.append(path);
2857 statement.append(
"\")");
2859 statement.assign(
"sys.path.append(\"");
2860 statement.append(path);
2861 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
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 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