[Go to site: main page, start]

LLDB mainline
ScriptInterpreterPython.cpp
Go to the documentation of this file.
1//===-- ScriptInterpreterPython.cpp ---------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "lldb-python.h"
10
12#include "PythonDataObjects.h"
13#include "PythonReadline.h"
14#include "SWIGPythonBridge.h"
16
17#include "lldb/API/SBError.h"
19#include "lldb/API/SBFrame.h"
20#include "lldb/API/SBValue.h"
23#include "lldb/Core/Debugger.h"
27#include "lldb/Host/Config.h"
30#include "lldb/Host/HostInfo.h"
31#include "lldb/Host/Pipe.h"
35#include "lldb/Target/Thread.h"
40#include "lldb/Utility/Timer.h"
43#include "lldb/lldb-forward.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"
51
52#if defined(_WIN32)
54#endif
55
56#include <cstdio>
57#include <cstdlib>
58#include <memory>
59#include <optional>
60#include <stdlib.h>
61#include <string>
62
63using namespace lldb;
64using namespace lldb_private;
65using namespace lldb_private::python;
66using llvm::Expected;
67
69
70// Defined in the SWIG source file
71extern "C" PyObject *PyInit__lldb(void);
72
73#define LLDBSwigPyInit PyInit__lldb
74
75#if defined(_WIN32)
76// Don't mess with the signal handlers on Windows.
77#define LLDB_USE_PYTHON_SET_INTERRUPT 0
78#else
79#define LLDB_USE_PYTHON_SET_INTERRUPT 1
80#endif
81
83 ScriptInterpreter *script_interpreter =
85 return static_cast<ScriptInterpreterPythonImpl *>(script_interpreter);
86}
87
88namespace {
89
90// Initializing Python is not a straightforward process. We cannot control
91// what external code may have done before getting to this point in LLDB,
92// including potentially having already initialized Python, so we need to do a
93// lot of work to ensure that the existing state of the system is maintained
94// across our initialization. We do this by using an RAII pattern where we
95// save off initial state at the beginning, and restore it at the end
96struct InitializePythonRAII {
97public:
98 InitializePythonRAII() {
99 // The table of built-in modules can only be extended before Python is
100 // initialized.
101 if (!Py_IsInitialized()) {
102#ifdef LLDB_USE_LIBEDIT_READLINE_COMPAT_MODULE
103 // Python's readline is incompatible with libedit being linked into lldb.
104 // Provide a patched version local to the embedded interpreter.
105 PyImport_AppendInittab("readline", initlldb_readline);
106#endif
107
108 // Register _lldb as a built-in module.
109 PyImport_AppendInittab("_lldb", LLDBSwigPyInit);
110 }
111
112#if LLDB_EMBED_PYTHON_HOME
113 PyConfig config;
114 PyConfig_InitPythonConfig(&config);
115
116 static std::string g_python_home = []() -> std::string {
117 if (llvm::sys::path::is_absolute(LLDB_PYTHON_HOME))
118 return LLDB_PYTHON_HOME;
119
120 FileSpec spec = HostInfo::GetShlibDir();
121 if (!spec)
122 return {};
123 spec.AppendPathComponent(LLDB_PYTHON_HOME);
124 return spec.GetPath();
125 }();
126 if (!g_python_home.empty()) {
127 PyConfig_SetBytesString(&config, &config.home, g_python_home.c_str());
128 }
129
130 config.install_signal_handlers = 0;
131 Py_InitializeFromConfig(&config);
132 PyConfig_Clear(&config);
133#else
134 Py_InitializeEx(/*install_sigs=*/0);
135#endif
136
137 // The only case we should go further and acquire the GIL: it is unlocked.
138 PyGILState_STATE gil_state = PyGILState_Ensure();
139 if (gil_state != PyGILState_UNLOCKED)
140 return;
141
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");
147 }
148
149 ~InitializePythonRAII() {
150 if (m_was_already_initialized) {
151 LLDB_LOG_VERBOSE(GetLog(LLDBLog::Script),
152 "Releasing PyGILState. Returning to state = {0}",
153 m_gil_state == PyGILState_UNLOCKED ? "unlocked"
154 : "locked");
155 PyGILState_Release(m_gil_state);
156 } else {
157 // We initialized the threads in this function, just unlock the GIL.
158 PyEval_SaveThread();
159 }
160 }
161
162private:
163 PyGILState_STATE m_gil_state = PyGILState_UNLOCKED;
164 bool m_was_already_initialized = false;
165};
166
167#if LLDB_USE_PYTHON_SET_INTERRUPT
168/// Saves the current signal handler for the specified signal and restores
169/// it at the end of the current scope.
170struct RestoreSignalHandlerScope {
171 /// The signal handler.
172 struct sigaction m_prev_handler;
173 int m_signal_code;
174 RestoreSignalHandlerScope(int signal_code) : m_signal_code(signal_code) {
175 // Initialize sigaction to their default state.
176 std::memset(&m_prev_handler, 0, sizeof(m_prev_handler));
177 // Don't install a new handler, just read back the old one.
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");
181 }
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");
185 }
186};
187#endif
188} // namespace
189
192 auto style = llvm::sys::path::Style::posix;
193
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) {
199 ComputePythonDir(path);
200 return;
201 }
202 path.resize(framework - rend);
203 llvm::sys::path::append(path, style, "LLDB.framework", "Resources", "Python");
204}
205
208 // Build the path by backing out of the lib dir, then building with whatever
209 // the real python interpreter uses. (e.g. lib for most, lib64 on RHEL
210 // x86_64, or bin on Windows).
211 llvm::sys::path::remove_filename(path);
212 llvm::sys::path::append(path, LLDB_PYTHON_RELATIVE_LIBDIR);
213
214#if defined(_WIN32)
215 // This will be injected directly through FileSpec.SetDirectory(),
216 // so we need to normalize manually.
217 std::replace(path.begin(), path.end(), '\\', '/');
218#endif
219}
220
222 static FileSpec g_spec = []() {
223 FileSpec spec = HostInfo::GetShlibDir();
224 if (!spec)
225 return FileSpec();
226 llvm::SmallString<64> path;
227 spec.GetPath(path);
228
229#if defined(__APPLE__)
231#else
232 ComputePythonDir(path);
233#endif
234 spec.SetDirectory(path);
235 return spec;
236 }();
237 return g_spec;
238}
239
240static const char GetInterpreterInfoScript[] = R"(
241import os
242import sys
243
244def main(lldb_python_dir, python_exe_relative_path):
245 info = {
246 "lldb-pythonpath": lldb_python_dir,
247 "language": "python",
248 "prefix": sys.prefix,
249 "executable": os.path.join(sys.prefix, python_exe_relative_path)
250 }
251 return info
252)";
253
254static const char python_exe_relative_path[] = LLDB_PYTHON_EXE_RELATIVE_PATH;
255
257 GIL gil;
258 FileSpec python_dir_spec = GetPythonDir();
259 if (!python_dir_spec)
260 return nullptr;
262 auto info_json = unwrapIgnoringErrors(
263 As<PythonDictionary>(get_info(PythonString(python_dir_spec.GetPath()),
265 if (!info_json)
266 return nullptr;
267 return info_json.CreateStructuredDictionary();
268}
269
271 lldb::ScriptedExtension extension) {
272 switch (extension) {
274 return "lldb.plugins.operating_system";
276 return "lldb.plugins.scripted_platform";
278 return "lldb.plugins.scripted_process";
280 return "lldb.plugins.scripted_hook";
282 return "lldb.plugins.scripted_breakpoint";
284 return "lldb.plugins.scripted_thread_plan";
286 return "lldb.plugins.scripted_frame_provider";
289 return "lldb.plugins.scripted_process";
291 return "lldb.plugins.scripted_stackframe_recognizer";
294 return "lldb.plugins.scripted_command";
296 return "lldb.plugins.scripted_string_summary";
298 return "lldb.plugins.scripted_synthetic_children";
300 return llvm::createStringError("invalid extension name");
301 }
302 return llvm::createStringError("invalid extension name");
303}
304
305llvm::Expected<StructuredData::ObjectSP>
307 const llvm::SmallVector<llvm::StringRef> &extension_path) {
308 lldb::ScriptedExtension extension =
309 ScriptInterpreter::StringToExtension(extension_path.back());
310 auto import_path_or_err = ExtensionToImportPath(extension);
311 if (!import_path_or_err)
312 return import_path_or_err.takeError();
313
314 StreamString command_stream;
315 // __import__(path, fromlist=['']) imports the submodule and returns it
316 // directly (rather than the top-level package), as a single expression --
317 // this keeps the whole call eval-able in one line while guaranteeing the
318 // module is imported first; referencing "<import_path>.<ClassName>"
319 // directly would only work if something else had already imported
320 // <import_path> as a side effect.
321 command_stream.Printf("lldb.embedded_interpreter.generate_extension_schema("
322 "__import__('%s', fromlist=['']).%s)",
323 import_path_or_err->c_str(),
324 ScriptInterpreter::ExtensionToString(extension).data());
325
326 // Use eScriptReturnTypeOpaqueObject: it transfers a real owned reference
327 // we can safely extract the string from. eScriptReturnTypeCharStrOrNone
328 // instead hands back a pointer to a temporary Python object's buffer
329 // that gets destroyed (and, for a freshly created string like this one,
330 // deallocated) as soon as ExecuteOneLineWithReturn returns -- reading
331 // it afterwards is a use-after-free.
332 void *result_obj = nullptr;
334 command_stream.GetData(),
336 ExecuteScriptOptions().SetEnableIO(false)))
337 return llvm::createStringError("invalid extension schema format");
338
339 // ExecuteOneLineWithReturn releases the GIL before returning, so touching
340 // the returned object (Str() below can execute arbitrary Python code) must
341 // re-acquire it first. py_result is scoped so its destructor (a DECREF)
342 // also runs before the GIL is released below, not after.
343 std::string schema_str;
344 {
345 PyGILState_STATE gil_state = PyGILState_Ensure();
346 {
348 static_cast<PyObject *>(result_obj));
349 if (py_result.IsAllocated() && py_result.get() != Py_None)
350 schema_str = py_result.Str().GetString().str();
351 }
352 PyGILState_Release(gil_state);
353 }
354
355 if (schema_str.empty())
356 return llvm::createStringError("empty extension schema");
357 return StructuredData::ParseJSON(schema_str);
358}
359
361 Stream &s, llvm::StringRef output_script_prefix,
362 const llvm::SmallVector<llvm::StringRef> &extension_path,
363 bool generate_non_abstract_methods, std::set<std::string> &typing_imports) {
364 auto schema_or_err = GetExtensionSchema(extension_path);
365 if (!schema_or_err)
366 return schema_or_err.takeError();
367
368 StructuredData::ObjectSP schema = *schema_or_err;
369 if (!schema)
370 return llvm::createStringError("empty extension schema");
371 StructuredData::Dictionary *dict = schema->GetAsDictionary();
372 if (!dict)
373 return llvm::createStringError("extension schema is not a JSON object");
374
375 // Merge each class' typing imports into the caller-owned set so the
376 // final `from typing import ...` line covers every class we emit.
377 StructuredData::Array *schema_typing;
378 if (dict->GetValueForKeyAsArray("typing_imports", schema_typing))
379 schema_typing->ForEach([&](StructuredData::Object *entry) {
380 if (auto *str = entry->GetAsString())
381 typing_imports.insert(str->GetValue().str());
382 return true;
383 });
384
385 llvm::StringRef base_class, import_path;
386 if (!dict->GetValueForKeyAsString("class", base_class))
387 return llvm::createStringError(
388 llvm::formatv("extension schema dictionary is missing 'class' key")
389 .str());
390 if (!dict->GetValueForKeyAsString("module", import_path))
391 return llvm::createStringError(
392 llvm::formatv("extension schema dictionary is missing 'module' key")
393 .str());
394
395 // imports
396 s.Printf("from %s import %s\n", import_path.data(), base_class.data());
397 s.EOL();
398
399 // class definition
400 s.Printf("class %s%s(%s):\n", output_script_prefix.data(), base_class.data(),
401 base_class.data());
402 s.IndentMore();
403
404 // Class docstring: list the non-callable members the base class exposes
405 // so the user sees what's available without having to hop back to the
406 // base class definition.
407 bool has_body = false;
408 StructuredData::Array *attributes;
409 if (dict->GetValueForKeyAsArray("attributes", attributes) &&
410 attributes->GetSize()) {
411 s.Indent();
412 s.PutCString("\"\"\"\n");
413 s.Indent();
414 s.Printf("Attributes inherited from %s:\n", base_class.data());
415 for (size_t i = 0; i < attributes->GetSize(); i++) {
416 auto maybe_dict = attributes->GetItemAtIndexAsDictionary(i);
417 if (!maybe_dict)
418 continue;
419 StructuredData::Dictionary *attr_dict = *maybe_dict;
420 llvm::StringRef attr_name;
421 if (!attr_dict->GetValueForKeyAsString("name", attr_name))
422 continue;
423 llvm::StringRef attr_type;
424 bool has_type = attr_dict->GetValueForKeyAsString("type", attr_type);
425 s.Indent();
426 s.Printf("- %s", attr_name.data());
427 if (has_type)
428 s.Printf(": %s", attr_type.data());
429 s.EOL();
430 }
431 s.Indent();
432 s.PutCString("\"\"\"\n\n");
433 has_body = true;
434 }
435
436 // members
437 StructuredData::Array *members;
438 if (!dict->GetValueForKeyAsArray("members", members))
439 return llvm::createStringError("missing 'members' key in extension schema");
440
441 // If the base class doesn't mark anything `@abstractmethod`, the filter
442 // "only stub abstract methods" would leave the derived class empty --
443 // which isn't a useful starting point. Fall back to emitting every
444 // method in that case so the user has actual code to edit.
445 bool any_abstract = false;
446 for (size_t i = 0; i < members->GetSize(); i++) {
447 auto maybe_dict = members->GetItemAtIndexAsDictionary(i);
448 if (!maybe_dict)
449 continue;
450 bool is_abstract = false;
451 if ((*maybe_dict)->GetValueForKeyAsBoolean("is_abstract", is_abstract) &&
452 is_abstract) {
453 any_abstract = true;
454 break;
455 }
456 }
457 bool emit_all_methods = generate_non_abstract_methods || !any_abstract;
458
459 for (size_t i = 0; i < members->GetSize(); i++) {
460 auto maybe_dict = members->GetItemAtIndexAsDictionary(i);
461 if (!maybe_dict)
462 return llvm::createStringError(
463 llvm::formatv(
464 "member at index {0} in extension schema isn't a dictionary")
465 .str());
466
467 StructuredData::Dictionary *member_dict = *maybe_dict;
468 llvm::StringRef symbol, args;
469 if (!member_dict->GetValueForKeyAsString("name", symbol))
470 return llvm::createStringError(
471 llvm::formatv(
472 "member at index {0} in extension schema is missing 'name' key")
473 .str());
474 if (!member_dict->GetValueForKeyAsString("signature", args))
475 return llvm::createStringError(
476 llvm::formatv("member at index {0} in extension schema is missing "
477 "'signature' key")
478 .str());
479
480 bool is_abstract = false;
481 bool has_is_abstract =
482 member_dict->GetValueForKeyAsBoolean("is_abstract", is_abstract);
483 if (!emit_all_methods)
484 if (!has_is_abstract || !is_abstract)
485 continue;
486
487 s.Indent();
488 s.Printf("def %s%s:\n", symbol.data(), args.data());
489
490 s.IndentMore();
491 llvm::StringRef documentation;
492 if (member_dict->GetValueForKeyAsString("doc", documentation)) {
493 s.Indent();
494 s.PutCString("\"\"\"\n");
495
496 llvm::SmallVector<llvm::StringRef> lines;
497 documentation.split(lines, "\n");
498
499 for (llvm::StringRef line : lines) {
500 s.Indent();
501 s.PutCString(line);
502 s.EOL();
503 }
504
505 s.Indent();
506 s.PutCString("\"\"\"");
507 s.EOL();
508 }
509
510 if (symbol == "__init__") {
511 // The base class' constructor sets up attributes (e.g. self.target,
512 // self.process) that the inherited, non-overridden methods rely on.
513 // Forward the same arguments so that state is still initialized.
514 // Splitting the param list on `,` requires bracket-depth awareness
515 // because annotations like `Union[X, Y]` also contain commas.
516 llvm::StringRef params = args.trim("()");
517 std::vector<std::string> forwarded_args;
518 int depth = 0;
519 size_t start = 0;
520 auto flush = [&](size_t end) {
521 llvm::StringRef param = params.slice(start, end);
522 param = param.split(':').first.split('=').first.trim();
523 if (!param.empty() && param != "self")
524 forwarded_args.push_back(param.str());
525 };
526 for (size_t i = 0; i < params.size(); ++i) {
527 char c = params[i];
528 if (c == '[' || c == '(' || c == '{')
529 ++depth;
530 else if (c == ']' || c == ')' || c == '}')
531 --depth;
532 else if (c == ',' && depth == 0) {
533 flush(i);
534 start = i + 1;
535 }
536 }
537 flush(params.size());
538 s.Indent();
539 s.Printf("super().__init__(%s)\n",
540 llvm::join(forwarded_args, ", ").c_str());
541 }
542
543 s.Indent();
544 s.PutCString("# TODO: Implement\n");
545 s.Indent();
546 s.PutCString("pass\n\n");
547 s.IndentLess();
548 has_body = true;
549 }
550
551 // A class with no body is a Python syntax error, so emit `pass` when the
552 // base class has nothing to stub out (no methods and no attributes to
553 // document).
554 if (!has_body) {
555 s.Indent();
556 s.PutCString("pass\n");
557 }
558
559 return llvm::Error::success();
560}
561
563 const std::string &name, std::vector<ExtensionTemplateRequest> &extensions,
564 bool generate_non_abstract_methods, std::string output_file) {
565 // `ParseExtensionSchema` accumulates every `typing` generic it sees
566 // (`Optional`, `Union`, `List`, ...) into this set so we can emit a
567 // targeted `from typing import ...` line only for what's actually
568 // referenced. The Python schema does the detection so we don't have
569 // to re-scan strings here.
570 std::set<std::string> typing_imports;
571 StreamString bodies;
572 for (const ExtensionTemplateRequest &extension : extensions) {
573 if (llvm::Error err =
574 ParseExtensionSchema(bodies, name, extension.path,
575 generate_non_abstract_methods, typing_imports))
576 return std::move(err);
577 bodies.PutCString("\n\n");
578 }
579
580 StreamString generated_file_stream;
581 generated_file_stream.PutCString("import lldb\n");
582 if (!typing_imports.empty()) {
583 std::vector<std::string> sorted_imports(typing_imports.begin(),
584 typing_imports.end());
585 generated_file_stream.Format("from typing import {0}\n",
586 llvm::join(sorted_imports, ", "));
587 }
588 generated_file_stream.PutCString("\n");
589 generated_file_stream.PutCString(bodies.GetString());
590
591 FileSpec save_location;
592 if (output_file.empty()) {
593 // Sanitize the caller-supplied class prefix so it can't escape the
594 // temp directory (`../`, path separators, ...). Only keep ASCII
595 // alphanumerics; everything else collapses to `_`, and an all-junk
596 // name falls back to a fixed default.
597 std::string sanitized;
598 sanitized.reserve(name.size());
599 for (char c : name)
600 sanitized.push_back(llvm::isAlnum(c) ? static_cast<char>(llvm::toLower(c))
601 : '_');
602 if (sanitized.find_first_not_of('_') == std::string::npos)
603 sanitized = "extension";
604 const std::string file_name = "lldb_" + sanitized + "_extension.py";
605 save_location = HostInfo::GetGlobalTempDir();
606 FileSystem::Instance().Resolve(save_location);
607 save_location.AppendPathComponent(file_name);
608 } else {
609 save_location = FileSpec(output_file);
610 FileSystem::Instance().Resolve(save_location);
611 }
612
616
617 auto opened_file = FileSystem::Instance().Open(save_location, flags);
618
619 if (!opened_file)
620 return opened_file.takeError();
621
622 FileUP file = std::move(opened_file.get());
623
624 size_t byte_size = generated_file_stream.GetSize();
625
626 Status error = file->Write(generated_file_stream.GetData(), byte_size);
627
628 if (error.Fail() || byte_size != generated_file_stream.GetSize())
629 return llvm::createStringError("Unable to write to destination file. Bytes "
630 "written do not match generated file size.");
631 return save_location;
632}
633
635 FileSpec &this_file) {
636 // When we're loaded from python, this_file will point to the file inside the
637 // python package directory. Replace it with the one in the lib directory.
638#ifdef _WIN32
639 // On windows, we need to manually back out of the python tree, and go into
640 // the bin directory. This is pretty much the inverse of what ComputePythonDir
641 // does.
642 if (this_file.GetFileNameExtension() == ".pyd") {
643 this_file.RemoveLastPathComponent(); // _lldb.pyd or _lldb_d.pyd
644 this_file.RemoveLastPathComponent(); // native
645 this_file.RemoveLastPathComponent(); // lldb
646 llvm::StringRef libdir = LLDB_PYTHON_RELATIVE_LIBDIR;
647 for (auto it = llvm::sys::path::begin(libdir),
648 end = llvm::sys::path::end(libdir);
649 it != end; ++it)
650 this_file.RemoveLastPathComponent();
651 this_file.AppendPathComponent("bin");
652 this_file.AppendPathComponent("liblldb.dll");
653 }
654#else
655 // The python file is a symlink, so we can find the real library by resolving
656 // it. We can do this unconditionally.
657 FileSystem::Instance().ResolveSymbolicLink(this_file, this_file);
658#endif
659}
660
662 return "Embedded Python interpreter";
663}
664
666#if LLDB_ENABLE_MTE
667 // Python's allocator (pymalloc) is not aware of Memory Tagging Extension
668 // (MTE) and crashes.
669 // https://bugs.python.org/issue43593
670 setenv("PYTHONMALLOC", "malloc", /*overwrite=*/true);
671#endif
672
673 // When the plugin is a separate shared library, the SWIG wrapper lives in
674 // the plugin library, so the path helper that redirects lookups back to
675 // liblldb is unnecessary.
676#if !LLDB_ENABLE_DYNAMIC_SCRIPTINTERPRETERS
677 HostInfo::SetSharedLibraryDirectoryHelper(
679#endif
686}
687
692
694 ScriptInterpreterPythonImpl *py_interpreter, uint16_t on_entry,
695 uint16_t on_leave, FileSP in, FileSP out, FileSP err)
698 m_python_interpreter(py_interpreter) {
700 if ((on_entry & InitSession) == InitSession) {
701 if (!DoInitSession(on_entry, in, out, err)) {
702 // Don't teardown the session if we didn't init it.
703 m_teardown_session = false;
704 }
705 }
706}
707
709 m_GILState = PyGILState_Ensure();
711 "Ensured PyGILState. Previous state = {0}",
712 m_GILState == PyGILState_UNLOCKED ? "unlocked" : "locked");
713
714 // we need to save the thread state when we first start the command because
715 // we might decide to interrupt it while some action is taking place outside
716 // of Python (e.g. printing to screen, waiting for the network, ...) in that
717 // case, _PyThreadState_Current will be NULL - and we would be unable to set
718 // the asynchronous exception - not a desirable situation
719 m_python_interpreter->SetThreadState(PyThreadState_Get());
720 m_python_interpreter->IncrementLockCount();
721 return true;
722}
723
725 FileSP in, FileSP out,
726 FileSP err) {
728 return false;
729 return m_python_interpreter->EnterSession(on_entry_flags, in, out, err);
730}
731
734 "Releasing PyGILState. Returning to state = {0}",
735 m_GILState == PyGILState_UNLOCKED ? "unlocked" : "locked");
736 PyGILState_Release(m_GILState);
737 m_python_interpreter->DecrementLockCount();
738 return true;
739}
740
743 return false;
744 m_python_interpreter->LeaveSession();
745 return true;
746}
747
753
760 m_dictionary_name(m_debugger.GetInstanceName()),
763 m_command_thread_state(nullptr) {
764
765 m_dictionary_name.append("_dict");
766 StreamString run_string;
767 run_string.Printf("%s = dict()", m_dictionary_name.c_str());
768
770 RunSimpleString(run_string.GetData());
771
772 run_string.Clear();
773 run_string.Printf("run_one_line (%s, 'import copy, keyword, os, re, sys, "
774 "uuid, lldb, importlib')",
775 m_dictionary_name.c_str());
776 RunSimpleString(run_string.GetData());
777
778 // WARNING: temporary code that loads Cocoa formatters - this should be done
779 // on a per-platform basis rather than loading the whole set and letting the
780 // individual formatter classes exploit APIs to check whether they can/cannot
781 // do their task
782 run_string.Clear();
783 run_string.Printf(
784 "run_one_line (%s, 'import lldb.formatters, lldb.formatters.cpp')",
785 m_dictionary_name.c_str());
786 RunSimpleString(run_string.GetData());
787 run_string.Clear();
788
789 run_string.Printf("run_one_line (%s, 'import lldb.embedded_interpreter; from "
790 "lldb.embedded_interpreter import run_python_interpreter; "
791 "from lldb.embedded_interpreter import run_one_line')",
792 m_dictionary_name.c_str());
793 RunSimpleString(run_string.GetData());
794 run_string.Clear();
795
796 // Configure pydoc (built-in module) to use the "plain" pager. The default one
797 // doesn't play nice with the statusline.
798 run_string.Printf("run_one_line (%s, 'import pydoc; pydoc.pager = "
799 "pydoc.plainpager')",
800 m_dictionary_name.c_str());
801 RunSimpleString(run_string.GetData());
802 run_string.Clear();
803
804 run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64
805 "')",
806 m_dictionary_name.c_str(), m_debugger.GetID());
807 RunSimpleString(run_string.GetData());
808}
809
810/// A Python sys.stdout/stderr file backed by a pipe whose read end is drained
811/// by a reader thread that writes to the debugger's terminal under the output
812/// lock (Debugger::PrintAsync). Handing Python the raw terminal descriptor
813/// instead lets a script's print() race the statusline, which redraws on the
814/// event thread under that lock. Its cursor save/restore then rewinds over and
815/// eats the script's output.
817public:
818 static std::unique_ptr<SessionIORedirect> Create(lldb::user_id_t debugger_id,
819 bool is_stdout) {
820 Pipe pipe;
821 if (pipe.CreateNew().Fail())
822 return nullptr;
823
824 std::unique_ptr<SessionIORedirect> redirect(
825 new SessionIORedirect(debugger_id, is_stdout));
826
827#if defined(_WIN32)
828 lldb::file_t read_handle = pipe.GetReadNativeHandle();
830 std::unique_ptr<Connection> conn =
831 std::make_unique<ConnectionGenericFile>(read_handle, true);
832#else
833 std::unique_ptr<Connection> conn =
834 std::make_unique<ConnectionFileDescriptor>(
835 pipe.ReleaseReadFileDescriptor(), /*owns_fd=*/true);
836#endif
837 if (!conn->IsConnected())
838 return nullptr;
839
840 redirect->m_communication.SetConnection(std::move(conn));
841 redirect->m_communication.SetReadThreadBytesReceivedCallback(
842 ReadThreadBytesReceived, redirect.get());
843 if (!redirect->m_communication.StartReadThread())
844 return nullptr;
845 redirect->m_connected = true;
846
847 // The write end is owned here. Python only borrows its descriptor.
848 redirect->m_write_file_sp = std::make_shared<NativeFile>(
851 return redirect;
852 }
853
855 if (!m_connected)
856 return;
857 // Close the write end so the reader sees EOF and exits, then join it.
858 if (m_write_file_sp)
859 m_write_file_sp->Close();
860 m_communication.JoinReadThread();
861 m_communication.Disconnect();
862 }
863
864 int GetWriteDescriptor() const {
865 return m_write_file_sp ? m_write_file_sp->GetDescriptor()
867 }
868
869private:
870 SessionIORedirect(lldb::user_id_t debugger_id, bool is_stdout)
871 : m_debugger_id(debugger_id), m_is_stdout(is_stdout),
872 m_communication("lldb.ScriptInterpreterPython.io-redirect") {}
873
874 static void ReadThreadBytesReceived(void *baton, const void *src,
875 size_t src_len) {
876 if (!src || !src_len)
877 return;
878 auto *self = static_cast<SessionIORedirect *>(baton);
879 if (lldb::DebuggerSP debugger_sp =
880 Debugger::FindDebuggerWithID(self->m_debugger_id))
881 debugger_sp->PrintAsync(static_cast<const char *>(src), src_len,
882 self->m_is_stdout);
883 }
884
889 bool m_connected = false;
890};
891
893 // the session dictionary may hold objects with complex state which means
894 // that they may need to be torn down with some level of smarts and that, in
895 // turn, requires a valid thread state force Python to procure itself such a
896 // thread state, nuke the session dictionary and then release it for others
897 // to use and proceed with the rest of the shutdown
898 auto gil_state = PyGILState_Ensure();
899 m_session_dict.Reset();
900 PyGILState_Release(gil_state);
901}
902
904 bool interactive) {
905 const char *instructions = nullptr;
906
907 switch (m_active_io_handler) {
908 case eIOHandlerNone:
909 break;
911 instructions = R"(Enter your Python command(s). Type 'DONE' to end.
912def function (frame, bp_loc, internal_dict):
913 """frame: the lldb.SBFrame for the location at which you stopped
914 bp_loc: an lldb.SBBreakpointLocation for the breakpoint location information
915 internal_dict: an LLDB support object not to be used"""
916)";
917 break;
919 instructions = "Enter your Python command(s). Type 'DONE' to end.\n";
920 break;
921 }
922
923 if (instructions && interactive) {
924 if (LockableStreamFileSP stream_sp = io_handler.GetOutputStreamFileSP()) {
925 LockedStreamFile locked_stream = stream_sp->Lock();
926 locked_stream.PutCString(instructions);
927 locked_stream.Flush();
928 }
929 }
930}
931
933 std::string &data) {
934 io_handler.SetIsDone(true);
935 bool batch_mode = m_debugger.GetCommandInterpreter().GetBatchCommandMode();
936
937 switch (m_active_io_handler) {
938 case eIOHandlerNone:
939 break;
941 std::vector<std::reference_wrapper<BreakpointOptions>> *bp_options_vec =
942 (std::vector<std::reference_wrapper<BreakpointOptions>> *)
943 io_handler.GetUserData();
944 for (BreakpointOptions &bp_options : *bp_options_vec) {
945
946 auto data_up = std::make_unique<CommandDataPython>();
947 if (!data_up)
948 break;
949 data_up->user_source.SplitIntoLines(data);
950
951 if (GenerateBreakpointCommandCallbackData(data_up->user_source,
952 data_up->script_source,
953 /*has_extra_args=*/false,
954 /*is_callback=*/false)
955 .Success()) {
956 auto baton_sp = std::make_shared<BreakpointOptions::CommandBaton>(
957 std::move(data_up));
958 bp_options.SetCallback(
960 } else if (!batch_mode) {
961 if (LockableStreamFileSP error_sp = io_handler.GetErrorStreamFileSP()) {
962 LockedStreamFile locked_stream = error_sp->Lock();
963 locked_stream.Printf("Warning: No command attached to breakpoint.\n");
964 }
965 }
966 }
968 } break;
970 WatchpointOptions *wp_options =
971 (WatchpointOptions *)io_handler.GetUserData();
972 auto data_up = std::make_unique<WatchpointOptions::CommandData>();
973 data_up->user_source.SplitIntoLines(data);
974
975 if (GenerateWatchpointCommandCallbackData(data_up->user_source,
976 data_up->script_source,
977 /*is_callback=*/false)) {
978 auto baton_sp =
979 std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up));
980 wp_options->SetCallback(
982 } else if (!batch_mode) {
983 if (LockableStreamFileSP error_sp = io_handler.GetErrorStreamFileSP()) {
984 LockedStreamFile locked_stream = error_sp->Lock();
985 locked_stream.Printf("Warning: No command attached to breakpoint.\n");
986 }
987 }
989 } break;
990 }
991}
992
995 return std::make_shared<ScriptInterpreterPythonImpl>(debugger);
996}
997
999 Log *log = GetLog(LLDBLog::Script);
1000 if (log)
1001 log->PutCString("ScriptInterpreterPythonImpl::LeaveSession()");
1002
1003 // Unset the LLDB global variables.
1004 RunSimpleString("lldb.debugger = None; lldb.target = None; lldb.process "
1005 "= None; lldb.thread = None; lldb.frame = None");
1006
1007 // checking that we have a valid thread state - since we use our own
1008 // threading and locking in some (rare) cases during cleanup Python may end
1009 // up believing we have no thread state and PyImport_AddModule will crash if
1010 // that is the case - since that seems to only happen when destroying the
1011 // SBDebugger, we can make do without clearing up stdout and stderr
1012 if (PyThreadState_GetDict()) {
1013 PythonDictionary &sys_module_dict = GetSysModuleDictionary();
1014 if (sys_module_dict.IsValid()) {
1015 // Flush the pipe-backed wrappers while they are still sys.stdout/stderr.
1016 // Line buffering already flushes on each newline, but a trailing
1017 // unterminated line would otherwise be stranded (and later flushed into
1018 // a closed descriptor) once we close the pipe write end below.
1019 auto flush_redirect = [&](const char *py_name,
1020 std::unique_ptr<SessionIORedirect> &redirect) {
1021 if (!redirect)
1022 return;
1023 PythonObject file =
1024 sys_module_dict.GetItemForKey(PythonString(py_name));
1025 if (!file.IsValid())
1026 return;
1027 if (llvm::Expected<PythonObject> result = file.CallMethod("flush"))
1028 (void)result;
1029 else
1030 llvm::consumeError(result.takeError());
1031 };
1032 flush_redirect("stdout", m_stdout_redirect);
1033 flush_redirect("stderr", m_stderr_redirect);
1034
1035 if (m_saved_stdin.IsValid()) {
1036 sys_module_dict.SetItemForKey(PythonString("stdin"), m_saved_stdin);
1038 }
1039 if (m_saved_stdout.IsValid()) {
1040 sys_module_dict.SetItemForKey(PythonString("stdout"), m_saved_stdout);
1041 m_saved_stdout.Reset();
1042 }
1043 if (m_saved_stderr.IsValid()) {
1044 sys_module_dict.SetItemForKey(PythonString("stderr"), m_saved_stderr);
1045 m_saved_stderr.Reset();
1046 }
1047 }
1048 }
1049
1050 // Tear down the pipe redirects (closes each write end and joins its reader).
1051 // The wrappers were flushed above, so nothing buffered is lost.
1052 m_stdout_redirect.reset();
1054
1055 m_session_is_active = false;
1056}
1057
1059 const char *py_name, PythonObject &save_file, const char *mode,
1060 File &file) {
1061 const bool is_stdout = ::strcmp(py_name, "stdout") == 0;
1062 if (!is_stdout && ::strcmp(py_name, "stderr") != 0)
1063 return false;
1064
1065 // The statusline is the only writer that races Python's terminal output.
1066 // When it isn't drawing there is nothing to serialize against, so keep the
1067 // normal wrapping and skip the reader thread and pipe.
1069 return false;
1070
1071 // Only the debugger's own terminal races the statusline. A redirect to a
1072 // pipe or user file (a different descriptor) is wrapped normally.
1073 lldb::FileSP debugger_file =
1075 int fd = file.GetDescriptor();
1076 if (!debugger_file || fd == File::kInvalidDescriptor ||
1077 fd != debugger_file->GetDescriptor())
1078 return false;
1079
1080 std::unique_ptr<SessionIORedirect> &redirect =
1082 redirect = SessionIORedirect::Create(m_debugger.GetID(), is_stdout);
1083 if (!redirect)
1084 return false;
1085
1086 // Line-buffer the wrapper so each print() reaches the reader (and the
1087 // terminal) promptly: the pipe descriptor is not a tty, so the default
1088 // buffering would hold output back until the buffer filled.
1089 PyObject *pipe_file = PyFile_FromFd(
1090 redirect->GetWriteDescriptor(), nullptr, mode, /*buffering=*/1,
1091 /*encoding=*/nullptr, /*errors=*/"ignore", /*newline=*/nullptr,
1092 /*closefd=*/0);
1093 if (!pipe_file) {
1094 // Fall back to the raw descriptor. That reopens the statusline race, so
1095 // leave a breadcrumb rather than failing silently.
1097 "failed to wrap sys.{0} on a synchronized pipe; falling back to "
1098 "the unsynchronized terminal descriptor",
1099 py_name);
1100 PyErr_Clear();
1101 redirect.reset();
1102 return false;
1103 }
1104
1105 PythonObject new_file(PyRefType::Owned, pipe_file);
1106 PythonDictionary &sys_module_dict = GetSysModuleDictionary();
1107 save_file = sys_module_dict.GetItemForKey(PythonString(py_name));
1108 sys_module_dict.SetItemForKey(PythonString(py_name), new_file);
1109 return true;
1110}
1111
1113 const char *py_name,
1114 PythonObject &save_file,
1115 const char *mode,
1116 bool serialize_terminal_output) {
1117 if (!file_sp || !*file_sp) {
1118 save_file.Reset();
1119 return false;
1120 }
1121 File &file = *file_sp;
1122
1123 // When stdout/stderr point at the debugger's own terminal, route Python's
1124 // output through a pipe drained under the output lock so a script's print()
1125 // cannot race the statusline. Any other target keeps the normal wrapping.
1126 if (serialize_terminal_output &&
1127 RedirectTerminalHandleThroughLock(py_name, save_file, mode, file))
1128 return true;
1129
1130 // Flush the file before giving it to python to avoid interleaved output.
1131 file.Flush();
1132
1133 PythonDictionary &sys_module_dict = GetSysModuleDictionary();
1134
1135 auto new_file = PythonFile::FromFile(file, mode);
1136 if (!new_file) {
1137 LLDB_LOG_ERROR(GetLog(LLDBLog::Script), new_file.takeError(),
1138 "ScriptInterpreterPythonImpl::SetStdHandle failed to wrap "
1139 "sys.{1}: {0}",
1140 py_name);
1141 return false;
1142 }
1143
1144 save_file = sys_module_dict.GetItemForKey(PythonString(py_name));
1146 sys_module_dict.SetItemForKey(PythonString(py_name), new_file.get());
1147 return true;
1148}
1149
1150bool ScriptInterpreterPythonImpl::EnterSession(uint16_t on_entry_flags,
1151 FileSP in_sp, FileSP out_sp,
1152 FileSP err_sp) {
1153 // If we have already entered the session, without having officially 'left'
1154 // it, then there is no need to 'enter' it again.
1155 Log *log = GetLog(LLDBLog::Script);
1156 if (m_session_is_active) {
1157 LLDB_LOGF(
1158 log,
1159 "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16
1160 ") session is already active, returning without doing anything",
1161 on_entry_flags);
1162 return false;
1163 }
1164
1165 LLDB_LOGF(
1166 log,
1167 "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16 ")",
1168 on_entry_flags);
1169
1170 m_session_is_active = true;
1171
1172 StreamString run_string;
1173
1174 if (on_entry_flags & Locker::InitGlobals) {
1175 run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64,
1177 run_string.Printf(
1178 "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64 ")",
1179 m_debugger.GetID());
1180 run_string.PutCString("; lldb.target = lldb.debugger.GetSelectedTarget()");
1181 run_string.PutCString("; lldb.process = lldb.target.GetProcess()");
1182 run_string.PutCString("; lldb.thread = lldb.process.GetSelectedThread ()");
1183 run_string.PutCString("; lldb.frame = lldb.thread.GetSelectedFrame ()");
1184 run_string.PutCString("')");
1185 } else {
1186 // If we aren't initing the globals, we should still always set the
1187 // debugger (since that is always unique.)
1188 run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64,
1189 m_dictionary_name.c_str(), m_debugger.GetID());
1190 run_string.Printf(
1191 "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64 ")",
1192 m_debugger.GetID());
1193 run_string.PutCString("')");
1194 }
1195
1196 RunSimpleString(run_string.GetData());
1197 run_string.Clear();
1198
1199 PythonDictionary &sys_module_dict = GetSysModuleDictionary();
1200 if (sys_module_dict.IsValid()) {
1201 lldb::FileSP top_in_sp;
1202 lldb::LockableStreamFileSP top_out_sp, top_err_sp;
1203 if (!in_sp || !out_sp || !err_sp || !*in_sp || !*out_sp || !*err_sp)
1204 m_debugger.AdoptTopIOHandlerFilesIfInvalid(top_in_sp, top_out_sp,
1205 top_err_sp);
1206
1207 if (on_entry_flags & Locker::NoSTDIN) {
1208 m_saved_stdin.Reset();
1209 } else {
1210 if (!SetStdHandle(in_sp, "stdin", m_saved_stdin, "r",
1211 /*serialize_terminal_output=*/false)) {
1212 if (top_in_sp)
1213 SetStdHandle(top_in_sp, "stdin", m_saved_stdin, "r",
1214 /*serialize_terminal_output=*/false);
1215 }
1216 }
1217
1218 // Serialize terminal output for every session except those that opt out
1219 // with NoOutputRedirect (see the flag for why).
1220 const bool serialize_terminal_output =
1221 !(on_entry_flags & Locker::NoOutputRedirect);
1222
1223 if (!SetStdHandle(out_sp, "stdout", m_saved_stdout, "w",
1224 serialize_terminal_output)) {
1225 if (top_out_sp)
1226 SetStdHandle(top_out_sp->GetUnlockedFileSP(), "stdout", m_saved_stdout,
1227 "w", serialize_terminal_output);
1228 }
1229
1230 if (!SetStdHandle(err_sp, "stderr", m_saved_stderr, "w",
1231 serialize_terminal_output)) {
1232 if (top_err_sp)
1233 SetStdHandle(top_err_sp->GetUnlockedFileSP(), "stderr", m_saved_stderr,
1234 "w", serialize_terminal_output);
1235 }
1236 }
1237
1238 if (PyErr_Occurred())
1239 PyErr_Clear();
1240
1241 return true;
1242}
1243
1245 if (!m_main_module.IsValid())
1247 return m_main_module;
1248}
1249
1251 if (m_session_dict.IsValid())
1252 return m_session_dict;
1253
1254 PythonObject &main_module = GetMainModule();
1255 if (!main_module.IsValid())
1256 return m_session_dict;
1257
1259 PyModule_GetDict(main_module.get()));
1260 if (!main_dict.IsValid())
1261 return m_session_dict;
1262
1270 return m_sys_module_dict;
1273 return m_sys_module_dict;
1274}
1275
1276llvm::Expected<unsigned>
1278 const llvm::StringRef &callable_name) {
1279 if (callable_name.empty()) {
1280 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1281 "called with empty callable name.");
1282 }
1283 Locker py_lock(this,
1288 callable_name, dict);
1289 if (!pfunc.IsAllocated()) {
1290 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1291 "can't find callable: %s",
1292 callable_name.str().c_str());
1293 }
1294 llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
1295 if (!arg_info) {
1296 // `-f` may point at a builtin, unlike other GetArgInfo() callers.
1297 LLDB_LOG_ERROR(GetLog(LLDBLog::Script), arg_info.takeError(),
1298 "GetArgInfo failed for callable {1}, falling back to "
1299 "inspect.signature: {0}",
1300 callable_name);
1302 }
1303 if (!arg_info)
1304 return arg_info.takeError();
1305 return arg_info.get().max_positional_args;
1306}
1307
1308static std::string GenerateUniqueName(const char *base_name_wanted,
1309 uint32_t &functions_counter,
1310 const void *name_token = nullptr) {
1311 StreamString sstr;
1312
1313 if (!base_name_wanted)
1314 return std::string();
1315
1316 if (!name_token)
1317 sstr.Printf("%s_%d", base_name_wanted, functions_counter++);
1318 else
1319 sstr.Printf("%s_%p", base_name_wanted, name_token);
1320
1321 return std::string(sstr.GetString());
1322}
1323
1326 return true;
1327
1329 PyImport_AddModule("lldb.embedded_interpreter"));
1330 if (!module.IsValid())
1331 return false;
1332
1334 PyModule_GetDict(module.get()));
1335 if (!module_dict.IsValid())
1336 return false;
1337
1339 module_dict.GetItemForKey(PythonString("run_one_line"));
1341 module_dict.GetItemForKey(PythonString("g_run_one_line_str"));
1342 return m_run_one_line_function.IsValid();
1343}
1344
1346 llvm::StringRef command, CommandReturnObject *result,
1347 const ExecuteScriptOptions &options) {
1348 std::string command_str = command.str();
1349
1350 if (!m_valid_session)
1351 return false;
1352
1353 if (!command.empty()) {
1354 // We want to call run_one_line, passing in the dictionary and the command
1355 // string. We cannot do this through RunSimpleString here because the
1356 // command string may contain escaped characters, and putting it inside
1357 // another string to pass to RunSimpleString messes up the escaping. So
1358 // we use the following more complicated method to pass the command string
1359 // directly down to Python.
1360 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
1361 io_redirect_or_error = ScriptInterpreterIORedirect::Create(
1362 options.GetEnableIO(), m_debugger, result);
1363 if (!io_redirect_or_error) {
1364 if (result)
1365 result->AppendErrorWithFormatv(
1366 "failed to redirect I/O: {0}\n",
1367 llvm::fmt_consume(io_redirect_or_error.takeError()));
1368 else
1369 llvm::consumeError(io_redirect_or_error.takeError());
1370 return false;
1371 }
1372
1373 ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
1374
1375 bool success = false;
1376 {
1377 // WARNING! It's imperative that this RAII scope be as tight as
1378 // possible. In particular, the scope must end *before* we try to join
1379 // the read thread. The reason for this is that a pre-requisite for
1380 // joining the read thread is that we close the write handle (to break
1381 // the pipe and cause it to wake up and exit). But acquiring the GIL as
1382 // below will redirect Python's stdio to use this same handle. If we
1383 // close the handle while Python is still using it, bad things will
1384 // happen.
1385 Locker locker(
1386 this,
1388 (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) |
1389 ((result && result->GetInteractive()) ? 0 : Locker::NoSTDIN),
1391 io_redirect.GetInputFile(), io_redirect.GetOutputFile(),
1392 io_redirect.GetErrorFile());
1393
1394 // Find the correct script interpreter dictionary in the main module.
1395 PythonDictionary &session_dict = GetSessionDictionary();
1396 if (session_dict.IsValid()) {
1398 if (PyCallable_Check(m_run_one_line_function.get())) {
1399 PythonObject pargs(
1401 Py_BuildValue("(Os)", session_dict.get(), command_str.c_str()));
1402 if (pargs.IsValid()) {
1403 PythonObject return_value(
1405 PyObject_CallObject(m_run_one_line_function.get(),
1406 pargs.get()));
1407 if (return_value.IsValid())
1408 success = true;
1409 else if (options.GetMaskoutErrors() && PyErr_Occurred()) {
1410 PyErr_Print();
1411 PyErr_Clear();
1412 }
1413 }
1414 }
1415 }
1416 }
1417
1418 io_redirect.Flush();
1419 }
1420
1421 if (success)
1422 return true;
1423
1424 // The one-liner failed. Append the error message.
1425 if (result) {
1426 result->AppendErrorWithFormat("python failed attempting to evaluate '%s'",
1427 command_str.c_str());
1428 }
1429 return false;
1430 }
1431
1432 if (result)
1433 result->AppendError("empty command passed to python\n");
1434 return false;
1435}
1436
1439
1440 Debugger &debugger = m_debugger;
1441
1442 // At the moment, the only time the debugger does not have an input file
1443 // handle is when this is called directly from Python, in which case it is
1444 // both dangerous and unnecessary (not to mention confusing) to try to embed
1445 // a running interpreter loop inside the already running Python interpreter
1446 // loop, so we won't do it.
1447
1448 if (!debugger.GetInputFile().IsValid())
1449 return;
1450
1451 IOHandlerSP io_handler_sp(new IOHandlerPythonInterpreter(debugger, this));
1452 if (io_handler_sp) {
1453 debugger.RunIOHandlerAsync(io_handler_sp);
1454 }
1455}
1456
1458#if LLDB_USE_PYTHON_SET_INTERRUPT
1459 // If the interpreter isn't evaluating any Python at the moment then return
1460 // false to signal that this function didn't handle the interrupt and the
1461 // next component should try handling it.
1462 if (!IsExecutingPython())
1463 return false;
1464
1465 // Tell Python that it should pretend to have received a SIGINT.
1466 PyErr_SetInterrupt();
1467 // PyErr_SetInterrupt has no way to return an error so we can only pretend the
1468 // signal got successfully handled and return true.
1469 // Python 3.10 introduces PyErr_SetInterruptEx that could return an error, but
1470 // the error handling is limited to checking the arguments which would be
1471 // just our (hardcoded) input signal code SIGINT, so that's not useful at all.
1472 return true;
1473#else
1474 Log *log = GetLog(LLDBLog::Script);
1475
1476 if (IsExecutingPython()) {
1477 PyThreadState *state = PyThreadState_Get();
1478 if (!state)
1479 state = GetThreadState();
1480 if (state) {
1481 long tid = PyThread_get_thread_ident();
1482 PyThreadState_Swap(state);
1483 int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt);
1484 LLDB_LOGF(log,
1485 "ScriptInterpreterPythonImpl::Interrupt() sending "
1486 "PyExc_KeyboardInterrupt (tid = %li, num_threads = %i)...",
1487 tid, num_threads);
1488 return true;
1489 }
1490 }
1491 LLDB_LOGF(log,
1492 "ScriptInterpreterPythonImpl::Interrupt() python code not running, "
1493 "can't interrupt");
1494 return false;
1495#endif
1496}
1497
1499 llvm::StringRef in_string, ScriptInterpreter::ScriptReturnType return_type,
1500 void *ret_value, const ExecuteScriptOptions &options) {
1501
1502 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
1503 io_redirect_or_error = ScriptInterpreterIORedirect::Create(
1504 options.GetEnableIO(), m_debugger, /*result=*/nullptr);
1505
1506 if (!io_redirect_or_error) {
1507 llvm::consumeError(io_redirect_or_error.takeError());
1508 return false;
1509 }
1510
1511 ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
1512
1513 Locker locker(this,
1515 (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) |
1518 io_redirect.GetInputFile(), io_redirect.GetOutputFile(),
1519 io_redirect.GetErrorFile());
1520
1521 PythonModule &main_module = GetMainModule();
1522 PythonDictionary globals = main_module.GetDictionary();
1523
1525 if (!locals.IsValid())
1526 locals = unwrapIgnoringErrors(
1528 if (!locals.IsValid())
1529 locals = globals;
1530
1531 Expected<PythonObject> maybe_py_return =
1532 runStringOneLine(in_string, globals, locals);
1533
1534 if (!maybe_py_return) {
1535 llvm::handleAllErrors(
1536 maybe_py_return.takeError(),
1537 [&](PythonException &E) {
1538 E.Restore();
1539 if (options.GetMaskoutErrors()) {
1540 if (E.Matches(PyExc_SyntaxError)) {
1541 PyErr_Print();
1542 }
1543 PyErr_Clear();
1544 }
1545 },
1546 [](const llvm::ErrorInfoBase &E) {});
1547 return false;
1548 }
1549
1550 PythonObject py_return = std::move(maybe_py_return.get());
1551 assert(py_return.IsValid());
1552
1553 switch (return_type) {
1554 case eScriptReturnTypeCharPtr: // "char *"
1555 {
1556 const char format[3] = "s#";
1557 return PyArg_Parse(py_return.get(), format, (char **)ret_value);
1558 }
1559 case eScriptReturnTypeCharStrOrNone: // char* or NULL if py_return ==
1560 // Py_None
1561 {
1562 const char format[3] = "z";
1563 return PyArg_Parse(py_return.get(), format, (char **)ret_value);
1564 }
1565 case eScriptReturnTypeBool: {
1566 const char format[2] = "b";
1567 return PyArg_Parse(py_return.get(), format, (bool *)ret_value);
1568 }
1569 case eScriptReturnTypeShortInt: {
1570 const char format[2] = "h";
1571 return PyArg_Parse(py_return.get(), format, (short *)ret_value);
1572 }
1573 case eScriptReturnTypeShortIntUnsigned: {
1574 const char format[2] = "H";
1575 return PyArg_Parse(py_return.get(), format, (unsigned short *)ret_value);
1576 }
1577 case eScriptReturnTypeInt: {
1578 const char format[2] = "i";
1579 return PyArg_Parse(py_return.get(), format, (int *)ret_value);
1580 }
1581 case eScriptReturnTypeIntUnsigned: {
1582 const char format[2] = "I";
1583 return PyArg_Parse(py_return.get(), format, (unsigned int *)ret_value);
1584 }
1585 case eScriptReturnTypeLongInt: {
1586 const char format[2] = "l";
1587 return PyArg_Parse(py_return.get(), format, (long *)ret_value);
1588 }
1589 case eScriptReturnTypeLongIntUnsigned: {
1590 const char format[2] = "k";
1591 return PyArg_Parse(py_return.get(), format, (unsigned long *)ret_value);
1592 }
1593 case eScriptReturnTypeLongLong: {
1594 const char format[2] = "L";
1595 return PyArg_Parse(py_return.get(), format, (long long *)ret_value);
1596 }
1597 case eScriptReturnTypeLongLongUnsigned: {
1598 const char format[2] = "K";
1599 return PyArg_Parse(py_return.get(), format,
1600 (unsigned long long *)ret_value);
1601 }
1602 case eScriptReturnTypeFloat: {
1603 const char format[2] = "f";
1604 return PyArg_Parse(py_return.get(), format, (float *)ret_value);
1605 }
1606 case eScriptReturnTypeDouble: {
1607 const char format[2] = "d";
1608 return PyArg_Parse(py_return.get(), format, (double *)ret_value);
1609 }
1610 case eScriptReturnTypeChar: {
1611 const char format[2] = "c";
1612 return PyArg_Parse(py_return.get(), format, (char *)ret_value);
1613 }
1614 case eScriptReturnTypeOpaqueObject: {
1615 *((PyObject **)ret_value) = py_return.release();
1616 return true;
1618 }
1619 llvm_unreachable("Fully covered switch!");
1620}
1621
1623 const char *in_string, const ExecuteScriptOptions &options) {
1624
1625 if (in_string == nullptr)
1626 return Status();
1627
1628 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
1629 io_redirect_or_error = ScriptInterpreterIORedirect::Create(
1630 options.GetEnableIO(), m_debugger, /*result=*/nullptr);
1631
1632 if (!io_redirect_or_error)
1633 return Status::FromError(io_redirect_or_error.takeError());
1634
1635 ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
1636
1637 Locker locker(this,
1639 (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) |
1642 io_redirect.GetInputFile(), io_redirect.GetOutputFile(),
1643 io_redirect.GetErrorFile());
1644
1645 PythonModule &main_module = GetMainModule();
1646 PythonDictionary globals = main_module.GetDictionary();
1647
1648 PythonDictionary locals = GetSessionDictionary();
1649 if (!locals.IsValid())
1650 locals = unwrapIgnoringErrors(
1652 if (!locals.IsValid())
1653 locals = globals;
1654
1655 Expected<PythonObject> return_value =
1656 runStringMultiLine(in_string, globals, locals);
1657
1658 if (!return_value) {
1659 llvm::Error error =
1660 llvm::handleErrors(return_value.takeError(), [&](PythonException &E) {
1661 llvm::Error error = llvm::createStringError(
1662 llvm::inconvertibleErrorCode(), E.ReadBacktrace());
1663 if (!options.GetMaskoutErrors())
1664 E.Restore();
1665 return error;
1666 });
1667 return Status::FromError(std::move(error));
1669
1670 return Status();
1671}
1672
1674 std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
1675 CommandReturnObject &result) {
1677 m_debugger.GetCommandInterpreter().GetPythonCommandsFromIOHandler(
1678 " ", *this, &bp_options_vec);
1679}
1680
1682 WatchpointOptions *wp_options, CommandReturnObject &result) {
1684 m_debugger.GetCommandInterpreter().GetPythonCommandsFromIOHandler(
1685 " ", *this, wp_options);
1686}
1687
1689 BreakpointOptions &bp_options, const char *function_name,
1690 StructuredData::ObjectSP extra_args_sp) {
1691 Status error;
1692 // For now just cons up a oneliner that calls the provided function.
1693 std::string function_signature = function_name;
1694
1695 llvm::Expected<unsigned> maybe_args =
1697 if (!maybe_args) {
1699 "could not get num args: %s",
1700 llvm::toString(maybe_args.takeError()).c_str());
1701 return error;
1702 }
1703 size_t max_args = *maybe_args;
1704
1705 bool uses_extra_args = false;
1706 if (max_args >= 4) {
1707 uses_extra_args = true;
1708 function_signature += "(frame, bp_loc, extra_args, internal_dict)";
1709 } else if (max_args >= 3) {
1710 if (extra_args_sp) {
1712 "cannot pass extra_args to a three argument callback");
1713 return error;
1714 }
1715 uses_extra_args = false;
1716 function_signature += "(frame, bp_loc, internal_dict)";
1717 } else {
1718 error = Status::FromErrorStringWithFormat("expected 3 or 4 argument "
1719 "function, %s can only take %zu",
1720 function_name, max_args);
1721 return error;
1722 }
1723
1724 SetBreakpointCommandCallback(bp_options, function_signature.c_str(),
1725 extra_args_sp, uses_extra_args,
1726 /*is_callback=*/true);
1727 return error;
1728}
1729
1731 BreakpointOptions &bp_options,
1732 std::unique_ptr<BreakpointOptions::CommandData> &cmd_data_up) {
1733 Status error;
1734 error = GenerateBreakpointCommandCallbackData(cmd_data_up->user_source,
1735 cmd_data_up->script_source,
1736 /*has_extra_args=*/false,
1737 /*is_callback=*/false);
1738 if (error.Fail()) {
1739 return error;
1740 }
1741 auto baton_sp =
1742 std::make_shared<BreakpointOptions::CommandBaton>(std::move(cmd_data_up));
1749 BreakpointOptions &bp_options, const char *command_body_text,
1750 bool is_callback) {
1751 return SetBreakpointCommandCallback(bp_options, command_body_text, {},
1752 /*uses_extra_args=*/false, is_callback);
1753}
1754
1755// Set a Python one-liner as the callback for the breakpoint.
1757 BreakpointOptions &bp_options, const char *command_body_text,
1758 StructuredData::ObjectSP extra_args_sp, bool uses_extra_args,
1759 bool is_callback) {
1760 auto data_up = std::make_unique<CommandDataPython>(extra_args_sp);
1761 // Split the command_body_text into lines, and pass that to
1762 // GenerateBreakpointCommandCallbackData. That will wrap the body in an
1763 // auto-generated function, and return the function name in script_source.
1764 // That is what the callback will actually invoke.
1765
1766 data_up->user_source.SplitIntoLines(command_body_text);
1768 data_up->user_source, data_up->script_source, uses_extra_args,
1769 is_callback);
1770 if (error.Success()) {
1771 auto baton_sp =
1772 std::make_shared<BreakpointOptions::CommandBaton>(std::move(data_up));
1773 bp_options.SetCallback(
1775 return error;
1777 return error;
1778}
1779
1780// Set a Python one-liner as the callback for the watchpoint.
1782 WatchpointOptions *wp_options, const char *user_input, bool is_callback) {
1783 auto data_up = std::make_unique<WatchpointOptions::CommandData>();
1784
1785 // It's necessary to set both user_source and script_source to the oneliner.
1786 // The former is used to generate callback description (as in watchpoint
1787 // command list) while the latter is used for Python to interpret during the
1788 // actual callback.
1789
1790 data_up->user_source.AppendString(user_input);
1791 data_up->script_source.assign(user_input);
1792
1794 data_up->user_source, data_up->script_source, is_callback)) {
1795 auto baton_sp =
1796 std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up));
1797 wp_options->SetCallback(
1799 }
1800}
1801
1803 StringList &function_def) {
1804 // Convert StringList to one long, newline delimited, const char *.
1805 std::string function_def_string(function_def.CopyList());
1806 LLDB_LOG(GetLog(LLDBLog::Script), "Added Function:\n{0}\n",
1807 function_def_string.c_str());
1808
1810 function_def_string.c_str(), ExecuteScriptOptions().SetEnableIO(false));
1811 return error;
1812}
1813
1815 const StringList &input,
1816 bool is_callback) {
1817 Status error;
1818 int num_lines = input.GetSize();
1819 if (num_lines == 0) {
1820 error = Status::FromErrorString("No input data.");
1821 return error;
1822 }
1823
1824 if (!signature || *signature == 0) {
1825 error = Status::FromErrorString("No output function name.");
1826 return error;
1827 }
1828
1829 StreamString sstr;
1830 StringList auto_generated_function;
1831 auto_generated_function.AppendString(signature);
1832 auto_generated_function.AppendString(
1833 " global_dict = globals()"); // Grab the global dictionary
1834 auto_generated_function.AppendString(
1835 " new_keys = internal_dict.keys()"); // Make a list of keys in the
1836 // session dict
1837 auto_generated_function.AppendString(
1838 " old_keys = global_dict.keys()"); // Save list of keys in global dict
1839 auto_generated_function.AppendString(
1840 " global_dict.update(internal_dict)"); // Add the session dictionary
1841 // to the global dictionary.
1842
1843 if (is_callback) {
1844 // If the user input is a callback to a python function, make sure the input
1845 // is only 1 line, otherwise appending the user input would break the
1846 // generated wrapped function
1847 if (num_lines == 1) {
1848 sstr.Clear();
1849 sstr.Printf(" __return_val = %s", input.GetStringAtIndex(0));
1850 auto_generated_function.AppendString(sstr.GetData());
1851 } else {
1853 "ScriptInterpreterPythonImpl::GenerateFunction(is_callback="
1854 "true) = ERROR: python function is multiline.");
1855 }
1856 } else {
1857 auto_generated_function.AppendString(
1858 " __return_val = None"); // Initialize user callback return value.
1859 auto_generated_function.AppendString(
1860 " def __user_code():"); // Create a nested function that will wrap
1861 // the user input. This is necessary to
1862 // capture the return value of the user input
1863 // and prevent early returns.
1864 for (int i = 0; i < num_lines; ++i) {
1865 sstr.Clear();
1866 sstr.Printf(" %s", input.GetStringAtIndex(i));
1867 auto_generated_function.AppendString(sstr.GetData());
1868 }
1869 auto_generated_function.AppendString(
1870 " __return_val = __user_code()"); // Call user code and capture
1871 // return value
1872 }
1873 auto_generated_function.AppendString(
1874 " for key in new_keys:"); // Iterate over all the keys from session
1875 // dict
1876 auto_generated_function.AppendString(
1877 " if key in old_keys:"); // If key was originally in
1878 // global dict
1879 auto_generated_function.AppendString(
1880 " internal_dict[key] = global_dict[key]"); // Update it
1881 auto_generated_function.AppendString(
1882 " elif key in global_dict:"); // Then if it is still in the
1883 // global dict
1884 auto_generated_function.AppendString(
1885 " del global_dict[key]"); // remove key/value from the
1886 // global dict
1887 auto_generated_function.AppendString(
1888 " return __return_val"); // Return the user callback return value.
1889
1890 // Verify that the results are valid Python.
1892
1893 return error;
1894}
1895
1897 StringList &user_input, std::string &output, const void *name_token) {
1898 static uint32_t num_created_functions = 0;
1899 user_input.RemoveBlankLines();
1900 StreamString sstr;
1901
1902 // Check to see if we have any data; if not, just return.
1903 if (user_input.GetSize() == 0)
1904 return false;
1905
1906 // Take what the user wrote, wrap it all up inside one big auto-generated
1907 // Python function, passing in the ValueObject as parameter to the function.
1908
1909 std::string auto_generated_function_name(
1910 GenerateUniqueName("lldb_autogen_python_type_print_func",
1911 num_created_functions, name_token));
1912 sstr.Printf("def %s (valobj, internal_dict):",
1913 auto_generated_function_name.c_str());
1914
1915 if (!GenerateFunction(sstr.GetData(), user_input, /*is_callback=*/false)
1916 .Success())
1917 return false;
1918
1919 // Store the name of the auto-generated function to be called.
1920 output.assign(auto_generated_function_name);
1921 return true;
1922}
1923
1925 StringList &user_input, std::string &output) {
1926 static uint32_t num_created_functions = 0;
1927 user_input.RemoveBlankLines();
1928 StreamString sstr;
1929
1930 // Check to see if we have any data; if not, just return.
1931 if (user_input.GetSize() == 0)
1932 return false;
1933
1934 std::string auto_generated_function_name(GenerateUniqueName(
1935 "lldb_autogen_python_cmd_alias_func", num_created_functions));
1936
1937 sstr.Printf("def %s (debugger, args, exe_ctx, result, internal_dict):",
1938 auto_generated_function_name.c_str());
1939
1940 if (!GenerateFunction(sstr.GetData(), user_input, /*is_callback=*/false)
1941 .Success())
1942 return false;
1943
1944 // Store the name of the auto-generated function to be called.
1945 output.assign(auto_generated_function_name);
1946 return true;
1947}
1948
1950 StringList &user_input, std::string &output, const void *name_token) {
1951 static uint32_t num_created_classes = 0;
1952 user_input.RemoveBlankLines();
1953 int num_lines = user_input.GetSize();
1954 StreamString sstr;
1955
1956 // Check to see if we have any data; if not, just return.
1957 if (user_input.GetSize() == 0)
1958 return false;
1959
1960 // Wrap all user input into a Python class
1961
1962 std::string auto_generated_class_name(GenerateUniqueName(
1963 "lldb_autogen_python_type_synth_class", num_created_classes, name_token));
1964
1965 StringList auto_generated_class;
1966
1967 // Create the function name & definition string.
1968
1969 sstr.Printf("class %s:", auto_generated_class_name.c_str());
1970 auto_generated_class.AppendString(sstr.GetString());
1971
1972 // Wrap everything up inside the class, increasing the indentation. we don't
1973 // need to play any fancy indentation tricks here because there is no
1974 // surrounding code whose indentation we need to honor
1975 for (int i = 0; i < num_lines; ++i) {
1976 sstr.Clear();
1977 sstr.Printf(" %s", user_input.GetStringAtIndex(i));
1978 auto_generated_class.AppendString(sstr.GetString());
1979 }
1980
1981 // Verify that the results are valid Python. (even though the method is
1982 // ExportFunctionDefinitionToInterpreter, a class will actually be exported)
1983 // (TODO: rename that method to ExportDefinitionToInterpreter)
1984 if (!ExportFunctionDefinitionToInterpreter(auto_generated_class).Success())
1985 return false;
1986
1987 // Store the name of the auto-generated class
1988
1989 output.assign(auto_generated_class_name);
1990 return true;
1991}
1992
1995 return std::make_unique<ScriptedProcessPythonInterface>(*this);
1996}
1997
2000 return std::make_shared<ScriptedHookPythonInterface>(*this);
2001}
2002
2005 return std::make_shared<ScriptedBreakpointPythonInterface>(*this);
2006}
2007
2010 return std::make_shared<ScriptedStackFrameRecognizerPythonInterface>(*this);
2011}
2012
2015 return std::make_shared<ScriptedCommandPythonInterface>(*this);
2016}
2017
2020 return std::make_shared<ScriptedStringSummaryPythonInterface>(*this);
2021}
2022
2025 return std::make_shared<ScriptedSyntheticChildrenPythonInterface>(*this);
2026}
2027
2030 return std::make_shared<ScriptedThreadPythonInterface>(*this);
2031}
2032
2035 return std::make_shared<ScriptedFramePythonInterface>(*this);
2036}
2037
2040 return std::make_shared<ScriptedFrameProviderPythonInterface>(*this);
2041}
2042
2045 return std::make_shared<ScriptedThreadPlanPythonInterface>(*this);
2046}
2047
2050 return std::make_shared<OperatingSystemPythonInterface>(*this);
2051}
2052
2055 ScriptObject obj) {
2056 void *ptr = const_cast<void *>(obj.GetPointer());
2058 PythonObject py_obj(PyRefType::Borrowed, static_cast<PyObject *>(ptr));
2059 if (!py_obj.IsValid() || py_obj.IsNone())
2060 return {};
2061 return py_obj.CreateStructuredObject();
2062}
2063
2067 if (!FileSystem::Instance().Exists(file_spec)) {
2068 error = Status::FromErrorString("no such file");
2069 return StructuredData::ObjectSP();
2070 }
2071
2072 StructuredData::ObjectSP module_sp;
2073
2074 LoadScriptOptions load_script_options =
2075 LoadScriptOptions().SetInitSession(true).SetSilent(false);
2076 if (LoadScriptingModule(file_spec.GetPath().c_str(), load_script_options,
2077 error, &module_sp))
2078 return module_sp;
2079
2080 return StructuredData::ObjectSP();
2081}
2082
2084 StructuredData::ObjectSP plugin_module_sp, Target *target,
2085 const char *setting_name, lldb_private::Status &error) {
2086 if (!plugin_module_sp || !target || !setting_name || !setting_name[0])
2088 StructuredData::Generic *generic = plugin_module_sp->GetAsGeneric();
2089 if (!generic)
2091
2092 Locker py_lock(this,
2094 TargetSP target_sp(target->shared_from_this());
2095
2096 auto setting = (PyObject *)SWIGBridge::LLDBSWIGPython_GetDynamicSetting(
2097 generic->GetValue(), setting_name, target_sp);
2098
2099 if (!setting)
2101
2102 PythonDictionary py_dict =
2104
2105 if (!py_dict)
2112 const char *oneliner, std::string &output, const void *name_token) {
2114 input.SplitIntoLines(oneliner, strlen(oneliner));
2115 return GenerateTypeScriptFunction(input, output, name_token);
2116}
2117
2119 const char *oneliner, std::string &output, const void *name_token) {
2121 input.SplitIntoLines(oneliner, strlen(oneliner));
2122 return GenerateTypeSynthClass(input, output, name_token);
2123}
2124
2126 StringList &user_input, std::string &output, bool has_extra_args,
2127 bool is_callback) {
2128 static uint32_t num_created_functions = 0;
2129 user_input.RemoveBlankLines();
2130 StreamString sstr;
2131 Status error;
2132 if (user_input.GetSize() == 0) {
2133 error = Status::FromErrorString("No input data.");
2134 return error;
2135 }
2136
2137 std::string auto_generated_function_name(GenerateUniqueName(
2138 "lldb_autogen_python_bp_callback_func_", num_created_functions));
2139 if (has_extra_args)
2140 sstr.Printf("def %s (frame, bp_loc, extra_args, internal_dict):",
2141 auto_generated_function_name.c_str());
2142 else
2143 sstr.Printf("def %s (frame, bp_loc, internal_dict):",
2144 auto_generated_function_name.c_str());
2145
2146 error = GenerateFunction(sstr.GetData(), user_input, is_callback);
2147 if (!error.Success())
2148 return error;
2149
2150 // Store the name of the auto-generated function to be called.
2151 output.assign(auto_generated_function_name);
2152 return error;
2153}
2154
2156 StringList &user_input, std::string &output, bool is_callback) {
2157 static uint32_t num_created_functions = 0;
2158 user_input.RemoveBlankLines();
2159 StreamString sstr;
2160
2161 if (user_input.GetSize() == 0)
2162 return false;
2163
2164 std::string auto_generated_function_name(GenerateUniqueName(
2165 "lldb_autogen_python_wp_callback_func_", num_created_functions));
2166 sstr.Printf("def %s (frame, wp, internal_dict):",
2167 auto_generated_function_name.c_str());
2168
2169 if (!GenerateFunction(sstr.GetData(), user_input, is_callback).Success())
2170 return false;
2171
2172 // Store the name of the auto-generated function to be called.
2173 output.assign(auto_generated_function_name);
2174 return true;
2175}
2176
2178 const char *python_function_name, lldb::ValueObjectSP valobj,
2179 StructuredData::ObjectSP &callee_wrapper_sp,
2180 const TypeSummaryOptions &options, std::string &retval) {
2181
2183
2184 if (!valobj.get()) {
2185 retval.assign("<no object>");
2186 return false;
2187 }
2188
2189 void *old_callee = nullptr;
2190 StructuredData::Generic *generic = nullptr;
2191 if (callee_wrapper_sp) {
2192 generic = callee_wrapper_sp->GetAsGeneric();
2193 if (generic)
2194 old_callee = generic->GetValue();
2195 }
2196 void *new_callee = old_callee;
2197
2198 bool ret_val;
2199 if (python_function_name && *python_function_name) {
2200 {
2203 {
2204 TypeSummaryOptionsSP options_sp(new TypeSummaryOptions(options));
2205
2206 static Timer::Category func_cat("LLDBSwigPythonCallTypeScript");
2207 Timer scoped_timer(func_cat, "LLDBSwigPythonCallTypeScript");
2209 python_function_name, GetSessionDictionary().get(), valobj,
2210 &new_callee, options_sp, retval);
2211 }
2212 }
2213 } else {
2214 retval.assign("<no function name>");
2215 return false;
2216 }
2217
2218 if (new_callee && old_callee != new_callee) {
2219 Locker py_lock(this,
2221 callee_wrapper_sp = std::make_shared<StructuredPythonObject>(
2222 PythonObject(PyRefType::Borrowed, static_cast<PyObject *>(new_callee)));
2224
2225 return ret_val;
2226}
2227
2229 const char *python_function_name, TypeImplSP type_impl_sp) {
2230 Locker py_lock(this,
2233 python_function_name, m_dictionary_name.c_str(), type_impl_sp);
2234}
2235
2237 void *baton, StoppointCallbackContext *context, user_id_t break_id,
2238 user_id_t break_loc_id) {
2239 CommandDataPython *bp_option_data = (CommandDataPython *)baton;
2240 const char *python_function_name = bp_option_data->script_source.c_str();
2241
2242 if (!context)
2243 return true;
2244
2245 ExecutionContext exe_ctx(context->exe_ctx_ref);
2246 Target *target = exe_ctx.GetTargetPtr();
2247
2248 if (!target)
2249 return true;
2250
2251 Debugger &debugger = target->GetDebugger();
2252 ScriptInterpreterPythonImpl *python_interpreter =
2253 GetPythonInterpreter(debugger);
2254
2255 if (!python_interpreter)
2256 return true;
2257
2258 if (python_function_name && python_function_name[0]) {
2259 const StackFrameSP stop_frame_sp(exe_ctx.GetFrameSP());
2260 BreakpointSP breakpoint_sp = target->GetBreakpointByID(break_id);
2261 if (breakpoint_sp) {
2262 const BreakpointLocationSP bp_loc_sp(
2263 breakpoint_sp->FindLocationByID(break_loc_id));
2264
2265 if (stop_frame_sp && bp_loc_sp) {
2266 bool ret_val = true;
2267 {
2268 Locker py_lock(python_interpreter, Locker::AcquireLock |
2271 Expected<bool> maybe_ret_val =
2273 python_function_name,
2274 python_interpreter->m_dictionary_name.c_str(), stop_frame_sp,
2275 bp_loc_sp, bp_option_data->m_extra_args);
2276
2277 if (!maybe_ret_val) {
2278
2279 llvm::handleAllErrors(
2280 maybe_ret_val.takeError(),
2281 [&](PythonException &E) {
2282 *debugger.GetAsyncErrorStream() << E.ReadBacktrace();
2283 },
2284 [&](const llvm::ErrorInfoBase &E) {
2285 *debugger.GetAsyncErrorStream() << E.message();
2286 });
2287
2288 } else {
2289 ret_val = maybe_ret_val.get();
2290 }
2291 }
2292 return ret_val;
2293 }
2294 }
2295 }
2296 // We currently always true so we stop in case anything goes wrong when
2297 // trying to call the script function
2298 return true;
2299}
2300
2302 void *baton, StoppointCallbackContext *context, user_id_t watch_id) {
2303 WatchpointOptions::CommandData *wp_option_data =
2305 const char *python_function_name = wp_option_data->script_source.c_str();
2306
2307 if (!context)
2308 return true;
2309
2310 ExecutionContext exe_ctx(context->exe_ctx_ref);
2311 Target *target = exe_ctx.GetTargetPtr();
2312
2313 if (!target)
2314 return true;
2315
2316 Debugger &debugger = target->GetDebugger();
2317 ScriptInterpreterPythonImpl *python_interpreter =
2318 GetPythonInterpreter(debugger);
2319
2320 if (!python_interpreter)
2321 return true;
2322
2323 if (python_function_name && python_function_name[0]) {
2324 const StackFrameSP stop_frame_sp(exe_ctx.GetFrameSP());
2325 WatchpointSP wp_sp = target->GetWatchpointList().FindByID(watch_id);
2326 if (wp_sp) {
2327 if (stop_frame_sp && wp_sp) {
2328 bool ret_val = true;
2329 {
2330 Locker py_lock(python_interpreter, Locker::AcquireLock |
2334 python_function_name,
2335 python_interpreter->m_dictionary_name.c_str(), stop_frame_sp,
2336 wp_sp);
2337 }
2338 return ret_val;
2339 }
2340 }
2341 }
2342 // We currently always true so we stop in case anything goes wrong when
2343 // trying to call the script function
2344 return true;
2345}
2346
2348 const char *impl_function, Process *process, std::string &output,
2349 Status &error) {
2350 bool ret_val;
2351 if (!process) {
2352 error = Status::FromErrorString("no process");
2353 return false;
2354 }
2355 if (!impl_function || !impl_function[0]) {
2356 error = Status::FromErrorString("no function to execute");
2357 return false;
2358 }
2359
2360 {
2361 Locker py_lock(this,
2364 impl_function, m_dictionary_name.c_str(), process->shared_from_this(),
2365 output);
2366 if (!ret_val)
2367 error = Status::FromErrorString("python script evaluation failed");
2368 }
2369 return ret_val;
2370}
2371
2373 const char *impl_function, Thread *thread, std::string &output,
2374 Status &error) {
2375 if (!thread) {
2376 error = Status::FromErrorString("no thread");
2377 return false;
2378 }
2379 if (!impl_function || !impl_function[0]) {
2380 error = Status::FromErrorString("no function to execute");
2381 return false;
2382 }
2383
2384 Locker py_lock(this,
2386 if (std::optional<std::string> result =
2388 impl_function, m_dictionary_name.c_str(),
2389 thread->shared_from_this())) {
2390 output = std::move(*result);
2391 return true;
2393 error = Status::FromErrorString("python script evaluation failed");
2394 return false;
2395}
2396
2398 const char *impl_function, Target *target, std::string &output,
2399 Status &error) {
2400 bool ret_val;
2401 if (!target) {
2402 error = Status::FromErrorString("no thread");
2403 return false;
2404 }
2405 if (!impl_function || !impl_function[0]) {
2406 error = Status::FromErrorString("no function to execute");
2407 return false;
2408 }
2409
2410 {
2411 TargetSP target_sp(target->shared_from_this());
2412 Locker py_lock(this,
2415 impl_function, m_dictionary_name.c_str(), target_sp, output);
2416 if (!ret_val)
2417 error = Status::FromErrorString("python script evaluation failed");
2418 }
2419 return ret_val;
2420}
2421
2423 const char *impl_function, StackFrame *frame, std::string &output,
2424 Status &error) {
2425 if (!frame) {
2426 error = Status::FromErrorString("no frame");
2427 return false;
2428 }
2429 if (!impl_function || !impl_function[0]) {
2430 error = Status::FromErrorString("no function to execute");
2431 return false;
2432 }
2433
2434 Locker py_lock(this,
2436 if (std::optional<std::string> result =
2438 impl_function, m_dictionary_name.c_str(),
2439 frame->shared_from_this())) {
2440 output = std::move(*result);
2441 return true;
2443 error = Status::FromErrorString("python script evaluation failed");
2444 return false;
2445}
2446
2448 const char *impl_function, ValueObject *value, std::string &output,
2449 Status &error) {
2450 bool ret_val;
2451 if (!value) {
2452 error = Status::FromErrorString("no value");
2453 return false;
2454 }
2455 if (!impl_function || !impl_function[0]) {
2456 error = Status::FromErrorString("no function to execute");
2457 return false;
2458 }
2459
2460 {
2461 Locker py_lock(this,
2464 impl_function, m_dictionary_name.c_str(), value->GetSP(), output);
2465 if (!ret_val)
2466 error = Status::FromErrorString("python script evaluation failed");
2467 }
2468 return ret_val;
2469}
2470
2471uint64_t replace_all(std::string &str, const std::string &oldStr,
2472 const std::string &newStr) {
2473 size_t pos = 0;
2474 uint64_t matches = 0;
2475 while ((pos = str.find(oldStr, pos)) != std::string::npos) {
2476 matches++;
2477 str.replace(pos, oldStr.length(), newStr);
2478 pos += newStr.length();
2479 }
2480 return matches;
2481}
2482
2484 const char *pathname, const LoadScriptOptions &options,
2486 FileSpec extra_search_dir, lldb::TargetSP target_sp) {
2487 namespace fs = llvm::sys::fs;
2488 namespace path = llvm::sys::path;
2489
2491 .SetEnableIO(!options.GetSilent())
2492 .SetSetLLDBGlobals(false);
2493
2494 if (!pathname || !pathname[0]) {
2495 error = Status::FromErrorString("empty path");
2496 return false;
2497 }
2498
2499 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
2500 io_redirect_or_error = ScriptInterpreterIORedirect::Create(
2501 exc_options.GetEnableIO(), m_debugger, /*result=*/nullptr);
2502
2503 if (!io_redirect_or_error) {
2504 error = Status::FromError(io_redirect_or_error.takeError());
2505 return false;
2506 }
2507
2508 ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
2509
2510 // Before executing Python code, lock the GIL.
2511 Locker py_lock(this,
2513 (options.GetInitSession() ? Locker::InitSession : 0) |
2516 (options.GetInitSession() ? Locker::TearDownSession : 0),
2517 io_redirect.GetInputFile(), io_redirect.GetOutputFile(),
2518 io_redirect.GetErrorFile());
2519
2520 auto ExtendSysPath = [&](std::string directory) -> llvm::Error {
2521 if (directory.empty()) {
2522 return llvm::createStringError("invalid directory name");
2523 }
2524
2525 replace_all(directory, "\\", "\\\\");
2526 replace_all(directory, "'", "\\'");
2527
2528 // Make sure that Python has "directory" in the search path.
2529 StreamString command_stream;
2530 command_stream.Printf("if not (sys.path.__contains__('%s')):\n "
2531 "sys.path.insert(1,'%s');\n\n",
2532 directory.c_str(), directory.c_str());
2533 bool syspath_retval =
2534 ExecuteMultipleLines(command_stream.GetData(), exc_options).Success();
2535 if (!syspath_retval)
2536 return llvm::createStringError("Python sys.path handling failed");
2537
2538 return llvm::Error::success();
2539 };
2540
2541 std::string module_name(pathname);
2542 bool possible_package = false;
2543
2544 if (extra_search_dir) {
2545 if (llvm::Error e = ExtendSysPath(extra_search_dir.GetPath())) {
2546 error = Status::FromError(std::move(e));
2547 return false;
2548 }
2549 } else {
2550 FileSpec module_file(pathname);
2551 FileSystem::Instance().Resolve(module_file);
2552
2553 fs::file_status st;
2554 std::error_code ec = status(module_file.GetPath(), st);
2555
2556 if (ec || st.type() == fs::file_type::status_error ||
2557 st.type() == fs::file_type::type_unknown ||
2558 st.type() == fs::file_type::file_not_found) {
2559 // if not a valid file of any sort, check if it might be a filename still
2560 // dot can't be used but / and \ can, and if either is found, reject
2561 if (strchr(pathname, '\\') || strchr(pathname, '/')) {
2562 error = Status::FromErrorStringWithFormatv("invalid pathname '{0}'",
2563 pathname);
2564 return false;
2565 }
2566 // Not a filename, probably a package of some sort, let it go through.
2567 possible_package = true;
2568 } else if (is_directory(st) || is_regular_file(st)) {
2569 if (module_file.GetDirectory().empty()) {
2571 "invalid directory name '{0}'", pathname);
2572 return false;
2573 }
2574 if (llvm::Error e = ExtendSysPath(module_file.GetDirectory().str())) {
2575 error = Status::FromError(std::move(e));
2576 return false;
2577 }
2578 module_name = module_file.GetFilename().str();
2579 } else {
2581 "no known way to import this module specification");
2582 return false;
2583 }
2584 }
2585
2586 // Strip .py or .pyc extension
2587 llvm::StringRef extension = llvm::sys::path::extension(module_name);
2588 if (!extension.empty()) {
2589 if (extension == ".py")
2590 module_name.resize(module_name.length() - 3);
2591 else if (extension == ".pyc")
2592 module_name.resize(module_name.length() - 4);
2593 }
2594
2595 if (!possible_package && module_name.find('.') != llvm::StringRef::npos) {
2597 "Python does not allow dots in module names: %s", module_name.c_str());
2598 return false;
2599 }
2600
2601 if (module_name.find('-') != llvm::StringRef::npos) {
2603 "Python discourages dashes in module names: %s", module_name.c_str());
2604 return false;
2605 }
2606
2607 // Check if the module is already imported.
2608 StreamString command_stream;
2609 command_stream.Clear();
2610 command_stream.Printf("sys.modules.__contains__('%s')", module_name.c_str());
2611 bool does_contain = false;
2612 // This call will succeed if the module was ever imported in any Debugger in
2613 // the lifetime of the process in which this LLDB framework is living.
2614 const bool does_contain_executed = ExecuteOneLineWithReturn(
2615 command_stream.GetData(),
2617 exc_options);
2618
2619 const bool was_imported_globally = does_contain_executed && does_contain;
2620 const bool was_imported_locally =
2622 .GetItemForKey(PythonString(module_name))
2623 .IsAllocated();
2624
2625 // now actually do the import
2626 command_stream.Clear();
2627
2628 if (was_imported_globally || was_imported_locally) {
2629 if (!was_imported_locally)
2630 command_stream.Printf("import %s ; importlib.reload(%s)",
2631 module_name.c_str(), module_name.c_str());
2632 else
2633 command_stream.Printf("importlib.reload(%s)", module_name.c_str());
2634 } else
2635 command_stream.Printf("import %s", module_name.c_str());
2636
2637 error = ExecuteMultipleLines(command_stream.GetData(), exc_options);
2638 if (error.Fail())
2639 return false;
2640
2641 // if we are here, everything worked
2642 // call __lldb_init_module(debugger,dict)
2644 module_name.c_str(), m_dictionary_name.c_str(),
2645 m_debugger.shared_from_this())) {
2646 error = Status::FromErrorString("calling __lldb_init_module failed");
2647 return false;
2648 }
2649
2650 if (module_sp) {
2651 // everything went just great, now set the module object
2652 command_stream.Clear();
2653 command_stream.Printf("%s", module_name.c_str());
2654 void *module_pyobj = nullptr;
2656 command_stream.GetData(),
2658 exc_options) &&
2659 module_pyobj)
2660 *module_sp = std::make_shared<StructuredPythonObject>(PythonObject(
2661 PyRefType::Owned, static_cast<PyObject *>(module_pyobj)));
2662 }
2663
2664 // Finally, if we got a target passed in, then we should tell the new module
2665 // about this target:
2666 if (target_sp)
2668 module_name.c_str(), m_dictionary_name.c_str(), target_sp);
2669
2670 return true;
2671}
2672
2673bool ScriptInterpreterPythonImpl::IsReservedWord(const char *word) {
2674 if (!word || !word[0])
2675 return false;
2676
2677 llvm::StringRef word_sr(word);
2678
2679 // filter out a few characters that would just confuse us and that are
2680 // clearly not keyword material anyway
2681 if (word_sr.find('"') != llvm::StringRef::npos ||
2682 word_sr.find('\'') != llvm::StringRef::npos)
2683 return false;
2684
2685 StreamString command_stream;
2686 command_stream.Printf("keyword.iskeyword('%s')", word);
2687 bool result;
2688 ExecuteScriptOptions options;
2689 options.SetEnableIO(false);
2690 options.SetMaskoutErrors(true);
2691 options.SetSetLLDBGlobals(false);
2692 if (ExecuteOneLineWithReturn(command_stream.GetData(),
2694 &result, options))
2695 return result;
2696 return false;
2697}
2698
2701 : m_debugger_sp(debugger_sp), m_synch_wanted(synchro),
2702 m_old_asynch(debugger_sp->GetAsyncExecution()) {
2704 m_debugger_sp->SetAsyncExecution(false);
2706 m_debugger_sp->SetAsyncExecution(true);
2707}
2708
2710 if (m_synch_wanted != eScriptedCommandSynchronicityCurrentValue)
2711 m_debugger_sp->SetAsyncExecution(m_old_asynch);
2712}
2713
2715 const char *impl_function, llvm::StringRef args,
2716 ScriptedCommandSynchronicity synchronicity,
2718 const lldb_private::ExecutionContext &exe_ctx) {
2719 if (!impl_function) {
2720 error = Status::FromErrorString("no function to execute");
2721 return false;
2722 }
2723
2724 lldb::DebuggerSP debugger_sp = m_debugger.shared_from_this();
2725 lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx));
2726
2727 if (!debugger_sp.get()) {
2728 error = Status::FromErrorString("invalid Debugger pointer");
2729 return false;
2730 }
2731
2732 bool ret_val = false;
2733
2734 {
2735 Locker py_lock(this,
2737 (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN),
2739
2740 SynchronicityHandler synch_handler(debugger_sp, synchronicity);
2741
2742 std::string args_str = args.str();
2744 impl_function, m_dictionary_name.c_str(), debugger_sp, args_str.c_str(),
2745 cmd_retobj, exe_ctx_ref_sp);
2746 }
2747
2748 if (!ret_val) {
2749 error = Status::FromErrorString("unable to execute script function");
2750 return false;
2751 }
2752 if (cmd_retobj.GetStatus() == eReturnStatusFailed)
2753 return false;
2754
2755 error.Clear();
2756 return ret_val;
2758
2759/// In Python, a special attribute __doc__ contains the docstring for an object
2760/// (function, method, class, ...) if any is defined Otherwise, the attribute's
2761/// value is None.
2763 std::string &dest) {
2764 dest.clear();
2765
2766 if (!item || !*item)
2767 return false;
2768
2769 std::string command(item);
2770 command += ".__doc__";
2771
2772 // Python is going to point this to valid data if ExecuteOneLineWithReturn
2773 // returns successfully.
2774 char *result_ptr = nullptr;
2775
2778 &result_ptr, ExecuteScriptOptions().SetEnableIO(false))) {
2779 if (result_ptr)
2780 dest.assign(result_ptr);
2781 return true;
2782 }
2783
2784 StreamString str_stream;
2785 str_stream << "Function " << item
2786 << " was not found. Containing module might be missing.";
2787 dest = std::string(str_stream.GetString());
2789 return false;
2790}
2791
2792std::unique_ptr<ScriptInterpreterLocker>
2794 std::unique_ptr<ScriptInterpreterLocker> py_lock(new Locker(
2797 return py_lock;
2798}
2799
2802
2803 // RAII-based initialization which correctly handles multiple-initialization,
2804 // version- specific differences among Python 2 and Python 3, and saving and
2805 // restoring various other pieces of state that can get mucked with during
2806 // initialization.
2807 InitializePythonRAII initialize_guard;
2808
2810
2811 // Update the path python uses to search for modules to include the current
2812 // directory.
2813
2814 RunSimpleString("import sys");
2816
2817 // Don't denormalize paths when calling file_spec.GetPath(). On platforms
2818 // that use a backslash as the path separator, this will result in executing
2819 // python code containing paths with unescaped backslashes. But Python also
2820 // accepts forward slashes, so to make life easier we just use that.
2821 if (FileSpec file_spec = GetPythonDir())
2822 AddToSysPath(AddLocation::Beginning, file_spec.GetPath(false));
2823 if (FileSpec file_spec = HostInfo::GetShlibDir())
2824 AddToSysPath(AddLocation::Beginning, file_spec.GetPath(false));
2825
2826 RunSimpleString("sys.dont_write_bytecode = 1; import "
2827 "lldb.embedded_interpreter; from "
2828 "lldb.embedded_interpreter import run_python_interpreter; "
2829 "from lldb.embedded_interpreter import run_one_line");
2830
2831#if LLDB_USE_PYTHON_SET_INTERRUPT
2832 // Python will not just overwrite its internal SIGINT handler but also the
2833 // one from the process. Backup the current SIGINT handler to prevent that
2834 // Python deletes it.
2835 RestoreSignalHandlerScope save_sigint(SIGINT);
2836
2837 // Setup a default SIGINT signal handler that works the same way as the
2838 // normal Python REPL signal handler which raises a KeyboardInterrupt.
2839 // Also make sure to not pollute the user's REPL with the signal module nor
2840 // our utility function.
2841 RunSimpleString("def lldb_setup_sigint_handler():\n"
2842 " import signal;\n"
2843 " def signal_handler(sig, frame):\n"
2844 " raise KeyboardInterrupt()\n"
2845 " signal.signal(signal.SIGINT, signal_handler);\n"
2846 "lldb_setup_sigint_handler();\n"
2847 "del lldb_setup_sigint_handler\n");
2848#endif
2849}
2850
2852 std::string path) {
2853 std::string statement;
2854 if (location == AddLocation::Beginning) {
2855 statement.assign("sys.path.insert(0,\"");
2856 statement.append(path);
2857 statement.append("\")");
2858 } else {
2859 statement.assign("sys.path.append(\"");
2860 statement.append(path);
2861 statement.append("\")");
2862 }
2863 RunSimpleString(statement.c_str());
2864}
2865
2866// We are intentionally NOT calling Py_Finalize here (this would be the logical
2867// place to call it). Calling Py_Finalize here causes test suite runs to seg
2868// fault: The test suite runs in Python. It registers SBDebugger::Terminate to
2869// be called 'at_exit'. When the test suite Python harness finishes up, it
2870// calls Py_Finalize, which calls all the 'at_exit' registered functions.
2871// SBDebugger::Terminate calls Debugger::Terminate, which calls lldb::Terminate,
2872// which calls ScriptInterpreter::Terminate, which calls
2873// ScriptInterpreterPythonImpl::Terminate. So if we call Py_Finalize here, we
2874// end up with Py_Finalize being called from within Py_Finalize, which results
2875// in a seg fault. Since this function only gets called when lldb is shutting
2876// down and going away anyway, the fact that we don't actually call Py_Finalize
2877// should not cause any problems (everything should shut down/go away anyway
2878// when the process exits).
2879//
2880// void ScriptInterpreterPythonImpl::Terminate() { Py_Finalize (); }
static llvm::raw_ostream & error(Stream &strm)
#define lldbassert(x)
Definition LLDBAssert.h:16
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:375
#define LLDB_LOGF(log,...)
Definition Log.h:389
#define LLDB_LOG_ERROR(log, error,...)
Definition Log.h:405
#define LLDB_LOG_VERBOSE(log,...)
Definition Log.h:382
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)
#define LLDBSwigPyInit
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()
Definition Timer.h:83
A Python sys.stdout/stderr file backed by a pipe whose read end is drained by a reader thread that wr...
static void ReadThreadBytesReceived(void *baton, const void *src, size_t src_len)
static std::unique_ptr< SessionIORedirect > Create(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.
void AppendError(llvm::StringRef in_string)
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
void AppendErrorWithFormatv(const char *format, Args &&...args)
A class to manage flag bits.
Definition Debugger.h:100
lldb::FileSP GetErrorFileSP()
Definition Debugger.h:162
lldb::FileSP GetOutputFileSP()
Definition Debugger.h:158
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={})
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.
A file utility class.
Definition FileSpec.h:56
void AppendPathComponent(llvm::StringRef component)
Definition FileSpec.cpp:454
bool RemoveLastPathComponent()
Removes the last path component by replacing the current path with its parent.
Definition FileSpec.cpp:465
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:380
void SetDirectory(llvm::StringRef directory)
Directory string set accessor.
Definition FileSpec.cpp:358
llvm::StringRef GetFileNameExtension() const
Extract the extension of the file.
Definition FileSpec.cpp:410
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.
Definition FileBase.h:34
static int kInvalidDescriptor
Definition FileBase.h:36
virtual int GetDescriptor() const
Get underlying OS file descriptor for this file, or kInvalidDescriptor.
Definition File.cpp:119
bool IsValid() const override
IsValid.
Definition File.cpp:106
virtual Status Flush()
Flush the current stream.
Definition File.cpp:149
lldb::LockableStreamFileSP GetErrorStreamFileSP()
Definition IOHandler.cpp:95
lldb::LockableStreamFileSP GetOutputStreamFileSP()
Definition IOHandler.cpp:93
void SetIsDone(bool b)
Definition IOHandler.h:81
void PutCString(const char *cstr)
Definition Log.cpp:162
Status CreateNew() override
Definition PipePosix.cpp:82
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.
Definition Process.h:359
void Flush()
Flush our output and error file handles.
static llvm::Expected< std::unique_ptr< ScriptInterpreterIORedirect > > Create(bool enable_io, Debugger &debugger, CommandReturnObject *result)
Create an IO redirect.
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)
SynchronicityHandler(lldb::DebuggerSP, ScriptedCommandSynchronicity)
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 GenerateWatchpointCommandCallbackData(StringList &input, std::string &output, bool is_callback) override
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)
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
lldb::ScriptedFrameProviderInterfaceSP CreateScriptedFrameProviderInterface() override
Status SetBreakpointCommandCallback(BreakpointOptions &bp_options, const char *callback_body, bool is_callback) override
Set the callback body text into the callback for the breakpoint.
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
static void AddToSysPath(AddLocation location, std::string path)
lldb::ScriptedStringSummaryInterfaceSP CreateScriptedStringSummaryInterface() 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
Status GenerateBreakpointCommandCallbackData(StringList &input, std::string &output, bool has_extra_args, bool is_callback) override
lldb::OperatingSystemInterfaceSP CreateOperatingSystemInterface() override
bool FormatterCallbackFunction(const char *function_name, lldb::TypeImplSP type_impl_sp) override
Status ExportFunctionDefinitionToInterpreter(StringList &function_def) override
bool ExecuteOneLine(llvm::StringRef command, CommandReturnObject *result, const ExecuteScriptOptions &options=ExecuteScriptOptions()) override
bool GetDocumentationForItem(const char *item, std::string &dest) override
In Python, a special attribute doc contains the docstring for an object (function,...
lldb::ScriptedSyntheticChildrenInterfaceSP CreateScriptedSyntheticChildrenInterface() override
lldb::ScriptedHookInterfaceSP CreateScriptedHookInterface() override
void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override
Called when a line or lines have been retrieved.
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
bool GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj, StructuredData::ObjectSP &callee_wrapper_sp, const TypeSummaryOptions &options, std::string &retval) override
lldb::ScriptedFrameInterfaceSP CreateScriptedFrameInterface() override
lldb::ScriptedProcessInterfaceUP CreateScriptedProcessInterface() override
bool 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
bool SetStdHandle(lldb::FileSP file, const char *py_name, python::PythonObject &save_file, const char *mode, bool serialize_terminal_output)
Point sys.
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
llvm::Expected< unsigned > GetMaxPositionalArgumentsForCallable(const llvm::StringRef &callable_name) override
static bool WatchpointCallbackFunction(void *baton, StoppointCallbackContext *context, lldb::user_id_t watch_id)
static lldb::ScriptInterpreterSP CreateInstance(Debugger &debugger)
lldb::ScriptedThreadPlanInterfaceSP CreateScriptedThreadPlanInterface() override
std::unique_ptr< SessionIORedirect > m_stdout_redirect
Abstract interface for the Python script interpreter.
static void ComputePythonDir(llvm::SmallVectorImpl< char > &path)
static void ComputePythonDirForApple(llvm::SmallVectorImpl< char > &path)
llvm::Expected< StructuredData::ObjectSP > GetExtensionSchema(const llvm::SmallVector< llvm::StringRef > &extension_path)
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 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)
const void * GetPointer() const
This base class provides an interface to stack frames.
Definition StackFrame.h:44
An error handling class.
Definition Status.h:118
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition Status.cpp:106
static Status FromErrorString(const char *str)
Definition Status.h:141
bool Fail() const
Test for error condition.
Definition Status.cpp:293
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
Definition Status.h:151
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
Definition Status.cpp:136
bool Success() const
Test for success condition.
Definition Status.cpp:303
General Outline: When we hit a breakpoint we need to package up whatever information is needed to eva...
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.
Definition Stream.h:28
void Format(const char *format, Args &&... args)
Forwards the arguments to llvm::formatv and writes to the stream.
Definition Stream.h:370
size_t Indent(llvm::StringRef s="")
Indent the current line in the stream.
Definition Stream.cpp:157
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition Stream.cpp:63
size_t EOL()
Output and End of Line character to the stream.
Definition Stream.cpp:155
void IndentLess(unsigned amount=2)
Decrement the current indentation level.
Definition Stream.cpp:204
void IndentMore(unsigned amount=2)
Increment the current indentation level.
Definition Stream.cpp:201
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)
Definition Target.cpp:437
Debugger & GetDebugger() const
Definition Target.h:1330
WatchpointList & GetWatchpointList()
Definition Target.h:959
"lldb/Core/ThreadedCommunication.h" Variation of Communication that supports threaded reads.
lldb::ValueObjectSP GetSP()
lldb::WatchpointSP FindByID(lldb::watch_id_t watchID) const
Returns a shared pointer to the watchpoint with id watchID, const version.
"lldb/Breakpoint/WatchpointOptions.h" Class that manages the options on a watchpoint.
void SetCallback(WatchpointHitCallback callback, const lldb::BatonSP &baton_sp, bool synchronous=false)
Adds a callback to the watchpoint option set.
static llvm::Expected< ArgInfo > GetArgInfoFromInspectSignature(const PythonCallable &callable)
StructuredData::DictionarySP CreateStructuredDictionary() const
PythonObject GetItemForKey(const PythonObject &key) const
void SetItemForKey(const PythonObject &key, const PythonObject &value)
static llvm::Expected< PythonFile > FromFile(File &file, const char *mode=nullptr)
static 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
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.
Definition Log.h:338
PipePosix Pipe
Definition Pipe.h:20
int file_t
Definition lldb-types.h:59
@ eScriptLanguagePython
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
@ eReturnStatusFailed
std::shared_ptr< lldb_private::Watchpoint > WatchpointSP
std::shared_ptr< lldb_private::ScriptedFrameProviderInterface > ScriptedFrameProviderInterfaceSP
std::shared_ptr< lldb_private::ScriptedCommandInterface > ScriptedCommandInterfaceSP
uint64_t user_id_t
Definition lldb-types.h:83
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.
Definition UserID.h:47