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 llvm::createStringError("invalid extension name");
297 }
298 return llvm::createStringError("invalid extension name");
299}
300
301llvm::Expected<StructuredData::ObjectSP>
303 const llvm::SmallVector<llvm::StringRef> &extension_path) {
304 lldb::ScriptedExtension extension =
305 ScriptInterpreter::StringToExtension(extension_path.back());
306 auto import_path_or_err = ExtensionToImportPath(extension);
307 if (!import_path_or_err)
308 return import_path_or_err.takeError();
309
310 StreamString command_stream;
311 // __import__(path, fromlist=['']) imports the submodule and returns it
312 // directly (rather than the top-level package), as a single expression --
313 // this keeps the whole call eval-able in one line while guaranteeing the
314 // module is imported first; referencing "<import_path>.<ClassName>"
315 // directly would only work if something else had already imported
316 // <import_path> as a side effect.
317 command_stream.Printf("lldb.embedded_interpreter.generate_extension_schema("
318 "__import__('%s', fromlist=['']).%s)",
319 import_path_or_err->c_str(),
320 ScriptInterpreter::ExtensionToString(extension).data());
321
322 // Use eScriptReturnTypeOpaqueObject: it transfers a real owned reference
323 // we can safely extract the string from. eScriptReturnTypeCharStrOrNone
324 // instead hands back a pointer to a temporary Python object's buffer
325 // that gets destroyed (and, for a freshly created string like this one,
326 // deallocated) as soon as ExecuteOneLineWithReturn returns -- reading
327 // it afterwards is a use-after-free.
328 void *result_obj = nullptr;
330 command_stream.GetData(),
332 ExecuteScriptOptions().SetEnableIO(false)))
333 return llvm::createStringError("invalid extension schema format");
334
335 // ExecuteOneLineWithReturn releases the GIL before returning, so touching
336 // the returned object (Str() below can execute arbitrary Python code) must
337 // re-acquire it first. py_result is scoped so its destructor (a DECREF)
338 // also runs before the GIL is released below, not after.
339 std::string schema_str;
340 {
341 PyGILState_STATE gil_state = PyGILState_Ensure();
342 {
344 static_cast<PyObject *>(result_obj));
345 if (py_result.IsAllocated() && py_result.get() != Py_None)
346 schema_str = py_result.Str().GetString().str();
347 }
348 PyGILState_Release(gil_state);
349 }
350
351 if (schema_str.empty())
352 return llvm::createStringError("empty extension schema");
353 return StructuredData::ParseJSON(schema_str);
354}
355
357 Stream &s, llvm::StringRef output_script_prefix,
358 const llvm::SmallVector<llvm::StringRef> &extension_path,
359 bool generate_non_abstract_methods, std::set<std::string> &typing_imports) {
360 auto schema_or_err = GetExtensionSchema(extension_path);
361 if (!schema_or_err)
362 return schema_or_err.takeError();
363
364 StructuredData::ObjectSP schema = *schema_or_err;
365 if (!schema)
366 return llvm::createStringError("empty extension schema");
367 StructuredData::Dictionary *dict = schema->GetAsDictionary();
368 if (!dict)
369 return llvm::createStringError("extension schema is not a JSON object");
370
371 // Merge each class' typing imports into the caller-owned set so the
372 // final `from typing import ...` line covers every class we emit.
373 StructuredData::Array *schema_typing;
374 if (dict->GetValueForKeyAsArray("typing_imports", schema_typing))
375 schema_typing->ForEach([&](StructuredData::Object *entry) {
376 if (auto *str = entry->GetAsString())
377 typing_imports.insert(str->GetValue().str());
378 return true;
379 });
380
381 llvm::StringRef base_class, import_path;
382 if (!dict->GetValueForKeyAsString("class", base_class))
383 return llvm::createStringError(
384 llvm::formatv("extension schema dictionary is missing 'class' key")
385 .str());
386 if (!dict->GetValueForKeyAsString("module", import_path))
387 return llvm::createStringError(
388 llvm::formatv("extension schema dictionary is missing 'module' key")
389 .str());
390
391 // imports
392 s.Printf("from %s import %s\n", import_path.data(), base_class.data());
393 s.EOL();
394
395 // class definition
396 s.Printf("class %s%s(%s):\n", output_script_prefix.data(), base_class.data(),
397 base_class.data());
398 s.IndentMore();
399
400 // Class docstring: list the non-callable members the base class exposes
401 // so the user sees what's available without having to hop back to the
402 // base class definition.
403 bool has_body = false;
404 StructuredData::Array *attributes;
405 if (dict->GetValueForKeyAsArray("attributes", attributes) &&
406 attributes->GetSize()) {
407 s.Indent();
408 s.PutCString("\"\"\"\n");
409 s.Indent();
410 s.Printf("Attributes inherited from %s:\n", base_class.data());
411 for (size_t i = 0; i < attributes->GetSize(); i++) {
412 auto maybe_dict = attributes->GetItemAtIndexAsDictionary(i);
413 if (!maybe_dict)
414 continue;
415 StructuredData::Dictionary *attr_dict = *maybe_dict;
416 llvm::StringRef attr_name;
417 if (!attr_dict->GetValueForKeyAsString("name", attr_name))
418 continue;
419 llvm::StringRef attr_type;
420 bool has_type = attr_dict->GetValueForKeyAsString("type", attr_type);
421 s.Indent();
422 s.Printf("- %s", attr_name.data());
423 if (has_type)
424 s.Printf(": %s", attr_type.data());
425 s.EOL();
426 }
427 s.Indent();
428 s.PutCString("\"\"\"\n\n");
429 has_body = true;
430 }
431
432 // members
433 StructuredData::Array *members;
434 if (!dict->GetValueForKeyAsArray("members", members))
435 return llvm::createStringError("missing 'members' key in extension schema");
436
437 // If the base class doesn't mark anything `@abstractmethod`, the filter
438 // "only stub abstract methods" would leave the derived class empty --
439 // which isn't a useful starting point. Fall back to emitting every
440 // method in that case so the user has actual code to edit.
441 bool any_abstract = false;
442 for (size_t i = 0; i < members->GetSize(); i++) {
443 auto maybe_dict = members->GetItemAtIndexAsDictionary(i);
444 if (!maybe_dict)
445 continue;
446 bool is_abstract = false;
447 if ((*maybe_dict)->GetValueForKeyAsBoolean("is_abstract", is_abstract) &&
448 is_abstract) {
449 any_abstract = true;
450 break;
451 }
452 }
453 bool emit_all_methods = generate_non_abstract_methods || !any_abstract;
454
455 for (size_t i = 0; i < members->GetSize(); i++) {
456 auto maybe_dict = members->GetItemAtIndexAsDictionary(i);
457 if (!maybe_dict)
458 return llvm::createStringError(
459 llvm::formatv(
460 "member at index {0} in extension schema isn't a dictionary")
461 .str());
462
463 StructuredData::Dictionary *member_dict = *maybe_dict;
464 llvm::StringRef symbol, args;
465 if (!member_dict->GetValueForKeyAsString("name", symbol))
466 return llvm::createStringError(
467 llvm::formatv(
468 "member at index {0} in extension schema is missing 'name' key")
469 .str());
470 if (!member_dict->GetValueForKeyAsString("signature", args))
471 return llvm::createStringError(
472 llvm::formatv("member at index {0} in extension schema is missing "
473 "'signature' key")
474 .str());
475
476 bool is_abstract = false;
477 bool has_is_abstract =
478 member_dict->GetValueForKeyAsBoolean("is_abstract", is_abstract);
479 if (!emit_all_methods)
480 if (!has_is_abstract || !is_abstract)
481 continue;
482
483 s.Indent();
484 s.Printf("def %s%s:\n", symbol.data(), args.data());
485
486 s.IndentMore();
487 llvm::StringRef documentation;
488 if (member_dict->GetValueForKeyAsString("doc", documentation)) {
489 s.Indent();
490 s.PutCString("\"\"\"\n");
491
492 llvm::SmallVector<llvm::StringRef> lines;
493 documentation.split(lines, "\n");
494
495 for (llvm::StringRef line : lines) {
496 s.Indent();
497 s.PutCString(line);
498 s.EOL();
499 }
500
501 s.Indent();
502 s.PutCString("\"\"\"");
503 s.EOL();
504 }
505
506 if (symbol == "__init__") {
507 // The base class' constructor sets up attributes (e.g. self.target,
508 // self.process) that the inherited, non-overridden methods rely on.
509 // Forward the same arguments so that state is still initialized.
510 // Splitting the param list on `,` requires bracket-depth awareness
511 // because annotations like `Union[X, Y]` also contain commas.
512 llvm::StringRef params = args.trim("()");
513 std::vector<std::string> forwarded_args;
514 int depth = 0;
515 size_t start = 0;
516 auto flush = [&](size_t end) {
517 llvm::StringRef param = params.slice(start, end);
518 param = param.split(':').first.split('=').first.trim();
519 if (!param.empty() && param != "self")
520 forwarded_args.push_back(param.str());
521 };
522 for (size_t i = 0; i < params.size(); ++i) {
523 char c = params[i];
524 if (c == '[' || c == '(' || c == '{')
525 ++depth;
526 else if (c == ']' || c == ')' || c == '}')
527 --depth;
528 else if (c == ',' && depth == 0) {
529 flush(i);
530 start = i + 1;
531 }
532 }
533 flush(params.size());
534 s.Indent();
535 s.Printf("super().__init__(%s)\n",
536 llvm::join(forwarded_args, ", ").c_str());
537 }
538
539 s.Indent();
540 s.PutCString("# TODO: Implement\n");
541 s.Indent();
542 s.PutCString("pass\n\n");
543 s.IndentLess();
544 has_body = true;
545 }
546
547 // A class with no body is a Python syntax error, so emit `pass` when the
548 // base class has nothing to stub out (no methods and no attributes to
549 // document).
550 if (!has_body) {
551 s.Indent();
552 s.PutCString("pass\n");
553 }
554
555 return llvm::Error::success();
556}
557
559 const std::string &name, std::vector<ExtensionTemplateRequest> &extensions,
560 bool generate_non_abstract_methods, std::string output_file) {
561 // `ParseExtensionSchema` accumulates every `typing` generic it sees
562 // (`Optional`, `Union`, `List`, ...) into this set so we can emit a
563 // targeted `from typing import ...` line only for what's actually
564 // referenced. The Python schema does the detection so we don't have
565 // to re-scan strings here.
566 std::set<std::string> typing_imports;
567 StreamString bodies;
568 for (const ExtensionTemplateRequest &extension : extensions) {
569 if (llvm::Error err =
570 ParseExtensionSchema(bodies, name, extension.path,
571 generate_non_abstract_methods, typing_imports))
572 return std::move(err);
573 bodies.PutCString("\n\n");
574 }
575
576 StreamString generated_file_stream;
577 generated_file_stream.PutCString("import lldb\n");
578 if (!typing_imports.empty()) {
579 std::vector<std::string> sorted_imports(typing_imports.begin(),
580 typing_imports.end());
581 generated_file_stream.Format("from typing import {0}\n",
582 llvm::join(sorted_imports, ", "));
583 }
584 generated_file_stream.PutCString("\n");
585 generated_file_stream.PutCString(bodies.GetString());
586
587 FileSpec save_location;
588 if (output_file.empty()) {
589 // Sanitize the caller-supplied class prefix so it can't escape the
590 // temp directory (`../`, path separators, ...). Only keep ASCII
591 // alphanumerics; everything else collapses to `_`, and an all-junk
592 // name falls back to a fixed default.
593 std::string sanitized;
594 sanitized.reserve(name.size());
595 for (char c : name)
596 sanitized.push_back(llvm::isAlnum(c) ? static_cast<char>(llvm::toLower(c))
597 : '_');
598 if (sanitized.find_first_not_of('_') == std::string::npos)
599 sanitized = "extension";
600 const std::string file_name = "lldb_" + sanitized + "_extension.py";
601 save_location = HostInfo::GetGlobalTempDir();
602 FileSystem::Instance().Resolve(save_location);
603 save_location.AppendPathComponent(file_name);
604 } else {
605 save_location = FileSpec(output_file);
606 FileSystem::Instance().Resolve(save_location);
607 }
608
612
613 auto opened_file = FileSystem::Instance().Open(save_location, flags);
614
615 if (!opened_file)
616 return opened_file.takeError();
617
618 FileUP file = std::move(opened_file.get());
619
620 size_t byte_size = generated_file_stream.GetSize();
621
622 Status error = file->Write(generated_file_stream.GetData(), byte_size);
623
624 if (error.Fail() || byte_size != generated_file_stream.GetSize())
625 return llvm::createStringError("Unable to write to destination file. Bytes "
626 "written do not match generated file size.");
627 return save_location;
628}
629
631 FileSpec &this_file) {
632 // When we're loaded from python, this_file will point to the file inside the
633 // python package directory. Replace it with the one in the lib directory.
634#ifdef _WIN32
635 // On windows, we need to manually back out of the python tree, and go into
636 // the bin directory. This is pretty much the inverse of what ComputePythonDir
637 // does.
638 if (this_file.GetFileNameExtension() == ".pyd") {
639 this_file.RemoveLastPathComponent(); // _lldb.pyd or _lldb_d.pyd
640 this_file.RemoveLastPathComponent(); // native
641 this_file.RemoveLastPathComponent(); // lldb
642 llvm::StringRef libdir = LLDB_PYTHON_RELATIVE_LIBDIR;
643 for (auto it = llvm::sys::path::begin(libdir),
644 end = llvm::sys::path::end(libdir);
645 it != end; ++it)
646 this_file.RemoveLastPathComponent();
647 this_file.AppendPathComponent("bin");
648 this_file.AppendPathComponent("liblldb.dll");
649 }
650#else
651 // The python file is a symlink, so we can find the real library by resolving
652 // it. We can do this unconditionally.
653 FileSystem::Instance().ResolveSymbolicLink(this_file, this_file);
654#endif
655}
656
658 return "Embedded Python interpreter";
659}
660
662#if LLDB_ENABLE_MTE
663 // Python's allocator (pymalloc) is not aware of Memory Tagging Extension
664 // (MTE) and crashes.
665 // https://bugs.python.org/issue43593
666 setenv("PYTHONMALLOC", "malloc", /*overwrite=*/true);
667#endif
668
669 // When the plugin is a separate shared library, the SWIG wrapper lives in
670 // the plugin library, so the path helper that redirects lookups back to
671 // liblldb is unnecessary.
672#if !LLDB_ENABLE_DYNAMIC_SCRIPTINTERPRETERS
673 HostInfo::SetSharedLibraryDirectoryHelper(
675#endif
682}
683
688
690 ScriptInterpreterPythonImpl *py_interpreter, uint16_t on_entry,
691 uint16_t on_leave, FileSP in, FileSP out, FileSP err)
694 m_python_interpreter(py_interpreter) {
696 if ((on_entry & InitSession) == InitSession) {
697 if (!DoInitSession(on_entry, in, out, err)) {
698 // Don't teardown the session if we didn't init it.
699 m_teardown_session = false;
700 }
701 }
702}
703
705 m_GILState = PyGILState_Ensure();
707 "Ensured PyGILState. Previous state = {0}",
708 m_GILState == PyGILState_UNLOCKED ? "unlocked" : "locked");
709
710 // we need to save the thread state when we first start the command because
711 // we might decide to interrupt it while some action is taking place outside
712 // of Python (e.g. printing to screen, waiting for the network, ...) in that
713 // case, _PyThreadState_Current will be NULL - and we would be unable to set
714 // the asynchronous exception - not a desirable situation
715 m_python_interpreter->SetThreadState(PyThreadState_Get());
716 m_python_interpreter->IncrementLockCount();
717 return true;
718}
719
721 FileSP in, FileSP out,
722 FileSP err) {
724 return false;
725 return m_python_interpreter->EnterSession(on_entry_flags, in, out, err);
726}
727
730 "Releasing PyGILState. Returning to state = {0}",
731 m_GILState == PyGILState_UNLOCKED ? "unlocked" : "locked");
732 PyGILState_Release(m_GILState);
733 m_python_interpreter->DecrementLockCount();
734 return true;
735}
736
739 return false;
740 m_python_interpreter->LeaveSession();
741 return true;
742}
743
749
756 m_dictionary_name(m_debugger.GetInstanceName()),
759 m_command_thread_state(nullptr) {
760
761 m_dictionary_name.append("_dict");
762 StreamString run_string;
763 run_string.Printf("%s = dict()", m_dictionary_name.c_str());
764
766 RunSimpleString(run_string.GetData());
767
768 run_string.Clear();
769 run_string.Printf(
770 "run_one_line (%s, 'import copy, keyword, os, re, sys, uuid, lldb')",
771 m_dictionary_name.c_str());
772 RunSimpleString(run_string.GetData());
773
774 // Reloading modules requires a different syntax in Python 2 and Python 3.
775 // This provides a consistent syntax no matter what version of Python.
776 run_string.Clear();
777 run_string.Printf(
778 "run_one_line (%s, 'from importlib import reload as reload_module')",
779 m_dictionary_name.c_str());
780 RunSimpleString(run_string.GetData());
781
782 // WARNING: temporary code that loads Cocoa formatters - this should be done
783 // on a per-platform basis rather than loading the whole set and letting the
784 // individual formatter classes exploit APIs to check whether they can/cannot
785 // do their task
786 run_string.Clear();
787 run_string.Printf(
788 "run_one_line (%s, 'import lldb.formatters, lldb.formatters.cpp')",
789 m_dictionary_name.c_str());
790 RunSimpleString(run_string.GetData());
791 run_string.Clear();
792
793 run_string.Printf("run_one_line (%s, 'import lldb.embedded_interpreter; from "
794 "lldb.embedded_interpreter import run_python_interpreter; "
795 "from lldb.embedded_interpreter import run_one_line')",
796 m_dictionary_name.c_str());
797 RunSimpleString(run_string.GetData());
798 run_string.Clear();
799
800 // Configure pydoc (built-in module) to use the "plain" pager. The default one
801 // doesn't play nice with the statusline.
802 run_string.Printf("run_one_line (%s, 'import pydoc; pydoc.pager = "
803 "pydoc.plainpager')",
804 m_dictionary_name.c_str());
805 RunSimpleString(run_string.GetData());
806 run_string.Clear();
807
808 run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64
809 "')",
810 m_dictionary_name.c_str(), m_debugger.GetID());
811 RunSimpleString(run_string.GetData());
812}
813
814/// A Python sys.stdout/stderr file backed by a pipe whose read end is drained
815/// by a reader thread that writes to the debugger's terminal under the output
816/// lock (Debugger::PrintAsync). Handing Python the raw terminal descriptor
817/// instead lets a script's print() race the statusline, which redraws on the
818/// event thread under that lock. Its cursor save/restore then rewinds over and
819/// eats the script's output.
821public:
822 static std::unique_ptr<SessionIORedirect> Create(lldb::user_id_t debugger_id,
823 bool is_stdout) {
824 Pipe pipe;
825 if (pipe.CreateNew().Fail())
826 return nullptr;
827
828 std::unique_ptr<SessionIORedirect> redirect(
829 new SessionIORedirect(debugger_id, is_stdout));
830
831#if defined(_WIN32)
832 lldb::file_t read_handle = pipe.GetReadNativeHandle();
834 std::unique_ptr<Connection> conn =
835 std::make_unique<ConnectionGenericFile>(read_handle, true);
836#else
837 std::unique_ptr<Connection> conn =
838 std::make_unique<ConnectionFileDescriptor>(
839 pipe.ReleaseReadFileDescriptor(), /*owns_fd=*/true);
840#endif
841 if (!conn->IsConnected())
842 return nullptr;
843
844 redirect->m_communication.SetConnection(std::move(conn));
845 redirect->m_communication.SetReadThreadBytesReceivedCallback(
846 ReadThreadBytesReceived, redirect.get());
847 if (!redirect->m_communication.StartReadThread())
848 return nullptr;
849 redirect->m_connected = true;
850
851 // The write end is owned here. Python only borrows its descriptor.
852 redirect->m_write_file_sp = std::make_shared<NativeFile>(
855 return redirect;
856 }
857
859 if (!m_connected)
860 return;
861 // Close the write end so the reader sees EOF and exits, then join it.
862 if (m_write_file_sp)
863 m_write_file_sp->Close();
864 m_communication.JoinReadThread();
865 m_communication.Disconnect();
866 }
867
868 int GetWriteDescriptor() const {
869 return m_write_file_sp ? m_write_file_sp->GetDescriptor()
871 }
872
873private:
874 SessionIORedirect(lldb::user_id_t debugger_id, bool is_stdout)
875 : m_debugger_id(debugger_id), m_is_stdout(is_stdout),
876 m_communication("lldb.ScriptInterpreterPython.io-redirect") {}
877
878 static void ReadThreadBytesReceived(void *baton, const void *src,
879 size_t src_len) {
880 if (!src || !src_len)
881 return;
882 auto *self = static_cast<SessionIORedirect *>(baton);
883 if (lldb::DebuggerSP debugger_sp =
884 Debugger::FindDebuggerWithID(self->m_debugger_id))
885 debugger_sp->PrintAsync(static_cast<const char *>(src), src_len,
886 self->m_is_stdout);
887 }
888
893 bool m_connected = false;
894};
895
897 // the session dictionary may hold objects with complex state which means
898 // that they may need to be torn down with some level of smarts and that, in
899 // turn, requires a valid thread state force Python to procure itself such a
900 // thread state, nuke the session dictionary and then release it for others
901 // to use and proceed with the rest of the shutdown
902 auto gil_state = PyGILState_Ensure();
903 m_session_dict.Reset();
904 PyGILState_Release(gil_state);
905}
906
908 bool interactive) {
909 const char *instructions = nullptr;
910
911 switch (m_active_io_handler) {
912 case eIOHandlerNone:
913 break;
915 instructions = R"(Enter your Python command(s). Type 'DONE' to end.
916def function (frame, bp_loc, internal_dict):
917 """frame: the lldb.SBFrame for the location at which you stopped
918 bp_loc: an lldb.SBBreakpointLocation for the breakpoint location information
919 internal_dict: an LLDB support object not to be used"""
920)";
921 break;
923 instructions = "Enter your Python command(s). Type 'DONE' to end.\n";
924 break;
925 }
926
927 if (instructions && interactive) {
928 if (LockableStreamFileSP stream_sp = io_handler.GetOutputStreamFileSP()) {
929 LockedStreamFile locked_stream = stream_sp->Lock();
930 locked_stream.PutCString(instructions);
931 locked_stream.Flush();
932 }
933 }
934}
935
937 std::string &data) {
938 io_handler.SetIsDone(true);
939 bool batch_mode = m_debugger.GetCommandInterpreter().GetBatchCommandMode();
940
941 switch (m_active_io_handler) {
942 case eIOHandlerNone:
943 break;
945 std::vector<std::reference_wrapper<BreakpointOptions>> *bp_options_vec =
946 (std::vector<std::reference_wrapper<BreakpointOptions>> *)
947 io_handler.GetUserData();
948 for (BreakpointOptions &bp_options : *bp_options_vec) {
949
950 auto data_up = std::make_unique<CommandDataPython>();
951 if (!data_up)
952 break;
953 data_up->user_source.SplitIntoLines(data);
954
955 if (GenerateBreakpointCommandCallbackData(data_up->user_source,
956 data_up->script_source,
957 /*has_extra_args=*/false,
958 /*is_callback=*/false)
959 .Success()) {
960 auto baton_sp = std::make_shared<BreakpointOptions::CommandBaton>(
961 std::move(data_up));
962 bp_options.SetCallback(
964 } else if (!batch_mode) {
965 if (LockableStreamFileSP error_sp = io_handler.GetErrorStreamFileSP()) {
966 LockedStreamFile locked_stream = error_sp->Lock();
967 locked_stream.Printf("Warning: No command attached to breakpoint.\n");
968 }
969 }
970 }
972 } break;
974 WatchpointOptions *wp_options =
975 (WatchpointOptions *)io_handler.GetUserData();
976 auto data_up = std::make_unique<WatchpointOptions::CommandData>();
977 data_up->user_source.SplitIntoLines(data);
978
979 if (GenerateWatchpointCommandCallbackData(data_up->user_source,
980 data_up->script_source,
981 /*is_callback=*/false)) {
982 auto baton_sp =
983 std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up));
984 wp_options->SetCallback(
986 } else if (!batch_mode) {
987 if (LockableStreamFileSP error_sp = io_handler.GetErrorStreamFileSP()) {
988 LockedStreamFile locked_stream = error_sp->Lock();
989 locked_stream.Printf("Warning: No command attached to breakpoint.\n");
990 }
991 }
993 } break;
994 }
995}
996
999 return std::make_shared<ScriptInterpreterPythonImpl>(debugger);
1000}
1001
1003 Log *log = GetLog(LLDBLog::Script);
1004 if (log)
1005 log->PutCString("ScriptInterpreterPythonImpl::LeaveSession()");
1006
1007 // Unset the LLDB global variables.
1008 RunSimpleString("lldb.debugger = None; lldb.target = None; lldb.process "
1009 "= None; lldb.thread = None; lldb.frame = None");
1010
1011 // checking that we have a valid thread state - since we use our own
1012 // threading and locking in some (rare) cases during cleanup Python may end
1013 // up believing we have no thread state and PyImport_AddModule will crash if
1014 // that is the case - since that seems to only happen when destroying the
1015 // SBDebugger, we can make do without clearing up stdout and stderr
1016 if (PyThreadState_GetDict()) {
1017 PythonDictionary &sys_module_dict = GetSysModuleDictionary();
1018 if (sys_module_dict.IsValid()) {
1019 // Flush the pipe-backed wrappers while they are still sys.stdout/stderr.
1020 // Line buffering already flushes on each newline, but a trailing
1021 // unterminated line would otherwise be stranded (and later flushed into
1022 // a closed descriptor) once we close the pipe write end below.
1023 auto flush_redirect = [&](const char *py_name,
1024 std::unique_ptr<SessionIORedirect> &redirect) {
1025 if (!redirect)
1026 return;
1027 PythonObject file =
1028 sys_module_dict.GetItemForKey(PythonString(py_name));
1029 if (!file.IsValid())
1030 return;
1031 if (llvm::Expected<PythonObject> result = file.CallMethod("flush"))
1032 (void)result;
1033 else
1034 llvm::consumeError(result.takeError());
1035 };
1036 flush_redirect("stdout", m_stdout_redirect);
1037 flush_redirect("stderr", m_stderr_redirect);
1038
1039 if (m_saved_stdin.IsValid()) {
1040 sys_module_dict.SetItemForKey(PythonString("stdin"), m_saved_stdin);
1042 }
1043 if (m_saved_stdout.IsValid()) {
1044 sys_module_dict.SetItemForKey(PythonString("stdout"), m_saved_stdout);
1045 m_saved_stdout.Reset();
1046 }
1047 if (m_saved_stderr.IsValid()) {
1048 sys_module_dict.SetItemForKey(PythonString("stderr"), m_saved_stderr);
1049 m_saved_stderr.Reset();
1050 }
1051 }
1052 }
1053
1054 // Tear down the pipe redirects (closes each write end and joins its reader).
1055 // The wrappers were flushed above, so nothing buffered is lost.
1056 m_stdout_redirect.reset();
1058
1059 m_session_is_active = false;
1060}
1061
1063 const char *py_name, PythonObject &save_file, const char *mode,
1064 File &file) {
1065 const bool is_stdout = ::strcmp(py_name, "stdout") == 0;
1066 if (!is_stdout && ::strcmp(py_name, "stderr") != 0)
1067 return false;
1068
1069 // The statusline is the only writer that races Python's terminal output.
1070 // When it isn't drawing there is nothing to serialize against, so keep the
1071 // normal wrapping and skip the reader thread and pipe.
1073 return false;
1074
1075 // Only the debugger's own terminal races the statusline. A redirect to a
1076 // pipe or user file (a different descriptor) is wrapped normally.
1077 lldb::FileSP debugger_file =
1079 int fd = file.GetDescriptor();
1080 if (!debugger_file || fd == File::kInvalidDescriptor ||
1081 fd != debugger_file->GetDescriptor())
1082 return false;
1083
1084 std::unique_ptr<SessionIORedirect> &redirect =
1086 redirect = SessionIORedirect::Create(m_debugger.GetID(), is_stdout);
1087 if (!redirect)
1088 return false;
1089
1090 // Line-buffer the wrapper so each print() reaches the reader (and the
1091 // terminal) promptly: the pipe descriptor is not a tty, so the default
1092 // buffering would hold output back until the buffer filled.
1093 PyObject *pipe_file = PyFile_FromFd(
1094 redirect->GetWriteDescriptor(), nullptr, mode, /*buffering=*/1,
1095 /*encoding=*/nullptr, /*errors=*/"ignore", /*newline=*/nullptr,
1096 /*closefd=*/0);
1097 if (!pipe_file) {
1098 // Fall back to the raw descriptor. That reopens the statusline race, so
1099 // leave a breadcrumb rather than failing silently.
1101 "failed to wrap sys.{0} on a synchronized pipe; falling back to "
1102 "the unsynchronized terminal descriptor",
1103 py_name);
1104 PyErr_Clear();
1105 redirect.reset();
1106 return false;
1107 }
1108
1109 PythonObject new_file(PyRefType::Owned, pipe_file);
1110 PythonDictionary &sys_module_dict = GetSysModuleDictionary();
1111 save_file = sys_module_dict.GetItemForKey(PythonString(py_name));
1112 sys_module_dict.SetItemForKey(PythonString(py_name), new_file);
1113 return true;
1114}
1115
1117 const char *py_name,
1118 PythonObject &save_file,
1119 const char *mode,
1120 bool serialize_terminal_output) {
1121 if (!file_sp || !*file_sp) {
1122 save_file.Reset();
1123 return false;
1124 }
1125 File &file = *file_sp;
1126
1127 // When stdout/stderr point at the debugger's own terminal, route Python's
1128 // output through a pipe drained under the output lock so a script's print()
1129 // cannot race the statusline. Any other target keeps the normal wrapping.
1130 if (serialize_terminal_output &&
1131 RedirectTerminalHandleThroughLock(py_name, save_file, mode, file))
1132 return true;
1133
1134 // Flush the file before giving it to python to avoid interleaved output.
1135 file.Flush();
1136
1137 PythonDictionary &sys_module_dict = GetSysModuleDictionary();
1138
1139 auto new_file = PythonFile::FromFile(file, mode);
1140 if (!new_file) {
1141 LLDB_LOG_ERROR(GetLog(LLDBLog::Script), new_file.takeError(),
1142 "ScriptInterpreterPythonImpl::SetStdHandle failed to wrap "
1143 "sys.{1}: {0}",
1144 py_name);
1145 return false;
1146 }
1147
1148 save_file = sys_module_dict.GetItemForKey(PythonString(py_name));
1150 sys_module_dict.SetItemForKey(PythonString(py_name), new_file.get());
1151 return true;
1152}
1153
1154bool ScriptInterpreterPythonImpl::EnterSession(uint16_t on_entry_flags,
1155 FileSP in_sp, FileSP out_sp,
1156 FileSP err_sp) {
1157 // If we have already entered the session, without having officially 'left'
1158 // it, then there is no need to 'enter' it again.
1159 Log *log = GetLog(LLDBLog::Script);
1160 if (m_session_is_active) {
1161 LLDB_LOGF(
1162 log,
1163 "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16
1164 ") session is already active, returning without doing anything",
1165 on_entry_flags);
1166 return false;
1167 }
1168
1169 LLDB_LOGF(
1170 log,
1171 "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16 ")",
1172 on_entry_flags);
1173
1174 m_session_is_active = true;
1175
1176 StreamString run_string;
1177
1178 if (on_entry_flags & Locker::InitGlobals) {
1179 run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64,
1181 run_string.Printf(
1182 "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64 ")",
1183 m_debugger.GetID());
1184 run_string.PutCString("; lldb.target = lldb.debugger.GetSelectedTarget()");
1185 run_string.PutCString("; lldb.process = lldb.target.GetProcess()");
1186 run_string.PutCString("; lldb.thread = lldb.process.GetSelectedThread ()");
1187 run_string.PutCString("; lldb.frame = lldb.thread.GetSelectedFrame ()");
1188 run_string.PutCString("')");
1189 } else {
1190 // If we aren't initing the globals, we should still always set the
1191 // debugger (since that is always unique.)
1192 run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64,
1193 m_dictionary_name.c_str(), m_debugger.GetID());
1194 run_string.Printf(
1195 "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64 ")",
1196 m_debugger.GetID());
1197 run_string.PutCString("')");
1198 }
1199
1200 RunSimpleString(run_string.GetData());
1201 run_string.Clear();
1202
1203 PythonDictionary &sys_module_dict = GetSysModuleDictionary();
1204 if (sys_module_dict.IsValid()) {
1205 lldb::FileSP top_in_sp;
1206 lldb::LockableStreamFileSP top_out_sp, top_err_sp;
1207 if (!in_sp || !out_sp || !err_sp || !*in_sp || !*out_sp || !*err_sp)
1208 m_debugger.AdoptTopIOHandlerFilesIfInvalid(top_in_sp, top_out_sp,
1209 top_err_sp);
1210
1211 if (on_entry_flags & Locker::NoSTDIN) {
1212 m_saved_stdin.Reset();
1213 } else {
1214 if (!SetStdHandle(in_sp, "stdin", m_saved_stdin, "r",
1215 /*serialize_terminal_output=*/false)) {
1216 if (top_in_sp)
1217 SetStdHandle(top_in_sp, "stdin", m_saved_stdin, "r",
1218 /*serialize_terminal_output=*/false);
1219 }
1220 }
1221
1222 // Serialize terminal output for every session except those that opt out
1223 // with NoOutputRedirect (see the flag for why).
1224 const bool serialize_terminal_output =
1225 !(on_entry_flags & Locker::NoOutputRedirect);
1226
1227 if (!SetStdHandle(out_sp, "stdout", m_saved_stdout, "w",
1228 serialize_terminal_output)) {
1229 if (top_out_sp)
1230 SetStdHandle(top_out_sp->GetUnlockedFileSP(), "stdout", m_saved_stdout,
1231 "w", serialize_terminal_output);
1232 }
1233
1234 if (!SetStdHandle(err_sp, "stderr", m_saved_stderr, "w",
1235 serialize_terminal_output)) {
1236 if (top_err_sp)
1237 SetStdHandle(top_err_sp->GetUnlockedFileSP(), "stderr", m_saved_stderr,
1238 "w", serialize_terminal_output);
1239 }
1240 }
1241
1242 if (PyErr_Occurred())
1243 PyErr_Clear();
1244
1245 return true;
1246}
1247
1249 if (!m_main_module.IsValid())
1251 return m_main_module;
1252}
1253
1255 if (m_session_dict.IsValid())
1256 return m_session_dict;
1257
1258 PythonObject &main_module = GetMainModule();
1259 if (!main_module.IsValid())
1260 return m_session_dict;
1261
1263 PyModule_GetDict(main_module.get()));
1264 if (!main_dict.IsValid())
1265 return m_session_dict;
1266
1274 return m_sys_module_dict;
1277 return m_sys_module_dict;
1278}
1279
1280llvm::Expected<unsigned>
1282 const llvm::StringRef &callable_name) {
1283 if (callable_name.empty()) {
1284 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1285 "called with empty callable name.");
1286 }
1287 Locker py_lock(this,
1292 callable_name, dict);
1293 if (!pfunc.IsAllocated()) {
1294 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1295 "can't find callable: %s",
1296 callable_name.str().c_str());
1297 }
1298 llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
1299 if (!arg_info)
1300 return arg_info.takeError();
1301 return arg_info.get().max_positional_args;
1302}
1303
1304static std::string GenerateUniqueName(const char *base_name_wanted,
1305 uint32_t &functions_counter,
1306 const void *name_token = nullptr) {
1307 StreamString sstr;
1308
1309 if (!base_name_wanted)
1310 return std::string();
1311
1312 if (!name_token)
1313 sstr.Printf("%s_%d", base_name_wanted, functions_counter++);
1314 else
1315 sstr.Printf("%s_%p", base_name_wanted, name_token);
1316
1317 return std::string(sstr.GetString());
1318}
1319
1322 return true;
1323
1325 PyImport_AddModule("lldb.embedded_interpreter"));
1326 if (!module.IsValid())
1327 return false;
1328
1330 PyModule_GetDict(module.get()));
1331 if (!module_dict.IsValid())
1332 return false;
1333
1335 module_dict.GetItemForKey(PythonString("run_one_line"));
1337 module_dict.GetItemForKey(PythonString("g_run_one_line_str"));
1338 return m_run_one_line_function.IsValid();
1339}
1340
1342 llvm::StringRef command, CommandReturnObject *result,
1343 const ExecuteScriptOptions &options) {
1344 std::string command_str = command.str();
1345
1346 if (!m_valid_session)
1347 return false;
1348
1349 if (!command.empty()) {
1350 // We want to call run_one_line, passing in the dictionary and the command
1351 // string. We cannot do this through RunSimpleString here because the
1352 // command string may contain escaped characters, and putting it inside
1353 // another string to pass to RunSimpleString messes up the escaping. So
1354 // we use the following more complicated method to pass the command string
1355 // directly down to Python.
1356 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
1357 io_redirect_or_error = ScriptInterpreterIORedirect::Create(
1358 options.GetEnableIO(), m_debugger, result);
1359 if (!io_redirect_or_error) {
1360 if (result)
1361 result->AppendErrorWithFormatv(
1362 "failed to redirect I/O: {0}\n",
1363 llvm::fmt_consume(io_redirect_or_error.takeError()));
1364 else
1365 llvm::consumeError(io_redirect_or_error.takeError());
1366 return false;
1367 }
1368
1369 ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
1370
1371 bool success = false;
1372 {
1373 // WARNING! It's imperative that this RAII scope be as tight as
1374 // possible. In particular, the scope must end *before* we try to join
1375 // the read thread. The reason for this is that a pre-requisite for
1376 // joining the read thread is that we close the write handle (to break
1377 // the pipe and cause it to wake up and exit). But acquiring the GIL as
1378 // below will redirect Python's stdio to use this same handle. If we
1379 // close the handle while Python is still using it, bad things will
1380 // happen.
1381 Locker locker(
1382 this,
1384 (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) |
1385 ((result && result->GetInteractive()) ? 0 : Locker::NoSTDIN),
1387 io_redirect.GetInputFile(), io_redirect.GetOutputFile(),
1388 io_redirect.GetErrorFile());
1389
1390 // Find the correct script interpreter dictionary in the main module.
1391 PythonDictionary &session_dict = GetSessionDictionary();
1392 if (session_dict.IsValid()) {
1394 if (PyCallable_Check(m_run_one_line_function.get())) {
1395 PythonObject pargs(
1397 Py_BuildValue("(Os)", session_dict.get(), command_str.c_str()));
1398 if (pargs.IsValid()) {
1399 PythonObject return_value(
1401 PyObject_CallObject(m_run_one_line_function.get(),
1402 pargs.get()));
1403 if (return_value.IsValid())
1404 success = true;
1405 else if (options.GetMaskoutErrors() && PyErr_Occurred()) {
1406 PyErr_Print();
1407 PyErr_Clear();
1408 }
1409 }
1410 }
1411 }
1412 }
1413
1414 io_redirect.Flush();
1415 }
1416
1417 if (success)
1418 return true;
1419
1420 // The one-liner failed. Append the error message.
1421 if (result) {
1422 result->AppendErrorWithFormat("python failed attempting to evaluate '%s'",
1423 command_str.c_str());
1424 }
1425 return false;
1426 }
1427
1428 if (result)
1429 result->AppendError("empty command passed to python\n");
1430 return false;
1431}
1432
1435
1436 Debugger &debugger = m_debugger;
1437
1438 // At the moment, the only time the debugger does not have an input file
1439 // handle is when this is called directly from Python, in which case it is
1440 // both dangerous and unnecessary (not to mention confusing) to try to embed
1441 // a running interpreter loop inside the already running Python interpreter
1442 // loop, so we won't do it.
1443
1444 if (!debugger.GetInputFile().IsValid())
1445 return;
1446
1447 IOHandlerSP io_handler_sp(new IOHandlerPythonInterpreter(debugger, this));
1448 if (io_handler_sp) {
1449 debugger.RunIOHandlerAsync(io_handler_sp);
1450 }
1451}
1452
1454#if LLDB_USE_PYTHON_SET_INTERRUPT
1455 // If the interpreter isn't evaluating any Python at the moment then return
1456 // false to signal that this function didn't handle the interrupt and the
1457 // next component should try handling it.
1458 if (!IsExecutingPython())
1459 return false;
1460
1461 // Tell Python that it should pretend to have received a SIGINT.
1462 PyErr_SetInterrupt();
1463 // PyErr_SetInterrupt has no way to return an error so we can only pretend the
1464 // signal got successfully handled and return true.
1465 // Python 3.10 introduces PyErr_SetInterruptEx that could return an error, but
1466 // the error handling is limited to checking the arguments which would be
1467 // just our (hardcoded) input signal code SIGINT, so that's not useful at all.
1468 return true;
1469#else
1470 Log *log = GetLog(LLDBLog::Script);
1471
1472 if (IsExecutingPython()) {
1473 PyThreadState *state = PyThreadState_Get();
1474 if (!state)
1475 state = GetThreadState();
1476 if (state) {
1477 long tid = PyThread_get_thread_ident();
1478 PyThreadState_Swap(state);
1479 int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt);
1480 LLDB_LOGF(log,
1481 "ScriptInterpreterPythonImpl::Interrupt() sending "
1482 "PyExc_KeyboardInterrupt (tid = %li, num_threads = %i)...",
1483 tid, num_threads);
1484 return true;
1485 }
1486 }
1487 LLDB_LOGF(log,
1488 "ScriptInterpreterPythonImpl::Interrupt() python code not running, "
1489 "can't interrupt");
1490 return false;
1491#endif
1492}
1493
1495 llvm::StringRef in_string, ScriptInterpreter::ScriptReturnType return_type,
1496 void *ret_value, const ExecuteScriptOptions &options) {
1497
1498 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
1499 io_redirect_or_error = ScriptInterpreterIORedirect::Create(
1500 options.GetEnableIO(), m_debugger, /*result=*/nullptr);
1501
1502 if (!io_redirect_or_error) {
1503 llvm::consumeError(io_redirect_or_error.takeError());
1504 return false;
1505 }
1506
1507 ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
1508
1509 Locker locker(this,
1511 (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) |
1514 io_redirect.GetInputFile(), io_redirect.GetOutputFile(),
1515 io_redirect.GetErrorFile());
1516
1517 PythonModule &main_module = GetMainModule();
1518 PythonDictionary globals = main_module.GetDictionary();
1519
1521 if (!locals.IsValid())
1522 locals = unwrapIgnoringErrors(
1524 if (!locals.IsValid())
1525 locals = globals;
1526
1527 Expected<PythonObject> maybe_py_return =
1528 runStringOneLine(in_string, globals, locals);
1529
1530 if (!maybe_py_return) {
1531 llvm::handleAllErrors(
1532 maybe_py_return.takeError(),
1533 [&](PythonException &E) {
1534 E.Restore();
1535 if (options.GetMaskoutErrors()) {
1536 if (E.Matches(PyExc_SyntaxError)) {
1537 PyErr_Print();
1538 }
1539 PyErr_Clear();
1540 }
1541 },
1542 [](const llvm::ErrorInfoBase &E) {});
1543 return false;
1544 }
1545
1546 PythonObject py_return = std::move(maybe_py_return.get());
1547 assert(py_return.IsValid());
1548
1549 switch (return_type) {
1550 case eScriptReturnTypeCharPtr: // "char *"
1551 {
1552 const char format[3] = "s#";
1553 return PyArg_Parse(py_return.get(), format, (char **)ret_value);
1554 }
1555 case eScriptReturnTypeCharStrOrNone: // char* or NULL if py_return ==
1556 // Py_None
1557 {
1558 const char format[3] = "z";
1559 return PyArg_Parse(py_return.get(), format, (char **)ret_value);
1560 }
1561 case eScriptReturnTypeBool: {
1562 const char format[2] = "b";
1563 return PyArg_Parse(py_return.get(), format, (bool *)ret_value);
1564 }
1565 case eScriptReturnTypeShortInt: {
1566 const char format[2] = "h";
1567 return PyArg_Parse(py_return.get(), format, (short *)ret_value);
1568 }
1569 case eScriptReturnTypeShortIntUnsigned: {
1570 const char format[2] = "H";
1571 return PyArg_Parse(py_return.get(), format, (unsigned short *)ret_value);
1572 }
1573 case eScriptReturnTypeInt: {
1574 const char format[2] = "i";
1575 return PyArg_Parse(py_return.get(), format, (int *)ret_value);
1576 }
1577 case eScriptReturnTypeIntUnsigned: {
1578 const char format[2] = "I";
1579 return PyArg_Parse(py_return.get(), format, (unsigned int *)ret_value);
1580 }
1581 case eScriptReturnTypeLongInt: {
1582 const char format[2] = "l";
1583 return PyArg_Parse(py_return.get(), format, (long *)ret_value);
1584 }
1585 case eScriptReturnTypeLongIntUnsigned: {
1586 const char format[2] = "k";
1587 return PyArg_Parse(py_return.get(), format, (unsigned long *)ret_value);
1588 }
1589 case eScriptReturnTypeLongLong: {
1590 const char format[2] = "L";
1591 return PyArg_Parse(py_return.get(), format, (long long *)ret_value);
1592 }
1593 case eScriptReturnTypeLongLongUnsigned: {
1594 const char format[2] = "K";
1595 return PyArg_Parse(py_return.get(), format,
1596 (unsigned long long *)ret_value);
1597 }
1598 case eScriptReturnTypeFloat: {
1599 const char format[2] = "f";
1600 return PyArg_Parse(py_return.get(), format, (float *)ret_value);
1601 }
1602 case eScriptReturnTypeDouble: {
1603 const char format[2] = "d";
1604 return PyArg_Parse(py_return.get(), format, (double *)ret_value);
1605 }
1606 case eScriptReturnTypeChar: {
1607 const char format[2] = "c";
1608 return PyArg_Parse(py_return.get(), format, (char *)ret_value);
1609 }
1610 case eScriptReturnTypeOpaqueObject: {
1611 *((PyObject **)ret_value) = py_return.release();
1612 return true;
1614 }
1615 llvm_unreachable("Fully covered switch!");
1616}
1617
1619 const char *in_string, const ExecuteScriptOptions &options) {
1620
1621 if (in_string == nullptr)
1622 return Status();
1623
1624 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
1625 io_redirect_or_error = ScriptInterpreterIORedirect::Create(
1626 options.GetEnableIO(), m_debugger, /*result=*/nullptr);
1627
1628 if (!io_redirect_or_error)
1629 return Status::FromError(io_redirect_or_error.takeError());
1630
1631 ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
1632
1633 Locker locker(this,
1635 (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) |
1638 io_redirect.GetInputFile(), io_redirect.GetOutputFile(),
1639 io_redirect.GetErrorFile());
1640
1641 PythonModule &main_module = GetMainModule();
1642 PythonDictionary globals = main_module.GetDictionary();
1643
1644 PythonDictionary locals = GetSessionDictionary();
1645 if (!locals.IsValid())
1646 locals = unwrapIgnoringErrors(
1648 if (!locals.IsValid())
1649 locals = globals;
1650
1651 Expected<PythonObject> return_value =
1652 runStringMultiLine(in_string, globals, locals);
1653
1654 if (!return_value) {
1655 llvm::Error error =
1656 llvm::handleErrors(return_value.takeError(), [&](PythonException &E) {
1657 llvm::Error error = llvm::createStringError(
1658 llvm::inconvertibleErrorCode(), E.ReadBacktrace());
1659 if (!options.GetMaskoutErrors())
1660 E.Restore();
1661 return error;
1662 });
1663 return Status::FromError(std::move(error));
1665
1666 return Status();
1667}
1668
1670 std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
1671 CommandReturnObject &result) {
1673 m_debugger.GetCommandInterpreter().GetPythonCommandsFromIOHandler(
1674 " ", *this, &bp_options_vec);
1675}
1676
1678 WatchpointOptions *wp_options, CommandReturnObject &result) {
1680 m_debugger.GetCommandInterpreter().GetPythonCommandsFromIOHandler(
1681 " ", *this, wp_options);
1682}
1683
1685 BreakpointOptions &bp_options, const char *function_name,
1686 StructuredData::ObjectSP extra_args_sp) {
1687 Status error;
1688 // For now just cons up a oneliner that calls the provided function.
1689 std::string function_signature = function_name;
1690
1691 llvm::Expected<unsigned> maybe_args =
1693 if (!maybe_args) {
1695 "could not get num args: %s",
1696 llvm::toString(maybe_args.takeError()).c_str());
1697 return error;
1698 }
1699 size_t max_args = *maybe_args;
1700
1701 bool uses_extra_args = false;
1702 if (max_args >= 4) {
1703 uses_extra_args = true;
1704 function_signature += "(frame, bp_loc, extra_args, internal_dict)";
1705 } else if (max_args >= 3) {
1706 if (extra_args_sp) {
1708 "cannot pass extra_args to a three argument callback");
1709 return error;
1710 }
1711 uses_extra_args = false;
1712 function_signature += "(frame, bp_loc, internal_dict)";
1713 } else {
1714 error = Status::FromErrorStringWithFormat("expected 3 or 4 argument "
1715 "function, %s can only take %zu",
1716 function_name, max_args);
1717 return error;
1718 }
1719
1720 SetBreakpointCommandCallback(bp_options, function_signature.c_str(),
1721 extra_args_sp, uses_extra_args,
1722 /*is_callback=*/true);
1723 return error;
1724}
1725
1727 BreakpointOptions &bp_options,
1728 std::unique_ptr<BreakpointOptions::CommandData> &cmd_data_up) {
1729 Status error;
1730 error = GenerateBreakpointCommandCallbackData(cmd_data_up->user_source,
1731 cmd_data_up->script_source,
1732 /*has_extra_args=*/false,
1733 /*is_callback=*/false);
1734 if (error.Fail()) {
1735 return error;
1736 }
1737 auto baton_sp =
1738 std::make_shared<BreakpointOptions::CommandBaton>(std::move(cmd_data_up));
1745 BreakpointOptions &bp_options, const char *command_body_text,
1746 bool is_callback) {
1747 return SetBreakpointCommandCallback(bp_options, command_body_text, {},
1748 /*uses_extra_args=*/false, is_callback);
1749}
1750
1751// Set a Python one-liner as the callback for the breakpoint.
1753 BreakpointOptions &bp_options, const char *command_body_text,
1754 StructuredData::ObjectSP extra_args_sp, bool uses_extra_args,
1755 bool is_callback) {
1756 auto data_up = std::make_unique<CommandDataPython>(extra_args_sp);
1757 // Split the command_body_text into lines, and pass that to
1758 // GenerateBreakpointCommandCallbackData. That will wrap the body in an
1759 // auto-generated function, and return the function name in script_source.
1760 // That is what the callback will actually invoke.
1761
1762 data_up->user_source.SplitIntoLines(command_body_text);
1764 data_up->user_source, data_up->script_source, uses_extra_args,
1765 is_callback);
1766 if (error.Success()) {
1767 auto baton_sp =
1768 std::make_shared<BreakpointOptions::CommandBaton>(std::move(data_up));
1769 bp_options.SetCallback(
1771 return error;
1773 return error;
1774}
1775
1776// Set a Python one-liner as the callback for the watchpoint.
1778 WatchpointOptions *wp_options, const char *user_input, bool is_callback) {
1779 auto data_up = std::make_unique<WatchpointOptions::CommandData>();
1780
1781 // It's necessary to set both user_source and script_source to the oneliner.
1782 // The former is used to generate callback description (as in watchpoint
1783 // command list) while the latter is used for Python to interpret during the
1784 // actual callback.
1785
1786 data_up->user_source.AppendString(user_input);
1787 data_up->script_source.assign(user_input);
1788
1790 data_up->user_source, data_up->script_source, is_callback)) {
1791 auto baton_sp =
1792 std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up));
1793 wp_options->SetCallback(
1795 }
1796}
1797
1799 StringList &function_def) {
1800 // Convert StringList to one long, newline delimited, const char *.
1801 std::string function_def_string(function_def.CopyList());
1802 LLDB_LOG(GetLog(LLDBLog::Script), "Added Function:\n{0}\n",
1803 function_def_string.c_str());
1804
1806 function_def_string.c_str(), ExecuteScriptOptions().SetEnableIO(false));
1807 return error;
1808}
1809
1811 const StringList &input,
1812 bool is_callback) {
1813 Status error;
1814 int num_lines = input.GetSize();
1815 if (num_lines == 0) {
1816 error = Status::FromErrorString("No input data.");
1817 return error;
1818 }
1819
1820 if (!signature || *signature == 0) {
1821 error = Status::FromErrorString("No output function name.");
1822 return error;
1823 }
1824
1825 StreamString sstr;
1826 StringList auto_generated_function;
1827 auto_generated_function.AppendString(signature);
1828 auto_generated_function.AppendString(
1829 " global_dict = globals()"); // Grab the global dictionary
1830 auto_generated_function.AppendString(
1831 " new_keys = internal_dict.keys()"); // Make a list of keys in the
1832 // session dict
1833 auto_generated_function.AppendString(
1834 " old_keys = global_dict.keys()"); // Save list of keys in global dict
1835 auto_generated_function.AppendString(
1836 " global_dict.update(internal_dict)"); // Add the session dictionary
1837 // to the global dictionary.
1838
1839 if (is_callback) {
1840 // If the user input is a callback to a python function, make sure the input
1841 // is only 1 line, otherwise appending the user input would break the
1842 // generated wrapped function
1843 if (num_lines == 1) {
1844 sstr.Clear();
1845 sstr.Printf(" __return_val = %s", input.GetStringAtIndex(0));
1846 auto_generated_function.AppendString(sstr.GetData());
1847 } else {
1849 "ScriptInterpreterPythonImpl::GenerateFunction(is_callback="
1850 "true) = ERROR: python function is multiline.");
1851 }
1852 } else {
1853 auto_generated_function.AppendString(
1854 " __return_val = None"); // Initialize user callback return value.
1855 auto_generated_function.AppendString(
1856 " def __user_code():"); // Create a nested function that will wrap
1857 // the user input. This is necessary to
1858 // capture the return value of the user input
1859 // and prevent early returns.
1860 for (int i = 0; i < num_lines; ++i) {
1861 sstr.Clear();
1862 sstr.Printf(" %s", input.GetStringAtIndex(i));
1863 auto_generated_function.AppendString(sstr.GetData());
1864 }
1865 auto_generated_function.AppendString(
1866 " __return_val = __user_code()"); // Call user code and capture
1867 // return value
1868 }
1869 auto_generated_function.AppendString(
1870 " for key in new_keys:"); // Iterate over all the keys from session
1871 // dict
1872 auto_generated_function.AppendString(
1873 " if key in old_keys:"); // If key was originally in
1874 // global dict
1875 auto_generated_function.AppendString(
1876 " internal_dict[key] = global_dict[key]"); // Update it
1877 auto_generated_function.AppendString(
1878 " elif key in global_dict:"); // Then if it is still in the
1879 // global dict
1880 auto_generated_function.AppendString(
1881 " del global_dict[key]"); // remove key/value from the
1882 // global dict
1883 auto_generated_function.AppendString(
1884 " return __return_val"); // Return the user callback return value.
1885
1886 // Verify that the results are valid Python.
1888
1889 return error;
1890}
1891
1893 StringList &user_input, std::string &output, const void *name_token) {
1894 static uint32_t num_created_functions = 0;
1895 user_input.RemoveBlankLines();
1896 StreamString sstr;
1897
1898 // Check to see if we have any data; if not, just return.
1899 if (user_input.GetSize() == 0)
1900 return false;
1901
1902 // Take what the user wrote, wrap it all up inside one big auto-generated
1903 // Python function, passing in the ValueObject as parameter to the function.
1904
1905 std::string auto_generated_function_name(
1906 GenerateUniqueName("lldb_autogen_python_type_print_func",
1907 num_created_functions, name_token));
1908 sstr.Printf("def %s (valobj, internal_dict):",
1909 auto_generated_function_name.c_str());
1910
1911 if (!GenerateFunction(sstr.GetData(), user_input, /*is_callback=*/false)
1912 .Success())
1913 return false;
1914
1915 // Store the name of the auto-generated function to be called.
1916 output.assign(auto_generated_function_name);
1917 return true;
1918}
1919
1921 StringList &user_input, std::string &output) {
1922 static uint32_t num_created_functions = 0;
1923 user_input.RemoveBlankLines();
1924 StreamString sstr;
1925
1926 // Check to see if we have any data; if not, just return.
1927 if (user_input.GetSize() == 0)
1928 return false;
1929
1930 std::string auto_generated_function_name(GenerateUniqueName(
1931 "lldb_autogen_python_cmd_alias_func", num_created_functions));
1932
1933 sstr.Printf("def %s (debugger, args, exe_ctx, result, internal_dict):",
1934 auto_generated_function_name.c_str());
1935
1936 if (!GenerateFunction(sstr.GetData(), user_input, /*is_callback=*/false)
1937 .Success())
1938 return false;
1939
1940 // Store the name of the auto-generated function to be called.
1941 output.assign(auto_generated_function_name);
1942 return true;
1943}
1944
1946 StringList &user_input, std::string &output, const void *name_token) {
1947 static uint32_t num_created_classes = 0;
1948 user_input.RemoveBlankLines();
1949 int num_lines = user_input.GetSize();
1950 StreamString sstr;
1951
1952 // Check to see if we have any data; if not, just return.
1953 if (user_input.GetSize() == 0)
1954 return false;
1955
1956 // Wrap all user input into a Python class
1957
1958 std::string auto_generated_class_name(GenerateUniqueName(
1959 "lldb_autogen_python_type_synth_class", num_created_classes, name_token));
1960
1961 StringList auto_generated_class;
1962
1963 // Create the function name & definition string.
1964
1965 sstr.Printf("class %s:", auto_generated_class_name.c_str());
1966 auto_generated_class.AppendString(sstr.GetString());
1967
1968 // Wrap everything up inside the class, increasing the indentation. we don't
1969 // need to play any fancy indentation tricks here because there is no
1970 // surrounding code whose indentation we need to honor
1971 for (int i = 0; i < num_lines; ++i) {
1972 sstr.Clear();
1973 sstr.Printf(" %s", user_input.GetStringAtIndex(i));
1974 auto_generated_class.AppendString(sstr.GetString());
1975 }
1976
1977 // Verify that the results are valid Python. (even though the method is
1978 // ExportFunctionDefinitionToInterpreter, a class will actually be exported)
1979 // (TODO: rename that method to ExportDefinitionToInterpreter)
1980 if (!ExportFunctionDefinitionToInterpreter(auto_generated_class).Success())
1981 return false;
1982
1983 // Store the name of the auto-generated class
1984
1985 output.assign(auto_generated_class_name);
1986 return true;
1987}
1988
1991 return std::make_unique<ScriptedProcessPythonInterface>(*this);
1992}
1993
1996 return std::make_shared<ScriptedHookPythonInterface>(*this);
1997}
1998
2001 return std::make_shared<ScriptedBreakpointPythonInterface>(*this);
2002}
2003
2006 return std::make_shared<ScriptedStackFrameRecognizerPythonInterface>(*this);
2007}
2008
2011 return std::make_shared<ScriptedCommandPythonInterface>(*this);
2012}
2013
2016 return std::make_shared<ScriptedThreadPythonInterface>(*this);
2017}
2018
2021 return std::make_shared<ScriptedFramePythonInterface>(*this);
2022}
2023
2026 return std::make_shared<ScriptedFrameProviderPythonInterface>(*this);
2027}
2028
2031 return std::make_shared<ScriptedThreadPlanPythonInterface>(*this);
2032}
2033
2036 return std::make_shared<OperatingSystemPythonInterface>(*this);
2037}
2038
2041 ScriptObject obj) {
2042 void *ptr = const_cast<void *>(obj.GetPointer());
2044 PythonObject py_obj(PyRefType::Borrowed, static_cast<PyObject *>(ptr));
2045 if (!py_obj.IsValid() || py_obj.IsNone())
2046 return {};
2047 return py_obj.CreateStructuredObject();
2048}
2049
2053 if (!FileSystem::Instance().Exists(file_spec)) {
2054 error = Status::FromErrorString("no such file");
2055 return StructuredData::ObjectSP();
2056 }
2057
2058 StructuredData::ObjectSP module_sp;
2059
2060 LoadScriptOptions load_script_options =
2061 LoadScriptOptions().SetInitSession(true).SetSilent(false);
2062 if (LoadScriptingModule(file_spec.GetPath().c_str(), load_script_options,
2063 error, &module_sp))
2064 return module_sp;
2065
2066 return StructuredData::ObjectSP();
2067}
2068
2070 StructuredData::ObjectSP plugin_module_sp, Target *target,
2071 const char *setting_name, lldb_private::Status &error) {
2072 if (!plugin_module_sp || !target || !setting_name || !setting_name[0])
2074 StructuredData::Generic *generic = plugin_module_sp->GetAsGeneric();
2075 if (!generic)
2077
2078 Locker py_lock(this,
2080 TargetSP target_sp(target->shared_from_this());
2081
2082 auto setting = (PyObject *)SWIGBridge::LLDBSWIGPython_GetDynamicSetting(
2083 generic->GetValue(), setting_name, target_sp);
2084
2085 if (!setting)
2087
2088 PythonDictionary py_dict =
2090
2091 if (!py_dict)
2094 return py_dict.CreateStructuredDictionary();
2095}
2096
2099 const char *class_name, lldb::ValueObjectSP valobj) {
2100 if (class_name == nullptr || class_name[0] == '\0')
2101 return StructuredData::ObjectSP();
2102
2103 if (!valobj.get())
2104 return StructuredData::ObjectSP();
2105
2106 ExecutionContext exe_ctx(valobj->GetExecutionContextRef());
2107 Target *target = exe_ctx.GetTargetPtr();
2108
2109 if (!target)
2110 return StructuredData::ObjectSP();
2111
2112 Debugger &debugger = target->GetDebugger();
2113 ScriptInterpreterPythonImpl *python_interpreter =
2114 GetPythonInterpreter(debugger);
2115
2116 if (!python_interpreter)
2117 return StructuredData::ObjectSP();
2118
2119 Locker py_lock(this,
2122 class_name, python_interpreter->m_dictionary_name.c_str(), valobj);
2129 const char *oneliner, std::string &output, const void *name_token) {
2131 input.SplitIntoLines(oneliner, strlen(oneliner));
2132 return GenerateTypeScriptFunction(input, output, name_token);
2133}
2134
2136 const char *oneliner, std::string &output, const void *name_token) {
2138 input.SplitIntoLines(oneliner, strlen(oneliner));
2139 return GenerateTypeSynthClass(input, output, name_token);
2140}
2141
2143 StringList &user_input, std::string &output, bool has_extra_args,
2144 bool is_callback) {
2145 static uint32_t num_created_functions = 0;
2146 user_input.RemoveBlankLines();
2147 StreamString sstr;
2148 Status error;
2149 if (user_input.GetSize() == 0) {
2150 error = Status::FromErrorString("No input data.");
2151 return error;
2152 }
2153
2154 std::string auto_generated_function_name(GenerateUniqueName(
2155 "lldb_autogen_python_bp_callback_func_", num_created_functions));
2156 if (has_extra_args)
2157 sstr.Printf("def %s (frame, bp_loc, extra_args, internal_dict):",
2158 auto_generated_function_name.c_str());
2159 else
2160 sstr.Printf("def %s (frame, bp_loc, internal_dict):",
2161 auto_generated_function_name.c_str());
2162
2163 error = GenerateFunction(sstr.GetData(), user_input, is_callback);
2164 if (!error.Success())
2165 return error;
2166
2167 // Store the name of the auto-generated function to be called.
2168 output.assign(auto_generated_function_name);
2169 return error;
2170}
2171
2173 StringList &user_input, std::string &output, bool is_callback) {
2174 static uint32_t num_created_functions = 0;
2175 user_input.RemoveBlankLines();
2176 StreamString sstr;
2177
2178 if (user_input.GetSize() == 0)
2179 return false;
2180
2181 std::string auto_generated_function_name(GenerateUniqueName(
2182 "lldb_autogen_python_wp_callback_func_", num_created_functions));
2183 sstr.Printf("def %s (frame, wp, internal_dict):",
2184 auto_generated_function_name.c_str());
2185
2186 if (!GenerateFunction(sstr.GetData(), user_input, is_callback).Success())
2187 return false;
2188
2189 // Store the name of the auto-generated function to be called.
2190 output.assign(auto_generated_function_name);
2191 return true;
2192}
2193
2195 const char *python_function_name, lldb::ValueObjectSP valobj,
2196 StructuredData::ObjectSP &callee_wrapper_sp,
2197 const TypeSummaryOptions &options, std::string &retval) {
2198
2200
2201 if (!valobj.get()) {
2202 retval.assign("<no object>");
2203 return false;
2204 }
2205
2206 void *old_callee = nullptr;
2207 StructuredData::Generic *generic = nullptr;
2208 if (callee_wrapper_sp) {
2209 generic = callee_wrapper_sp->GetAsGeneric();
2210 if (generic)
2211 old_callee = generic->GetValue();
2212 }
2213 void *new_callee = old_callee;
2214
2215 bool ret_val;
2216 if (python_function_name && *python_function_name) {
2217 {
2220 {
2221 TypeSummaryOptionsSP options_sp(new TypeSummaryOptions(options));
2222
2223 static Timer::Category func_cat("LLDBSwigPythonCallTypeScript");
2224 Timer scoped_timer(func_cat, "LLDBSwigPythonCallTypeScript");
2226 python_function_name, GetSessionDictionary().get(), valobj,
2227 &new_callee, options_sp, retval);
2228 }
2229 }
2230 } else {
2231 retval.assign("<no function name>");
2232 return false;
2233 }
2234
2235 if (new_callee && old_callee != new_callee) {
2236 Locker py_lock(this,
2238 callee_wrapper_sp = std::make_shared<StructuredPythonObject>(
2239 PythonObject(PyRefType::Borrowed, static_cast<PyObject *>(new_callee)));
2241
2242 return ret_val;
2243}
2244
2246 const char *python_function_name, TypeImplSP type_impl_sp) {
2247 Locker py_lock(this,
2250 python_function_name, m_dictionary_name.c_str(), type_impl_sp);
2251}
2252
2254 void *baton, StoppointCallbackContext *context, user_id_t break_id,
2255 user_id_t break_loc_id) {
2256 CommandDataPython *bp_option_data = (CommandDataPython *)baton;
2257 const char *python_function_name = bp_option_data->script_source.c_str();
2258
2259 if (!context)
2260 return true;
2261
2262 ExecutionContext exe_ctx(context->exe_ctx_ref);
2263 Target *target = exe_ctx.GetTargetPtr();
2264
2265 if (!target)
2266 return true;
2267
2268 Debugger &debugger = target->GetDebugger();
2269 ScriptInterpreterPythonImpl *python_interpreter =
2270 GetPythonInterpreter(debugger);
2271
2272 if (!python_interpreter)
2273 return true;
2274
2275 if (python_function_name && python_function_name[0]) {
2276 const StackFrameSP stop_frame_sp(exe_ctx.GetFrameSP());
2277 BreakpointSP breakpoint_sp = target->GetBreakpointByID(break_id);
2278 if (breakpoint_sp) {
2279 const BreakpointLocationSP bp_loc_sp(
2280 breakpoint_sp->FindLocationByID(break_loc_id));
2281
2282 if (stop_frame_sp && bp_loc_sp) {
2283 bool ret_val = true;
2284 {
2285 Locker py_lock(python_interpreter, Locker::AcquireLock |
2288 Expected<bool> maybe_ret_val =
2290 python_function_name,
2291 python_interpreter->m_dictionary_name.c_str(), stop_frame_sp,
2292 bp_loc_sp, bp_option_data->m_extra_args);
2293
2294 if (!maybe_ret_val) {
2295
2296 llvm::handleAllErrors(
2297 maybe_ret_val.takeError(),
2298 [&](PythonException &E) {
2299 *debugger.GetAsyncErrorStream() << E.ReadBacktrace();
2300 },
2301 [&](const llvm::ErrorInfoBase &E) {
2302 *debugger.GetAsyncErrorStream() << E.message();
2303 });
2304
2305 } else {
2306 ret_val = maybe_ret_val.get();
2307 }
2308 }
2309 return ret_val;
2310 }
2311 }
2312 }
2313 // We currently always true so we stop in case anything goes wrong when
2314 // trying to call the script function
2315 return true;
2316}
2317
2319 void *baton, StoppointCallbackContext *context, user_id_t watch_id) {
2320 WatchpointOptions::CommandData *wp_option_data =
2322 const char *python_function_name = wp_option_data->script_source.c_str();
2323
2324 if (!context)
2325 return true;
2326
2327 ExecutionContext exe_ctx(context->exe_ctx_ref);
2328 Target *target = exe_ctx.GetTargetPtr();
2329
2330 if (!target)
2331 return true;
2332
2333 Debugger &debugger = target->GetDebugger();
2334 ScriptInterpreterPythonImpl *python_interpreter =
2335 GetPythonInterpreter(debugger);
2336
2337 if (!python_interpreter)
2338 return true;
2339
2340 if (python_function_name && python_function_name[0]) {
2341 const StackFrameSP stop_frame_sp(exe_ctx.GetFrameSP());
2342 WatchpointSP wp_sp = target->GetWatchpointList().FindByID(watch_id);
2343 if (wp_sp) {
2344 if (stop_frame_sp && wp_sp) {
2345 bool ret_val = true;
2346 {
2347 Locker py_lock(python_interpreter, Locker::AcquireLock |
2351 python_function_name,
2352 python_interpreter->m_dictionary_name.c_str(), stop_frame_sp,
2353 wp_sp);
2354 }
2355 return ret_val;
2356 }
2357 }
2358 }
2359 // We currently always true so we stop in case anything goes wrong when
2360 // trying to call the script function
2361 return true;
2362}
2363
2365 const StructuredData::ObjectSP &implementor_sp, uint32_t max) {
2366 if (!implementor_sp)
2367 return 0;
2368 StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
2369 if (!generic)
2370 return 0;
2371 auto *implementor = static_cast<PyObject *>(generic->GetValue());
2372 if (!implementor)
2373 return 0;
2374
2375 size_t ret_val = 0;
2376
2377 {
2378 Locker py_lock(this,
2380 ret_val = SWIGBridge::LLDBSwigPython_CalculateNumChildren(implementor, max);
2382
2383 return ret_val;
2384}
2385
2387 const StructuredData::ObjectSP &implementor_sp, uint32_t idx) {
2388 if (!implementor_sp)
2389 return lldb::ValueObjectSP();
2390
2391 StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
2392 if (!generic)
2393 return lldb::ValueObjectSP();
2394 auto *implementor = static_cast<PyObject *>(generic->GetValue());
2395 if (!implementor)
2396 return lldb::ValueObjectSP();
2397
2398 lldb::ValueObjectSP ret_val;
2399 {
2400 Locker py_lock(this,
2402 PyObject *child_ptr =
2404 if (child_ptr != nullptr && child_ptr != Py_None) {
2405 lldb::SBValue *sb_value_ptr =
2407 if (sb_value_ptr == nullptr)
2408 Py_XDECREF(child_ptr);
2409 else
2411 sb_value_ptr);
2412 } else {
2413 Py_XDECREF(child_ptr);
2414 }
2416
2417 return ret_val;
2418}
2419
2421 const StructuredData::ObjectSP &implementor_sp, const char *child_name) {
2422 if (!implementor_sp)
2423 return llvm::createStringErrorV("type has no child named '{0}'",
2424 child_name);
2425
2426 StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
2427 if (!generic)
2428 return llvm::createStringErrorV("type has no child named '{0}'",
2429 child_name);
2430 auto *implementor = static_cast<PyObject *>(generic->GetValue());
2431 if (!implementor)
2432 return llvm::createStringErrorV("type has no child named '{0}'",
2433 child_name);
2434
2435 uint32_t ret_val = UINT32_MAX;
2436
2437 {
2438 Locker py_lock(this,
2441 child_name);
2442 }
2443
2444 if (ret_val == UINT32_MAX)
2445 return llvm::createStringErrorV("type has no child named '{0}'",
2446 child_name);
2447 return ret_val;
2448}
2449
2451 const StructuredData::ObjectSP &implementor_sp) {
2452 bool ret_val = false;
2453
2454 if (!implementor_sp)
2455 return ret_val;
2456
2457 StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
2458 if (!generic)
2459 return ret_val;
2460 auto *implementor = static_cast<PyObject *>(generic->GetValue());
2461 if (!implementor)
2462 return ret_val;
2463
2464 {
2465 Locker py_lock(this,
2467 ret_val =
2470
2471 return ret_val;
2472}
2473
2475 const StructuredData::ObjectSP &implementor_sp) {
2476 bool ret_val = false;
2477
2478 if (!implementor_sp)
2479 return ret_val;
2480
2481 StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
2482 if (!generic)
2483 return ret_val;
2484 auto *implementor = static_cast<PyObject *>(generic->GetValue());
2485 if (!implementor)
2486 return ret_val;
2487
2488 {
2489 Locker py_lock(this,
2492 implementor);
2494
2495 return ret_val;
2496}
2497
2499 const StructuredData::ObjectSP &implementor_sp) {
2500 lldb::ValueObjectSP ret_val(nullptr);
2501
2502 if (!implementor_sp)
2503 return ret_val;
2504
2505 StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
2506 if (!generic)
2507 return ret_val;
2508 auto *implementor = static_cast<PyObject *>(generic->GetValue());
2509 if (!implementor)
2510 return ret_val;
2511
2512 {
2513 Locker py_lock(this,
2515 PyObject *child_ptr =
2517 if (child_ptr != nullptr && child_ptr != Py_None) {
2518 lldb::SBValue *sb_value_ptr =
2520 if (sb_value_ptr == nullptr)
2521 Py_XDECREF(child_ptr);
2522 else
2524 sb_value_ptr);
2525 } else {
2526 Py_XDECREF(child_ptr);
2527 }
2529
2530 return ret_val;
2531}
2532
2534 const StructuredData::ObjectSP &implementor_sp) {
2535 Locker py_lock(this,
2537
2538 if (!implementor_sp)
2539 return {};
2540
2541 StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
2542 if (!generic)
2543 return {};
2544
2545 PythonObject implementor(PyRefType::Borrowed,
2546 (PyObject *)generic->GetValue());
2547 if (!implementor.IsAllocated())
2548 return {};
2549
2550 llvm::Expected<PythonObject> expected_py_return =
2551 implementor.CallMethod("get_type_name");
2552
2553 if (!expected_py_return) {
2554 llvm::consumeError(expected_py_return.takeError());
2555 return {};
2556 }
2557
2558 PythonObject py_return = std::move(expected_py_return.get());
2559 if (!py_return.IsAllocated() || !PythonString::Check(py_return.get()))
2560 return {};
2562 PythonString type_name(PyRefType::Borrowed, py_return.get());
2563 return ConstString(type_name.GetString());
2564}
2565
2567 const char *impl_function, Process *process, std::string &output,
2568 Status &error) {
2569 bool ret_val;
2570 if (!process) {
2571 error = Status::FromErrorString("no process");
2572 return false;
2573 }
2574 if (!impl_function || !impl_function[0]) {
2575 error = Status::FromErrorString("no function to execute");
2576 return false;
2577 }
2578
2579 {
2580 Locker py_lock(this,
2583 impl_function, m_dictionary_name.c_str(), process->shared_from_this(),
2584 output);
2585 if (!ret_val)
2586 error = Status::FromErrorString("python script evaluation failed");
2587 }
2588 return ret_val;
2589}
2590
2592 const char *impl_function, Thread *thread, std::string &output,
2593 Status &error) {
2594 if (!thread) {
2595 error = Status::FromErrorString("no thread");
2596 return false;
2597 }
2598 if (!impl_function || !impl_function[0]) {
2599 error = Status::FromErrorString("no function to execute");
2600 return false;
2601 }
2602
2603 Locker py_lock(this,
2605 if (std::optional<std::string> result =
2607 impl_function, m_dictionary_name.c_str(),
2608 thread->shared_from_this())) {
2609 output = std::move(*result);
2610 return true;
2612 error = Status::FromErrorString("python script evaluation failed");
2613 return false;
2614}
2615
2617 const char *impl_function, Target *target, std::string &output,
2618 Status &error) {
2619 bool ret_val;
2620 if (!target) {
2621 error = Status::FromErrorString("no thread");
2622 return false;
2623 }
2624 if (!impl_function || !impl_function[0]) {
2625 error = Status::FromErrorString("no function to execute");
2626 return false;
2627 }
2628
2629 {
2630 TargetSP target_sp(target->shared_from_this());
2631 Locker py_lock(this,
2634 impl_function, m_dictionary_name.c_str(), target_sp, output);
2635 if (!ret_val)
2636 error = Status::FromErrorString("python script evaluation failed");
2637 }
2638 return ret_val;
2639}
2640
2642 const char *impl_function, StackFrame *frame, std::string &output,
2643 Status &error) {
2644 if (!frame) {
2645 error = Status::FromErrorString("no frame");
2646 return false;
2647 }
2648 if (!impl_function || !impl_function[0]) {
2649 error = Status::FromErrorString("no function to execute");
2650 return false;
2651 }
2652
2653 Locker py_lock(this,
2655 if (std::optional<std::string> result =
2657 impl_function, m_dictionary_name.c_str(),
2658 frame->shared_from_this())) {
2659 output = std::move(*result);
2660 return true;
2662 error = Status::FromErrorString("python script evaluation failed");
2663 return false;
2664}
2665
2667 const char *impl_function, ValueObject *value, std::string &output,
2668 Status &error) {
2669 bool ret_val;
2670 if (!value) {
2671 error = Status::FromErrorString("no value");
2672 return false;
2673 }
2674 if (!impl_function || !impl_function[0]) {
2675 error = Status::FromErrorString("no function to execute");
2676 return false;
2677 }
2678
2679 {
2680 Locker py_lock(this,
2683 impl_function, m_dictionary_name.c_str(), value->GetSP(), output);
2684 if (!ret_val)
2685 error = Status::FromErrorString("python script evaluation failed");
2686 }
2687 return ret_val;
2688}
2689
2690uint64_t replace_all(std::string &str, const std::string &oldStr,
2691 const std::string &newStr) {
2692 size_t pos = 0;
2693 uint64_t matches = 0;
2694 while ((pos = str.find(oldStr, pos)) != std::string::npos) {
2695 matches++;
2696 str.replace(pos, oldStr.length(), newStr);
2697 pos += newStr.length();
2698 }
2699 return matches;
2700}
2701
2703 const char *pathname, const LoadScriptOptions &options,
2705 FileSpec extra_search_dir, lldb::TargetSP target_sp) {
2706 namespace fs = llvm::sys::fs;
2707 namespace path = llvm::sys::path;
2708
2710 .SetEnableIO(!options.GetSilent())
2711 .SetSetLLDBGlobals(false);
2712
2713 if (!pathname || !pathname[0]) {
2714 error = Status::FromErrorString("empty path");
2715 return false;
2716 }
2717
2718 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
2719 io_redirect_or_error = ScriptInterpreterIORedirect::Create(
2720 exc_options.GetEnableIO(), m_debugger, /*result=*/nullptr);
2721
2722 if (!io_redirect_or_error) {
2723 error = Status::FromError(io_redirect_or_error.takeError());
2724 return false;
2725 }
2726
2727 ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
2728
2729 // Before executing Python code, lock the GIL.
2730 Locker py_lock(this,
2732 (options.GetInitSession() ? Locker::InitSession : 0) |
2735 (options.GetInitSession() ? Locker::TearDownSession : 0),
2736 io_redirect.GetInputFile(), io_redirect.GetOutputFile(),
2737 io_redirect.GetErrorFile());
2738
2739 auto ExtendSysPath = [&](std::string directory) -> llvm::Error {
2740 if (directory.empty()) {
2741 return llvm::createStringError("invalid directory name");
2742 }
2743
2744 replace_all(directory, "\\", "\\\\");
2745 replace_all(directory, "'", "\\'");
2746
2747 // Make sure that Python has "directory" in the search path.
2748 StreamString command_stream;
2749 command_stream.Printf("if not (sys.path.__contains__('%s')):\n "
2750 "sys.path.insert(1,'%s');\n\n",
2751 directory.c_str(), directory.c_str());
2752 bool syspath_retval =
2753 ExecuteMultipleLines(command_stream.GetData(), exc_options).Success();
2754 if (!syspath_retval)
2755 return llvm::createStringError("Python sys.path handling failed");
2756
2757 return llvm::Error::success();
2758 };
2759
2760 std::string module_name(pathname);
2761 bool possible_package = false;
2762
2763 if (extra_search_dir) {
2764 if (llvm::Error e = ExtendSysPath(extra_search_dir.GetPath())) {
2765 error = Status::FromError(std::move(e));
2766 return false;
2767 }
2768 } else {
2769 FileSpec module_file(pathname);
2770 FileSystem::Instance().Resolve(module_file);
2771
2772 fs::file_status st;
2773 std::error_code ec = status(module_file.GetPath(), st);
2774
2775 if (ec || st.type() == fs::file_type::status_error ||
2776 st.type() == fs::file_type::type_unknown ||
2777 st.type() == fs::file_type::file_not_found) {
2778 // if not a valid file of any sort, check if it might be a filename still
2779 // dot can't be used but / and \ can, and if either is found, reject
2780 if (strchr(pathname, '\\') || strchr(pathname, '/')) {
2781 error = Status::FromErrorStringWithFormatv("invalid pathname '{0}'",
2782 pathname);
2783 return false;
2784 }
2785 // Not a filename, probably a package of some sort, let it go through.
2786 possible_package = true;
2787 } else if (is_directory(st) || is_regular_file(st)) {
2788 if (module_file.GetDirectory().empty()) {
2790 "invalid directory name '{0}'", pathname);
2791 return false;
2792 }
2793 if (llvm::Error e = ExtendSysPath(module_file.GetDirectory().str())) {
2794 error = Status::FromError(std::move(e));
2795 return false;
2796 }
2797 module_name = module_file.GetFilename().str();
2798 } else {
2800 "no known way to import this module specification");
2801 return false;
2802 }
2803 }
2804
2805 // Strip .py or .pyc extension
2806 llvm::StringRef extension = llvm::sys::path::extension(module_name);
2807 if (!extension.empty()) {
2808 if (extension == ".py")
2809 module_name.resize(module_name.length() - 3);
2810 else if (extension == ".pyc")
2811 module_name.resize(module_name.length() - 4);
2812 }
2813
2814 if (!possible_package && module_name.find('.') != llvm::StringRef::npos) {
2816 "Python does not allow dots in module names: %s", module_name.c_str());
2817 return false;
2818 }
2819
2820 if (module_name.find('-') != llvm::StringRef::npos) {
2822 "Python discourages dashes in module names: %s", module_name.c_str());
2823 return false;
2824 }
2825
2826 // Check if the module is already imported.
2827 StreamString command_stream;
2828 command_stream.Clear();
2829 command_stream.Printf("sys.modules.__contains__('%s')", module_name.c_str());
2830 bool does_contain = false;
2831 // This call will succeed if the module was ever imported in any Debugger in
2832 // the lifetime of the process in which this LLDB framework is living.
2833 const bool does_contain_executed = ExecuteOneLineWithReturn(
2834 command_stream.GetData(),
2836 exc_options);
2837
2838 const bool was_imported_globally = does_contain_executed && does_contain;
2839 const bool was_imported_locally =
2841 .GetItemForKey(PythonString(module_name))
2842 .IsAllocated();
2843
2844 // now actually do the import
2845 command_stream.Clear();
2846
2847 if (was_imported_globally || was_imported_locally) {
2848 if (!was_imported_locally)
2849 command_stream.Printf("import %s ; reload_module(%s)",
2850 module_name.c_str(), module_name.c_str());
2851 else
2852 command_stream.Printf("reload_module(%s)", module_name.c_str());
2853 } else
2854 command_stream.Printf("import %s", module_name.c_str());
2855
2856 error = ExecuteMultipleLines(command_stream.GetData(), exc_options);
2857 if (error.Fail())
2858 return false;
2859
2860 // if we are here, everything worked
2861 // call __lldb_init_module(debugger,dict)
2863 module_name.c_str(), m_dictionary_name.c_str(),
2864 m_debugger.shared_from_this())) {
2865 error = Status::FromErrorString("calling __lldb_init_module failed");
2866 return false;
2867 }
2868
2869 if (module_sp) {
2870 // everything went just great, now set the module object
2871 command_stream.Clear();
2872 command_stream.Printf("%s", module_name.c_str());
2873 void *module_pyobj = nullptr;
2875 command_stream.GetData(),
2877 exc_options) &&
2878 module_pyobj)
2879 *module_sp = std::make_shared<StructuredPythonObject>(PythonObject(
2880 PyRefType::Owned, static_cast<PyObject *>(module_pyobj)));
2881 }
2882
2883 // Finally, if we got a target passed in, then we should tell the new module
2884 // about this target:
2885 if (target_sp)
2887 module_name.c_str(), m_dictionary_name.c_str(), target_sp);
2888
2889 return true;
2890}
2891
2892bool ScriptInterpreterPythonImpl::IsReservedWord(const char *word) {
2893 if (!word || !word[0])
2894 return false;
2895
2896 llvm::StringRef word_sr(word);
2897
2898 // filter out a few characters that would just confuse us and that are
2899 // clearly not keyword material anyway
2900 if (word_sr.find('"') != llvm::StringRef::npos ||
2901 word_sr.find('\'') != llvm::StringRef::npos)
2902 return false;
2903
2904 StreamString command_stream;
2905 command_stream.Printf("keyword.iskeyword('%s')", word);
2906 bool result;
2907 ExecuteScriptOptions options;
2908 options.SetEnableIO(false);
2909 options.SetMaskoutErrors(true);
2910 options.SetSetLLDBGlobals(false);
2911 if (ExecuteOneLineWithReturn(command_stream.GetData(),
2913 &result, options))
2914 return result;
2915 return false;
2916}
2917
2920 : m_debugger_sp(debugger_sp), m_synch_wanted(synchro),
2921 m_old_asynch(debugger_sp->GetAsyncExecution()) {
2923 m_debugger_sp->SetAsyncExecution(false);
2925 m_debugger_sp->SetAsyncExecution(true);
2926}
2927
2929 if (m_synch_wanted != eScriptedCommandSynchronicityCurrentValue)
2930 m_debugger_sp->SetAsyncExecution(m_old_asynch);
2931}
2932
2934 const char *impl_function, llvm::StringRef args,
2935 ScriptedCommandSynchronicity synchronicity,
2937 const lldb_private::ExecutionContext &exe_ctx) {
2938 if (!impl_function) {
2939 error = Status::FromErrorString("no function to execute");
2940 return false;
2941 }
2942
2943 lldb::DebuggerSP debugger_sp = m_debugger.shared_from_this();
2944 lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx));
2945
2946 if (!debugger_sp.get()) {
2947 error = Status::FromErrorString("invalid Debugger pointer");
2948 return false;
2949 }
2950
2951 bool ret_val = false;
2952
2953 {
2954 Locker py_lock(this,
2956 (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN),
2958
2959 SynchronicityHandler synch_handler(debugger_sp, synchronicity);
2960
2961 std::string args_str = args.str();
2963 impl_function, m_dictionary_name.c_str(), debugger_sp, args_str.c_str(),
2964 cmd_retobj, exe_ctx_ref_sp);
2965 }
2966
2967 if (!ret_val)
2968 error = Status::FromErrorString("unable to execute script function");
2969 else if (cmd_retobj.GetStatus() == eReturnStatusFailed)
2970 return false;
2971
2972 error.Clear();
2973 return ret_val;
2975
2976/// In Python, a special attribute __doc__ contains the docstring for an object
2977/// (function, method, class, ...) if any is defined Otherwise, the attribute's
2978/// value is None.
2980 std::string &dest) {
2981 dest.clear();
2982
2983 if (!item || !*item)
2984 return false;
2985
2986 std::string command(item);
2987 command += ".__doc__";
2988
2989 // Python is going to point this to valid data if ExecuteOneLineWithReturn
2990 // returns successfully.
2991 char *result_ptr = nullptr;
2992
2995 &result_ptr, ExecuteScriptOptions().SetEnableIO(false))) {
2996 if (result_ptr)
2997 dest.assign(result_ptr);
2998 return true;
2999 }
3000
3001 StreamString str_stream;
3002 str_stream << "Function " << item
3003 << " was not found. Containing module might be missing.";
3004 dest = std::string(str_stream.GetString());
3006 return false;
3007}
3008
3009std::unique_ptr<ScriptInterpreterLocker>
3011 std::unique_ptr<ScriptInterpreterLocker> py_lock(new Locker(
3014 return py_lock;
3015}
3016
3019
3020 // RAII-based initialization which correctly handles multiple-initialization,
3021 // version- specific differences among Python 2 and Python 3, and saving and
3022 // restoring various other pieces of state that can get mucked with during
3023 // initialization.
3024 InitializePythonRAII initialize_guard;
3025
3027
3028 // Update the path python uses to search for modules to include the current
3029 // directory.
3030
3031 RunSimpleString("import sys");
3033
3034 // Don't denormalize paths when calling file_spec.GetPath(). On platforms
3035 // that use a backslash as the path separator, this will result in executing
3036 // python code containing paths with unescaped backslashes. But Python also
3037 // accepts forward slashes, so to make life easier we just use that.
3038 if (FileSpec file_spec = GetPythonDir())
3039 AddToSysPath(AddLocation::Beginning, file_spec.GetPath(false));
3040 if (FileSpec file_spec = HostInfo::GetShlibDir())
3041 AddToSysPath(AddLocation::Beginning, file_spec.GetPath(false));
3042
3043 RunSimpleString("sys.dont_write_bytecode = 1; import "
3044 "lldb.embedded_interpreter; from "
3045 "lldb.embedded_interpreter import run_python_interpreter; "
3046 "from lldb.embedded_interpreter import run_one_line");
3047
3048#if LLDB_USE_PYTHON_SET_INTERRUPT
3049 // Python will not just overwrite its internal SIGINT handler but also the
3050 // one from the process. Backup the current SIGINT handler to prevent that
3051 // Python deletes it.
3052 RestoreSignalHandlerScope save_sigint(SIGINT);
3053
3054 // Setup a default SIGINT signal handler that works the same way as the
3055 // normal Python REPL signal handler which raises a KeyboardInterrupt.
3056 // Also make sure to not pollute the user's REPL with the signal module nor
3057 // our utility function.
3058 RunSimpleString("def lldb_setup_sigint_handler():\n"
3059 " import signal;\n"
3060 " def signal_handler(sig, frame):\n"
3061 " raise KeyboardInterrupt()\n"
3062 " signal.signal(signal.SIGINT, signal_handler);\n"
3063 "lldb_setup_sigint_handler();\n"
3064 "del lldb_setup_sigint_handler\n");
3065#endif
3066}
3067
3069 std::string path) {
3070 std::string statement;
3071 if (location == AddLocation::Beginning) {
3072 statement.assign("sys.path.insert(0,\"");
3073 statement.append(path);
3074 statement.append("\")");
3075 } else {
3076 statement.assign("sys.path.append(\"");
3077 statement.append(path);
3078 statement.append("\")");
3079 }
3080 RunSimpleString(statement.c_str());
3081}
3082
3083// We are intentionally NOT calling Py_Finalize here (this would be the logical
3084// place to call it). Calling Py_Finalize here causes test suite runs to seg
3085// fault: The test suite runs in Python. It registers SBDebugger::Terminate to
3086// be called 'at_exit'. When the test suite Python harness finishes up, it
3087// calls Py_Finalize, which calls all the 'at_exit' registered functions.
3088// SBDebugger::Terminate calls Debugger::Terminate, which calls lldb::Terminate,
3089// which calls ScriptInterpreter::Terminate, which calls
3090// ScriptInterpreterPythonImpl::Terminate. So if we call Py_Finalize here, we
3091// end up with Py_Finalize being called from within Py_Finalize, which results
3092// in a seg fault. Since this function only gets called when lldb is shutting
3093// down and going away anyway, the fact that we don't actually call Py_Finalize
3094// should not cause any problems (everything should shut down/go away anyway
3095// when the process exits).
3096//
3097// 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 uniqued constant string class.
Definition ConstString.h:40
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:57
void AppendPathComponent(llvm::StringRef component)
Definition FileSpec.cpp:452
bool RemoveLastPathComponent()
Removes the last path component by replacing the current path with its parent.
Definition FileSpec.cpp:463
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:376
void SetDirectory(llvm::StringRef directory)
Directory string set accessor.
Definition FileSpec.cpp:354
llvm::StringRef GetFileNameExtension() const
Extract the extension of the file.
Definition FileSpec.cpp:408
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.
lldb::ValueObjectSP GetSyntheticValue(const StructuredData::ObjectSP &implementor) override
std::unique_ptr< ScriptInterpreterLocker > AcquireInterpreterLock() override
void CollectDataForBreakpointCommandCallback(std::vector< std::reference_wrapper< BreakpointOptions > > &bp_options_vec, CommandReturnObject &result) override
bool UpdateSynthProviderInstance(const StructuredData::ObjectSP &implementor) override
static void AddToSysPath(AddLocation location, std::string path)
bool MightHaveChildrenSynthProviderInstance(const StructuredData::ObjectSP &implementor) override
bool LoadScriptingModule(const char *filename, const LoadScriptOptions &options, lldb_private::Status &error, StructuredData::ObjectSP *module_sp=nullptr, FileSpec extra_search_dir={}, lldb::TargetSP loaded_into_target_sp={}) override
ConstString GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) override
Status GenerateBreakpointCommandCallbackData(StringList &input, std::string &output, bool has_extra_args, bool is_callback) override
lldb::OperatingSystemInterfaceSP CreateOperatingSystemInterface() override
llvm::Expected< uint32_t > GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor, const char *child_name) override
bool FormatterCallbackFunction(const char *function_name, lldb::TypeImplSP type_impl_sp) override
Status ExportFunctionDefinitionToInterpreter(StringList &function_def) override
StructuredData::ObjectSP CreateSyntheticScriptedProvider(const char *class_name, lldb::ValueObjectSP valobj) override
bool ExecuteOneLine(llvm::StringRef command, CommandReturnObject *result, const ExecuteScriptOptions &options=ExecuteScriptOptions()) override
bool GetDocumentationForItem(const char *item, std::string &dest) override
In Python, a special attribute doc contains the docstring for an object (function,...
lldb::ScriptedHookInterfaceSP CreateScriptedHookInterface() override
void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override
Called when a line or lines have been retrieved.
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
bool GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj, StructuredData::ObjectSP &callee_wrapper_sp, const TypeSummaryOptions &options, std::string &retval) override
lldb::ScriptedFrameInterfaceSP CreateScriptedFrameInterface() override
lldb::ScriptedProcessInterfaceUP CreateScriptedProcessInterface() override
size_t CalculateNumChildren(const StructuredData::ObjectSP &implementor, uint32_t max) override
bool ExecuteOneLineWithReturn(llvm::StringRef in_string, ScriptInterpreter::ScriptReturnType return_type, void *ret_value, const ExecuteScriptOptions &options=ExecuteScriptOptions()) override
lldb::ScriptedBreakpointInterfaceSP CreateScriptedBreakpointInterface() override
bool RunScriptFormatKeyword(const char *impl_function, Process *process, std::string &output, Status &error) override
bool SetStdHandle(lldb::FileSP file, const char *py_name, python::PythonObject &save_file, const char *mode, bool serialize_terminal_output)
Point sys.
lldb::ValueObjectSP GetChildAtIndex(const StructuredData::ObjectSP &implementor, uint32_t idx) override
bool GenerateTypeSynthClass(StringList &input, std::string &output, const void *name_token=nullptr) override
StructuredData::ObjectSP CreateStructuredDataFromScriptObject(ScriptObject obj) override
StructuredData::ObjectSP LoadPluginModule(const FileSpec &file_spec, lldb_private::Status &error) override
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:1326
WatchpointList & GetWatchpointList()
Definition Target.h:955
"lldb/Core/ThreadedCommunication.h" Variation of Communication that supports threaded reads.
lldb::ValueObjectSP GetSP()
lldb::WatchpointSP FindByID(lldb::watch_id_t watchID) const
Returns a shared pointer to the watchpoint with id watchID, const version.
"lldb/Breakpoint/WatchpointOptions.h" Class that manages the options on a watchpoint.
void SetCallback(WatchpointHitCallback callback, const lldb::BatonSP &baton_sp, bool synchronous=false)
Adds a callback to the watchpoint option set.
StructuredData::DictionarySP CreateStructuredDictionary() const
PythonObject GetItemForKey(const PythonObject &key) const
void SetItemForKey(const PythonObject &key, const PythonObject &value)
static llvm::Expected< PythonFile > FromFile(File &file, const char *mode=nullptr)
static 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 Check(PyObject *py_obj)
static bool LLDBSWIGPythonRunScriptKeywordValue(const char *python_function_name, const char *session_dictionary_name, const lldb::ValueObjectSP &value, std::string &output)
static bool LLDBSwigPythonCallTypeScript(const char *python_function_name, const void *session_dictionary, const lldb::ValueObjectSP &valobj_sp, void **pyfunct_wrapper, const lldb::TypeSummaryOptionsSP &options_sp, std::string &retval)
static void * LLDBSWIGPython_GetDynamicSetting(void *module, const char *setting, const lldb::TargetSP &target_sp)
static lldb::ValueObjectSP LLDBSWIGPython_GetValueObjectSPFromSBValue(void *data)
static std::optional< std::string > LLDBSWIGPythonRunScriptKeywordThread(const char *python_function_name, const char *session_dictionary_name, lldb::ThreadSP thread)
static bool LLDBSwigPythonCallCommand(const char *python_function_name, const char *session_dictionary_name, lldb::DebuggerSP debugger, const char *args, lldb_private::CommandReturnObject &cmd_retobj, lldb::ExecutionContextRefSP exe_ctx_ref_sp)
static PyObject * LLDBSwigPython_GetValueSynthProviderInstance(PyObject *implementor)
static bool LLDBSwigPython_UpdateSynthProviderInstance(PyObject *implementor)
static bool LLDBSWIGPythonRunScriptKeywordTarget(const char *python_function_name, const char *session_dictionary_name, const lldb::TargetSP &target, std::string &output)
static uint32_t LLDBSwigPython_GetIndexOfChildWithName(PyObject *implementor, const char *child_name)
static std::optional< std::string > LLDBSWIGPythonRunScriptKeywordFrame(const char *python_function_name, const char *session_dictionary_name, lldb::StackFrameSP frame)
static PyObject * LLDBSwigPython_GetChildAtIndex(PyObject *implementor, uint32_t idx)
static bool LLDBSWIGPythonRunScriptKeywordProcess(const char *python_function_name, const char *session_dictionary_name, const lldb::ProcessSP &process, std::string &output)
static bool LLDBSwigPythonFormatterCallbackFunction(const char *python_function_name, const char *session_dictionary_name, lldb::TypeImplSP type_impl_sp)
static bool LLDBSwigPythonCallModuleInit(const char *python_module_name, const char *session_dictionary_name, lldb::DebuggerSP debugger)
static python::PythonObject LLDBSwigPythonCreateSyntheticProvider(const char *python_class_name, const char *session_dictionary_name, const lldb::ValueObjectSP &valobj_sp)
static bool LLDBSwigPythonWatchpointCallbackFunction(const char *python_function_name, const char *session_dictionary_name, const lldb::StackFrameSP &sb_frame, const lldb::WatchpointSP &sb_wp)
static size_t LLDBSwigPython_CalculateNumChildren(PyObject *implementor, uint32_t max)
static bool LLDBSwigPython_MightHaveChildrenSynthProviderInstance(PyObject *implementor)
static bool LLDBSwigPythonCallModuleNewTarget(const char *python_module_name, const char *session_dictionary_name, lldb::TargetSP target)
static llvm::Expected< bool > LLDBSwigPythonBreakpointCallbackFunction(const char *python_function_name, const char *session_dictionary_name, const lldb::StackFrameSP &sb_frame, const lldb::BreakpointLocationSP &sb_bp_loc, const lldb_private::StructuredDataImpl &args_impl)
#define UINT32_MAX
llvm::Expected< T > As(llvm::Expected< PythonObject > &&obj)
T unwrapIgnoringErrors(llvm::Expected< T > expected)
llvm::Expected< PythonObject > runStringMultiLine(const llvm::Twine &string, const PythonDictionary &globals, const PythonDictionary &locals)
int RunSimpleString(const char *str)
void * LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data)
llvm::Expected< PythonObject > runStringOneLine(const llvm::Twine &string, const PythonDictionary &globals, const PythonDictionary &locals)
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
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
@ eScriptedExtensionScriptedFrameProvider
@ eScriptedExtensionScriptedThread
@ eScriptedExtensionScriptedStackFrameRecognizer
@ eScriptedExtensionInvalid
std::shared_ptr< lldb_private::ScriptedHookInterface > ScriptedHookInterfaceSP
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
std::shared_ptr< lldb_private::BreakpointLocation > BreakpointLocationSP
std::shared_ptr< lldb_private::IOHandler > IOHandlerSP
std::shared_ptr< lldb_private::ScriptInterpreter > ScriptInterpreterSP
std::shared_ptr< lldb_private::ScriptedThreadPlanInterface > ScriptedThreadPlanInterfaceSP
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
std::unique_ptr< lldb_private::File > FileUP
std::shared_ptr< lldb_private::TypeSummaryOptions > TypeSummaryOptionsSP
std::shared_ptr< lldb_private::OperatingSystemInterface > OperatingSystemInterfaceSP
std::shared_ptr< lldb_private::Breakpoint > BreakpointSP
std::shared_ptr< lldb_private::ScriptedBreakpointInterface > ScriptedBreakpointInterfaceSP
std::shared_ptr< lldb_private::ScriptedThreadInterface > ScriptedThreadInterfaceSP
std::shared_ptr< lldb_private::Debugger > DebuggerSP
@ 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:82
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