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 llvm::createStringError(
"invalid extension name");
298 return llvm::createStringError(
"invalid extension name");
301llvm::Expected<StructuredData::ObjectSP>
303 const llvm::SmallVector<llvm::StringRef> &extension_path) {
307 if (!import_path_or_err)
308 return import_path_or_err.takeError();
317 command_stream.
Printf(
"lldb.embedded_interpreter.generate_extension_schema("
318 "__import__('%s', fromlist=['']).%s)",
319 import_path_or_err->c_str(),
328 void *result_obj =
nullptr;
333 return llvm::createStringError(
"invalid extension schema format");
339 std::string schema_str;
341 PyGILState_STATE gil_state = PyGILState_Ensure();
344 static_cast<PyObject *
>(result_obj));
348 PyGILState_Release(gil_state);
351 if (schema_str.empty())
352 return llvm::createStringError(
"empty extension schema");
357 Stream &s, llvm::StringRef output_script_prefix,
358 const llvm::SmallVector<llvm::StringRef> &extension_path,
359 bool generate_non_abstract_methods, std::set<std::string> &typing_imports) {
362 return schema_or_err.takeError();
366 return llvm::createStringError(
"empty extension schema");
369 return llvm::createStringError(
"extension schema is not a JSON object");
377 typing_imports.insert(str->GetValue().str());
381 llvm::StringRef base_class, import_path;
383 return llvm::createStringError(
384 llvm::formatv(
"extension schema dictionary is missing 'class' key")
387 return llvm::createStringError(
388 llvm::formatv(
"extension schema dictionary is missing 'module' key")
392 s.
Printf(
"from %s import %s\n", import_path.data(), base_class.data());
396 s.
Printf(
"class %s%s(%s):\n", output_script_prefix.data(), base_class.data(),
403 bool has_body =
false;
410 s.
Printf(
"Attributes inherited from %s:\n", base_class.data());
411 for (
size_t i = 0; i < attributes->
GetSize(); i++) {
416 llvm::StringRef attr_name;
419 llvm::StringRef attr_type;
422 s.
Printf(
"- %s", attr_name.data());
424 s.
Printf(
": %s", attr_type.data());
435 return llvm::createStringError(
"missing 'members' key in extension schema");
441 bool any_abstract =
false;
442 for (
size_t i = 0; i < members->
GetSize(); i++) {
446 bool is_abstract =
false;
447 if ((*maybe_dict)->GetValueForKeyAsBoolean(
"is_abstract", is_abstract) &&
453 bool emit_all_methods = generate_non_abstract_methods || !any_abstract;
455 for (
size_t i = 0; i < members->
GetSize(); i++) {
458 return llvm::createStringError(
460 "member at index {0} in extension schema isn't a dictionary")
464 llvm::StringRef symbol, args;
466 return llvm::createStringError(
468 "member at index {0} in extension schema is missing 'name' key")
471 return llvm::createStringError(
472 llvm::formatv(
"member at index {0} in extension schema is missing "
476 bool is_abstract =
false;
477 bool has_is_abstract =
479 if (!emit_all_methods)
480 if (!has_is_abstract || !is_abstract)
484 s.
Printf(
"def %s%s:\n", symbol.data(), args.data());
487 llvm::StringRef documentation;
492 llvm::SmallVector<llvm::StringRef> lines;
493 documentation.split(lines,
"\n");
495 for (llvm::StringRef line : lines) {
506 if (symbol ==
"__init__") {
512 llvm::StringRef params = args.trim(
"()");
513 std::vector<std::string> forwarded_args;
516 auto flush = [&](
size_t end) {
517 llvm::StringRef param = params.slice(start, end);
518 param = param.split(
':').first.split(
'=').first.trim();
519 if (!param.empty() && param !=
"self")
520 forwarded_args.push_back(param.str());
522 for (
size_t i = 0; i < params.size(); ++i) {
524 if (c ==
'[' || c ==
'(' || c ==
'{')
526 else if (c ==
']' || c ==
')' || c ==
'}')
528 else if (c ==
',' && depth == 0) {
533 flush(params.size());
535 s.
Printf(
"super().__init__(%s)\n",
536 llvm::join(forwarded_args,
", ").c_str());
555 return llvm::Error::success();
559 const std::string &name, std::vector<ExtensionTemplateRequest> &extensions,
560 bool generate_non_abstract_methods, std::string output_file) {
566 std::set<std::string> typing_imports;
569 if (llvm::Error err =
571 generate_non_abstract_methods, typing_imports))
572 return std::move(err);
577 generated_file_stream.
PutCString(
"import lldb\n");
578 if (!typing_imports.empty()) {
579 std::vector<std::string> sorted_imports(typing_imports.begin(),
580 typing_imports.end());
581 generated_file_stream.
Format(
"from typing import {0}\n",
582 llvm::join(sorted_imports,
", "));
588 if (output_file.empty()) {
593 std::string sanitized;
594 sanitized.reserve(name.size());
596 sanitized.push_back(llvm::isAlnum(c) ?
static_cast<char>(llvm::toLower(c))
598 if (sanitized.find_first_not_of(
'_') == std::string::npos)
599 sanitized =
"extension";
600 const std::string file_name =
"lldb_" + sanitized +
"_extension.py";
601 save_location = HostInfo::GetGlobalTempDir();
605 save_location =
FileSpec(output_file);
616 return opened_file.takeError();
618 FileUP file = std::move(opened_file.get());
620 size_t byte_size = generated_file_stream.
GetSize();
624 if (
error.Fail() || byte_size != generated_file_stream.
GetSize())
625 return llvm::createStringError(
"Unable to write to destination file. Bytes "
626 "written do not match generated file size.");
627 return save_location;
642 llvm::StringRef libdir = LLDB_PYTHON_RELATIVE_LIBDIR;
643 for (
auto it = llvm::sys::path::begin(libdir),
644 end = llvm::sys::path::end(libdir);
658 return "Embedded Python interpreter";
666 setenv(
"PYTHONMALLOC",
"malloc",
true);
672#if !LLDB_ENABLE_DYNAMIC_SCRIPTINTERPRETERS
673 HostInfo::SetSharedLibraryDirectoryHelper(
707 "Ensured PyGILState. Previous state = {0}",
708 m_GILState == PyGILState_UNLOCKED ?
"unlocked" :
"locked");
730 "Releasing PyGILState. Returning to state = {0}",
731 m_GILState == PyGILState_UNLOCKED ?
"unlocked" :
"locked");
770 "run_one_line (%s, 'import copy, keyword, os, re, sys, uuid, lldb')",
778 "run_one_line (%s, 'from importlib import reload as reload_module')",
788 "run_one_line (%s, 'import lldb.formatters, lldb.formatters.cpp')",
793 run_string.
Printf(
"run_one_line (%s, 'import lldb.embedded_interpreter; from "
794 "lldb.embedded_interpreter import run_python_interpreter; "
795 "from lldb.embedded_interpreter import run_one_line')",
802 run_string.
Printf(
"run_one_line (%s, 'import pydoc; pydoc.pager = "
803 "pydoc.plainpager')",
808 run_string.
Printf(
"run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64
828 std::unique_ptr<SessionIORedirect> redirect(
834 std::unique_ptr<Connection> conn =
835 std::make_unique<ConnectionGenericFile>(read_handle,
true);
837 std::unique_ptr<Connection> conn =
838 std::make_unique<ConnectionFileDescriptor>(
841 if (!conn->IsConnected())
844 redirect->m_communication.SetConnection(std::move(conn));
845 redirect->m_communication.SetReadThreadBytesReceivedCallback(
847 if (!redirect->m_communication.StartReadThread())
849 redirect->m_connected =
true;
852 redirect->m_write_file_sp = std::make_shared<NativeFile>(
880 if (!src || !src_len)
885 debugger_sp->PrintAsync(
static_cast<const char *
>(src), src_len,
902 auto gil_state = PyGILState_Ensure();
904 PyGILState_Release(gil_state);
909 const char *instructions =
nullptr;
915 instructions = R
"(Enter your Python command(s). Type 'DONE' to end.
916def function (frame, bp_loc, internal_dict):
917 """frame: the lldb.SBFrame for the location at which you stopped
918 bp_loc: an lldb.SBBreakpointLocation for the breakpoint location information
919 internal_dict: an LLDB support object not to be used"""
923 instructions =
"Enter your Python command(s). Type 'DONE' to end.\n";
927 if (instructions && interactive) {
939 bool batch_mode =
m_debugger.GetCommandInterpreter().GetBatchCommandMode();
945 std::vector<std::reference_wrapper<BreakpointOptions>> *bp_options_vec =
946 (std::vector<std::reference_wrapper<BreakpointOptions>> *)
948 for (BreakpointOptions &bp_options : *bp_options_vec) {
950 auto data_up = std::make_unique<CommandDataPython>();
953 data_up->user_source.SplitIntoLines(data);
956 data_up->script_source,
960 auto baton_sp = std::make_shared<BreakpointOptions::CommandBaton>(
962 bp_options.SetCallback(
964 }
else if (!batch_mode) {
966 LockedStreamFile locked_stream = error_sp->Lock();
967 locked_stream.
Printf(
"Warning: No command attached to breakpoint.\n");
974 WatchpointOptions *wp_options =
976 auto data_up = std::make_unique<WatchpointOptions::CommandData>();
977 data_up->user_source.SplitIntoLines(data);
980 data_up->script_source,
983 std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up));
986 }
else if (!batch_mode) {
988 LockedStreamFile locked_stream = error_sp->Lock();
989 locked_stream.
Printf(
"Warning: No command attached to breakpoint.\n");
999 return std::make_shared<ScriptInterpreterPythonImpl>(debugger);
1005 log->
PutCString(
"ScriptInterpreterPythonImpl::LeaveSession()");
1008 RunSimpleString(
"lldb.debugger = None; lldb.target = None; lldb.process "
1009 "= None; lldb.thread = None; lldb.frame = None");
1016 if (PyThreadState_GetDict()) {
1018 if (sys_module_dict.
IsValid()) {
1023 auto flush_redirect = [&](
const char *py_name,
1024 std::unique_ptr<SessionIORedirect> &redirect) {
1031 if (llvm::Expected<PythonObject> result = file.
CallMethod(
"flush"))
1034 llvm::consumeError(result.takeError());
1063 const char *py_name,
PythonObject &save_file,
const char *mode,
1065 const bool is_stdout = ::strcmp(py_name,
"stdout") == 0;
1066 if (!is_stdout && ::strcmp(py_name,
"stderr") != 0)
1081 fd != debugger_file->GetDescriptor())
1084 std::unique_ptr<SessionIORedirect> &redirect =
1093 PyObject *pipe_file = PyFile_FromFd(
1094 redirect->GetWriteDescriptor(),
nullptr, mode, 1,
1095 nullptr,
"ignore",
nullptr,
1101 "failed to wrap sys.{0} on a synchronized pipe; falling back to "
1102 "the unsynchronized terminal descriptor",
1117 const char *py_name,
1120 bool serialize_terminal_output) {
1121 if (!file_sp || !*file_sp) {
1125 File &file = *file_sp;
1130 if (serialize_terminal_output &&
1142 "ScriptInterpreterPythonImpl::SetStdHandle failed to wrap "
1148 save_file = sys_module_dict.
GetItemForKey(PythonString(py_name));
1163 "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16
1164 ") session is already active, returning without doing anything",
1171 "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16
")",
1179 run_string.
Printf(
"run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64,
1182 "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64
")",
1184 run_string.
PutCString(
"; lldb.target = lldb.debugger.GetSelectedTarget()");
1185 run_string.
PutCString(
"; lldb.process = lldb.target.GetProcess()");
1186 run_string.
PutCString(
"; lldb.thread = lldb.process.GetSelectedThread ()");
1187 run_string.
PutCString(
"; lldb.frame = lldb.thread.GetSelectedFrame ()");
1192 run_string.
Printf(
"run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64,
1195 "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64
")",
1204 if (sys_module_dict.
IsValid()) {
1207 if (!in_sp || !out_sp || !err_sp || !*in_sp || !*out_sp || !*err_sp)
1208 m_debugger.AdoptTopIOHandlerFilesIfInvalid(top_in_sp, top_out_sp,
1224 const bool serialize_terminal_output =
1228 serialize_terminal_output)) {
1231 "w", serialize_terminal_output);
1235 serialize_terminal_output)) {
1238 "w", serialize_terminal_output);
1242 if (PyErr_Occurred())
1263 PyModule_GetDict(main_module.
get()));
1264 if (!main_dict.IsValid())
1280llvm::Expected<unsigned>
1282 const llvm::StringRef &callable_name) {
1283 if (callable_name.empty()) {
1284 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1285 "called with empty callable name.");
1292 callable_name, dict);
1294 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1295 "can't find callable: %s",
1296 callable_name.str().c_str());
1298 llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
1300 return arg_info.takeError();
1301 return arg_info.
get().max_positional_args;
1305 uint32_t &functions_counter,
1306 const void *name_token =
nullptr) {
1309 if (!base_name_wanted)
1310 return std::string();
1313 sstr.
Printf(
"%s_%d", base_name_wanted, functions_counter++);
1315 sstr.
Printf(
"%s_%p", base_name_wanted, name_token);
1325 PyImport_AddModule(
"lldb.embedded_interpreter"));
1326 if (!module.IsValid())
1330 PyModule_GetDict(module.get()));
1331 if (!module_dict.IsValid())
1335 module_dict.GetItemForKey(
PythonString(
"run_one_line"));
1337 module_dict.GetItemForKey(
PythonString(
"g_run_one_line_str"));
1344 std::string command_str = command.str();
1349 if (!command.empty()) {
1356 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
1359 if (!io_redirect_or_error) {
1362 "failed to redirect I/O: {0}\n",
1363 llvm::fmt_consume(io_redirect_or_error.takeError()));
1365 llvm::consumeError(io_redirect_or_error.takeError());
1371 bool success =
false;
1397 Py_BuildValue(
"(Os)", session_dict.
get(), command_str.c_str()));
1414 io_redirect.
Flush();
1423 command_str.c_str());
1429 result->
AppendError(
"empty command passed to python\n");
1448 if (io_handler_sp) {
1454#if LLDB_USE_PYTHON_SET_INTERRUPT
1462 PyErr_SetInterrupt();
1473 PyThreadState *state = PyThreadState_Get();
1477 long tid = PyThread_get_thread_ident();
1478 PyThreadState_Swap(state);
1479 int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt);
1481 "ScriptInterpreterPythonImpl::Interrupt() sending "
1482 "PyExc_KeyboardInterrupt (tid = %li, num_threads = %i)...",
1488 "ScriptInterpreterPythonImpl::Interrupt() python code not running, "
1498 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
1502 if (!io_redirect_or_error) {
1503 llvm::consumeError(io_redirect_or_error.takeError());
1527 Expected<PythonObject> maybe_py_return =
1530 if (!maybe_py_return) {
1531 llvm::handleAllErrors(
1532 maybe_py_return.takeError(),
1535 if (options.GetMaskoutErrors()) {
1536 if (E.Matches(PyExc_SyntaxError)) {
1542 [](
const llvm::ErrorInfoBase &E) {});
1546 PythonObject py_return = std::move(maybe_py_return.get());
1549 switch (return_type) {
1550 case eScriptReturnTypeCharPtr:
1552 const char format[3] =
"s#";
1553 return PyArg_Parse(py_return.
get(), format, (
char **)ret_value);
1555 case eScriptReturnTypeCharStrOrNone:
1558 const char format[3] =
"z";
1559 return PyArg_Parse(py_return.
get(), format, (
char **)ret_value);
1561 case eScriptReturnTypeBool: {
1562 const char format[2] =
"b";
1563 return PyArg_Parse(py_return.
get(), format, (
bool *)ret_value);
1565 case eScriptReturnTypeShortInt: {
1566 const char format[2] =
"h";
1567 return PyArg_Parse(py_return.
get(), format, (
short *)ret_value);
1569 case eScriptReturnTypeShortIntUnsigned: {
1570 const char format[2] =
"H";
1571 return PyArg_Parse(py_return.
get(), format, (
unsigned short *)ret_value);
1573 case eScriptReturnTypeInt: {
1574 const char format[2] =
"i";
1575 return PyArg_Parse(py_return.
get(), format, (
int *)ret_value);
1577 case eScriptReturnTypeIntUnsigned: {
1578 const char format[2] =
"I";
1579 return PyArg_Parse(py_return.
get(), format, (
unsigned int *)ret_value);
1581 case eScriptReturnTypeLongInt: {
1582 const char format[2] =
"l";
1583 return PyArg_Parse(py_return.
get(), format, (
long *)ret_value);
1585 case eScriptReturnTypeLongIntUnsigned: {
1586 const char format[2] =
"k";
1587 return PyArg_Parse(py_return.
get(), format, (
unsigned long *)ret_value);
1589 case eScriptReturnTypeLongLong: {
1590 const char format[2] =
"L";
1591 return PyArg_Parse(py_return.
get(), format, (
long long *)ret_value);
1593 case eScriptReturnTypeLongLongUnsigned: {
1594 const char format[2] =
"K";
1595 return PyArg_Parse(py_return.
get(), format,
1596 (
unsigned long long *)ret_value);
1598 case eScriptReturnTypeFloat: {
1599 const char format[2] =
"f";
1600 return PyArg_Parse(py_return.
get(), format, (
float *)ret_value);
1602 case eScriptReturnTypeDouble: {
1603 const char format[2] =
"d";
1604 return PyArg_Parse(py_return.
get(), format, (
double *)ret_value);
1606 case eScriptReturnTypeChar: {
1607 const char format[2] =
"c";
1608 return PyArg_Parse(py_return.
get(), format, (
char *)ret_value);
1610 case eScriptReturnTypeOpaqueObject: {
1611 *((PyObject **)ret_value) = py_return.
release();
1615 llvm_unreachable(
"Fully covered switch!");
1621 if (in_string ==
nullptr)
1624 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
1628 if (!io_redirect_or_error)
1631 ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
1651 Expected<PythonObject> return_value =
1654 if (!return_value) {
1656 llvm::handleErrors(return_value.takeError(), [&](PythonException &E) {
1657 llvm::Error error = llvm::createStringError(
1658 llvm::inconvertibleErrorCode(), E.ReadBacktrace());
1659 if (!options.GetMaskoutErrors())
1670 std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
1673 m_debugger.GetCommandInterpreter().GetPythonCommandsFromIOHandler(
1674 " ", *
this, &bp_options_vec);
1680 m_debugger.GetCommandInterpreter().GetPythonCommandsFromIOHandler(
1681 " ", *
this, wp_options);
1689 std::string function_signature = function_name;
1691 llvm::Expected<unsigned> maybe_args =
1695 "could not get num args: %s",
1696 llvm::toString(maybe_args.takeError()).c_str());
1699 size_t max_args = *maybe_args;
1701 bool uses_extra_args =
false;
1702 if (max_args >= 4) {
1703 uses_extra_args =
true;
1704 function_signature +=
"(frame, bp_loc, extra_args, internal_dict)";
1705 }
else if (max_args >= 3) {
1706 if (extra_args_sp) {
1708 "cannot pass extra_args to a three argument callback");
1711 uses_extra_args =
false;
1712 function_signature +=
"(frame, bp_loc, internal_dict)";
1715 "function, %s can only take %zu",
1716 function_name, max_args);
1721 extra_args_sp, uses_extra_args,
1728 std::unique_ptr<BreakpointOptions::CommandData> &cmd_data_up) {
1731 cmd_data_up->script_source,
1738 std::make_shared<BreakpointOptions::CommandBaton>(std::move(cmd_data_up));
1748 false, is_callback);
1756 auto data_up = std::make_unique<CommandDataPython>(extra_args_sp);
1762 data_up->user_source.SplitIntoLines(command_body_text);
1764 data_up->user_source, data_up->script_source, uses_extra_args,
1766 if (
error.Success()) {
1768 std::make_shared<BreakpointOptions::CommandBaton>(std::move(data_up));
1779 auto data_up = std::make_unique<WatchpointOptions::CommandData>();
1786 data_up->user_source.AppendString(user_input);
1787 data_up->script_source.assign(user_input);
1790 data_up->user_source, data_up->script_source, is_callback)) {
1792 std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up));
1801 std::string function_def_string(function_def.
CopyList());
1803 function_def_string.c_str());
1814 int num_lines = input.
GetSize();
1815 if (num_lines == 0) {
1820 if (!signature || *signature == 0) {
1826 StringList auto_generated_function;
1829 " global_dict = globals()");
1831 " new_keys = internal_dict.keys()");
1834 " old_keys = global_dict.keys()");
1836 " global_dict.update(internal_dict)");
1843 if (num_lines == 1) {
1849 "ScriptInterpreterPythonImpl::GenerateFunction(is_callback="
1850 "true) = ERROR: python function is multiline.");
1854 " __return_val = None");
1856 " def __user_code():");
1860 for (
int i = 0; i < num_lines; ++i) {
1866 " __return_val = __user_code()");
1870 " for key in new_keys:");
1873 " if key in old_keys:");
1876 " internal_dict[key] = global_dict[key]");
1878 " elif key in global_dict:");
1881 " del global_dict[key]");
1884 " return __return_val");
1893 StringList &user_input, std::string &output,
const void *name_token) {
1894 static uint32_t num_created_functions = 0;
1899 if (user_input.
GetSize() == 0)
1905 std::string auto_generated_function_name(
1907 num_created_functions, name_token));
1908 sstr.
Printf(
"def %s (valobj, internal_dict):",
1909 auto_generated_function_name.c_str());
1916 output.assign(auto_generated_function_name);
1921 StringList &user_input, std::string &output) {
1922 static uint32_t num_created_functions = 0;
1927 if (user_input.
GetSize() == 0)
1931 "lldb_autogen_python_cmd_alias_func", num_created_functions));
1933 sstr.
Printf(
"def %s (debugger, args, exe_ctx, result, internal_dict):",
1934 auto_generated_function_name.c_str());
1941 output.assign(auto_generated_function_name);
1946 StringList &user_input, std::string &output,
const void *name_token) {
1947 static uint32_t num_created_classes = 0;
1949 int num_lines = user_input.
GetSize();
1953 if (user_input.
GetSize() == 0)
1959 "lldb_autogen_python_type_synth_class", num_created_classes, name_token));
1965 sstr.
Printf(
"class %s:", auto_generated_class_name.c_str());
1971 for (
int i = 0; i < num_lines; ++i) {
1985 output.assign(auto_generated_class_name);
1991 return std::make_unique<ScriptedProcessPythonInterface>(*
this);
1996 return std::make_shared<ScriptedHookPythonInterface>(*
this);
2001 return std::make_shared<ScriptedBreakpointPythonInterface>(*
this);
2006 return std::make_shared<ScriptedStackFrameRecognizerPythonInterface>(*
this);
2011 return std::make_shared<ScriptedCommandPythonInterface>(*
this);
2016 return std::make_shared<ScriptedThreadPythonInterface>(*
this);
2021 return std::make_shared<ScriptedFramePythonInterface>(*
this);
2026 return std::make_shared<ScriptedFrameProviderPythonInterface>(*
this);
2031 return std::make_shared<ScriptedThreadPlanPythonInterface>(*
this);
2036 return std::make_shared<OperatingSystemPythonInterface>(*
this);
2042 void *ptr =
const_cast<void *
>(obj.
GetPointer());
2045 if (!py_obj.IsValid() || py_obj.IsNone())
2047 return py_obj.CreateStructuredObject();
2060 LoadScriptOptions load_script_options =
2061 LoadScriptOptions().SetInitSession(
true).SetSilent(
false);
2072 if (!plugin_module_sp || !target || !setting_name || !setting_name[0])
2080 TargetSP target_sp(target->shared_from_this());
2083 generic->GetValue(), setting_name, target_sp);
2100 if (class_name ==
nullptr || class_name[0] ==
'\0')
2116 if (!python_interpreter)
2129 const char *oneliner, std::string &output,
const void *name_token) {
2136 const char *oneliner, std::string &output,
const void *name_token) {
2143 StringList &user_input, std::string &output,
bool has_extra_args,
2145 static uint32_t num_created_functions = 0;
2149 if (user_input.
GetSize() == 0) {
2155 "lldb_autogen_python_bp_callback_func_", num_created_functions));
2157 sstr.
Printf(
"def %s (frame, bp_loc, extra_args, internal_dict):",
2158 auto_generated_function_name.c_str());
2160 sstr.
Printf(
"def %s (frame, bp_loc, internal_dict):",
2161 auto_generated_function_name.c_str());
2164 if (!
error.Success())
2168 output.assign(auto_generated_function_name);
2173 StringList &user_input, std::string &output,
bool is_callback) {
2174 static uint32_t num_created_functions = 0;
2178 if (user_input.
GetSize() == 0)
2182 "lldb_autogen_python_wp_callback_func_", num_created_functions));
2183 sstr.
Printf(
"def %s (frame, wp, internal_dict):",
2184 auto_generated_function_name.c_str());
2190 output.assign(auto_generated_function_name);
2201 if (!valobj.get()) {
2202 retval.assign(
"<no object>");
2206 void *old_callee =
nullptr;
2208 if (callee_wrapper_sp) {
2209 generic = callee_wrapper_sp->GetAsGeneric();
2211 old_callee =
generic->GetValue();
2213 void *new_callee = old_callee;
2216 if (python_function_name && *python_function_name) {
2223 static Timer::Category func_cat(
"LLDBSwigPythonCallTypeScript");
2224 Timer scoped_timer(func_cat,
"LLDBSwigPythonCallTypeScript");
2227 &new_callee, options_sp, retval);
2231 retval.assign(
"<no function name>");
2235 if (new_callee && old_callee != new_callee) {
2238 callee_wrapper_sp = std::make_shared<StructuredPythonObject>(
2239 PythonObject(PyRefType::Borrowed,
static_cast<PyObject *
>(new_callee)));
2246 const char *python_function_name,
TypeImplSP type_impl_sp) {
2256 CommandDataPython *bp_option_data = (CommandDataPython *)baton;
2257 const char *python_function_name = bp_option_data->script_source.c_str();
2272 if (!python_interpreter)
2275 if (python_function_name && python_function_name[0]) {
2278 if (breakpoint_sp) {
2280 breakpoint_sp->FindLocationByID(break_loc_id));
2282 if (stop_frame_sp && bp_loc_sp) {
2283 bool ret_val =
true;
2288 Expected<bool> maybe_ret_val =
2290 python_function_name,
2292 bp_loc_sp, bp_option_data->m_extra_args);
2294 if (!maybe_ret_val) {
2296 llvm::handleAllErrors(
2297 maybe_ret_val.takeError(),
2299 *debugger.GetAsyncErrorStream() << E.ReadBacktrace();
2301 [&](
const llvm::ErrorInfoBase &E) {
2302 *debugger.GetAsyncErrorStream() << E.message();
2306 ret_val = maybe_ret_val.get();
2322 const char *python_function_name = wp_option_data->
script_source.c_str();
2337 if (!python_interpreter)
2340 if (python_function_name && python_function_name[0]) {
2344 if (stop_frame_sp && wp_sp) {
2345 bool ret_val =
true;
2351 python_function_name,
2366 if (!implementor_sp)
2371 auto *implementor =
static_cast<PyObject *
>(
generic->GetValue());
2388 if (!implementor_sp)
2394 auto *implementor =
static_cast<PyObject *
>(
generic->GetValue());
2402 PyObject *child_ptr =
2404 if (child_ptr !=
nullptr && child_ptr != Py_None) {
2407 if (sb_value_ptr ==
nullptr)
2408 Py_XDECREF(child_ptr);
2413 Py_XDECREF(child_ptr);
2422 if (!implementor_sp)
2423 return llvm::createStringErrorV(
"type has no child named '{0}'",
2428 return llvm::createStringErrorV(
"type has no child named '{0}'",
2430 auto *implementor =
static_cast<PyObject *
>(
generic->GetValue());
2432 return llvm::createStringErrorV(
"type has no child named '{0}'",
2445 return llvm::createStringErrorV(
"type has no child named '{0}'",
2452 bool ret_val =
false;
2454 if (!implementor_sp)
2460 auto *implementor =
static_cast<PyObject *
>(
generic->GetValue());
2476 bool ret_val =
false;
2478 if (!implementor_sp)
2484 auto *implementor =
static_cast<PyObject *
>(
generic->GetValue());
2502 if (!implementor_sp)
2508 auto *implementor =
static_cast<PyObject *
>(
generic->GetValue());
2515 PyObject *child_ptr =
2517 if (child_ptr !=
nullptr && child_ptr != Py_None) {
2520 if (sb_value_ptr ==
nullptr)
2521 Py_XDECREF(child_ptr);
2526 Py_XDECREF(child_ptr);
2538 if (!implementor_sp)
2541 StructuredData::Generic *
generic = implementor_sp->GetAsGeneric();
2545 PythonObject implementor(PyRefType::Borrowed,
2546 (PyObject *)generic->GetValue());
2547 if (!implementor.IsAllocated())
2550 llvm::Expected<PythonObject> expected_py_return =
2551 implementor.CallMethod(
"get_type_name");
2553 if (!expected_py_return) {
2554 llvm::consumeError(expected_py_return.takeError());
2558 PythonObject py_return = std::move(expected_py_return.get());
2567 const char *impl_function,
Process *process, std::string &output,
2574 if (!impl_function || !impl_function[0]) {
2592 const char *impl_function,
Thread *thread, std::string &output,
2598 if (!impl_function || !impl_function[0]) {
2605 if (std::optional<std::string> result =
2608 thread->shared_from_this())) {
2609 output = std::move(*result);
2617 const char *impl_function,
Target *target, std::string &output,
2624 if (!impl_function || !impl_function[0]) {
2630 TargetSP target_sp(target->shared_from_this());
2642 const char *impl_function,
StackFrame *frame, std::string &output,
2648 if (!impl_function || !impl_function[0]) {
2655 if (std::optional<std::string> result =
2658 frame->shared_from_this())) {
2659 output = std::move(*result);
2667 const char *impl_function,
ValueObject *value, std::string &output,
2674 if (!impl_function || !impl_function[0]) {
2690uint64_t
replace_all(std::string &str,
const std::string &oldStr,
2691 const std::string &newStr) {
2693 uint64_t matches = 0;
2694 while ((pos = str.find(oldStr, pos)) != std::string::npos) {
2696 str.replace(pos, oldStr.length(), newStr);
2697 pos += newStr.length();
2706 namespace fs = llvm::sys::fs;
2707 namespace path = llvm::sys::path;
2713 if (!pathname || !pathname[0]) {
2718 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
2722 if (!io_redirect_or_error) {
2727 ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
2739 auto ExtendSysPath = [&](std::string directory) -> llvm::Error {
2740 if (directory.empty()) {
2741 return llvm::createStringError(
"invalid directory name");
2748 StreamString command_stream;
2749 command_stream.
Printf(
"if not (sys.path.__contains__('%s')):\n "
2750 "sys.path.insert(1,'%s');\n\n",
2751 directory.c_str(), directory.c_str());
2752 bool syspath_retval =
2754 if (!syspath_retval)
2755 return llvm::createStringError(
"Python sys.path handling failed");
2757 return llvm::Error::success();
2760 std::string module_name(pathname);
2761 bool possible_package =
false;
2763 if (extra_search_dir) {
2764 if (llvm::Error e = ExtendSysPath(extra_search_dir.
GetPath())) {
2769 FileSpec module_file(pathname);
2773 std::error_code ec = status(module_file.GetPath(), st);
2775 if (ec || st.type() == fs::file_type::status_error ||
2776 st.type() == fs::file_type::type_unknown ||
2777 st.type() == fs::file_type::file_not_found) {
2780 if (strchr(pathname,
'\\') || strchr(pathname,
'/')) {
2786 possible_package =
true;
2787 }
else if (is_directory(st) || is_regular_file(st)) {
2788 if (module_file.GetDirectory().empty()) {
2790 "invalid directory name '{0}'", pathname);
2793 if (llvm::Error e = ExtendSysPath(module_file.GetDirectory().str())) {
2797 module_name = module_file.GetFilename().str();
2800 "no known way to import this module specification");
2806 llvm::StringRef extension = llvm::sys::path::extension(module_name);
2807 if (!extension.empty()) {
2808 if (extension ==
".py")
2809 module_name.resize(module_name.length() - 3);
2810 else if (extension ==
".pyc")
2811 module_name.resize(module_name.length() - 4);
2814 if (!possible_package && module_name.find(
'.') != llvm::StringRef::npos) {
2816 "Python does not allow dots in module names: %s", module_name.c_str());
2820 if (module_name.find(
'-') != llvm::StringRef::npos) {
2822 "Python discourages dashes in module names: %s", module_name.c_str());
2827 StreamString command_stream;
2828 command_stream.
Clear();
2829 command_stream.
Printf(
"sys.modules.__contains__('%s')", module_name.c_str());
2830 bool does_contain =
false;
2838 const bool was_imported_globally = does_contain_executed && does_contain;
2839 const bool was_imported_locally =
2845 command_stream.
Clear();
2847 if (was_imported_globally || was_imported_locally) {
2848 if (!was_imported_locally)
2849 command_stream.
Printf(
"import %s ; reload_module(%s)",
2850 module_name.c_str(), module_name.c_str());
2852 command_stream.
Printf(
"reload_module(%s)", module_name.c_str());
2854 command_stream.
Printf(
"import %s", module_name.c_str());
2871 command_stream.
Clear();
2872 command_stream.
Printf(
"%s", module_name.c_str());
2873 void *module_pyobj =
nullptr;
2879 *module_sp = std::make_shared<StructuredPythonObject>(PythonObject(
2880 PyRefType::Owned,
static_cast<PyObject *
>(module_pyobj)));
2893 if (!word || !word[0])
2896 llvm::StringRef word_sr(word);
2900 if (word_sr.find(
'"') != llvm::StringRef::npos ||
2901 word_sr.find(
'\'') != llvm::StringRef::npos)
2905 command_stream.
Printf(
"keyword.iskeyword('%s')", word);
2920 : m_debugger_sp(debugger_sp), m_synch_wanted(synchro),
2921 m_old_asynch(debugger_sp->GetAsyncExecution()) {
2930 m_debugger_sp->SetAsyncExecution(m_old_asynch);
2934 const char *impl_function, llvm::StringRef args,
2938 if (!impl_function) {
2946 if (!debugger_sp.get()) {
2951 bool ret_val =
false;
2961 std::string args_str = args.str();
2964 cmd_retobj, exe_ctx_ref_sp);
2980 std::string &dest) {
2983 if (!item || !*item)
2986 std::string command(item);
2987 command +=
".__doc__";
2991 char *result_ptr =
nullptr;
2997 dest.assign(result_ptr);
3002 str_stream <<
"Function " << item
3003 <<
" was not found. Containing module might be missing.";
3004 dest = std::string(str_stream.
GetString());
3009std::unique_ptr<ScriptInterpreterLocker>
3011 std::unique_ptr<ScriptInterpreterLocker> py_lock(
new Locker(
3024 InitializePythonRAII initialize_guard;
3040 if (
FileSpec file_spec = HostInfo::GetShlibDir())
3044 "lldb.embedded_interpreter; from "
3045 "lldb.embedded_interpreter import run_python_interpreter; "
3046 "from lldb.embedded_interpreter import run_one_line");
3048#if LLDB_USE_PYTHON_SET_INTERRUPT
3052 RestoreSignalHandlerScope save_sigint(SIGINT);
3060 " def signal_handler(sig, frame):\n"
3061 " raise KeyboardInterrupt()\n"
3062 " signal.signal(signal.SIGINT, signal_handler);\n"
3063 "lldb_setup_sigint_handler();\n"
3064 "del lldb_setup_sigint_handler\n");
3070 std::string statement;
3072 statement.assign(
"sys.path.insert(0,\"");
3073 statement.append(path);
3074 statement.append(
"\")");
3076 statement.assign(
"sys.path.append(\"");
3077 statement.append(path);
3078 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 uniqued constant string class.
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.
lldb::ValueObjectSP GetSyntheticValue(const StructuredData::ObjectSP &implementor) override
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()
bool UpdateSynthProviderInstance(const StructuredData::ObjectSP &implementor) override
static void AddToSysPath(AddLocation location, std::string path)
python::PythonDictionary & GetSessionDictionary()
bool MightHaveChildrenSynthProviderInstance(const StructuredData::ObjectSP &implementor) override
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
ConstString GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) 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
llvm::Expected< uint32_t > GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor, const char *child_name) override
bool FormatterCallbackFunction(const char *function_name, lldb::TypeImplSP type_impl_sp) override
void ExecuteInterpreterLoop() override
Status ExportFunctionDefinitionToInterpreter(StringList &function_def) override
StructuredData::ObjectSP CreateSyntheticScriptedProvider(const char *class_name, lldb::ValueObjectSP valobj) 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::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
size_t CalculateNumChildren(const StructuredData::ObjectSP &implementor, uint32_t max) override
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()
lldb::ValueObjectSP GetChildAtIndex(const StructuredData::ObjectSP &implementor, uint32_t idx) override
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.
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 Check(PyObject *py_obj)
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 lldb::ValueObjectSP LLDBSWIGPython_GetValueObjectSPFromSBValue(void *data)
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 PyObject * LLDBSwigPython_GetValueSynthProviderInstance(PyObject *implementor)
static bool LLDBSwigPython_UpdateSynthProviderInstance(PyObject *implementor)
static bool LLDBSWIGPythonRunScriptKeywordTarget(const char *python_function_name, const char *session_dictionary_name, const lldb::TargetSP &target, std::string &output)
static uint32_t LLDBSwigPython_GetIndexOfChildWithName(PyObject *implementor, const char *child_name)
static std::optional< std::string > LLDBSWIGPythonRunScriptKeywordFrame(const char *python_function_name, const char *session_dictionary_name, lldb::StackFrameSP frame)
static PyObject * LLDBSwigPython_GetChildAtIndex(PyObject *implementor, uint32_t idx)
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 python::PythonObject LLDBSwigPythonCreateSyntheticProvider(const char *python_class_name, const char *session_dictionary_name, const lldb::ValueObjectSP &valobj_sp)
static bool LLDBSwigPythonWatchpointCallbackFunction(const char *python_function_name, const char *session_dictionary_name, const lldb::StackFrameSP &sb_frame, const lldb::WatchpointSP &sb_wp)
static size_t LLDBSwigPython_CalculateNumChildren(PyObject *implementor, uint32_t max)
static bool LLDBSwigPython_MightHaveChildrenSynthProviderInstance(PyObject *implementor)
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)
void * LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data)
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
@ eScriptedExtensionScriptedFrameProvider
@ eScriptedExtensionScriptedThread
@ eScriptedExtensionScriptedStackFrameRecognizer
@ eScriptedExtensionInvalid
std::shared_ptr< lldb_private::ScriptedHookInterface > ScriptedHookInterfaceSP
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
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