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 =
696 if (llvm::Error
error = loader->Load()) {
705 setenv(
"PYTHONMALLOC",
"malloc",
true);
711#if !LLDB_ENABLE_DYNAMIC_SCRIPTINTERPRETERS
712 HostInfo::SetSharedLibraryDirectoryHelper(
755 "Ensured PyGILState. Previous state = {0}",
756 m_GILState == PyGILState_UNLOCKED ?
"unlocked" :
"locked");
778 "Releasing PyGILState. Returning to state = {0}",
779 m_GILState == PyGILState_UNLOCKED ?
"unlocked" :
"locked");
817 run_string.
Printf(
"run_one_line (%s, 'import copy, keyword, os, re, sys, "
818 "uuid, lldb, importlib')",
828 "run_one_line (%s, 'import lldb.formatters, lldb.formatters.cpp')",
833 run_string.
Printf(
"run_one_line (%s, 'import lldb.embedded_interpreter; from "
834 "lldb.embedded_interpreter import run_python_interpreter; "
835 "from lldb.embedded_interpreter import run_one_line')",
842 run_string.
Printf(
"run_one_line (%s, 'import pydoc; pydoc.pager = "
843 "pydoc.plainpager')",
848 run_string.
Printf(
"run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64
868 std::unique_ptr<SessionIORedirect> redirect(
874 std::unique_ptr<Connection> conn =
875 std::make_unique<ConnectionGenericFile>(read_handle,
true);
877 std::unique_ptr<Connection> conn =
878 std::make_unique<ConnectionFileDescriptor>(
881 if (!conn->IsConnected())
884 redirect->m_communication.SetConnection(std::move(conn));
885 redirect->m_communication.SetReadThreadBytesReceivedCallback(
887 if (!redirect->m_communication.StartReadThread())
889 redirect->m_connected =
true;
892 redirect->m_write_file_sp = std::make_shared<NativeFile>(
920 if (!src || !src_len)
925 debugger_sp->PrintAsync(
static_cast<const char *
>(src), src_len,
942 auto gil_state = PyGILState_Ensure();
944 PyGILState_Release(gil_state);
949 const char *instructions =
nullptr;
955 instructions = R
"(Enter your Python command(s). Type 'DONE' to end.
956def function (frame, bp_loc, internal_dict):
957 """frame: the lldb.SBFrame for the location at which you stopped
958 bp_loc: an lldb.SBBreakpointLocation for the breakpoint location information
959 internal_dict: an LLDB support object not to be used"""
963 instructions =
"Enter your Python command(s). Type 'DONE' to end.\n";
967 if (instructions && interactive) {
979 bool batch_mode =
m_debugger.GetCommandInterpreter().GetBatchCommandMode();
985 std::vector<std::reference_wrapper<BreakpointOptions>> *bp_options_vec =
986 (std::vector<std::reference_wrapper<BreakpointOptions>> *)
988 for (BreakpointOptions &bp_options : *bp_options_vec) {
990 auto data_up = std::make_unique<CommandDataPython>();
993 data_up->user_source.SplitIntoLines(data);
996 data_up->script_source,
1000 auto baton_sp = std::make_shared<BreakpointOptions::CommandBaton>(
1001 std::move(data_up));
1002 bp_options.SetCallback(
1004 }
else if (!batch_mode) {
1006 LockedStreamFile locked_stream = error_sp->Lock();
1007 locked_stream.
Printf(
"Warning: No command attached to breakpoint.\n");
1014 WatchpointOptions *wp_options =
1016 auto data_up = std::make_unique<WatchpointOptions::CommandData>();
1017 data_up->user_source.SplitIntoLines(data);
1020 data_up->script_source,
1023 std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up));
1026 }
else if (!batch_mode) {
1028 LockedStreamFile locked_stream = error_sp->Lock();
1029 locked_stream.
Printf(
"Warning: No command attached to breakpoint.\n");
1039 return std::make_shared<ScriptInterpreterPythonImpl>(debugger);
1045 log->
PutCString(
"ScriptInterpreterPythonImpl::LeaveSession()");
1048 RunSimpleString(
"lldb.debugger = None; lldb.target = None; lldb.process "
1049 "= None; lldb.thread = None; lldb.frame = None");
1056 if (PyThreadState_GetDict()) {
1058 if (sys_module_dict.
IsValid()) {
1063 auto flush_redirect = [&](
const char *py_name,
1064 std::unique_ptr<SessionIORedirect> &redirect) {
1071 if (llvm::Expected<PythonObject> result = file.
CallMethod(
"flush"))
1074 llvm::consumeError(result.takeError());
1103 const char *py_name,
PythonObject &save_file,
const char *mode,
1105 const bool is_stdout = ::strcmp(py_name,
"stdout") == 0;
1106 if (!is_stdout && ::strcmp(py_name,
"stderr") != 0)
1121 fd != debugger_file->GetDescriptor())
1124 std::unique_ptr<SessionIORedirect> &redirect =
1133 PyObject *pipe_file = PyFile_FromFd(
1143 "failed to wrap sys.{0} on a synchronized pipe; falling back to "
1144 "the unsynchronized terminal descriptor",
1159 const char *py_name,
1162 bool serialize_terminal_output) {
1163 if (!file_sp || !*file_sp) {
1167 File &file = *file_sp;
1172 if (serialize_terminal_output &&
1184 "ScriptInterpreterPythonImpl::SetStdHandle failed to wrap "
1190 save_file = sys_module_dict.
GetItemForKey(PythonString(py_name));
1205 "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16
1206 ") session is already active, returning without doing anything",
1213 "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16
")",
1221 run_string.
Printf(
"run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64,
1224 "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64
")",
1226 run_string.
PutCString(
"; lldb.target = lldb.debugger.GetSelectedTarget()");
1227 run_string.
PutCString(
"; lldb.process = lldb.target.GetProcess()");
1228 run_string.
PutCString(
"; lldb.thread = lldb.process.GetSelectedThread ()");
1229 run_string.
PutCString(
"; lldb.frame = lldb.thread.GetSelectedFrame ()");
1234 run_string.
Printf(
"run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64,
1237 "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64
")",
1246 if (sys_module_dict.
IsValid()) {
1249 if (!in_sp || !out_sp || !err_sp || !*in_sp || !*out_sp || !*err_sp)
1250 m_debugger.AdoptTopIOHandlerFilesIfInvalid(top_in_sp, top_out_sp,
1266 const bool serialize_terminal_output =
1270 serialize_terminal_output)) {
1273 "w", serialize_terminal_output);
1277 serialize_terminal_output)) {
1280 "w", serialize_terminal_output);
1284 if (PyErr_Occurred())
1305 PyModule_GetDict(main_module.
get()));
1306 if (!main_dict.IsValid())
1322llvm::Expected<unsigned>
1324 const llvm::StringRef &callable_name) {
1325 if (callable_name.empty()) {
1326 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1327 "called with empty callable name.");
1334 callable_name, dict);
1336 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1337 "can't find callable: %s",
1338 callable_name.str().c_str());
1340 llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
1344 "GetArgInfo failed for callable {1}, falling back to "
1345 "inspect.signature: {0}",
1350 return arg_info.takeError();
1351 return arg_info.
get().max_positional_args;
1355 uint32_t &functions_counter,
1356 const void *name_token =
nullptr) {
1359 if (!base_name_wanted)
1360 return std::string();
1363 sstr.
Printf(
"%s_%d", base_name_wanted, functions_counter++);
1365 sstr.
Printf(
"%s_%p", base_name_wanted, name_token);
1375 PyImport_AddModule(
"lldb.embedded_interpreter"));
1376 if (!module.IsValid())
1380 PyModule_GetDict(module.get()));
1381 if (!module_dict.IsValid())
1385 module_dict.GetItemForKey(
PythonString(
"run_one_line"));
1387 module_dict.GetItemForKey(
PythonString(
"g_run_one_line_str"));
1394 std::string command_str = command.str();
1399 if (!command.empty()) {
1406 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
1409 if (!io_redirect_or_error) {
1412 "failed to redirect I/O: {0}\n",
1413 llvm::fmt_consume(io_redirect_or_error.takeError()));
1415 llvm::consumeError(io_redirect_or_error.takeError());
1421 bool success =
false;
1447 Py_BuildValue(
"(Os)", session_dict.
get(), command_str.c_str()));
1464 io_redirect.
Flush();
1473 command_str.c_str());
1479 result->
AppendError(
"empty command passed to python\n");
1498 if (io_handler_sp) {
1504#if LLDB_USE_PYTHON_SET_INTERRUPT
1512 PyErr_SetInterrupt();
1523 PyThreadState *state = PyThreadState_Get();
1527 long tid = PyThread_get_thread_ident();
1528 PyThreadState_Swap(state);
1529 int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt);
1531 "ScriptInterpreterPythonImpl::Interrupt() sending "
1532 "PyExc_KeyboardInterrupt (tid = %li, num_threads = %i)...",
1538 "ScriptInterpreterPythonImpl::Interrupt() python code not running, "
1548 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
1552 if (!io_redirect_or_error) {
1553 llvm::consumeError(io_redirect_or_error.takeError());
1577 Expected<PythonObject> maybe_py_return =
1580 if (!maybe_py_return) {
1581 llvm::handleAllErrors(
1582 maybe_py_return.takeError(),
1585 if (options.GetMaskoutErrors()) {
1586 if (E.Matches(PyExc_SyntaxError)) {
1592 [](
const llvm::ErrorInfoBase &E) {});
1596 PythonObject py_return = std::move(maybe_py_return.get());
1599 switch (return_type) {
1600 case eScriptReturnTypeCharPtr:
1602 const char format[3] =
"s#";
1603 return PyArg_Parse(py_return.
get(), format, (
char **)ret_value);
1605 case eScriptReturnTypeCharStrOrNone:
1608 const char format[3] =
"z";
1609 return PyArg_Parse(py_return.
get(), format, (
char **)ret_value);
1611 case eScriptReturnTypeBool: {
1612 const char format[2] =
"b";
1613 return PyArg_Parse(py_return.
get(), format, (
bool *)ret_value);
1615 case eScriptReturnTypeShortInt: {
1616 const char format[2] =
"h";
1617 return PyArg_Parse(py_return.
get(), format, (
short *)ret_value);
1619 case eScriptReturnTypeShortIntUnsigned: {
1620 const char format[2] =
"H";
1621 return PyArg_Parse(py_return.
get(), format, (
unsigned short *)ret_value);
1623 case eScriptReturnTypeInt: {
1624 const char format[2] =
"i";
1625 return PyArg_Parse(py_return.
get(), format, (
int *)ret_value);
1627 case eScriptReturnTypeIntUnsigned: {
1628 const char format[2] =
"I";
1629 return PyArg_Parse(py_return.
get(), format, (
unsigned int *)ret_value);
1631 case eScriptReturnTypeLongInt: {
1632 const char format[2] =
"l";
1633 return PyArg_Parse(py_return.
get(), format, (
long *)ret_value);
1635 case eScriptReturnTypeLongIntUnsigned: {
1636 const char format[2] =
"k";
1637 return PyArg_Parse(py_return.
get(), format, (
unsigned long *)ret_value);
1639 case eScriptReturnTypeLongLong: {
1640 const char format[2] =
"L";
1641 return PyArg_Parse(py_return.
get(), format, (
long long *)ret_value);
1643 case eScriptReturnTypeLongLongUnsigned: {
1644 const char format[2] =
"K";
1645 return PyArg_Parse(py_return.
get(), format,
1646 (
unsigned long long *)ret_value);
1648 case eScriptReturnTypeFloat: {
1649 const char format[2] =
"f";
1650 return PyArg_Parse(py_return.
get(), format, (
float *)ret_value);
1652 case eScriptReturnTypeDouble: {
1653 const char format[2] =
"d";
1654 return PyArg_Parse(py_return.
get(), format, (
double *)ret_value);
1656 case eScriptReturnTypeChar: {
1657 const char format[2] =
"c";
1658 return PyArg_Parse(py_return.
get(), format, (
char *)ret_value);
1660 case eScriptReturnTypeOpaqueObject: {
1661 *((PyObject **)ret_value) = py_return.
release();
1665 llvm_unreachable(
"Fully covered switch!");
1671 if (in_string ==
nullptr)
1674 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
1678 if (!io_redirect_or_error)
1681 ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
1701 Expected<PythonObject> return_value =
1704 if (!return_value) {
1706 llvm::handleErrors(return_value.takeError(), [&](PythonException &E) {
1707 llvm::Error error = llvm::createStringError(
1708 llvm::inconvertibleErrorCode(), E.ReadBacktrace());
1709 if (!options.GetMaskoutErrors())
1720 std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
1723 m_debugger.GetCommandInterpreter().GetPythonCommandsFromIOHandler(
1724 " ", *
this, &bp_options_vec);
1730 m_debugger.GetCommandInterpreter().GetPythonCommandsFromIOHandler(
1731 " ", *
this, wp_options);
1739 std::string function_signature = function_name;
1741 llvm::Expected<unsigned> maybe_args =
1745 "could not get num args: %s",
1746 llvm::toString(maybe_args.takeError()).c_str());
1749 size_t max_args = *maybe_args;
1751 bool uses_extra_args =
false;
1752 if (max_args >= 4) {
1753 uses_extra_args =
true;
1754 function_signature +=
"(frame, bp_loc, extra_args, internal_dict)";
1755 }
else if (max_args >= 3) {
1756 if (extra_args_sp) {
1758 "cannot pass extra_args to a three argument callback");
1761 uses_extra_args =
false;
1762 function_signature +=
"(frame, bp_loc, internal_dict)";
1765 "function, %s can only take %zu",
1766 function_name, max_args);
1771 extra_args_sp, uses_extra_args,
1778 std::unique_ptr<BreakpointOptions::CommandData> &cmd_data_up) {
1781 cmd_data_up->script_source,
1788 std::make_shared<BreakpointOptions::CommandBaton>(std::move(cmd_data_up));
1798 false, is_callback);
1806 auto data_up = std::make_unique<CommandDataPython>(extra_args_sp);
1812 data_up->user_source.SplitIntoLines(command_body_text);
1814 data_up->user_source, data_up->script_source, uses_extra_args,
1816 if (
error.Success()) {
1818 std::make_shared<BreakpointOptions::CommandBaton>(std::move(data_up));
1829 auto data_up = std::make_unique<WatchpointOptions::CommandData>();
1836 data_up->user_source.AppendString(user_input);
1837 data_up->script_source.assign(user_input);
1840 data_up->user_source, data_up->script_source, is_callback)) {
1842 std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up));
1851 std::string function_def_string(function_def.
CopyList());
1853 function_def_string.c_str());
1864 int num_lines = input.
GetSize();
1865 if (num_lines == 0) {
1870 if (!signature || *signature == 0) {
1876 StringList auto_generated_function;
1879 " global_dict = globals()");
1881 " new_keys = internal_dict.keys()");
1884 " old_keys = global_dict.keys()");
1886 " global_dict.update(internal_dict)");
1893 if (num_lines == 1) {
1899 "ScriptInterpreterPythonImpl::GenerateFunction(is_callback="
1900 "true) = ERROR: python function is multiline.");
1904 " __return_val = None");
1906 " def __user_code():");
1910 for (
int i = 0; i < num_lines; ++i) {
1916 " __return_val = __user_code()");
1920 " for key in new_keys:");
1923 " if key in old_keys:");
1926 " internal_dict[key] = global_dict[key]");
1928 " elif key in global_dict:");
1931 " del global_dict[key]");
1934 " return __return_val");
1943 StringList &user_input, std::string &output,
const void *name_token) {
1944 static uint32_t num_created_functions = 0;
1949 if (user_input.
GetSize() == 0)
1955 std::string auto_generated_function_name(
1957 num_created_functions, name_token));
1958 sstr.
Printf(
"def %s (valobj, internal_dict):",
1959 auto_generated_function_name.c_str());
1966 output.assign(auto_generated_function_name);
1971 StringList &user_input, std::string &output) {
1972 static uint32_t num_created_functions = 0;
1977 if (user_input.
GetSize() == 0)
1981 "lldb_autogen_python_cmd_alias_func", num_created_functions));
1983 sstr.
Printf(
"def %s (debugger, args, exe_ctx, result, internal_dict):",
1984 auto_generated_function_name.c_str());
1991 output.assign(auto_generated_function_name);
1996 StringList &user_input, std::string &output,
const void *name_token) {
1997 static uint32_t num_created_classes = 0;
1999 int num_lines = user_input.
GetSize();
2003 if (user_input.
GetSize() == 0)
2009 "lldb_autogen_python_type_synth_class", num_created_classes, name_token));
2015 sstr.
Printf(
"class %s:", auto_generated_class_name.c_str());
2021 for (
int i = 0; i < num_lines; ++i) {
2035 output.assign(auto_generated_class_name);
2041 return std::make_unique<ScriptedProcessPythonInterface>(*
this);
2046 return std::make_shared<ScriptedHookPythonInterface>(*
this);
2051 return std::make_shared<ScriptedBreakpointPythonInterface>(*
this);
2056 return std::make_shared<ScriptedStackFrameRecognizerPythonInterface>(*
this);
2061 return std::make_shared<ScriptedCommandPythonInterface>(*
this);
2066 return std::make_shared<ScriptedStringSummaryPythonInterface>(*
this);
2071 return std::make_shared<ScriptedSyntheticChildrenPythonInterface>(*
this);
2076 return std::make_shared<ScriptedThreadPythonInterface>(*
this);
2081 return std::make_shared<ScriptedFramePythonInterface>(*
this);
2086 return std::make_shared<ScriptedFrameProviderPythonInterface>(*
this);
2091 return std::make_shared<ScriptedThreadPlanPythonInterface>(*
this);
2096 return std::make_shared<OperatingSystemPythonInterface>(*
this);
2102 void *ptr =
const_cast<void *
>(obj.
GetPointer());
2105 if (!py_obj.IsValid() || py_obj.IsNone())
2107 return py_obj.CreateStructuredObject();
2120 LoadScriptOptions load_script_options =
2121 LoadScriptOptions().SetInitSession(
true).SetSilent(
false);
2132 if (!plugin_module_sp || !target || !setting_name || !setting_name[0])
2140 TargetSP target_sp(target->shared_from_this());
2143 generic->GetValue(), setting_name, target_sp);
2158 const char *oneliner, std::string &output,
const void *name_token) {
2165 const char *oneliner, std::string &output,
const void *name_token) {
2172 StringList &user_input, std::string &output,
bool has_extra_args,
2174 static uint32_t num_created_functions = 0;
2178 if (user_input.
GetSize() == 0) {
2184 "lldb_autogen_python_bp_callback_func_", num_created_functions));
2186 sstr.
Printf(
"def %s (frame, bp_loc, extra_args, internal_dict):",
2187 auto_generated_function_name.c_str());
2189 sstr.
Printf(
"def %s (frame, bp_loc, internal_dict):",
2190 auto_generated_function_name.c_str());
2193 if (!
error.Success())
2197 output.assign(auto_generated_function_name);
2202 StringList &user_input, std::string &output,
bool is_callback) {
2203 static uint32_t num_created_functions = 0;
2207 if (user_input.
GetSize() == 0)
2211 "lldb_autogen_python_wp_callback_func_", num_created_functions));
2212 sstr.
Printf(
"def %s (frame, wp, internal_dict):",
2213 auto_generated_function_name.c_str());
2219 output.assign(auto_generated_function_name);
2230 if (!valobj.get()) {
2231 retval.assign(
"<no object>");
2235 void *old_callee =
nullptr;
2237 if (callee_wrapper_sp) {
2238 generic = callee_wrapper_sp->GetAsGeneric();
2240 old_callee =
generic->GetValue();
2242 void *new_callee = old_callee;
2245 if (python_function_name && *python_function_name) {
2252 static Timer::Category func_cat(
"LLDBSwigPythonCallTypeScript");
2253 Timer scoped_timer(func_cat,
"LLDBSwigPythonCallTypeScript");
2256 &new_callee, options_sp, retval);
2260 retval.assign(
"<no function name>");
2264 if (new_callee && old_callee != new_callee) {
2267 callee_wrapper_sp = std::make_shared<StructuredPythonObject>(
2268 PythonObject(PyRefType::Borrowed,
static_cast<PyObject *
>(new_callee)));
2275 const char *python_function_name,
TypeImplSP type_impl_sp) {
2285 CommandDataPython *bp_option_data = (CommandDataPython *)baton;
2286 const char *python_function_name = bp_option_data->script_source.c_str();
2292 Target *target = exe_ctx.GetTargetPtr();
2301 if (!python_interpreter)
2304 if (python_function_name && python_function_name[0]) {
2305 const StackFrameSP stop_frame_sp(exe_ctx.GetFrameSP());
2307 if (breakpoint_sp) {
2309 breakpoint_sp->FindLocationByID(break_loc_id));
2311 if (stop_frame_sp && bp_loc_sp) {
2312 bool ret_val =
true;
2317 Expected<bool> maybe_ret_val =
2319 python_function_name,
2321 bp_loc_sp, bp_option_data->m_extra_args);
2323 if (!maybe_ret_val) {
2325 llvm::handleAllErrors(
2326 maybe_ret_val.takeError(),
2328 *debugger.GetAsyncErrorStream() << E.ReadBacktrace();
2330 [&](
const llvm::ErrorInfoBase &E) {
2331 *debugger.GetAsyncErrorStream() << E.message();
2335 ret_val = maybe_ret_val.get();
2351 const char *python_function_name = wp_option_data->
script_source.c_str();
2366 if (!python_interpreter)
2369 if (python_function_name && python_function_name[0]) {
2373 if (stop_frame_sp && wp_sp) {
2374 bool ret_val =
true;
2380 python_function_name,
2394 const char *impl_function,
Process *process, std::string &output,
2401 if (!impl_function || !impl_function[0]) {
2419 const char *impl_function,
Thread *thread, std::string &output,
2425 if (!impl_function || !impl_function[0]) {
2432 if (std::optional<std::string> result =
2435 thread->shared_from_this())) {
2436 output = std::move(*result);
2444 const char *impl_function,
Target *target, std::string &output,
2451 if (!impl_function || !impl_function[0]) {
2457 TargetSP target_sp(target->shared_from_this());
2469 const char *impl_function,
StackFrame *frame, std::string &output,
2475 if (!impl_function || !impl_function[0]) {
2482 if (std::optional<std::string> result =
2485 frame->shared_from_this())) {
2486 output = std::move(*result);
2494 const char *impl_function,
ValueObject *value, std::string &output,
2501 if (!impl_function || !impl_function[0]) {
2517uint64_t
replace_all(std::string &str,
const std::string &oldStr,
2518 const std::string &newStr) {
2520 uint64_t matches = 0;
2521 while ((pos = str.find(oldStr, pos)) != std::string::npos) {
2523 str.replace(pos, oldStr.length(), newStr);
2524 pos += newStr.length();
2533 namespace fs = llvm::sys::fs;
2534 namespace path = llvm::sys::path;
2540 if (!pathname || !pathname[0]) {
2545 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
2549 if (!io_redirect_or_error) {
2554 ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
2566 auto ExtendSysPath = [&](std::string directory) -> llvm::Error {
2567 if (directory.empty()) {
2568 return llvm::createStringError(
"invalid directory name");
2575 StreamString command_stream;
2576 command_stream.
Printf(
"if not (sys.path.__contains__('%s')):\n "
2577 "sys.path.insert(1,'%s');\n\n",
2578 directory.c_str(), directory.c_str());
2579 bool syspath_retval =
2581 if (!syspath_retval)
2582 return llvm::createStringError(
"Python sys.path handling failed");
2584 return llvm::Error::success();
2587 std::string module_name(pathname);
2588 bool possible_package =
false;
2590 if (extra_search_dir) {
2591 if (llvm::Error e = ExtendSysPath(extra_search_dir.
GetPath())) {
2596 FileSpec module_file(pathname);
2600 std::error_code ec = status(module_file.GetPath(), st);
2602 if (ec || st.type() == fs::file_type::status_error ||
2603 st.type() == fs::file_type::type_unknown ||
2604 st.type() == fs::file_type::file_not_found) {
2607 if (strchr(pathname,
'\\') || strchr(pathname,
'/')) {
2613 possible_package =
true;
2614 }
else if (is_directory(st) || is_regular_file(st)) {
2615 if (module_file.GetDirectory().empty()) {
2617 "invalid directory name '{0}'", pathname);
2620 if (llvm::Error e = ExtendSysPath(module_file.GetDirectory().str())) {
2624 module_name = module_file.GetFilename().str();
2627 "no known way to import this module specification");
2633 llvm::StringRef extension = llvm::sys::path::extension(module_name);
2634 if (!extension.empty()) {
2635 if (extension ==
".py")
2636 module_name.resize(module_name.length() - 3);
2637 else if (extension ==
".pyc")
2638 module_name.resize(module_name.length() - 4);
2641 if (!possible_package && module_name.find(
'.') != llvm::StringRef::npos) {
2643 "Python does not allow dots in module names: %s", module_name.c_str());
2647 if (module_name.find(
'-') != llvm::StringRef::npos) {
2649 "Python discourages dashes in module names: %s", module_name.c_str());
2654 StreamString command_stream;
2655 command_stream.
Clear();
2656 command_stream.
Printf(
"sys.modules.__contains__('%s')", module_name.c_str());
2657 bool does_contain =
false;
2665 const bool was_imported_globally = does_contain_executed && does_contain;
2666 const bool was_imported_locally =
2672 command_stream.
Clear();
2674 if (was_imported_globally || was_imported_locally) {
2675 if (!was_imported_locally)
2676 command_stream.
Printf(
"import %s ; importlib.reload(%s)",
2677 module_name.c_str(), module_name.c_str());
2679 command_stream.
Printf(
"importlib.reload(%s)", module_name.c_str());
2681 command_stream.
Printf(
"import %s", module_name.c_str());
2698 command_stream.
Clear();
2699 command_stream.
Printf(
"%s", module_name.c_str());
2700 void *module_pyobj =
nullptr;
2706 *module_sp = std::make_shared<StructuredPythonObject>(PythonObject(
2707 PyRefType::Owned,
static_cast<PyObject *
>(module_pyobj)));
2720 if (!word || !word[0])
2723 llvm::StringRef word_sr(word);
2727 if (word_sr.find(
'"') != llvm::StringRef::npos ||
2728 word_sr.find(
'\'') != llvm::StringRef::npos)
2732 command_stream.
Printf(
"keyword.iskeyword('%s')", word);
2747 : m_debugger_sp(debugger_sp), m_synch_wanted(synchro),
2748 m_old_asynch(debugger_sp->GetAsyncExecution()) {
2757 m_debugger_sp->SetAsyncExecution(m_old_asynch);
2761 const char *impl_function, llvm::StringRef args,
2765 if (!impl_function) {
2773 if (!debugger_sp.get()) {
2778 bool ret_val =
false;
2788 std::string args_str = args.str();
2791 cmd_retobj, exe_ctx_ref_sp);
2809 std::string &dest) {
2812 if (!item || !*item)
2815 std::string command(item);
2816 command +=
".__doc__";
2820 char *result_ptr =
nullptr;
2826 dest.assign(result_ptr);
2831 str_stream <<
"Function " << item
2832 <<
" was not found. Containing module might be missing.";
2833 dest = std::string(str_stream.
GetString());
2838std::unique_ptr<ScriptInterpreterLocker>
2840 std::unique_ptr<ScriptInterpreterLocker> py_lock(
new Locker(
2853 InitializePythonRAII initialize_guard;
2854 if (llvm::Error
error = initialize_guard.DoInitialize())
2871 if (
FileSpec file_spec = HostInfo::GetShlibDir())
2875 "lldb.embedded_interpreter; from "
2876 "lldb.embedded_interpreter import run_python_interpreter; "
2877 "from lldb.embedded_interpreter import run_one_line");
2879#if LLDB_USE_PYTHON_SET_INTERRUPT
2883 RestoreSignalHandlerScope save_sigint(SIGINT);
2891 " def signal_handler(sig, frame):\n"
2892 " raise KeyboardInterrupt()\n"
2893 " signal.signal(signal.SIGINT, signal_handler);\n"
2894 "lldb_setup_sigint_handler();\n"
2895 "del lldb_setup_sigint_handler\n");
2897 return llvm::Error::success();
2902 std::string statement;
2904 statement.assign(
"sys.path.insert(0,\"");
2905 statement.append(path);
2906 statement.append(
"\")");
2908 statement.assign(
"sys.path.append(\"");
2909 statement.append(path);
2910 statement.append(
"\")");
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF(log,...)
#define LLDB_LOG_ERROR(log, error,...)
#define LLDB_LOG_VERBOSE(log,...)
ScriptInterpreterPythonImpl::Locker Locker
#define LLDB_PLUGIN_DEFINE(PluginName)
PyObject * PyInit__lldb(void)
static std::string GenerateUniqueName(const char *base_name_wanted, uint32_t &functions_counter, const void *name_token=nullptr)
static ScriptInterpreterPythonImpl * GetPythonInterpreter(Debugger &debugger)
static const char python_exe_relative_path[]
uint64_t replace_all(std::string &str, const std::string &oldStr, const std::string &newStr)
static const char GetInterpreterInfoScript[]
#define LLDB_SCOPED_TIMER()
A Python sys.stdout/stderr file backed by a pipe whose read end is drained by a reader thread that wr...
lldb::user_id_t m_debugger_id
int GetWriteDescriptor() const
ThreadedCommunication m_communication
static void ReadThreadBytesReceived(void *baton, const void *src, size_t src_len)
lldb::FileSP m_write_file_sp
static std::unique_ptr< SessionIORedirect > Create(lldb::user_id_t debugger_id, bool is_stdout)
SessionIORedirect(lldb::user_id_t debugger_id, bool is_stdout)
"lldb/Breakpoint/BreakpointOptions.h" Class that manages the options on a breakpoint or breakpoint lo...
void SetCallback(BreakpointHitCallback callback, const lldb::BatonSP &baton_sp, bool synchronous=false)
Adds a callback to the breakpoint option set.
bool GetInteractive() const
void AppendError(llvm::StringRef in_string)
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
lldb::ReturnStatus GetStatus() const
void AppendErrorWithFormatv(const char *format, Args &&...args)
A class to manage flag bits.
lldb::FileSP GetErrorFileSP()
lldb::FileSP GetOutputFileSP()
void RunIOHandlerAsync(const lldb::IOHandlerSP &reader_sp, bool cancel_top_handler=true)
Run the given IO handler and return immediately.
bool StatuslineSupported()
Whether the statusline can be drawn: show-statusline is enabled and the output is an escape-code-capa...
static lldb::DebuggerSP FindDebuggerWithID(lldb::user_id_t id)
ScriptInterpreter * GetScriptInterpreter(bool can_create=true, std::optional< lldb::ScriptLanguage > language={})
bool GetSetLLDBGlobals() const
bool GetMaskoutErrors() const
ExecuteScriptOptions & SetMaskoutErrors(bool maskout)
ExecuteScriptOptions & SetSetLLDBGlobals(bool set)
ExecuteScriptOptions & SetEnableIO(bool enable)
Execution context objects refer to objects in the execution of the program that is being debugged.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
const lldb::StackFrameSP & GetFrameSP() const
Get accessor to get the frame shared pointer.
Target * GetTargetPtr() const
Returns a pointer to the target object.
void AppendPathComponent(llvm::StringRef component)
bool RemoveLastPathComponent()
Removes the last path component by replacing the current path with its parent.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
void SetDirectory(llvm::StringRef directory)
Directory string set accessor.
llvm::StringRef GetFileNameExtension() const
Extract the extension of the file.
Status ResolveSymbolicLink(const FileSpec &src, FileSpec &dst)
int Open(const char *path, int flags, int mode=0600)
Wraps open in a platform-independent way.
static FileSystem & Instance()
void Resolve(llvm::SmallVectorImpl< char > &path, bool force_make_absolute=false)
Resolve path to make it canonical.
An abstract base class for files.
static int kInvalidDescriptor
virtual int GetDescriptor() const
Get underlying OS file descriptor for this file, or kInvalidDescriptor.
bool IsValid() const override
IsValid.
virtual Status Flush()
Flush the current stream.
lldb::LockableStreamFileSP GetErrorStreamFileSP()
lldb::LockableStreamFileSP GetOutputStreamFileSP()
bool GetInitSession() const
void PutCString(const char *cstr)
Status CreateNew() override
int ReleaseReadFileDescriptor() override
int ReleaseWriteFileDescriptor() override
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
A plug-in interface definition class for debugging a process.
lldb::FileSP GetOutputFile() const
lldb::FileSP GetErrorFile() const
void Flush()
Flush our output and error file handles.
lldb::FileSP GetInputFile() const
static llvm::Expected< std::unique_ptr< ScriptInterpreterIORedirect > > Create(bool enable_io, Debugger &debugger, CommandReturnObject *result)
Create an IO redirect.
ScriptInterpreterLocker()=default
bool DoInitSession(uint16_t on_entry_flags, lldb::FileSP in, lldb::FileSP out, lldb::FileSP err)
Locker(ScriptInterpreterPythonImpl *py_interpreter, uint16_t on_entry=AcquireLock|InitSession, uint16_t on_leave=FreeLock|TearDownSession, lldb::FileSP in=nullptr, lldb::FileSP out=nullptr, lldb::FileSP err=nullptr)
PyGILState_STATE m_GILState
ScriptInterpreterPythonImpl * m_python_interpreter
ScriptedCommandSynchronicity m_synch_wanted
SynchronicityHandler(lldb::DebuggerSP, ScriptedCommandSynchronicity)
lldb::DebuggerSP m_debugger_sp
bool GenerateTypeScriptFunction(StringList &input, std::string &output, const void *name_token=nullptr) override
Status GenerateFunction(const char *signature, const StringList &input, bool is_callback) override
bool GenerateScriptAliasFunction(StringList &input, std::string &output) override
lldb_private::Status ExecuteMultipleLines(const char *in_string, const ExecuteScriptOptions &options=ExecuteScriptOptions()) override
static llvm::Error Initialize()
bool IsReservedWord(const char *word) override
python::PythonObject m_run_one_line_function
python::PythonObject m_saved_stderr
bool GenerateWatchpointCommandCallbackData(StringList &input, std::string &output, bool is_callback) override
friend class IOHandlerPythonInterpreter
bool Interrupt() override
ScriptInterpreterPythonImpl(Debugger &debugger)
Status SetBreakpointCommandCallbackFunction(BreakpointOptions &bp_options, const char *function_name, StructuredData::ObjectSP extra_args_sp) override
Set a script function as the callback for the breakpoint.
lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() override
std::unique_ptr< SessionIORedirect > m_stderr_redirect
static bool BreakpointCallbackFunction(void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
std::string m_dictionary_name
StructuredData::DictionarySP GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target, const char *setting_name, lldb_private::Status &error) override
void CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options, CommandReturnObject &result) override
lldb::ScriptedCommandInterfaceSP CreateScriptedCommandInterface() override
bool RunScriptBasedCommand(const char *impl_function, llvm::StringRef args, ScriptedCommandSynchronicity synchronicity, lldb_private::CommandReturnObject &cmd_retobj, Status &error, const lldb_private::ExecutionContext &exe_ctx) override
python::PythonModule & GetMainModule()
lldb::ScriptedFrameProviderInterfaceSP CreateScriptedFrameProviderInterface() override
python::PythonObject m_saved_stdin
Status SetBreakpointCommandCallback(BreakpointOptions &bp_options, const char *callback_body, bool is_callback) override
Set the callback body text into the callback for the breakpoint.
PyThreadState * GetThreadState()
lldb::ScriptedStackFrameRecognizerInterfaceSP CreateScriptedStackFrameRecognizerInterface() override
bool EnterSession(uint16_t on_entry_flags, lldb::FileSP in, lldb::FileSP out, lldb::FileSP err)
void SetWatchpointCommandCallback(WatchpointOptions *wp_options, const char *user_input, bool is_callback) override
Set a one-liner as the callback for the watchpoint.
bool RedirectTerminalHandleThroughLock(const char *py_name, python::PythonObject &save_file, const char *mode, File &file)
If file is the debugger's own terminal, point sys.
std::unique_ptr< ScriptInterpreterLocker > AcquireInterpreterLock() override
void CollectDataForBreakpointCommandCallback(std::vector< std::reference_wrapper< BreakpointOptions > > &bp_options_vec, CommandReturnObject &result) override
python::PythonDictionary m_session_dict
uint32_t IsExecutingPython()
static void AddToSysPath(AddLocation location, std::string path)
lldb::ScriptedStringSummaryInterfaceSP CreateScriptedStringSummaryInterface() override
python::PythonDictionary & GetSessionDictionary()
bool LoadScriptingModule(const char *filename, const LoadScriptOptions &options, lldb_private::Status &error, StructuredData::ObjectSP *module_sp=nullptr, FileSpec extra_search_dir={}, lldb::TargetSP loaded_into_target_sp={}) override
Status GenerateBreakpointCommandCallbackData(StringList &input, std::string &output, bool has_extra_args, bool is_callback) override
PyThreadState * m_command_thread_state
lldb::OperatingSystemInterfaceSP CreateOperatingSystemInterface() override
python::PythonObject m_saved_stdout
bool FormatterCallbackFunction(const char *function_name, lldb::TypeImplSP type_impl_sp) override
void ExecuteInterpreterLoop() override
Status ExportFunctionDefinitionToInterpreter(StringList &function_def) override
bool ExecuteOneLine(llvm::StringRef command, CommandReturnObject *result, const ExecuteScriptOptions &options=ExecuteScriptOptions()) override
bool GetDocumentationForItem(const char *item, std::string &dest) override
In Python, a special attribute doc contains the docstring for an object (function,...
lldb::ScriptedSyntheticChildrenInterfaceSP CreateScriptedSyntheticChildrenInterface() override
lldb::ScriptedHookInterfaceSP CreateScriptedHookInterface() override
void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override
Called when a line or lines have been retrieved.
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
bool GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj, StructuredData::ObjectSP &callee_wrapper_sp, const TypeSummaryOptions &options, std::string &retval) override
lldb::ScriptedFrameInterfaceSP CreateScriptedFrameInterface() override
lldb::ScriptedProcessInterfaceUP CreateScriptedProcessInterface() override
bool m_pty_secondary_is_open
python::PythonDictionary m_sys_module_dict
bool ExecuteOneLineWithReturn(llvm::StringRef in_string, ScriptInterpreter::ScriptReturnType return_type, void *ret_value, const ExecuteScriptOptions &options=ExecuteScriptOptions()) override
lldb::ScriptedBreakpointInterfaceSP CreateScriptedBreakpointInterface() override
bool RunScriptFormatKeyword(const char *impl_function, Process *process, std::string &output, Status &error) override
python::PythonDictionary & GetSysModuleDictionary()
bool SetStdHandle(lldb::FileSP file, const char *py_name, python::PythonObject &save_file, const char *mode, bool serialize_terminal_output)
Point sys.
bool GetEmbeddedInterpreterModuleObjects()
bool GenerateTypeSynthClass(StringList &input, std::string &output, const void *name_token=nullptr) override
StructuredData::ObjectSP CreateStructuredDataFromScriptObject(ScriptObject obj) override
StructuredData::ObjectSP LoadPluginModule(const FileSpec &file_spec, lldb_private::Status &error) override
python::PythonModule m_main_module
llvm::Expected< unsigned > GetMaxPositionalArgumentsForCallable(const llvm::StringRef &callable_name) override
python::PythonObject m_run_one_line_str_global
static bool WatchpointCallbackFunction(void *baton, StoppointCallbackContext *context, lldb::user_id_t watch_id)
~ScriptInterpreterPythonImpl() override
static lldb::ScriptInterpreterSP CreateInstance(Debugger &debugger)
lldb::ScriptedThreadPlanInterfaceSP CreateScriptedThreadPlanInterface() override
ActiveIOHandler m_active_io_handler
std::unique_ptr< SessionIORedirect > m_stdout_redirect
Abstract interface for the Python script interpreter.
static void ComputePythonDir(llvm::SmallVectorImpl< char > &path)
static llvm::StringRef GetPluginNameStatic()
static void ComputePythonDirForApple(llvm::SmallVectorImpl< char > &path)
llvm::Expected< StructuredData::ObjectSP > GetExtensionSchema(const llvm::SmallVector< llvm::StringRef > &extension_path)
ScriptInterpreterPython(Debugger &debugger)
static llvm::StringRef GetPluginDescriptionStatic()
StructuredData::DictionarySP GetInterpreterInfo() override
llvm::Error ParseExtensionSchema(Stream &s, llvm::StringRef output_script_prefix, const llvm::SmallVector< llvm::StringRef > &extension_path, bool generate_non_abstract_methods, std::set< std::string > &typing_imports)
static FileSpec GetPythonDir()
static void SharedLibraryDirectoryHelper(FileSpec &this_file)
llvm::Expected< std::string > ExtensionToImportPath(lldb::ScriptedExtension extension) override
llvm::Expected< FileSpec > GenerateExtensionTemplate(const std::string &name, std::vector< ExtensionTemplateRequest > &extensions, bool generate_non_abstract_methods, std::string output_file) override
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
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