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/Host/Config.h"
10
11#if LLDB_ENABLE_PYTHON
12
13// LLDB Python header must be included first
14#include "lldb-python.h"
15
17#include "PythonDataObjects.h"
18#include "PythonReadline.h"
19#include "SWIGPythonBridge.h"
21
22#include "lldb/API/SBError.h"
24#include "lldb/API/SBFrame.h"
25#include "lldb/API/SBValue.h"
28#include "lldb/Core/Debugger.h"
33#include "lldb/Host/HostInfo.h"
34#include "lldb/Host/Pipe.h"
38#include "lldb/Target/Thread.h"
42#include "lldb/Utility/Timer.h"
45#include "lldb/lldb-forward.h"
46#include "llvm/ADT/STLExtras.h"
47#include "llvm/ADT/StringRef.h"
48#include "llvm/Support/Error.h"
49#include "llvm/Support/FileSystem.h"
50#include "llvm/Support/FormatAdapters.h"
51
52#include <cstdio>
53#include <cstdlib>
54#include <memory>
55#include <mutex>
56#include <optional>
57#include <string>
58
59using namespace lldb;
60using namespace lldb_private;
61using namespace lldb_private::python;
62using llvm::Expected;
63
64LLDB_PLUGIN_DEFINE(ScriptInterpreterPython)
65
66// Defined in the SWIG source file
67extern "C" PyObject *PyInit__lldb(void);
68
69#define LLDBSwigPyInit PyInit__lldb
70
71#if defined(_WIN32)
72// Don't mess with the signal handlers on Windows.
73#define LLDB_USE_PYTHON_SET_INTERRUPT 0
74#else
75#define LLDB_USE_PYTHON_SET_INTERRUPT 1
76#endif
77
78static ScriptInterpreterPythonImpl *GetPythonInterpreter(Debugger &debugger) {
79 ScriptInterpreter *script_interpreter =
81 return static_cast<ScriptInterpreterPythonImpl *>(script_interpreter);
82}
83
84namespace {
85
86// Initializing Python is not a straightforward process. We cannot control
87// what external code may have done before getting to this point in LLDB,
88// including potentially having already initialized Python, so we need to do a
89// lot of work to ensure that the existing state of the system is maintained
90// across our initialization. We do this by using an RAII pattern where we
91// save off initial state at the beginning, and restore it at the end
92struct InitializePythonRAII {
93public:
94 InitializePythonRAII() {
95 // The table of built-in modules can only be extended before Python is
96 // initialized.
97 if (!Py_IsInitialized()) {
98#ifdef LLDB_USE_LIBEDIT_READLINE_COMPAT_MODULE
99 // Python's readline is incompatible with libedit being linked into lldb.
100 // Provide a patched version local to the embedded interpreter.
101 PyImport_AppendInittab("readline", initlldb_readline);
102#endif
103
104 // Register _lldb as a built-in module.
105 PyImport_AppendInittab("_lldb", LLDBSwigPyInit);
106 }
107
108#if LLDB_EMBED_PYTHON_HOME
109 PyConfig config;
110 PyConfig_InitPythonConfig(&config);
111
112 static std::string g_python_home = []() -> std::string {
113 if (llvm::sys::path::is_absolute(LLDB_PYTHON_HOME))
114 return LLDB_PYTHON_HOME;
115
116 FileSpec spec = HostInfo::GetShlibDir();
117 if (!spec)
118 return {};
119 spec.AppendPathComponent(LLDB_PYTHON_HOME);
120 return spec.GetPath();
121 }();
122 if (!g_python_home.empty()) {
123 PyConfig_SetBytesString(&config, &config.home, g_python_home.c_str());
124 }
125
126 config.install_signal_handlers = 0;
127 Py_InitializeFromConfig(&config);
128 PyConfig_Clear(&config);
129#else
130 Py_InitializeEx(/*install_sigs=*/0);
131#endif
132
133 // The only case we should go further and acquire the GIL: it is unlocked.
134 PyGILState_STATE gil_state = PyGILState_Ensure();
135 if (gil_state != PyGILState_UNLOCKED)
136 return;
137
138 m_was_already_initialized = true;
139 m_gil_state = gil_state;
140 LLDB_LOGV(GetLog(LLDBLog::Script),
141 "Ensured PyGILState. Previous state = {0}",
142 m_gil_state == PyGILState_UNLOCKED ? "unlocked" : "locked");
143 }
144
145 ~InitializePythonRAII() {
146 if (m_was_already_initialized) {
147 LLDB_LOGV(GetLog(LLDBLog::Script),
148 "Releasing PyGILState. Returning to state = {0}",
149 m_gil_state == PyGILState_UNLOCKED ? "unlocked" : "locked");
150 PyGILState_Release(m_gil_state);
151 } else {
152 // We initialized the threads in this function, just unlock the GIL.
153 PyEval_SaveThread();
154 }
155 }
156
157private:
158 PyGILState_STATE m_gil_state = PyGILState_UNLOCKED;
159 bool m_was_already_initialized = false;
160};
161
162#if LLDB_USE_PYTHON_SET_INTERRUPT
163/// Saves the current signal handler for the specified signal and restores
164/// it at the end of the current scope.
165struct RestoreSignalHandlerScope {
166 /// The signal handler.
167 struct sigaction m_prev_handler;
168 int m_signal_code;
169 RestoreSignalHandlerScope(int signal_code) : m_signal_code(signal_code) {
170 // Initialize sigaction to their default state.
171 std::memset(&m_prev_handler, 0, sizeof(m_prev_handler));
172 // Don't install a new handler, just read back the old one.
173 struct sigaction *new_handler = nullptr;
174 int signal_err = ::sigaction(m_signal_code, new_handler, &m_prev_handler);
175 lldbassert(signal_err == 0 && "sigaction failed to read handler");
176 }
177 ~RestoreSignalHandlerScope() {
178 int signal_err = ::sigaction(m_signal_code, &m_prev_handler, nullptr);
179 lldbassert(signal_err == 0 && "sigaction failed to restore old handler");
180 }
181};
182#endif
183} // namespace
184
185void ScriptInterpreterPython::ComputePythonDirForApple(
187 auto style = llvm::sys::path::Style::posix;
188
189 llvm::StringRef path_ref(path.begin(), path.size());
190 auto rbegin = llvm::sys::path::rbegin(path_ref, style);
191 auto rend = llvm::sys::path::rend(path_ref);
192 auto framework = std::find(rbegin, rend, "LLDB.framework");
193 if (framework == rend) {
194 ComputePythonDir(path);
195 return;
196 }
197 path.resize(framework - rend);
198 llvm::sys::path::append(path, style, "LLDB.framework", "Resources", "Python");
199}
200
201void ScriptInterpreterPython::ComputePythonDir(
203 // Build the path by backing out of the lib dir, then building with whatever
204 // the real python interpreter uses. (e.g. lib for most, lib64 on RHEL
205 // x86_64, or bin on Windows).
206 llvm::sys::path::remove_filename(path);
207 llvm::sys::path::append(path, LLDB_PYTHON_RELATIVE_LIBDIR);
208
209#if defined(_WIN32)
210 // This will be injected directly through FileSpec.SetDirectory(),
211 // so we need to normalize manually.
212 std::replace(path.begin(), path.end(), '\\', '/');
213#endif
214}
215
216FileSpec ScriptInterpreterPython::GetPythonDir() {
217 static FileSpec g_spec = []() {
218 FileSpec spec = HostInfo::GetShlibDir();
219 if (!spec)
220 return FileSpec();
221 llvm::SmallString<64> path;
222 spec.GetPath(path);
223
224#if defined(__APPLE__)
225 ComputePythonDirForApple(path);
226#else
227 ComputePythonDir(path);
228#endif
229 spec.SetDirectory(path);
230 return spec;
231 }();
232 return g_spec;
233}
234
235static const char GetInterpreterInfoScript[] = R"(
236import os
237import sys
238
239def main(lldb_python_dir, python_exe_relative_path):
240 info = {
241 "lldb-pythonpath": lldb_python_dir,
242 "language": "python",
243 "prefix": sys.prefix,
244 "executable": os.path.join(sys.prefix, python_exe_relative_path)
245 }
246 return info
247)";
248
249static const char python_exe_relative_path[] = LLDB_PYTHON_EXE_RELATIVE_PATH;
250
251StructuredData::DictionarySP ScriptInterpreterPython::GetInterpreterInfo() {
252 GIL gil;
253 FileSpec python_dir_spec = GetPythonDir();
254 if (!python_dir_spec)
255 return nullptr;
256 PythonScript get_info(GetInterpreterInfoScript);
257 auto info_json = unwrapIgnoringErrors(
258 As<PythonDictionary>(get_info(PythonString(python_dir_spec.GetPath()),
259 PythonString(python_exe_relative_path))));
260 if (!info_json)
261 return nullptr;
262 return info_json.CreateStructuredDictionary();
263}
264
265void ScriptInterpreterPython::SharedLibraryDirectoryHelper(
266 FileSpec &this_file) {
267 // When we're loaded from python, this_file will point to the file inside the
268 // python package directory. Replace it with the one in the lib directory.
269#ifdef _WIN32
270 // On windows, we need to manually back out of the python tree, and go into
271 // the bin directory. This is pretty much the inverse of what ComputePythonDir
272 // does.
273 if (this_file.GetFileNameExtension() == ".pyd") {
274 this_file.RemoveLastPathComponent(); // _lldb.pyd or _lldb_d.pyd
275 this_file.RemoveLastPathComponent(); // lldb
276 llvm::StringRef libdir = LLDB_PYTHON_RELATIVE_LIBDIR;
277 for (auto it = llvm::sys::path::begin(libdir),
278 end = llvm::sys::path::end(libdir);
279 it != end; ++it)
280 this_file.RemoveLastPathComponent();
281 this_file.AppendPathComponent("bin");
282 this_file.AppendPathComponent("liblldb.dll");
283 }
284#else
285 // The python file is a symlink, so we can find the real library by resolving
286 // it. We can do this unconditionally.
287 FileSystem::Instance().ResolveSymbolicLink(this_file, this_file);
288#endif
289}
290
291llvm::StringRef ScriptInterpreterPython::GetPluginDescriptionStatic() {
292 return "Embedded Python interpreter";
293}
294
295void ScriptInterpreterPython::Initialize() {
296 static llvm::once_flag g_once_flag;
297 llvm::call_once(g_once_flag, []() {
298 PluginManager::RegisterPlugin(GetPluginNameStatic(),
299 GetPluginDescriptionStatic(),
301 ScriptInterpreterPythonImpl::CreateInstance);
302 ScriptInterpreterPythonImpl::Initialize();
303 });
304}
305
306void ScriptInterpreterPython::Terminate() {}
307
308ScriptInterpreterPythonImpl::Locker::Locker(
309 ScriptInterpreterPythonImpl *py_interpreter, uint16_t on_entry,
310 uint16_t on_leave, FileSP in, FileSP out, FileSP err)
312 m_teardown_session((on_leave & TearDownSession) == TearDownSession),
313 m_python_interpreter(py_interpreter) {
314 DoAcquireLock();
315 if ((on_entry & InitSession) == InitSession) {
316 if (!DoInitSession(on_entry, in, out, err)) {
317 // Don't teardown the session if we didn't init it.
318 m_teardown_session = false;
319 }
320 }
321}
322
323bool ScriptInterpreterPythonImpl::Locker::DoAcquireLock() {
324 m_GILState = PyGILState_Ensure();
325 LLDB_LOGV(GetLog(LLDBLog::Script), "Ensured PyGILState. Previous state = {0}",
326 m_GILState == PyGILState_UNLOCKED ? "unlocked" : "locked");
327
328 // we need to save the thread state when we first start the command because
329 // we might decide to interrupt it while some action is taking place outside
330 // of Python (e.g. printing to screen, waiting for the network, ...) in that
331 // case, _PyThreadState_Current will be NULL - and we would be unable to set
332 // the asynchronous exception - not a desirable situation
333 m_python_interpreter->SetThreadState(PyThreadState_Get());
334 m_python_interpreter->IncrementLockCount();
335 return true;
336}
337
338bool ScriptInterpreterPythonImpl::Locker::DoInitSession(uint16_t on_entry_flags,
339 FileSP in, FileSP out,
340 FileSP err) {
341 if (!m_python_interpreter)
342 return false;
343 return m_python_interpreter->EnterSession(on_entry_flags, in, out, err);
344}
345
346bool ScriptInterpreterPythonImpl::Locker::DoFreeLock() {
348 "Releasing PyGILState. Returning to state = {0}",
349 m_GILState == PyGILState_UNLOCKED ? "unlocked" : "locked");
350 PyGILState_Release(m_GILState);
351 m_python_interpreter->DecrementLockCount();
352 return true;
353}
354
355bool ScriptInterpreterPythonImpl::Locker::DoTearDownSession() {
356 if (!m_python_interpreter)
357 return false;
358 m_python_interpreter->LeaveSession();
359 return true;
360}
361
362ScriptInterpreterPythonImpl::Locker::~Locker() {
363 if (m_teardown_session)
364 DoTearDownSession();
365 DoFreeLock();
366}
367
368ScriptInterpreterPythonImpl::ScriptInterpreterPythonImpl(Debugger &debugger)
369 : ScriptInterpreterPython(debugger), m_saved_stdin(), m_saved_stdout(),
370 m_saved_stderr(), m_main_module(),
371 m_session_dict(PyInitialValue::Invalid),
372 m_sys_module_dict(PyInitialValue::Invalid), m_run_one_line_function(),
373 m_run_one_line_str_global(),
374 m_dictionary_name(m_debugger.GetInstanceName()),
375 m_active_io_handler(eIOHandlerNone), m_session_is_active(false),
376 m_pty_secondary_is_open(false), m_valid_session(true), m_lock_count(0),
377 m_command_thread_state(nullptr) {
378
379 m_dictionary_name.append("_dict");
380 StreamString run_string;
381 run_string.Printf("%s = dict()", m_dictionary_name.c_str());
382
383 Locker locker(this, Locker::AcquireLock, Locker::FreeAcquiredLock);
384 RunSimpleString(run_string.GetData());
385
386 run_string.Clear();
387 run_string.Printf(
388 "run_one_line (%s, 'import copy, keyword, os, re, sys, uuid, lldb')",
389 m_dictionary_name.c_str());
390 RunSimpleString(run_string.GetData());
391
392 // Reloading modules requires a different syntax in Python 2 and Python 3.
393 // This provides a consistent syntax no matter what version of Python.
394 run_string.Clear();
395 run_string.Printf(
396 "run_one_line (%s, 'from importlib import reload as reload_module')",
397 m_dictionary_name.c_str());
398 RunSimpleString(run_string.GetData());
399
400 // WARNING: temporary code that loads Cocoa formatters - this should be done
401 // on a per-platform basis rather than loading the whole set and letting the
402 // individual formatter classes exploit APIs to check whether they can/cannot
403 // do their task
404 run_string.Clear();
405 run_string.Printf(
406 "run_one_line (%s, 'import lldb.formatters, lldb.formatters.cpp')",
407 m_dictionary_name.c_str());
408 RunSimpleString(run_string.GetData());
409 run_string.Clear();
410
411 run_string.Printf("run_one_line (%s, 'import lldb.embedded_interpreter; from "
412 "lldb.embedded_interpreter import run_python_interpreter; "
413 "from lldb.embedded_interpreter import run_one_line')",
414 m_dictionary_name.c_str());
415 RunSimpleString(run_string.GetData());
416 run_string.Clear();
417
418 run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64
419 "')",
420 m_dictionary_name.c_str(), m_debugger.GetID());
421 RunSimpleString(run_string.GetData());
422}
423
424ScriptInterpreterPythonImpl::~ScriptInterpreterPythonImpl() {
425 // the session dictionary may hold objects with complex state which means
426 // that they may need to be torn down with some level of smarts and that, in
427 // turn, requires a valid thread state force Python to procure itself such a
428 // thread state, nuke the session dictionary and then release it for others
429 // to use and proceed with the rest of the shutdown
430 auto gil_state = PyGILState_Ensure();
431 m_session_dict.Reset();
432 PyGILState_Release(gil_state);
433}
434
435void ScriptInterpreterPythonImpl::IOHandlerActivated(IOHandler &io_handler,
436 bool interactive) {
437 const char *instructions = nullptr;
438
439 switch (m_active_io_handler) {
440 case eIOHandlerNone:
441 break;
443 instructions = R"(Enter your Python command(s). Type 'DONE' to end.
444def function (frame, bp_loc, internal_dict):
445 """frame: the lldb.SBFrame for the location at which you stopped
446 bp_loc: an lldb.SBBreakpointLocation for the breakpoint location information
447 internal_dict: an LLDB support object not to be used"""
448)";
449 break;
451 instructions = "Enter your Python command(s). Type 'DONE' to end.\n";
452 break;
453 }
454
455 if (instructions && interactive) {
456 if (LockableStreamFileSP stream_sp = io_handler.GetOutputStreamFileSP()) {
457 LockedStreamFile locked_stream = stream_sp->Lock();
458 locked_stream.PutCString(instructions);
459 locked_stream.Flush();
460 }
461 }
462}
463
464void ScriptInterpreterPythonImpl::IOHandlerInputComplete(IOHandler &io_handler,
465 std::string &data) {
466 io_handler.SetIsDone(true);
467 bool batch_mode = m_debugger.GetCommandInterpreter().GetBatchCommandMode();
468
469 switch (m_active_io_handler) {
470 case eIOHandlerNone:
471 break;
473 std::vector<std::reference_wrapper<BreakpointOptions>> *bp_options_vec =
474 (std::vector<std::reference_wrapper<BreakpointOptions>> *)
475 io_handler.GetUserData();
476 for (BreakpointOptions &bp_options : *bp_options_vec) {
477
478 auto data_up = std::make_unique<CommandDataPython>();
479 if (!data_up)
480 break;
481 data_up->user_source.SplitIntoLines(data);
482
483 if (GenerateBreakpointCommandCallbackData(data_up->user_source,
484 data_up->script_source,
485 /*has_extra_args=*/false,
486 /*is_callback=*/false)
487 .Success()) {
488 auto baton_sp = std::make_shared<BreakpointOptions::CommandBaton>(
489 std::move(data_up));
490 bp_options.SetCallback(
491 ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp);
492 } else if (!batch_mode) {
493 if (LockableStreamFileSP error_sp = io_handler.GetErrorStreamFileSP()) {
494 LockedStreamFile locked_stream = error_sp->Lock();
495 locked_stream.Printf("Warning: No command attached to breakpoint.\n");
496 }
497 }
498 }
499 m_active_io_handler = eIOHandlerNone;
500 } break;
502 WatchpointOptions *wp_options =
503 (WatchpointOptions *)io_handler.GetUserData();
504 auto data_up = std::make_unique<WatchpointOptions::CommandData>();
505 data_up->user_source.SplitIntoLines(data);
506
507 if (GenerateWatchpointCommandCallbackData(data_up->user_source,
508 data_up->script_source,
509 /*is_callback=*/false)) {
510 auto baton_sp =
511 std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up));
512 wp_options->SetCallback(
513 ScriptInterpreterPythonImpl::WatchpointCallbackFunction, baton_sp);
514 } else if (!batch_mode) {
515 if (LockableStreamFileSP error_sp = io_handler.GetErrorStreamFileSP()) {
516 LockedStreamFile locked_stream = error_sp->Lock();
517 locked_stream.Printf("Warning: No command attached to breakpoint.\n");
518 }
519 }
520 m_active_io_handler = eIOHandlerNone;
521 } break;
522 }
523}
524
526ScriptInterpreterPythonImpl::CreateInstance(Debugger &debugger) {
527 return std::make_shared<ScriptInterpreterPythonImpl>(debugger);
528}
529
530void ScriptInterpreterPythonImpl::LeaveSession() {
531 Log *log = GetLog(LLDBLog::Script);
532 if (log)
533 log->PutCString("ScriptInterpreterPythonImpl::LeaveSession()");
534
535 // Unset the LLDB global variables.
536 RunSimpleString("lldb.debugger = None; lldb.target = None; lldb.process "
537 "= None; lldb.thread = None; lldb.frame = None");
538
539 // checking that we have a valid thread state - since we use our own
540 // threading and locking in some (rare) cases during cleanup Python may end
541 // up believing we have no thread state and PyImport_AddModule will crash if
542 // that is the case - since that seems to only happen when destroying the
543 // SBDebugger, we can make do without clearing up stdout and stderr
544 if (PyThreadState_GetDict()) {
545 PythonDictionary &sys_module_dict = GetSysModuleDictionary();
546 if (sys_module_dict.IsValid()) {
547 if (m_saved_stdin.IsValid()) {
548 sys_module_dict.SetItemForKey(PythonString("stdin"), m_saved_stdin);
549 m_saved_stdin.Reset();
550 }
551 if (m_saved_stdout.IsValid()) {
552 sys_module_dict.SetItemForKey(PythonString("stdout"), m_saved_stdout);
553 m_saved_stdout.Reset();
554 }
555 if (m_saved_stderr.IsValid()) {
556 sys_module_dict.SetItemForKey(PythonString("stderr"), m_saved_stderr);
557 m_saved_stderr.Reset();
558 }
559 }
560 }
561
562 m_session_is_active = false;
563}
564
565bool ScriptInterpreterPythonImpl::SetStdHandle(FileSP file_sp,
566 const char *py_name,
567 PythonObject &save_file,
568 const char *mode) {
569 if (!file_sp || !*file_sp) {
570 save_file.Reset();
571 return false;
572 }
573 File &file = *file_sp;
574
575 // Flush the file before giving it to python to avoid interleaved output.
576 file.Flush();
577
578 PythonDictionary &sys_module_dict = GetSysModuleDictionary();
579
580 auto new_file = PythonFile::FromFile(file, mode);
581 if (!new_file) {
582 llvm::consumeError(new_file.takeError());
583 return false;
584 }
585
586 save_file = sys_module_dict.GetItemForKey(PythonString(py_name));
587
588 sys_module_dict.SetItemForKey(PythonString(py_name), new_file.get());
589 return true;
590}
591
592bool ScriptInterpreterPythonImpl::EnterSession(uint16_t on_entry_flags,
593 FileSP in_sp, FileSP out_sp,
594 FileSP err_sp) {
595 // If we have already entered the session, without having officially 'left'
596 // it, then there is no need to 'enter' it again.
597 Log *log = GetLog(LLDBLog::Script);
598 if (m_session_is_active) {
599 LLDB_LOGF(
600 log,
601 "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16
602 ") session is already active, returning without doing anything",
603 on_entry_flags);
604 return false;
605 }
606
607 LLDB_LOGF(
608 log,
609 "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16 ")",
610 on_entry_flags);
611
612 m_session_is_active = true;
613
614 StreamString run_string;
615
616 if (on_entry_flags & Locker::InitGlobals) {
617 run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64,
618 m_dictionary_name.c_str(), m_debugger.GetID());
619 run_string.Printf(
620 "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64 ")",
621 m_debugger.GetID());
622 run_string.PutCString("; lldb.target = lldb.debugger.GetSelectedTarget()");
623 run_string.PutCString("; lldb.process = lldb.target.GetProcess()");
624 run_string.PutCString("; lldb.thread = lldb.process.GetSelectedThread ()");
625 run_string.PutCString("; lldb.frame = lldb.thread.GetSelectedFrame ()");
626 run_string.PutCString("')");
627 } else {
628 // If we aren't initing the globals, we should still always set the
629 // debugger (since that is always unique.)
630 run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64,
631 m_dictionary_name.c_str(), m_debugger.GetID());
632 run_string.Printf(
633 "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64 ")",
634 m_debugger.GetID());
635 run_string.PutCString("')");
636 }
637
638 RunSimpleString(run_string.GetData());
639 run_string.Clear();
640
641 PythonDictionary &sys_module_dict = GetSysModuleDictionary();
642 if (sys_module_dict.IsValid()) {
643 lldb::FileSP top_in_sp;
644 lldb::LockableStreamFileSP top_out_sp, top_err_sp;
645 if (!in_sp || !out_sp || !err_sp || !*in_sp || !*out_sp || !*err_sp)
646 m_debugger.AdoptTopIOHandlerFilesIfInvalid(top_in_sp, top_out_sp,
647 top_err_sp);
648
649 if (on_entry_flags & Locker::NoSTDIN) {
650 m_saved_stdin.Reset();
651 } else {
652 if (!SetStdHandle(in_sp, "stdin", m_saved_stdin, "r")) {
653 if (top_in_sp)
654 SetStdHandle(top_in_sp, "stdin", m_saved_stdin, "r");
655 }
656 }
657
658 if (!SetStdHandle(out_sp, "stdout", m_saved_stdout, "w")) {
659 if (top_out_sp)
660 SetStdHandle(top_out_sp->GetUnlockedFileSP(), "stdout", m_saved_stdout,
661 "w");
662 }
663
664 if (!SetStdHandle(err_sp, "stderr", m_saved_stderr, "w")) {
665 if (top_err_sp)
666 SetStdHandle(top_err_sp->GetUnlockedFileSP(), "stderr", m_saved_stderr,
667 "w");
668 }
669 }
670
671 if (PyErr_Occurred())
672 PyErr_Clear();
673
674 return true;
675}
676
677PythonModule &ScriptInterpreterPythonImpl::GetMainModule() {
678 if (!m_main_module.IsValid())
679 m_main_module = unwrapIgnoringErrors(PythonModule::Import("__main__"));
680 return m_main_module;
681}
682
683PythonDictionary &ScriptInterpreterPythonImpl::GetSessionDictionary() {
684 if (m_session_dict.IsValid())
685 return m_session_dict;
686
687 PythonObject &main_module = GetMainModule();
688 if (!main_module.IsValid())
689 return m_session_dict;
690
691 PythonDictionary main_dict(PyRefType::Borrowed,
692 PyModule_GetDict(main_module.get()));
693 if (!main_dict.IsValid())
694 return m_session_dict;
695
696 m_session_dict = unwrapIgnoringErrors(
697 As<PythonDictionary>(main_dict.GetItem(m_dictionary_name)));
698 return m_session_dict;
699}
700
701PythonDictionary &ScriptInterpreterPythonImpl::GetSysModuleDictionary() {
702 if (m_sys_module_dict.IsValid())
703 return m_sys_module_dict;
704 PythonModule sys_module = unwrapIgnoringErrors(PythonModule::Import("sys"));
705 m_sys_module_dict = sys_module.GetDictionary();
706 return m_sys_module_dict;
707}
708
709llvm::Expected<unsigned>
710ScriptInterpreterPythonImpl::GetMaxPositionalArgumentsForCallable(
711 const llvm::StringRef &callable_name) {
712 if (callable_name.empty()) {
713 return llvm::createStringError(llvm::inconvertibleErrorCode(),
714 "called with empty callable name.");
715 }
716 Locker py_lock(this,
717 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
718 auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
719 m_dictionary_name);
720 auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
721 callable_name, dict);
722 if (!pfunc.IsAllocated()) {
723 return llvm::createStringError(llvm::inconvertibleErrorCode(),
724 "can't find callable: %s",
725 callable_name.str().c_str());
726 }
727 llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
728 if (!arg_info)
729 return arg_info.takeError();
730 return arg_info.get().max_positional_args;
731}
732
733static std::string GenerateUniqueName(const char *base_name_wanted,
734 uint32_t &functions_counter,
735 const void *name_token = nullptr) {
736 StreamString sstr;
737
738 if (!base_name_wanted)
739 return std::string();
740
741 if (!name_token)
742 sstr.Printf("%s_%d", base_name_wanted, functions_counter++);
743 else
744 sstr.Printf("%s_%p", base_name_wanted, name_token);
745
746 return std::string(sstr.GetString());
747}
748
749bool ScriptInterpreterPythonImpl::GetEmbeddedInterpreterModuleObjects() {
750 if (m_run_one_line_function.IsValid())
751 return true;
752
753 PythonObject module(PyRefType::Borrowed,
754 PyImport_AddModule("lldb.embedded_interpreter"));
755 if (!module.IsValid())
756 return false;
757
758 PythonDictionary module_dict(PyRefType::Borrowed,
759 PyModule_GetDict(module.get()));
760 if (!module_dict.IsValid())
761 return false;
762
763 m_run_one_line_function =
764 module_dict.GetItemForKey(PythonString("run_one_line"));
765 m_run_one_line_str_global =
766 module_dict.GetItemForKey(PythonString("g_run_one_line_str"));
767 return m_run_one_line_function.IsValid();
768}
769
770bool ScriptInterpreterPythonImpl::ExecuteOneLine(
771 llvm::StringRef command, CommandReturnObject *result,
772 const ExecuteScriptOptions &options) {
773 std::string command_str = command.str();
774
775 if (!m_valid_session)
776 return false;
777
778 if (!command.empty()) {
779 // We want to call run_one_line, passing in the dictionary and the command
780 // string. We cannot do this through RunSimpleString here because the
781 // command string may contain escaped characters, and putting it inside
782 // another string to pass to RunSimpleString messes up the escaping. So
783 // we use the following more complicated method to pass the command string
784 // directly down to Python.
785 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
786 io_redirect_or_error = ScriptInterpreterIORedirect::Create(
787 options.GetEnableIO(), m_debugger, result);
788 if (!io_redirect_or_error) {
789 if (result)
791 "failed to redirect I/O: {0}\n",
792 llvm::fmt_consume(io_redirect_or_error.takeError()));
793 else
794 llvm::consumeError(io_redirect_or_error.takeError());
795 return false;
796 }
797
798 ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
799
800 bool success = false;
801 {
802 // WARNING! It's imperative that this RAII scope be as tight as
803 // possible. In particular, the scope must end *before* we try to join
804 // the read thread. The reason for this is that a pre-requisite for
805 // joining the read thread is that we close the write handle (to break
806 // the pipe and cause it to wake up and exit). But acquiring the GIL as
807 // below will redirect Python's stdio to use this same handle. If we
808 // close the handle while Python is still using it, bad things will
809 // happen.
810 Locker locker(
811 this,
812 Locker::AcquireLock | Locker::InitSession |
813 (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) |
814 ((result && result->GetInteractive()) ? 0 : Locker::NoSTDIN),
815 Locker::FreeAcquiredLock | Locker::TearDownSession,
816 io_redirect.GetInputFile(), io_redirect.GetOutputFile(),
817 io_redirect.GetErrorFile());
818
819 // Find the correct script interpreter dictionary in the main module.
820 PythonDictionary &session_dict = GetSessionDictionary();
821 if (session_dict.IsValid()) {
822 if (GetEmbeddedInterpreterModuleObjects()) {
823 if (PyCallable_Check(m_run_one_line_function.get())) {
824 PythonObject pargs(
825 PyRefType::Owned,
826 Py_BuildValue("(Os)", session_dict.get(), command_str.c_str()));
827 if (pargs.IsValid()) {
828 PythonObject return_value(
829 PyRefType::Owned,
830 PyObject_CallObject(m_run_one_line_function.get(),
831 pargs.get()));
832 if (return_value.IsValid())
833 success = true;
834 else if (options.GetMaskoutErrors() && PyErr_Occurred()) {
835 PyErr_Print();
836 PyErr_Clear();
837 }
838 }
839 }
840 }
841 }
842
843 io_redirect.Flush();
844 }
845
846 if (success)
847 return true;
848
849 // The one-liner failed. Append the error message.
850 if (result) {
851 result->AppendErrorWithFormat(
852 "python failed attempting to evaluate '%s'\n", command_str.c_str());
853 }
854 return false;
855 }
856
857 if (result)
858 result->AppendError("empty command passed to python\n");
859 return false;
860}
861
862void ScriptInterpreterPythonImpl::ExecuteInterpreterLoop() {
864
865 Debugger &debugger = m_debugger;
866
867 // At the moment, the only time the debugger does not have an input file
868 // handle is when this is called directly from Python, in which case it is
869 // both dangerous and unnecessary (not to mention confusing) to try to embed
870 // a running interpreter loop inside the already running Python interpreter
871 // loop, so we won't do it.
872
873 if (!debugger.GetInputFile().IsValid())
874 return;
875
876 IOHandlerSP io_handler_sp(new IOHandlerPythonInterpreter(debugger, this));
877 if (io_handler_sp) {
878 debugger.RunIOHandlerAsync(io_handler_sp);
879 }
880}
881
882bool ScriptInterpreterPythonImpl::Interrupt() {
883#if LLDB_USE_PYTHON_SET_INTERRUPT
884 // If the interpreter isn't evaluating any Python at the moment then return
885 // false to signal that this function didn't handle the interrupt and the
886 // next component should try handling it.
887 if (!IsExecutingPython())
888 return false;
889
890 // Tell Python that it should pretend to have received a SIGINT.
891 PyErr_SetInterrupt();
892 // PyErr_SetInterrupt has no way to return an error so we can only pretend the
893 // signal got successfully handled and return true.
894 // Python 3.10 introduces PyErr_SetInterruptEx that could return an error, but
895 // the error handling is limited to checking the arguments which would be
896 // just our (hardcoded) input signal code SIGINT, so that's not useful at all.
897 return true;
898#else
899 Log *log = GetLog(LLDBLog::Script);
900
901 if (IsExecutingPython()) {
902 PyThreadState *state = PyThreadState_Get();
903 if (!state)
904 state = GetThreadState();
905 if (state) {
906 long tid = PyThread_get_thread_ident();
907 PyThreadState_Swap(state);
908 int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt);
909 LLDB_LOGF(log,
910 "ScriptInterpreterPythonImpl::Interrupt() sending "
911 "PyExc_KeyboardInterrupt (tid = %li, num_threads = %i)...",
912 tid, num_threads);
913 return true;
914 }
915 }
916 LLDB_LOGF(log,
917 "ScriptInterpreterPythonImpl::Interrupt() python code not running, "
918 "can't interrupt");
919 return false;
920#endif
921}
922
923bool ScriptInterpreterPythonImpl::ExecuteOneLineWithReturn(
924 llvm::StringRef in_string, ScriptInterpreter::ScriptReturnType return_type,
925 void *ret_value, const ExecuteScriptOptions &options) {
926
927 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
928 io_redirect_or_error = ScriptInterpreterIORedirect::Create(
929 options.GetEnableIO(), m_debugger, /*result=*/nullptr);
930
931 if (!io_redirect_or_error) {
932 llvm::consumeError(io_redirect_or_error.takeError());
933 return false;
934 }
935
936 ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
937
938 Locker locker(this,
939 Locker::AcquireLock | Locker::InitSession |
940 (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) |
941 Locker::NoSTDIN,
942 Locker::FreeAcquiredLock | Locker::TearDownSession,
943 io_redirect.GetInputFile(), io_redirect.GetOutputFile(),
944 io_redirect.GetErrorFile());
945
946 PythonModule &main_module = GetMainModule();
947 PythonDictionary globals = main_module.GetDictionary();
948
949 PythonDictionary locals = GetSessionDictionary();
950 if (!locals.IsValid())
951 locals = unwrapIgnoringErrors(
952 As<PythonDictionary>(globals.GetAttribute(m_dictionary_name)));
953 if (!locals.IsValid())
954 locals = globals;
955
956 Expected<PythonObject> maybe_py_return =
957 runStringOneLine(in_string, globals, locals);
958
959 if (!maybe_py_return) {
960 llvm::handleAllErrors(
961 maybe_py_return.takeError(),
962 [&](PythonException &E) {
963 E.Restore();
964 if (options.GetMaskoutErrors()) {
965 if (E.Matches(PyExc_SyntaxError)) {
966 PyErr_Print();
967 }
968 PyErr_Clear();
969 }
970 },
971 [](const llvm::ErrorInfoBase &E) {});
972 return false;
973 }
974
975 PythonObject py_return = std::move(maybe_py_return.get());
976 assert(py_return.IsValid());
977
978 switch (return_type) {
979 case eScriptReturnTypeCharPtr: // "char *"
980 {
981 const char format[3] = "s#";
982 return PyArg_Parse(py_return.get(), format, (char **)ret_value);
983 }
984 case eScriptReturnTypeCharStrOrNone: // char* or NULL if py_return ==
985 // Py_None
986 {
987 const char format[3] = "z";
988 return PyArg_Parse(py_return.get(), format, (char **)ret_value);
989 }
990 case eScriptReturnTypeBool: {
991 const char format[2] = "b";
992 return PyArg_Parse(py_return.get(), format, (bool *)ret_value);
993 }
994 case eScriptReturnTypeShortInt: {
995 const char format[2] = "h";
996 return PyArg_Parse(py_return.get(), format, (short *)ret_value);
997 }
998 case eScriptReturnTypeShortIntUnsigned: {
999 const char format[2] = "H";
1000 return PyArg_Parse(py_return.get(), format, (unsigned short *)ret_value);
1001 }
1002 case eScriptReturnTypeInt: {
1003 const char format[2] = "i";
1004 return PyArg_Parse(py_return.get(), format, (int *)ret_value);
1005 }
1006 case eScriptReturnTypeIntUnsigned: {
1007 const char format[2] = "I";
1008 return PyArg_Parse(py_return.get(), format, (unsigned int *)ret_value);
1009 }
1010 case eScriptReturnTypeLongInt: {
1011 const char format[2] = "l";
1012 return PyArg_Parse(py_return.get(), format, (long *)ret_value);
1013 }
1014 case eScriptReturnTypeLongIntUnsigned: {
1015 const char format[2] = "k";
1016 return PyArg_Parse(py_return.get(), format, (unsigned long *)ret_value);
1017 }
1018 case eScriptReturnTypeLongLong: {
1019 const char format[2] = "L";
1020 return PyArg_Parse(py_return.get(), format, (long long *)ret_value);
1021 }
1022 case eScriptReturnTypeLongLongUnsigned: {
1023 const char format[2] = "K";
1024 return PyArg_Parse(py_return.get(), format,
1025 (unsigned long long *)ret_value);
1026 }
1027 case eScriptReturnTypeFloat: {
1028 const char format[2] = "f";
1029 return PyArg_Parse(py_return.get(), format, (float *)ret_value);
1030 }
1031 case eScriptReturnTypeDouble: {
1032 const char format[2] = "d";
1033 return PyArg_Parse(py_return.get(), format, (double *)ret_value);
1034 }
1035 case eScriptReturnTypeChar: {
1036 const char format[2] = "c";
1037 return PyArg_Parse(py_return.get(), format, (char *)ret_value);
1038 }
1039 case eScriptReturnTypeOpaqueObject: {
1040 *((PyObject **)ret_value) = py_return.release();
1041 return true;
1042 }
1043 }
1044 llvm_unreachable("Fully covered switch!");
1045}
1046
1047Status ScriptInterpreterPythonImpl::ExecuteMultipleLines(
1048 const char *in_string, const ExecuteScriptOptions &options) {
1049
1050 if (in_string == nullptr)
1051 return Status();
1052
1053 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
1054 io_redirect_or_error = ScriptInterpreterIORedirect::Create(
1055 options.GetEnableIO(), m_debugger, /*result=*/nullptr);
1056
1057 if (!io_redirect_or_error)
1058 return Status::FromError(io_redirect_or_error.takeError());
1059
1060 ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
1061
1062 Locker locker(this,
1063 Locker::AcquireLock | Locker::InitSession |
1064 (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) |
1065 Locker::NoSTDIN,
1066 Locker::FreeAcquiredLock | Locker::TearDownSession,
1067 io_redirect.GetInputFile(), io_redirect.GetOutputFile(),
1068 io_redirect.GetErrorFile());
1069
1070 PythonModule &main_module = GetMainModule();
1071 PythonDictionary globals = main_module.GetDictionary();
1072
1073 PythonDictionary locals = GetSessionDictionary();
1074 if (!locals.IsValid())
1075 locals = unwrapIgnoringErrors(
1076 As<PythonDictionary>(globals.GetAttribute(m_dictionary_name)));
1077 if (!locals.IsValid())
1078 locals = globals;
1079
1080 Expected<PythonObject> return_value =
1081 runStringMultiLine(in_string, globals, locals);
1082
1083 if (!return_value) {
1084 llvm::Error error =
1085 llvm::handleErrors(return_value.takeError(), [&](PythonException &E) {
1086 llvm::Error error = llvm::createStringError(
1087 llvm::inconvertibleErrorCode(), E.ReadBacktrace());
1088 if (!options.GetMaskoutErrors())
1089 E.Restore();
1090 return error;
1091 });
1092 return Status::FromError(std::move(error));
1093 }
1094
1095 return Status();
1096}
1097
1098void ScriptInterpreterPythonImpl::CollectDataForBreakpointCommandCallback(
1099 std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
1100 CommandReturnObject &result) {
1101 m_active_io_handler = eIOHandlerBreakpoint;
1102 m_debugger.GetCommandInterpreter().GetPythonCommandsFromIOHandler(
1103 " ", *this, &bp_options_vec);
1104}
1105
1106void ScriptInterpreterPythonImpl::CollectDataForWatchpointCommandCallback(
1107 WatchpointOptions *wp_options, CommandReturnObject &result) {
1108 m_active_io_handler = eIOHandlerWatchpoint;
1109 m_debugger.GetCommandInterpreter().GetPythonCommandsFromIOHandler(
1110 " ", *this, wp_options);
1111}
1112
1113Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallbackFunction(
1114 BreakpointOptions &bp_options, const char *function_name,
1115 StructuredData::ObjectSP extra_args_sp) {
1116 Status error;
1117 // For now just cons up a oneliner that calls the provided function.
1118 std::string function_signature = function_name;
1119
1120 llvm::Expected<unsigned> maybe_args =
1121 GetMaxPositionalArgumentsForCallable(function_name);
1122 if (!maybe_args) {
1124 "could not get num args: %s",
1125 llvm::toString(maybe_args.takeError()).c_str());
1126 return error;
1127 }
1128 size_t max_args = *maybe_args;
1129
1130 bool uses_extra_args = false;
1131 if (max_args >= 4) {
1132 uses_extra_args = true;
1133 function_signature += "(frame, bp_loc, extra_args, internal_dict)";
1134 } else if (max_args >= 3) {
1135 if (extra_args_sp) {
1137 "cannot pass extra_args to a three argument callback");
1138 return error;
1139 }
1140 uses_extra_args = false;
1141 function_signature += "(frame, bp_loc, internal_dict)";
1142 } else {
1143 error = Status::FromErrorStringWithFormat("expected 3 or 4 argument "
1144 "function, %s can only take %zu",
1145 function_name, max_args);
1146 return error;
1147 }
1148
1149 SetBreakpointCommandCallback(bp_options, function_signature.c_str(),
1150 extra_args_sp, uses_extra_args,
1151 /*is_callback=*/true);
1152 return error;
1153}
1154
1155Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback(
1156 BreakpointOptions &bp_options,
1157 std::unique_ptr<BreakpointOptions::CommandData> &cmd_data_up) {
1158 Status error;
1159 error = GenerateBreakpointCommandCallbackData(cmd_data_up->user_source,
1160 cmd_data_up->script_source,
1161 /*has_extra_args=*/false,
1162 /*is_callback=*/false);
1163 if (error.Fail()) {
1164 return error;
1165 }
1166 auto baton_sp =
1167 std::make_shared<BreakpointOptions::CommandBaton>(std::move(cmd_data_up));
1168 bp_options.SetCallback(
1169 ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp);
1170 return error;
1171}
1172
1173Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback(
1174 BreakpointOptions &bp_options, const char *command_body_text,
1175 bool is_callback) {
1176 return SetBreakpointCommandCallback(bp_options, command_body_text, {},
1177 /*uses_extra_args=*/false, is_callback);
1178}
1179
1180// Set a Python one-liner as the callback for the breakpoint.
1181Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback(
1182 BreakpointOptions &bp_options, const char *command_body_text,
1183 StructuredData::ObjectSP extra_args_sp, bool uses_extra_args,
1184 bool is_callback) {
1185 auto data_up = std::make_unique<CommandDataPython>(extra_args_sp);
1186 // Split the command_body_text into lines, and pass that to
1187 // GenerateBreakpointCommandCallbackData. That will wrap the body in an
1188 // auto-generated function, and return the function name in script_source.
1189 // That is what the callback will actually invoke.
1190
1191 data_up->user_source.SplitIntoLines(command_body_text);
1192 Status error = GenerateBreakpointCommandCallbackData(
1193 data_up->user_source, data_up->script_source, uses_extra_args,
1194 is_callback);
1195 if (error.Success()) {
1196 auto baton_sp =
1197 std::make_shared<BreakpointOptions::CommandBaton>(std::move(data_up));
1198 bp_options.SetCallback(
1199 ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp);
1200 return error;
1201 }
1202 return error;
1203}
1204
1205// Set a Python one-liner as the callback for the watchpoint.
1206void ScriptInterpreterPythonImpl::SetWatchpointCommandCallback(
1207 WatchpointOptions *wp_options, const char *user_input, bool is_callback) {
1208 auto data_up = std::make_unique<WatchpointOptions::CommandData>();
1209
1210 // It's necessary to set both user_source and script_source to the oneliner.
1211 // The former is used to generate callback description (as in watchpoint
1212 // command list) while the latter is used for Python to interpret during the
1213 // actual callback.
1214
1215 data_up->user_source.AppendString(user_input);
1216 data_up->script_source.assign(user_input);
1217
1218 if (GenerateWatchpointCommandCallbackData(
1219 data_up->user_source, data_up->script_source, is_callback)) {
1220 auto baton_sp =
1221 std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up));
1222 wp_options->SetCallback(
1223 ScriptInterpreterPythonImpl::WatchpointCallbackFunction, baton_sp);
1224 }
1225}
1226
1227Status ScriptInterpreterPythonImpl::ExportFunctionDefinitionToInterpreter(
1228 StringList &function_def) {
1229 // Convert StringList to one long, newline delimited, const char *.
1230 std::string function_def_string(function_def.CopyList());
1231 LLDB_LOG(GetLog(LLDBLog::Script), "Added Function:\n%s\n",
1232 function_def_string.c_str());
1233
1234 Status error = ExecuteMultipleLines(
1235 function_def_string.c_str(), ExecuteScriptOptions().SetEnableIO(false));
1236 return error;
1237}
1238
1239Status ScriptInterpreterPythonImpl::GenerateFunction(const char *signature,
1240 const StringList &input,
1241 bool is_callback) {
1242 Status error;
1243 int num_lines = input.GetSize();
1244 if (num_lines == 0) {
1245 error = Status::FromErrorString("No input data.");
1246 return error;
1247 }
1248
1249 if (!signature || *signature == 0) {
1250 error = Status::FromErrorString("No output function name.");
1251 return error;
1252 }
1253
1254 StreamString sstr;
1255 StringList auto_generated_function;
1256 auto_generated_function.AppendString(signature);
1257 auto_generated_function.AppendString(
1258 " global_dict = globals()"); // Grab the global dictionary
1259 auto_generated_function.AppendString(
1260 " new_keys = internal_dict.keys()"); // Make a list of keys in the
1261 // session dict
1262 auto_generated_function.AppendString(
1263 " old_keys = global_dict.keys()"); // Save list of keys in global dict
1264 auto_generated_function.AppendString(
1265 " global_dict.update(internal_dict)"); // Add the session dictionary
1266 // to the global dictionary.
1267
1268 if (is_callback) {
1269 // If the user input is a callback to a python function, make sure the input
1270 // is only 1 line, otherwise appending the user input would break the
1271 // generated wrapped function
1272 if (num_lines == 1) {
1273 sstr.Clear();
1274 sstr.Printf(" __return_val = %s", input.GetStringAtIndex(0));
1275 auto_generated_function.AppendString(sstr.GetData());
1276 } else {
1278 "ScriptInterpreterPythonImpl::GenerateFunction(is_callback="
1279 "true) = ERROR: python function is multiline.");
1280 }
1281 } else {
1282 auto_generated_function.AppendString(
1283 " __return_val = None"); // Initialize user callback return value.
1284 auto_generated_function.AppendString(
1285 " def __user_code():"); // Create a nested function that will wrap
1286 // the user input. This is necessary to
1287 // capture the return value of the user input
1288 // and prevent early returns.
1289 for (int i = 0; i < num_lines; ++i) {
1290 sstr.Clear();
1291 sstr.Printf(" %s", input.GetStringAtIndex(i));
1292 auto_generated_function.AppendString(sstr.GetData());
1293 }
1294 auto_generated_function.AppendString(
1295 " __return_val = __user_code()"); // Call user code and capture
1296 // return value
1297 }
1298 auto_generated_function.AppendString(
1299 " for key in new_keys:"); // Iterate over all the keys from session
1300 // dict
1301 auto_generated_function.AppendString(
1302 " if key in old_keys:"); // If key was originally in
1303 // global dict
1304 auto_generated_function.AppendString(
1305 " internal_dict[key] = global_dict[key]"); // Update it
1306 auto_generated_function.AppendString(
1307 " elif key in global_dict:"); // Then if it is still in the
1308 // global dict
1309 auto_generated_function.AppendString(
1310 " del global_dict[key]"); // remove key/value from the
1311 // global dict
1312 auto_generated_function.AppendString(
1313 " return __return_val"); // Return the user callback return value.
1314
1315 // Verify that the results are valid Python.
1316 error = ExportFunctionDefinitionToInterpreter(auto_generated_function);
1317
1318 return error;
1319}
1320
1321bool ScriptInterpreterPythonImpl::GenerateTypeScriptFunction(
1322 StringList &user_input, std::string &output, const void *name_token) {
1323 static uint32_t num_created_functions = 0;
1324 user_input.RemoveBlankLines();
1325 StreamString sstr;
1326
1327 // Check to see if we have any data; if not, just return.
1328 if (user_input.GetSize() == 0)
1329 return false;
1330
1331 // Take what the user wrote, wrap it all up inside one big auto-generated
1332 // Python function, passing in the ValueObject as parameter to the function.
1333
1334 std::string auto_generated_function_name(
1335 GenerateUniqueName("lldb_autogen_python_type_print_func",
1336 num_created_functions, name_token));
1337 sstr.Printf("def %s (valobj, internal_dict):",
1338 auto_generated_function_name.c_str());
1339
1340 if (!GenerateFunction(sstr.GetData(), user_input, /*is_callback=*/false)
1341 .Success())
1342 return false;
1343
1344 // Store the name of the auto-generated function to be called.
1345 output.assign(auto_generated_function_name);
1346 return true;
1347}
1348
1349bool ScriptInterpreterPythonImpl::GenerateScriptAliasFunction(
1350 StringList &user_input, std::string &output) {
1351 static uint32_t num_created_functions = 0;
1352 user_input.RemoveBlankLines();
1353 StreamString sstr;
1354
1355 // Check to see if we have any data; if not, just return.
1356 if (user_input.GetSize() == 0)
1357 return false;
1358
1359 std::string auto_generated_function_name(GenerateUniqueName(
1360 "lldb_autogen_python_cmd_alias_func", num_created_functions));
1361
1362 sstr.Printf("def %s (debugger, args, exe_ctx, result, internal_dict):",
1363 auto_generated_function_name.c_str());
1364
1365 if (!GenerateFunction(sstr.GetData(), user_input, /*is_callback=*/false)
1366 .Success())
1367 return false;
1368
1369 // Store the name of the auto-generated function to be called.
1370 output.assign(auto_generated_function_name);
1371 return true;
1372}
1373
1374bool ScriptInterpreterPythonImpl::GenerateTypeSynthClass(
1375 StringList &user_input, std::string &output, const void *name_token) {
1376 static uint32_t num_created_classes = 0;
1377 user_input.RemoveBlankLines();
1378 int num_lines = user_input.GetSize();
1379 StreamString sstr;
1380
1381 // Check to see if we have any data; if not, just return.
1382 if (user_input.GetSize() == 0)
1383 return false;
1384
1385 // Wrap all user input into a Python class
1386
1387 std::string auto_generated_class_name(GenerateUniqueName(
1388 "lldb_autogen_python_type_synth_class", num_created_classes, name_token));
1389
1390 StringList auto_generated_class;
1391
1392 // Create the function name & definition string.
1393
1394 sstr.Printf("class %s:", auto_generated_class_name.c_str());
1395 auto_generated_class.AppendString(sstr.GetString());
1396
1397 // Wrap everything up inside the class, increasing the indentation. we don't
1398 // need to play any fancy indentation tricks here because there is no
1399 // surrounding code whose indentation we need to honor
1400 for (int i = 0; i < num_lines; ++i) {
1401 sstr.Clear();
1402 sstr.Printf(" %s", user_input.GetStringAtIndex(i));
1403 auto_generated_class.AppendString(sstr.GetString());
1404 }
1405
1406 // Verify that the results are valid Python. (even though the method is
1407 // ExportFunctionDefinitionToInterpreter, a class will actually be exported)
1408 // (TODO: rename that method to ExportDefinitionToInterpreter)
1409 if (!ExportFunctionDefinitionToInterpreter(auto_generated_class).Success())
1410 return false;
1411
1412 // Store the name of the auto-generated class
1413
1414 output.assign(auto_generated_class_name);
1415 return true;
1416}
1417
1419ScriptInterpreterPythonImpl::CreateFrameRecognizer(const char *class_name) {
1420 if (class_name == nullptr || class_name[0] == '\0')
1422
1423 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
1424 PythonObject ret_val = SWIGBridge::LLDBSWIGPython_CreateFrameRecognizer(
1425 class_name, m_dictionary_name.c_str());
1426
1428 new StructuredPythonObject(std::move(ret_val)));
1429}
1430
1431lldb::ValueObjectListSP ScriptInterpreterPythonImpl::GetRecognizedArguments(
1432 const StructuredData::ObjectSP &os_plugin_object_sp,
1433 lldb::StackFrameSP frame_sp) {
1434 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
1435
1436 if (!os_plugin_object_sp)
1437 return ValueObjectListSP();
1438
1439 StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
1440 if (!generic)
1441 return nullptr;
1442
1443 PythonObject implementor(PyRefType::Borrowed,
1444 (PyObject *)generic->GetValue());
1445
1446 if (!implementor.IsAllocated())
1447 return ValueObjectListSP();
1448
1449 PythonObject py_return(PyRefType::Owned,
1450 SWIGBridge::LLDBSwigPython_GetRecognizedArguments(
1451 implementor.get(), frame_sp));
1452
1453 // if it fails, print the error but otherwise go on
1454 if (PyErr_Occurred()) {
1455 PyErr_Print();
1456 PyErr_Clear();
1457 }
1458 if (py_return.get()) {
1459 PythonList result_list(PyRefType::Borrowed, py_return.get());
1460 ValueObjectListSP result = std::make_shared<ValueObjectList>();
1461 for (size_t i = 0; i < result_list.GetSize(); i++) {
1462 PyObject *item = result_list.GetItemAtIndex(i).get();
1463 lldb::SBValue *sb_value_ptr =
1464 (lldb::SBValue *)LLDBSWIGPython_CastPyObjectToSBValue(item);
1465 auto valobj_sp =
1466 SWIGBridge::LLDBSWIGPython_GetValueObjectSPFromSBValue(sb_value_ptr);
1467 if (valobj_sp)
1468 result->Append(valobj_sp);
1469 }
1470 return result;
1471 }
1472 return ValueObjectListSP();
1473}
1474
1475bool ScriptInterpreterPythonImpl::ShouldHide(
1476 const StructuredData::ObjectSP &os_plugin_object_sp,
1477 lldb::StackFrameSP frame_sp) {
1478 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
1479
1480 if (!os_plugin_object_sp)
1481 return false;
1482
1483 StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
1484 if (!generic)
1485 return false;
1486
1487 PythonObject implementor(PyRefType::Borrowed,
1488 (PyObject *)generic->GetValue());
1489
1490 if (!implementor.IsAllocated())
1491 return false;
1492
1493 bool result =
1494 SWIGBridge::LLDBSwigPython_ShouldHide(implementor.get(), frame_sp);
1495
1496 // if it fails, print the error but otherwise go on
1497 if (PyErr_Occurred()) {
1498 PyErr_Print();
1499 PyErr_Clear();
1500 }
1501 return result;
1502}
1503
1505ScriptInterpreterPythonImpl::CreateScriptedProcessInterface() {
1506 return std::make_unique<ScriptedProcessPythonInterface>(*this);
1507}
1508
1510ScriptInterpreterPythonImpl::CreateScriptedStopHookInterface() {
1511 return std::make_shared<ScriptedStopHookPythonInterface>(*this);
1512}
1513
1515ScriptInterpreterPythonImpl::CreateScriptedBreakpointInterface() {
1516 return std::make_shared<ScriptedBreakpointPythonInterface>(*this);
1517}
1518
1520ScriptInterpreterPythonImpl::CreateScriptedThreadInterface() {
1521 return std::make_shared<ScriptedThreadPythonInterface>(*this);
1522}
1523
1525ScriptInterpreterPythonImpl::CreateScriptedFrameInterface() {
1526 return std::make_shared<ScriptedFramePythonInterface>(*this);
1527}
1528
1530ScriptInterpreterPythonImpl::CreateScriptedFrameProviderInterface() {
1531 return std::make_shared<ScriptedFrameProviderPythonInterface>(*this);
1532}
1533
1535ScriptInterpreterPythonImpl::CreateScriptedThreadPlanInterface() {
1536 return std::make_shared<ScriptedThreadPlanPythonInterface>(*this);
1537}
1538
1540ScriptInterpreterPythonImpl::CreateOperatingSystemInterface() {
1541 return std::make_shared<OperatingSystemPythonInterface>(*this);
1542}
1543
1545ScriptInterpreterPythonImpl::CreateStructuredDataFromScriptObject(
1546 ScriptObject obj) {
1547 void *ptr = const_cast<void *>(obj.GetPointer());
1548 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
1549 PythonObject py_obj(PyRefType::Borrowed, static_cast<PyObject *>(ptr));
1550 if (!py_obj.IsValid() || py_obj.IsNone())
1551 return {};
1552 return py_obj.CreateStructuredObject();
1553}
1554
1556ScriptInterpreterPythonImpl::LoadPluginModule(const FileSpec &file_spec,
1558 if (!FileSystem::Instance().Exists(file_spec)) {
1559 error = Status::FromErrorString("no such file");
1560 return StructuredData::ObjectSP();
1561 }
1562
1563 StructuredData::ObjectSP module_sp;
1564
1565 LoadScriptOptions load_script_options =
1567 if (LoadScriptingModule(file_spec.GetPath().c_str(), load_script_options,
1568 error, &module_sp))
1569 return module_sp;
1570
1571 return StructuredData::ObjectSP();
1572}
1573
1574StructuredData::DictionarySP ScriptInterpreterPythonImpl::GetDynamicSettings(
1575 StructuredData::ObjectSP plugin_module_sp, Target *target,
1576 const char *setting_name, lldb_private::Status &error) {
1577 if (!plugin_module_sp || !target || !setting_name || !setting_name[0])
1579 StructuredData::Generic *generic = plugin_module_sp->GetAsGeneric();
1580 if (!generic)
1582
1583 Locker py_lock(this,
1584 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1585 TargetSP target_sp(target->shared_from_this());
1586
1587 auto setting = (PyObject *)SWIGBridge::LLDBSWIGPython_GetDynamicSetting(
1588 generic->GetValue(), setting_name, target_sp);
1589
1590 if (!setting)
1592
1593 PythonDictionary py_dict =
1594 unwrapIgnoringErrors(As<PythonDictionary>(Take<PythonObject>(setting)));
1595
1596 if (!py_dict)
1598
1599 return py_dict.CreateStructuredDictionary();
1600}
1601
1603ScriptInterpreterPythonImpl::CreateSyntheticScriptedProvider(
1604 const char *class_name, lldb::ValueObjectSP valobj) {
1605 if (class_name == nullptr || class_name[0] == '\0')
1606 return StructuredData::ObjectSP();
1607
1608 if (!valobj.get())
1609 return StructuredData::ObjectSP();
1610
1611 ExecutionContext exe_ctx(valobj->GetExecutionContextRef());
1612 Target *target = exe_ctx.GetTargetPtr();
1613
1614 if (!target)
1615 return StructuredData::ObjectSP();
1616
1617 Debugger &debugger = target->GetDebugger();
1618 ScriptInterpreterPythonImpl *python_interpreter =
1619 GetPythonInterpreter(debugger);
1620
1621 if (!python_interpreter)
1622 return StructuredData::ObjectSP();
1623
1624 Locker py_lock(this,
1625 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1626 PythonObject ret_val = SWIGBridge::LLDBSwigPythonCreateSyntheticProvider(
1627 class_name, python_interpreter->m_dictionary_name.c_str(), valobj);
1628
1630 new StructuredPythonObject(std::move(ret_val)));
1631}
1632
1634ScriptInterpreterPythonImpl::CreateScriptCommandObject(const char *class_name) {
1635 DebuggerSP debugger_sp(m_debugger.shared_from_this());
1636
1637 if (class_name == nullptr || class_name[0] == '\0')
1639
1640 if (!debugger_sp.get())
1642
1643 Locker py_lock(this,
1644 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1645 PythonObject ret_val = SWIGBridge::LLDBSwigPythonCreateCommandObject(
1646 class_name, m_dictionary_name.c_str(), debugger_sp);
1647
1648 if (ret_val.IsValid())
1650 new StructuredPythonObject(std::move(ret_val)));
1651 else
1652 return {};
1653}
1654
1655bool ScriptInterpreterPythonImpl::GenerateTypeScriptFunction(
1656 const char *oneliner, std::string &output, const void *name_token) {
1657 StringList input;
1658 input.SplitIntoLines(oneliner, strlen(oneliner));
1659 return GenerateTypeScriptFunction(input, output, name_token);
1660}
1661
1662bool ScriptInterpreterPythonImpl::GenerateTypeSynthClass(
1663 const char *oneliner, std::string &output, const void *name_token) {
1664 StringList input;
1665 input.SplitIntoLines(oneliner, strlen(oneliner));
1666 return GenerateTypeSynthClass(input, output, name_token);
1667}
1668
1669Status ScriptInterpreterPythonImpl::GenerateBreakpointCommandCallbackData(
1670 StringList &user_input, std::string &output, bool has_extra_args,
1671 bool is_callback) {
1672 static uint32_t num_created_functions = 0;
1673 user_input.RemoveBlankLines();
1674 StreamString sstr;
1675 Status error;
1676 if (user_input.GetSize() == 0) {
1677 error = Status::FromErrorString("No input data.");
1678 return error;
1679 }
1680
1681 std::string auto_generated_function_name(GenerateUniqueName(
1682 "lldb_autogen_python_bp_callback_func_", num_created_functions));
1683 if (has_extra_args)
1684 sstr.Printf("def %s (frame, bp_loc, extra_args, internal_dict):",
1685 auto_generated_function_name.c_str());
1686 else
1687 sstr.Printf("def %s (frame, bp_loc, internal_dict):",
1688 auto_generated_function_name.c_str());
1689
1690 error = GenerateFunction(sstr.GetData(), user_input, is_callback);
1691 if (!error.Success())
1692 return error;
1693
1694 // Store the name of the auto-generated function to be called.
1695 output.assign(auto_generated_function_name);
1696 return error;
1697}
1698
1699bool ScriptInterpreterPythonImpl::GenerateWatchpointCommandCallbackData(
1700 StringList &user_input, std::string &output, bool is_callback) {
1701 static uint32_t num_created_functions = 0;
1702 user_input.RemoveBlankLines();
1703 StreamString sstr;
1704
1705 if (user_input.GetSize() == 0)
1706 return false;
1707
1708 std::string auto_generated_function_name(GenerateUniqueName(
1709 "lldb_autogen_python_wp_callback_func_", num_created_functions));
1710 sstr.Printf("def %s (frame, wp, internal_dict):",
1711 auto_generated_function_name.c_str());
1712
1713 if (!GenerateFunction(sstr.GetData(), user_input, is_callback).Success())
1714 return false;
1715
1716 // Store the name of the auto-generated function to be called.
1717 output.assign(auto_generated_function_name);
1718 return true;
1719}
1720
1721bool ScriptInterpreterPythonImpl::GetScriptedSummary(
1722 const char *python_function_name, lldb::ValueObjectSP valobj,
1723 StructuredData::ObjectSP &callee_wrapper_sp,
1724 const TypeSummaryOptions &options, std::string &retval) {
1725
1727
1728 if (!valobj.get()) {
1729 retval.assign("<no object>");
1730 return false;
1731 }
1732
1733 void *old_callee = nullptr;
1734 StructuredData::Generic *generic = nullptr;
1735 if (callee_wrapper_sp) {
1736 generic = callee_wrapper_sp->GetAsGeneric();
1737 if (generic)
1738 old_callee = generic->GetValue();
1739 }
1740 void *new_callee = old_callee;
1741
1742 bool ret_val;
1743 if (python_function_name && *python_function_name) {
1744 {
1745 Locker py_lock(this, Locker::AcquireLock | Locker::InitSession |
1746 Locker::NoSTDIN);
1747 {
1748 TypeSummaryOptionsSP options_sp(new TypeSummaryOptions(options));
1749
1750 static Timer::Category func_cat("LLDBSwigPythonCallTypeScript");
1751 Timer scoped_timer(func_cat, "LLDBSwigPythonCallTypeScript");
1752 ret_val = SWIGBridge::LLDBSwigPythonCallTypeScript(
1753 python_function_name, GetSessionDictionary().get(), valobj,
1754 &new_callee, options_sp, retval);
1755 }
1756 }
1757 } else {
1758 retval.assign("<no function name>");
1759 return false;
1760 }
1761
1762 if (new_callee && old_callee != new_callee) {
1763 Locker py_lock(this,
1764 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1765 callee_wrapper_sp = std::make_shared<StructuredPythonObject>(
1766 PythonObject(PyRefType::Borrowed, static_cast<PyObject *>(new_callee)));
1767 }
1768
1769 return ret_val;
1770}
1771
1772bool ScriptInterpreterPythonImpl::FormatterCallbackFunction(
1773 const char *python_function_name, TypeImplSP type_impl_sp) {
1774 Locker py_lock(this,
1775 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1776 return SWIGBridge::LLDBSwigPythonFormatterCallbackFunction(
1777 python_function_name, m_dictionary_name.c_str(), type_impl_sp);
1778}
1779
1780bool ScriptInterpreterPythonImpl::BreakpointCallbackFunction(
1781 void *baton, StoppointCallbackContext *context, user_id_t break_id,
1782 user_id_t break_loc_id) {
1783 CommandDataPython *bp_option_data = (CommandDataPython *)baton;
1784 const char *python_function_name = bp_option_data->script_source.c_str();
1785
1786 if (!context)
1787 return true;
1788
1789 ExecutionContext exe_ctx(context->exe_ctx_ref);
1790 Target *target = exe_ctx.GetTargetPtr();
1791
1792 if (!target)
1793 return true;
1794
1795 Debugger &debugger = target->GetDebugger();
1796 ScriptInterpreterPythonImpl *python_interpreter =
1797 GetPythonInterpreter(debugger);
1798
1799 if (!python_interpreter)
1800 return true;
1801
1802 if (python_function_name && python_function_name[0]) {
1803 const StackFrameSP stop_frame_sp(exe_ctx.GetFrameSP());
1804 BreakpointSP breakpoint_sp = target->GetBreakpointByID(break_id);
1805 if (breakpoint_sp) {
1806 const BreakpointLocationSP bp_loc_sp(
1807 breakpoint_sp->FindLocationByID(break_loc_id));
1808
1809 if (stop_frame_sp && bp_loc_sp) {
1810 bool ret_val = true;
1811 {
1812 Locker py_lock(python_interpreter, Locker::AcquireLock |
1813 Locker::InitSession |
1814 Locker::NoSTDIN);
1815 Expected<bool> maybe_ret_val =
1816 SWIGBridge::LLDBSwigPythonBreakpointCallbackFunction(
1817 python_function_name,
1818 python_interpreter->m_dictionary_name.c_str(), stop_frame_sp,
1819 bp_loc_sp, bp_option_data->m_extra_args);
1820
1821 if (!maybe_ret_val) {
1822
1823 llvm::handleAllErrors(
1824 maybe_ret_val.takeError(),
1825 [&](PythonException &E) {
1826 *debugger.GetAsyncErrorStream() << E.ReadBacktrace();
1827 },
1828 [&](const llvm::ErrorInfoBase &E) {
1829 *debugger.GetAsyncErrorStream() << E.message();
1830 });
1831
1832 } else {
1833 ret_val = maybe_ret_val.get();
1834 }
1835 }
1836 return ret_val;
1837 }
1838 }
1839 }
1840 // We currently always true so we stop in case anything goes wrong when
1841 // trying to call the script function
1842 return true;
1843}
1844
1845bool ScriptInterpreterPythonImpl::WatchpointCallbackFunction(
1846 void *baton, StoppointCallbackContext *context, user_id_t watch_id) {
1847 WatchpointOptions::CommandData *wp_option_data =
1849 const char *python_function_name = wp_option_data->script_source.c_str();
1850
1851 if (!context)
1852 return true;
1853
1854 ExecutionContext exe_ctx(context->exe_ctx_ref);
1855 Target *target = exe_ctx.GetTargetPtr();
1856
1857 if (!target)
1858 return true;
1859
1860 Debugger &debugger = target->GetDebugger();
1861 ScriptInterpreterPythonImpl *python_interpreter =
1862 GetPythonInterpreter(debugger);
1863
1864 if (!python_interpreter)
1865 return true;
1866
1867 if (python_function_name && python_function_name[0]) {
1868 const StackFrameSP stop_frame_sp(exe_ctx.GetFrameSP());
1869 WatchpointSP wp_sp = target->GetWatchpointList().FindByID(watch_id);
1870 if (wp_sp) {
1871 if (stop_frame_sp && wp_sp) {
1872 bool ret_val = true;
1873 {
1874 Locker py_lock(python_interpreter, Locker::AcquireLock |
1875 Locker::InitSession |
1876 Locker::NoSTDIN);
1877 ret_val = SWIGBridge::LLDBSwigPythonWatchpointCallbackFunction(
1878 python_function_name,
1879 python_interpreter->m_dictionary_name.c_str(), stop_frame_sp,
1880 wp_sp);
1881 }
1882 return ret_val;
1883 }
1884 }
1885 }
1886 // We currently always true so we stop in case anything goes wrong when
1887 // trying to call the script function
1888 return true;
1889}
1890
1891size_t ScriptInterpreterPythonImpl::CalculateNumChildren(
1892 const StructuredData::ObjectSP &implementor_sp, uint32_t max) {
1893 if (!implementor_sp)
1894 return 0;
1895 StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
1896 if (!generic)
1897 return 0;
1898 auto *implementor = static_cast<PyObject *>(generic->GetValue());
1899 if (!implementor)
1900 return 0;
1901
1902 size_t ret_val = 0;
1903
1904 {
1905 Locker py_lock(this,
1906 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1907 ret_val = SWIGBridge::LLDBSwigPython_CalculateNumChildren(implementor, max);
1908 }
1909
1910 return ret_val;
1911}
1912
1913lldb::ValueObjectSP ScriptInterpreterPythonImpl::GetChildAtIndex(
1914 const StructuredData::ObjectSP &implementor_sp, uint32_t idx) {
1915 if (!implementor_sp)
1916 return lldb::ValueObjectSP();
1917
1918 StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
1919 if (!generic)
1920 return lldb::ValueObjectSP();
1921 auto *implementor = static_cast<PyObject *>(generic->GetValue());
1922 if (!implementor)
1923 return lldb::ValueObjectSP();
1924
1925 lldb::ValueObjectSP ret_val;
1926 {
1927 Locker py_lock(this,
1928 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1929 PyObject *child_ptr =
1930 SWIGBridge::LLDBSwigPython_GetChildAtIndex(implementor, idx);
1931 if (child_ptr != nullptr && child_ptr != Py_None) {
1932 lldb::SBValue *sb_value_ptr =
1933 (lldb::SBValue *)LLDBSWIGPython_CastPyObjectToSBValue(child_ptr);
1934 if (sb_value_ptr == nullptr)
1935 Py_XDECREF(child_ptr);
1936 else
1937 ret_val = SWIGBridge::LLDBSWIGPython_GetValueObjectSPFromSBValue(
1938 sb_value_ptr);
1939 } else {
1940 Py_XDECREF(child_ptr);
1941 }
1942 }
1943
1944 return ret_val;
1945}
1946
1947llvm::Expected<uint32_t> ScriptInterpreterPythonImpl::GetIndexOfChildWithName(
1948 const StructuredData::ObjectSP &implementor_sp, const char *child_name) {
1949 if (!implementor_sp)
1950 return llvm::createStringError("Type has no child named '%s'", child_name);
1951
1952 StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
1953 if (!generic)
1954 return llvm::createStringError("Type has no child named '%s'", child_name);
1955 auto *implementor = static_cast<PyObject *>(generic->GetValue());
1956 if (!implementor)
1957 return llvm::createStringError("Type has no child named '%s'", child_name);
1958
1959 uint32_t ret_val = UINT32_MAX;
1960
1961 {
1962 Locker py_lock(this,
1963 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1964 ret_val = SWIGBridge::LLDBSwigPython_GetIndexOfChildWithName(implementor,
1965 child_name);
1966 }
1967
1968 if (ret_val == UINT32_MAX)
1969 return llvm::createStringError("Type has no child named '%s'", child_name);
1970 return ret_val;
1971}
1972
1973bool ScriptInterpreterPythonImpl::UpdateSynthProviderInstance(
1974 const StructuredData::ObjectSP &implementor_sp) {
1975 bool ret_val = false;
1976
1977 if (!implementor_sp)
1978 return ret_val;
1979
1980 StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
1981 if (!generic)
1982 return ret_val;
1983 auto *implementor = static_cast<PyObject *>(generic->GetValue());
1984 if (!implementor)
1985 return ret_val;
1986
1987 {
1988 Locker py_lock(this,
1989 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1990 ret_val =
1991 SWIGBridge::LLDBSwigPython_UpdateSynthProviderInstance(implementor);
1992 }
1993
1994 return ret_val;
1995}
1996
1997bool ScriptInterpreterPythonImpl::MightHaveChildrenSynthProviderInstance(
1998 const StructuredData::ObjectSP &implementor_sp) {
1999 bool ret_val = false;
2000
2001 if (!implementor_sp)
2002 return ret_val;
2003
2004 StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
2005 if (!generic)
2006 return ret_val;
2007 auto *implementor = static_cast<PyObject *>(generic->GetValue());
2008 if (!implementor)
2009 return ret_val;
2010
2011 {
2012 Locker py_lock(this,
2013 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2014 ret_val = SWIGBridge::LLDBSwigPython_MightHaveChildrenSynthProviderInstance(
2015 implementor);
2016 }
2017
2018 return ret_val;
2019}
2020
2021lldb::ValueObjectSP ScriptInterpreterPythonImpl::GetSyntheticValue(
2022 const StructuredData::ObjectSP &implementor_sp) {
2023 lldb::ValueObjectSP ret_val(nullptr);
2024
2025 if (!implementor_sp)
2026 return ret_val;
2027
2028 StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
2029 if (!generic)
2030 return ret_val;
2031 auto *implementor = static_cast<PyObject *>(generic->GetValue());
2032 if (!implementor)
2033 return ret_val;
2034
2035 {
2036 Locker py_lock(this,
2037 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2038 PyObject *child_ptr =
2039 SWIGBridge::LLDBSwigPython_GetValueSynthProviderInstance(implementor);
2040 if (child_ptr != nullptr && child_ptr != Py_None) {
2041 lldb::SBValue *sb_value_ptr =
2042 (lldb::SBValue *)LLDBSWIGPython_CastPyObjectToSBValue(child_ptr);
2043 if (sb_value_ptr == nullptr)
2044 Py_XDECREF(child_ptr);
2045 else
2046 ret_val = SWIGBridge::LLDBSWIGPython_GetValueObjectSPFromSBValue(
2047 sb_value_ptr);
2048 } else {
2049 Py_XDECREF(child_ptr);
2050 }
2051 }
2052
2053 return ret_val;
2054}
2055
2056ConstString ScriptInterpreterPythonImpl::GetSyntheticTypeName(
2057 const StructuredData::ObjectSP &implementor_sp) {
2058 Locker py_lock(this,
2059 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2060
2061 if (!implementor_sp)
2062 return {};
2063
2064 StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
2065 if (!generic)
2066 return {};
2067
2068 PythonObject implementor(PyRefType::Borrowed,
2069 (PyObject *)generic->GetValue());
2070 if (!implementor.IsAllocated())
2071 return {};
2072
2073 llvm::Expected<PythonObject> expected_py_return =
2074 implementor.CallMethod("get_type_name");
2075
2076 if (!expected_py_return) {
2077 llvm::consumeError(expected_py_return.takeError());
2078 return {};
2079 }
2080
2081 PythonObject py_return = std::move(expected_py_return.get());
2082 if (!py_return.IsAllocated() || !PythonString::Check(py_return.get()))
2083 return {};
2084
2085 PythonString type_name(PyRefType::Borrowed, py_return.get());
2086 return ConstString(type_name.GetString());
2087}
2088
2089bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
2090 const char *impl_function, Process *process, std::string &output,
2091 Status &error) {
2092 bool ret_val;
2093 if (!process) {
2094 error = Status::FromErrorString("no process");
2095 return false;
2096 }
2097 if (!impl_function || !impl_function[0]) {
2098 error = Status::FromErrorString("no function to execute");
2099 return false;
2100 }
2101
2102 {
2103 Locker py_lock(this,
2104 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2105 ret_val = SWIGBridge::LLDBSWIGPythonRunScriptKeywordProcess(
2106 impl_function, m_dictionary_name.c_str(), process->shared_from_this(),
2107 output);
2108 if (!ret_val)
2109 error = Status::FromErrorString("python script evaluation failed");
2110 }
2111 return ret_val;
2112}
2113
2114bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
2115 const char *impl_function, Thread *thread, std::string &output,
2116 Status &error) {
2117 if (!thread) {
2118 error = Status::FromErrorString("no thread");
2119 return false;
2120 }
2121 if (!impl_function || !impl_function[0]) {
2122 error = Status::FromErrorString("no function to execute");
2123 return false;
2124 }
2125
2126 Locker py_lock(this,
2127 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2128 if (std::optional<std::string> result =
2129 SWIGBridge::LLDBSWIGPythonRunScriptKeywordThread(
2130 impl_function, m_dictionary_name.c_str(),
2131 thread->shared_from_this())) {
2132 output = std::move(*result);
2133 return true;
2134 }
2135 error = Status::FromErrorString("python script evaluation failed");
2136 return false;
2137}
2138
2139bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
2140 const char *impl_function, Target *target, std::string &output,
2141 Status &error) {
2142 bool ret_val;
2143 if (!target) {
2144 error = Status::FromErrorString("no thread");
2145 return false;
2146 }
2147 if (!impl_function || !impl_function[0]) {
2148 error = Status::FromErrorString("no function to execute");
2149 return false;
2150 }
2151
2152 {
2153 TargetSP target_sp(target->shared_from_this());
2154 Locker py_lock(this,
2155 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2156 ret_val = SWIGBridge::LLDBSWIGPythonRunScriptKeywordTarget(
2157 impl_function, m_dictionary_name.c_str(), target_sp, output);
2158 if (!ret_val)
2159 error = Status::FromErrorString("python script evaluation failed");
2160 }
2161 return ret_val;
2162}
2163
2164bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
2165 const char *impl_function, StackFrame *frame, std::string &output,
2166 Status &error) {
2167 if (!frame) {
2168 error = Status::FromErrorString("no frame");
2169 return false;
2170 }
2171 if (!impl_function || !impl_function[0]) {
2172 error = Status::FromErrorString("no function to execute");
2173 return false;
2174 }
2175
2176 Locker py_lock(this,
2177 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2178 if (std::optional<std::string> result =
2179 SWIGBridge::LLDBSWIGPythonRunScriptKeywordFrame(
2180 impl_function, m_dictionary_name.c_str(),
2181 frame->shared_from_this())) {
2182 output = std::move(*result);
2183 return true;
2184 }
2185 error = Status::FromErrorString("python script evaluation failed");
2186 return false;
2187}
2188
2189bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
2190 const char *impl_function, ValueObject *value, std::string &output,
2191 Status &error) {
2192 bool ret_val;
2193 if (!value) {
2194 error = Status::FromErrorString("no value");
2195 return false;
2196 }
2197 if (!impl_function || !impl_function[0]) {
2198 error = Status::FromErrorString("no function to execute");
2199 return false;
2200 }
2201
2202 {
2203 Locker py_lock(this,
2204 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2205 ret_val = SWIGBridge::LLDBSWIGPythonRunScriptKeywordValue(
2206 impl_function, m_dictionary_name.c_str(), value->GetSP(), output);
2207 if (!ret_val)
2208 error = Status::FromErrorString("python script evaluation failed");
2209 }
2210 return ret_val;
2211}
2212
2213uint64_t replace_all(std::string &str, const std::string &oldStr,
2214 const std::string &newStr) {
2215 size_t pos = 0;
2216 uint64_t matches = 0;
2217 while ((pos = str.find(oldStr, pos)) != std::string::npos) {
2218 matches++;
2219 str.replace(pos, oldStr.length(), newStr);
2220 pos += newStr.length();
2221 }
2222 return matches;
2223}
2224
2225bool ScriptInterpreterPythonImpl::LoadScriptingModule(
2226 const char *pathname, const LoadScriptOptions &options,
2228 FileSpec extra_search_dir, lldb::TargetSP target_sp) {
2229 namespace fs = llvm::sys::fs;
2230 namespace path = llvm::sys::path;
2231
2233 .SetEnableIO(!options.GetSilent())
2234 .SetSetLLDBGlobals(false);
2235
2236 if (!pathname || !pathname[0]) {
2237 error = Status::FromErrorString("empty path");
2238 return false;
2239 }
2240
2241 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
2242 io_redirect_or_error = ScriptInterpreterIORedirect::Create(
2243 exc_options.GetEnableIO(), m_debugger, /*result=*/nullptr);
2244
2245 if (!io_redirect_or_error) {
2246 error = Status::FromError(io_redirect_or_error.takeError());
2247 return false;
2248 }
2249
2250 ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
2251
2252 // Before executing Python code, lock the GIL.
2253 Locker py_lock(this,
2254 Locker::AcquireLock |
2255 (options.GetInitSession() ? Locker::InitSession : 0) |
2256 Locker::NoSTDIN,
2257 Locker::FreeAcquiredLock |
2258 (options.GetInitSession() ? Locker::TearDownSession : 0),
2259 io_redirect.GetInputFile(), io_redirect.GetOutputFile(),
2260 io_redirect.GetErrorFile());
2261
2262 auto ExtendSysPath = [&](std::string directory) -> llvm::Error {
2263 if (directory.empty()) {
2264 return llvm::createStringError("invalid directory name");
2265 }
2266
2267 replace_all(directory, "\\", "\\\\");
2268 replace_all(directory, "'", "\\'");
2269
2270 // Make sure that Python has "directory" in the search path.
2271 StreamString command_stream;
2272 command_stream.Printf("if not (sys.path.__contains__('%s')):\n "
2273 "sys.path.insert(1,'%s');\n\n",
2274 directory.c_str(), directory.c_str());
2275 bool syspath_retval =
2276 ExecuteMultipleLines(command_stream.GetData(), exc_options).Success();
2277 if (!syspath_retval)
2278 return llvm::createStringError("Python sys.path handling failed");
2279
2280 return llvm::Error::success();
2281 };
2282
2283 std::string module_name(pathname);
2284 bool possible_package = false;
2285
2286 if (extra_search_dir) {
2287 if (llvm::Error e = ExtendSysPath(extra_search_dir.GetPath())) {
2288 error = Status::FromError(std::move(e));
2289 return false;
2290 }
2291 } else {
2292 FileSpec module_file(pathname);
2293 FileSystem::Instance().Resolve(module_file);
2294
2295 fs::file_status st;
2296 std::error_code ec = status(module_file.GetPath(), st);
2297
2298 if (ec || st.type() == fs::file_type::status_error ||
2299 st.type() == fs::file_type::type_unknown ||
2300 st.type() == fs::file_type::file_not_found) {
2301 // if not a valid file of any sort, check if it might be a filename still
2302 // dot can't be used but / and \ can, and if either is found, reject
2303 if (strchr(pathname, '\\') || strchr(pathname, '/')) {
2304 error = Status::FromErrorStringWithFormatv("invalid pathname '{0}'",
2305 pathname);
2306 return false;
2307 }
2308 // Not a filename, probably a package of some sort, let it go through.
2309 possible_package = true;
2310 } else if (is_directory(st) || is_regular_file(st)) {
2311 if (module_file.GetDirectory().IsEmpty()) {
2313 "invalid directory name '{0}'", pathname);
2314 return false;
2315 }
2316 if (llvm::Error e =
2317 ExtendSysPath(module_file.GetDirectory().GetCString())) {
2318 error = Status::FromError(std::move(e));
2319 return false;
2320 }
2321 module_name = module_file.GetFilename().GetCString();
2322 } else {
2324 "no known way to import this module specification");
2325 return false;
2326 }
2327 }
2328
2329 // Strip .py or .pyc extension
2330 llvm::StringRef extension = llvm::sys::path::extension(module_name);
2331 if (!extension.empty()) {
2332 if (extension == ".py")
2333 module_name.resize(module_name.length() - 3);
2334 else if (extension == ".pyc")
2335 module_name.resize(module_name.length() - 4);
2336 }
2337
2338 if (!possible_package && module_name.find('.') != llvm::StringRef::npos) {
2340 "Python does not allow dots in module names: %s", module_name.c_str());
2341 return false;
2342 }
2343
2344 if (module_name.find('-') != llvm::StringRef::npos) {
2346 "Python discourages dashes in module names: %s", module_name.c_str());
2347 return false;
2348 }
2349
2350 // Check if the module is already imported.
2351 StreamString command_stream;
2352 command_stream.Clear();
2353 command_stream.Printf("sys.modules.__contains__('%s')", module_name.c_str());
2354 bool does_contain = false;
2355 // This call will succeed if the module was ever imported in any Debugger in
2356 // the lifetime of the process in which this LLDB framework is living.
2357 const bool does_contain_executed = ExecuteOneLineWithReturn(
2358 command_stream.GetData(),
2359 ScriptInterpreterPythonImpl::eScriptReturnTypeBool, &does_contain,
2360 exc_options);
2361
2362 const bool was_imported_globally = does_contain_executed && does_contain;
2363 const bool was_imported_locally =
2364 GetSessionDictionary()
2365 .GetItemForKey(PythonString(module_name))
2366 .IsAllocated();
2367
2368 // now actually do the import
2369 command_stream.Clear();
2370
2371 if (was_imported_globally || was_imported_locally) {
2372 if (!was_imported_locally)
2373 command_stream.Printf("import %s ; reload_module(%s)",
2374 module_name.c_str(), module_name.c_str());
2375 else
2376 command_stream.Printf("reload_module(%s)", module_name.c_str());
2377 } else
2378 command_stream.Printf("import %s", module_name.c_str());
2379
2380 error = ExecuteMultipleLines(command_stream.GetData(), exc_options);
2381 if (error.Fail())
2382 return false;
2383
2384 // if we are here, everything worked
2385 // call __lldb_init_module(debugger,dict)
2386 if (!SWIGBridge::LLDBSwigPythonCallModuleInit(
2387 module_name.c_str(), m_dictionary_name.c_str(),
2388 m_debugger.shared_from_this())) {
2389 error = Status::FromErrorString("calling __lldb_init_module failed");
2390 return false;
2391 }
2392
2393 if (module_sp) {
2394 // everything went just great, now set the module object
2395 command_stream.Clear();
2396 command_stream.Printf("%s", module_name.c_str());
2397 void *module_pyobj = nullptr;
2398 if (ExecuteOneLineWithReturn(
2399 command_stream.GetData(),
2401 exc_options) &&
2402 module_pyobj)
2403 *module_sp = std::make_shared<StructuredPythonObject>(PythonObject(
2404 PyRefType::Owned, static_cast<PyObject *>(module_pyobj)));
2405 }
2406
2407 // Finally, if we got a target passed in, then we should tell the new module
2408 // about this target:
2409 if (target_sp)
2410 return SWIGBridge::LLDBSwigPythonCallModuleNewTarget(
2411 module_name.c_str(), m_dictionary_name.c_str(), target_sp);
2412
2413 return true;
2414}
2415
2416bool ScriptInterpreterPythonImpl::IsReservedWord(const char *word) {
2417 if (!word || !word[0])
2418 return false;
2419
2420 llvm::StringRef word_sr(word);
2421
2422 // filter out a few characters that would just confuse us and that are
2423 // clearly not keyword material anyway
2424 if (word_sr.find('"') != llvm::StringRef::npos ||
2425 word_sr.find('\'') != llvm::StringRef::npos)
2426 return false;
2427
2428 StreamString command_stream;
2429 command_stream.Printf("keyword.iskeyword('%s')", word);
2430 bool result;
2431 ExecuteScriptOptions options;
2432 options.SetEnableIO(false);
2433 options.SetMaskoutErrors(true);
2434 options.SetSetLLDBGlobals(false);
2435 if (ExecuteOneLineWithReturn(command_stream.GetData(),
2437 &result, options))
2438 return result;
2439 return false;
2440}
2441
2442ScriptInterpreterPythonImpl::SynchronicityHandler::SynchronicityHandler(
2443 lldb::DebuggerSP debugger_sp, ScriptedCommandSynchronicity synchro)
2444 : m_debugger_sp(debugger_sp), m_synch_wanted(synchro),
2445 m_old_asynch(debugger_sp->GetAsyncExecution()) {
2446 if (m_synch_wanted == eScriptedCommandSynchronicitySynchronous)
2447 m_debugger_sp->SetAsyncExecution(false);
2448 else if (m_synch_wanted == eScriptedCommandSynchronicityAsynchronous)
2449 m_debugger_sp->SetAsyncExecution(true);
2450}
2451
2452ScriptInterpreterPythonImpl::SynchronicityHandler::~SynchronicityHandler() {
2453 if (m_synch_wanted != eScriptedCommandSynchronicityCurrentValue)
2454 m_debugger_sp->SetAsyncExecution(m_old_asynch);
2455}
2456
2457bool ScriptInterpreterPythonImpl::RunScriptBasedCommand(
2458 const char *impl_function, llvm::StringRef args,
2459 ScriptedCommandSynchronicity synchronicity,
2461 const lldb_private::ExecutionContext &exe_ctx) {
2462 if (!impl_function) {
2463 error = Status::FromErrorString("no function to execute");
2464 return false;
2465 }
2466
2467 lldb::DebuggerSP debugger_sp = m_debugger.shared_from_this();
2468 lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx));
2469
2470 if (!debugger_sp.get()) {
2471 error = Status::FromErrorString("invalid Debugger pointer");
2472 return false;
2473 }
2474
2475 bool ret_val = false;
2476
2477 {
2478 Locker py_lock(this,
2479 Locker::AcquireLock | Locker::InitSession |
2480 (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN),
2481 Locker::FreeLock | Locker::TearDownSession);
2482
2483 SynchronicityHandler synch_handler(debugger_sp, synchronicity);
2484
2485 std::string args_str = args.str();
2486 ret_val = SWIGBridge::LLDBSwigPythonCallCommand(
2487 impl_function, m_dictionary_name.c_str(), debugger_sp, args_str.c_str(),
2488 cmd_retobj, exe_ctx_ref_sp);
2489 }
2490
2491 if (!ret_val)
2492 error = Status::FromErrorString("unable to execute script function");
2493 else if (cmd_retobj.GetStatus() == eReturnStatusFailed)
2494 return false;
2495
2496 error.Clear();
2497 return ret_val;
2498}
2499
2500bool ScriptInterpreterPythonImpl::RunScriptBasedCommand(
2501 StructuredData::GenericSP impl_obj_sp, llvm::StringRef args,
2502 ScriptedCommandSynchronicity synchronicity,
2504 const lldb_private::ExecutionContext &exe_ctx) {
2505 if (!impl_obj_sp || !impl_obj_sp->IsValid()) {
2506 error = Status::FromErrorString("no function to execute");
2507 return false;
2508 }
2509
2510 lldb::DebuggerSP debugger_sp = m_debugger.shared_from_this();
2511 lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx));
2512
2513 if (!debugger_sp.get()) {
2514 error = Status::FromErrorString("invalid Debugger pointer");
2515 return false;
2516 }
2517
2518 bool ret_val = false;
2519
2520 {
2521 Locker py_lock(this,
2522 Locker::AcquireLock | Locker::InitSession |
2523 (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN),
2524 Locker::FreeLock | Locker::TearDownSession);
2525
2526 SynchronicityHandler synch_handler(debugger_sp, synchronicity);
2527
2528 std::string args_str = args.str();
2529 ret_val = SWIGBridge::LLDBSwigPythonCallCommandObject(
2530 static_cast<PyObject *>(impl_obj_sp->GetValue()), debugger_sp,
2531 args_str.c_str(), cmd_retobj, exe_ctx_ref_sp);
2532 }
2533
2534 if (!ret_val)
2535 error = Status::FromErrorString("unable to execute script function");
2536 else if (cmd_retobj.GetStatus() == eReturnStatusFailed)
2537 return false;
2538
2539 error.Clear();
2540 return ret_val;
2541}
2542
2543bool ScriptInterpreterPythonImpl::RunScriptBasedParsedCommand(
2544 StructuredData::GenericSP impl_obj_sp, Args &args,
2545 ScriptedCommandSynchronicity synchronicity,
2547 const lldb_private::ExecutionContext &exe_ctx) {
2548 if (!impl_obj_sp || !impl_obj_sp->IsValid()) {
2549 error = Status::FromErrorString("no function to execute");
2550 return false;
2551 }
2552
2553 lldb::DebuggerSP debugger_sp = m_debugger.shared_from_this();
2554 lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx));
2555
2556 if (!debugger_sp.get()) {
2557 error = Status::FromErrorString("invalid Debugger pointer");
2558 return false;
2559 }
2560
2561 bool ret_val = false;
2562
2563 {
2564 Locker py_lock(this,
2565 Locker::AcquireLock | Locker::InitSession |
2566 (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN),
2567 Locker::FreeLock | Locker::TearDownSession);
2568
2569 SynchronicityHandler synch_handler(debugger_sp, synchronicity);
2570
2572
2573 for (const Args::ArgEntry &entry : args) {
2574 args_arr_sp->AddStringItem(entry.ref());
2575 }
2576 StructuredDataImpl args_impl(args_arr_sp);
2577
2578 ret_val = SWIGBridge::LLDBSwigPythonCallParsedCommandObject(
2579 static_cast<PyObject *>(impl_obj_sp->GetValue()), debugger_sp,
2580 args_impl, cmd_retobj, exe_ctx_ref_sp);
2581 }
2582
2583 if (!ret_val)
2584 error = Status::FromErrorString("unable to execute script function");
2585 else if (cmd_retobj.GetStatus() == eReturnStatusFailed)
2586 return false;
2587
2588 error.Clear();
2589 return ret_val;
2590}
2591
2592std::optional<std::string>
2593ScriptInterpreterPythonImpl::GetRepeatCommandForScriptedCommand(
2594 StructuredData::GenericSP impl_obj_sp, Args &args) {
2595 if (!impl_obj_sp || !impl_obj_sp->IsValid())
2596 return std::nullopt;
2597
2598 lldb::DebuggerSP debugger_sp = m_debugger.shared_from_this();
2599
2600 if (!debugger_sp.get())
2601 return std::nullopt;
2602
2603 std::optional<std::string> ret_val;
2604
2605 {
2606 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN,
2607 Locker::FreeLock);
2608
2610
2611 // For scripting commands, we send the command string:
2612 std::string command;
2613 args.GetQuotedCommandString(command);
2614 ret_val = SWIGBridge::LLDBSwigPythonGetRepeatCommandForScriptedCommand(
2615 static_cast<PyObject *>(impl_obj_sp->GetValue()), command);
2616 }
2617 return ret_val;
2618}
2619
2621ScriptInterpreterPythonImpl::HandleArgumentCompletionForScriptedCommand(
2622 StructuredData::GenericSP impl_obj_sp, std::vector<llvm::StringRef> &args,
2623 size_t args_pos, size_t char_in_arg) {
2624 StructuredData::DictionarySP completion_dict_sp;
2625 if (!impl_obj_sp || !impl_obj_sp->IsValid())
2626 return completion_dict_sp;
2627
2628 {
2629 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN,
2630 Locker::FreeLock);
2631
2632 completion_dict_sp =
2633 SWIGBridge::LLDBSwigPythonHandleArgumentCompletionForScriptedCommand(
2634 static_cast<PyObject *>(impl_obj_sp->GetValue()), args, args_pos,
2635 char_in_arg);
2636 }
2637 return completion_dict_sp;
2638}
2639
2641ScriptInterpreterPythonImpl::HandleOptionArgumentCompletionForScriptedCommand(
2642 StructuredData::GenericSP impl_obj_sp, llvm::StringRef &long_option,
2643 size_t char_in_arg) {
2644 StructuredData::DictionarySP completion_dict_sp;
2645 if (!impl_obj_sp || !impl_obj_sp->IsValid())
2646 return completion_dict_sp;
2647
2648 {
2649 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN,
2650 Locker::FreeLock);
2651
2652 completion_dict_sp = SWIGBridge::
2653 LLDBSwigPythonHandleOptionArgumentCompletionForScriptedCommand(
2654 static_cast<PyObject *>(impl_obj_sp->GetValue()), long_option,
2655 char_in_arg);
2656 }
2657 return completion_dict_sp;
2658}
2659
2660/// In Python, a special attribute __doc__ contains the docstring for an object
2661/// (function, method, class, ...) if any is defined Otherwise, the attribute's
2662/// value is None.
2663bool ScriptInterpreterPythonImpl::GetDocumentationForItem(const char *item,
2664 std::string &dest) {
2665 dest.clear();
2666
2667 if (!item || !*item)
2668 return false;
2669
2670 std::string command(item);
2671 command += ".__doc__";
2672
2673 // Python is going to point this to valid data if ExecuteOneLineWithReturn
2674 // returns successfully.
2675 char *result_ptr = nullptr;
2676
2677 if (ExecuteOneLineWithReturn(
2679 &result_ptr, ExecuteScriptOptions().SetEnableIO(false))) {
2680 if (result_ptr)
2681 dest.assign(result_ptr);
2682 return true;
2683 }
2684
2685 StreamString str_stream;
2686 str_stream << "Function " << item
2687 << " was not found. Containing module might be missing.";
2688 dest = std::string(str_stream.GetString());
2689
2690 return false;
2691}
2692
2693bool ScriptInterpreterPythonImpl::GetShortHelpForCommandObject(
2694 StructuredData::GenericSP cmd_obj_sp, std::string &dest) {
2695 dest.clear();
2696
2697 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
2698
2699 if (!cmd_obj_sp)
2700 return false;
2701
2702 PythonObject implementor(PyRefType::Borrowed,
2703 (PyObject *)cmd_obj_sp->GetValue());
2704
2705 if (!implementor.IsAllocated())
2706 return false;
2707
2708 llvm::Expected<PythonObject> expected_py_return =
2709 implementor.CallMethod("get_short_help");
2710
2711 if (!expected_py_return) {
2712 llvm::consumeError(expected_py_return.takeError());
2713 return false;
2714 }
2715
2716 PythonObject py_return = std::move(expected_py_return.get());
2717
2718 if (py_return.IsAllocated() && PythonString::Check(py_return.get())) {
2719 PythonString py_string(PyRefType::Borrowed, py_return.get());
2720 llvm::StringRef return_data(py_string.GetString());
2721 dest.assign(return_data.data(), return_data.size());
2722 return true;
2723 }
2724
2725 return false;
2726}
2727
2728uint32_t ScriptInterpreterPythonImpl::GetFlagsForCommandObject(
2729 StructuredData::GenericSP cmd_obj_sp) {
2730 uint32_t result = 0;
2731
2732 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
2733
2734 static char callee_name[] = "get_flags";
2735
2736 if (!cmd_obj_sp)
2737 return result;
2738
2739 PythonObject implementor(PyRefType::Borrowed,
2740 (PyObject *)cmd_obj_sp->GetValue());
2741
2742 if (!implementor.IsAllocated())
2743 return result;
2744
2745 PythonObject pmeth(PyRefType::Owned,
2746 PyObject_GetAttrString(implementor.get(), callee_name));
2747
2748 if (PyErr_Occurred())
2749 PyErr_Clear();
2750
2751 if (!pmeth.IsAllocated())
2752 return result;
2753
2754 if (PyCallable_Check(pmeth.get()) == 0) {
2755 if (PyErr_Occurred())
2756 PyErr_Clear();
2757 return result;
2758 }
2759
2760 if (PyErr_Occurred())
2761 PyErr_Clear();
2762
2763 long long py_return = unwrapOrSetPythonException(
2764 As<long long>(implementor.CallMethod(callee_name)));
2765
2766 // if it fails, print the error but otherwise go on
2767 if (PyErr_Occurred()) {
2768 PyErr_Print();
2769 PyErr_Clear();
2770 } else {
2771 result = py_return;
2772 }
2773
2774 return result;
2775}
2776
2778ScriptInterpreterPythonImpl::GetOptionsForCommandObject(
2779 StructuredData::GenericSP cmd_obj_sp) {
2780 StructuredData::ObjectSP result = {};
2781
2782 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
2783
2784 static char callee_name[] = "get_options_definition";
2785
2786 if (!cmd_obj_sp)
2787 return result;
2788
2789 PythonObject implementor(PyRefType::Borrowed,
2790 (PyObject *)cmd_obj_sp->GetValue());
2791
2792 if (!implementor.IsAllocated())
2793 return result;
2794
2795 PythonObject pmeth(PyRefType::Owned,
2796 PyObject_GetAttrString(implementor.get(), callee_name));
2797
2798 if (PyErr_Occurred())
2799 PyErr_Clear();
2800
2801 if (!pmeth.IsAllocated())
2802 return result;
2803
2804 if (PyCallable_Check(pmeth.get()) == 0) {
2805 if (PyErr_Occurred())
2806 PyErr_Clear();
2807 return result;
2808 }
2809
2810 if (PyErr_Occurred())
2811 PyErr_Clear();
2812
2813 PythonDictionary py_return = unwrapOrSetPythonException(
2814 As<PythonDictionary>(implementor.CallMethod(callee_name)));
2815
2816 // if it fails, print the error but otherwise go on
2817 if (PyErr_Occurred()) {
2818 PyErr_Print();
2819 PyErr_Clear();
2820 return {};
2821 }
2822 return py_return.CreateStructuredObject();
2823}
2824
2826ScriptInterpreterPythonImpl::GetArgumentsForCommandObject(
2827 StructuredData::GenericSP cmd_obj_sp) {
2828 StructuredData::ObjectSP result = {};
2829
2830 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
2831
2832 static char callee_name[] = "get_args_definition";
2833
2834 if (!cmd_obj_sp)
2835 return result;
2836
2837 PythonObject implementor(PyRefType::Borrowed,
2838 (PyObject *)cmd_obj_sp->GetValue());
2839
2840 if (!implementor.IsAllocated())
2841 return result;
2842
2843 PythonObject pmeth(PyRefType::Owned,
2844 PyObject_GetAttrString(implementor.get(), callee_name));
2845
2846 if (PyErr_Occurred())
2847 PyErr_Clear();
2848
2849 if (!pmeth.IsAllocated())
2850 return result;
2851
2852 if (PyCallable_Check(pmeth.get()) == 0) {
2853 if (PyErr_Occurred())
2854 PyErr_Clear();
2855 return result;
2856 }
2857
2858 if (PyErr_Occurred())
2859 PyErr_Clear();
2860
2861 PythonList py_return = unwrapOrSetPythonException(
2862 As<PythonList>(implementor.CallMethod(callee_name)));
2863
2864 // if it fails, print the error but otherwise go on
2865 if (PyErr_Occurred()) {
2866 PyErr_Print();
2867 PyErr_Clear();
2868 return {};
2869 }
2870 return py_return.CreateStructuredObject();
2871}
2872
2873void ScriptInterpreterPythonImpl::OptionParsingStartedForCommandObject(
2874 StructuredData::GenericSP cmd_obj_sp) {
2875
2876 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
2877
2878 static char callee_name[] = "option_parsing_started";
2879
2880 if (!cmd_obj_sp)
2881 return;
2882
2883 PythonObject implementor(PyRefType::Borrowed,
2884 (PyObject *)cmd_obj_sp->GetValue());
2885
2886 if (!implementor.IsAllocated())
2887 return;
2888
2889 PythonObject pmeth(PyRefType::Owned,
2890 PyObject_GetAttrString(implementor.get(), callee_name));
2891
2892 if (PyErr_Occurred())
2893 PyErr_Clear();
2894
2895 if (!pmeth.IsAllocated())
2896 return;
2897
2898 if (PyCallable_Check(pmeth.get()) == 0) {
2899 if (PyErr_Occurred())
2900 PyErr_Clear();
2901 return;
2902 }
2903
2904 if (PyErr_Occurred())
2905 PyErr_Clear();
2906
2907 // option_parsing_starting doesn't return anything, ignore anything but
2908 // python errors.
2909 unwrapOrSetPythonException(As<bool>(implementor.CallMethod(callee_name)));
2910
2911 // if it fails, print the error but otherwise go on
2912 if (PyErr_Occurred()) {
2913 PyErr_Print();
2914 PyErr_Clear();
2915 return;
2916 }
2917}
2918
2919bool ScriptInterpreterPythonImpl::SetOptionValueForCommandObject(
2920 StructuredData::GenericSP cmd_obj_sp, ExecutionContext *exe_ctx,
2921 llvm::StringRef long_option, llvm::StringRef value) {
2922 StructuredData::ObjectSP result = {};
2923
2924 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
2925
2926 static char callee_name[] = "set_option_value";
2927
2928 if (!cmd_obj_sp)
2929 return false;
2930
2931 PythonObject implementor(PyRefType::Borrowed,
2932 (PyObject *)cmd_obj_sp->GetValue());
2933
2934 if (!implementor.IsAllocated())
2935 return false;
2936
2937 PythonObject pmeth(PyRefType::Owned,
2938 PyObject_GetAttrString(implementor.get(), callee_name));
2939
2940 if (PyErr_Occurred())
2941 PyErr_Clear();
2942
2943 if (!pmeth.IsAllocated())
2944 return false;
2945
2946 if (PyCallable_Check(pmeth.get()) == 0) {
2947 if (PyErr_Occurred())
2948 PyErr_Clear();
2949 return false;
2950 }
2951
2952 if (PyErr_Occurred())
2953 PyErr_Clear();
2954
2955 lldb::ExecutionContextRefSP exe_ctx_ref_sp;
2956 if (exe_ctx)
2957 exe_ctx_ref_sp = std::make_shared<ExecutionContextRef>(exe_ctx);
2958 PythonObject ctx_ref_obj = SWIGBridge::ToSWIGWrapper(exe_ctx_ref_sp);
2959
2960 bool py_return = unwrapOrSetPythonException(As<bool>(
2961 implementor.CallMethod(callee_name, ctx_ref_obj,
2962 long_option.str().c_str(), value.str().c_str())));
2963
2964 // if it fails, print the error but otherwise go on
2965 if (PyErr_Occurred()) {
2966 PyErr_Print();
2967 PyErr_Clear();
2968 return false;
2969 }
2970 return py_return;
2971}
2972
2973bool ScriptInterpreterPythonImpl::GetLongHelpForCommandObject(
2974 StructuredData::GenericSP cmd_obj_sp, std::string &dest) {
2975 dest.clear();
2976
2977 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
2978
2979 if (!cmd_obj_sp)
2980 return false;
2981
2982 PythonObject implementor(PyRefType::Borrowed,
2983 (PyObject *)cmd_obj_sp->GetValue());
2984
2985 if (!implementor.IsAllocated())
2986 return false;
2987
2988 llvm::Expected<PythonObject> expected_py_return =
2989 implementor.CallMethod("get_long_help");
2990
2991 if (!expected_py_return) {
2992 llvm::consumeError(expected_py_return.takeError());
2993 return false;
2994 }
2995
2996 PythonObject py_return = std::move(expected_py_return.get());
2997
2998 bool got_string = false;
2999 if (py_return.IsAllocated() && PythonString::Check(py_return.get())) {
3000 PythonString str(PyRefType::Borrowed, py_return.get());
3001 llvm::StringRef str_data(str.GetString());
3002 dest.assign(str_data.data(), str_data.size());
3003 got_string = true;
3004 }
3005
3006 return got_string;
3007}
3008
3009std::unique_ptr<ScriptInterpreterLocker>
3010ScriptInterpreterPythonImpl::AcquireInterpreterLock() {
3011 std::unique_ptr<ScriptInterpreterLocker> py_lock(new Locker(
3012 this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN,
3013 Locker::FreeLock | Locker::TearDownSession));
3014 return py_lock;
3015}
3016
3017void ScriptInterpreterPythonImpl::Initialize() {
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
3026 LLDBSwigPyInit();
3027
3028 // Update the path python uses to search for modules to include the current
3029 // directory.
3030
3031 RunSimpleString("import sys");
3032 AddToSysPath(AddLocation::End, ".");
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
3068void ScriptInterpreterPythonImpl::AddToSysPath(AddLocation location,
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 (); }
3098
3099#endif
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:369
#define LLDB_LOGF(log,...)
Definition Log.h:376
#define LLDB_LOGV(log,...)
Definition Log.h:383
#define LLDB_PLUGIN_DEFINE(PluginName)
@ eIOHandlerWatchpoint
@ eIOHandlerBreakpoint
#define LLDB_SCOPED_TIMER()
Definition Timer.h:83
"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 void AppendError(llvm::StringRef in_string)
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
void AppendErrorWithFormatv(const char *format, Args &&...args)
A class to manage flag bits.
Definition Debugger.h:80
void RunIOHandlerAsync(const lldb::IOHandlerSP &reader_sp, bool cancel_top_handler=true)
Run the given IO handler and return immediately.
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.
static FileSystem & Instance()
bool IsValid() const override
IsValid.
Definition File.cpp:113
virtual Status Flush()
Flush the current stream.
Definition File.cpp:156
lldb::LockableStreamFileSP GetErrorStreamFileSP()
Definition IOHandler.cpp:95
lldb::LockableStreamFileSP GetOutputStreamFileSP()
Definition IOHandler.cpp:93
void SetIsDone(bool b)
Definition IOHandler.h:81
LoadScriptOptions & SetInitSession(bool b)
LoadScriptOptions & SetSilent(bool b)
void PutCString(const char *cstr)
Definition Log.cpp:145
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
A plug-in interface definition class for debugging a process.
Definition Process.h:354
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.
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
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:137
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
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:65
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
std::shared_ptr< Generic > GenericSP
std::shared_ptr< Dictionary > DictionarySP
std::shared_ptr< Object > ObjectSP
std::shared_ptr< Array > ArraySP
lldb::BreakpointSP GetBreakpointByID(lldb::break_id_t break_id)
Definition Target.cpp:420
Debugger & GetDebugger() const
Definition Target.h:1139
WatchpointList & GetWatchpointList()
Definition Target.h:849
A timer class that simplifies common timing metrics.
Definition Timer.h:23
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.
#define UINT32_MAX
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:332
@ eScriptLanguagePython
std::shared_ptr< lldb_private::ScriptedStopHookInterface > ScriptedStopHookInterfaceSP
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::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::ValueObjectList > ValueObjectListSP
std::shared_ptr< lldb_private::Debugger > DebuggerSP
@ eReturnStatusFailed
std::shared_ptr< lldb_private::ScriptedFrameProviderInterface > ScriptedFrameProviderInterfaceSP
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::unique_ptr< lldb_private::ScriptedProcessInterface > ScriptedProcessInterfaceUP
std::shared_ptr< lldb_private::ScriptedFrameInterface > ScriptedFrameInterfaceSP
std::shared_ptr< lldb_private::ExecutionContextRef > ExecutionContextRefSP