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::CreateScriptedThreadPlanInterface() {
1531 return std::make_shared<ScriptedThreadPlanPythonInterface>(*this);
1532}
1533
1535ScriptInterpreterPythonImpl::CreateOperatingSystemInterface() {
1536 return std::make_shared<OperatingSystemPythonInterface>(*this);
1537}
1538
1540ScriptInterpreterPythonImpl::CreateStructuredDataFromScriptObject(
1541 ScriptObject obj) {
1542 void *ptr = const_cast<void *>(obj.GetPointer());
1543 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
1544 PythonObject py_obj(PyRefType::Borrowed, static_cast<PyObject *>(ptr));
1545 if (!py_obj.IsValid() || py_obj.IsNone())
1546 return {};
1547 return py_obj.CreateStructuredObject();
1548}
1549
1551ScriptInterpreterPythonImpl::LoadPluginModule(const FileSpec &file_spec,
1553 if (!FileSystem::Instance().Exists(file_spec)) {
1554 error = Status::FromErrorString("no such file");
1555 return StructuredData::ObjectSP();
1556 }
1557
1558 StructuredData::ObjectSP module_sp;
1559
1560 LoadScriptOptions load_script_options =
1562 if (LoadScriptingModule(file_spec.GetPath().c_str(), load_script_options,
1563 error, &module_sp))
1564 return module_sp;
1565
1566 return StructuredData::ObjectSP();
1567}
1568
1569StructuredData::DictionarySP ScriptInterpreterPythonImpl::GetDynamicSettings(
1570 StructuredData::ObjectSP plugin_module_sp, Target *target,
1571 const char *setting_name, lldb_private::Status &error) {
1572 if (!plugin_module_sp || !target || !setting_name || !setting_name[0])
1574 StructuredData::Generic *generic = plugin_module_sp->GetAsGeneric();
1575 if (!generic)
1577
1578 Locker py_lock(this,
1579 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1580 TargetSP target_sp(target->shared_from_this());
1581
1582 auto setting = (PyObject *)SWIGBridge::LLDBSWIGPython_GetDynamicSetting(
1583 generic->GetValue(), setting_name, target_sp);
1584
1585 if (!setting)
1587
1588 PythonDictionary py_dict =
1589 unwrapIgnoringErrors(As<PythonDictionary>(Take<PythonObject>(setting)));
1590
1591 if (!py_dict)
1593
1594 return py_dict.CreateStructuredDictionary();
1595}
1596
1598ScriptInterpreterPythonImpl::CreateSyntheticScriptedProvider(
1599 const char *class_name, lldb::ValueObjectSP valobj) {
1600 if (class_name == nullptr || class_name[0] == '\0')
1601 return StructuredData::ObjectSP();
1602
1603 if (!valobj.get())
1604 return StructuredData::ObjectSP();
1605
1606 ExecutionContext exe_ctx(valobj->GetExecutionContextRef());
1607 Target *target = exe_ctx.GetTargetPtr();
1608
1609 if (!target)
1610 return StructuredData::ObjectSP();
1611
1612 Debugger &debugger = target->GetDebugger();
1613 ScriptInterpreterPythonImpl *python_interpreter =
1614 GetPythonInterpreter(debugger);
1615
1616 if (!python_interpreter)
1617 return StructuredData::ObjectSP();
1618
1619 Locker py_lock(this,
1620 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1621 PythonObject ret_val = SWIGBridge::LLDBSwigPythonCreateSyntheticProvider(
1622 class_name, python_interpreter->m_dictionary_name.c_str(), valobj);
1623
1625 new StructuredPythonObject(std::move(ret_val)));
1626}
1627
1629ScriptInterpreterPythonImpl::CreateScriptCommandObject(const char *class_name) {
1630 DebuggerSP debugger_sp(m_debugger.shared_from_this());
1631
1632 if (class_name == nullptr || class_name[0] == '\0')
1634
1635 if (!debugger_sp.get())
1637
1638 Locker py_lock(this,
1639 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1640 PythonObject ret_val = SWIGBridge::LLDBSwigPythonCreateCommandObject(
1641 class_name, m_dictionary_name.c_str(), debugger_sp);
1642
1643 if (ret_val.IsValid())
1645 new StructuredPythonObject(std::move(ret_val)));
1646 else
1647 return {};
1648}
1649
1650bool ScriptInterpreterPythonImpl::GenerateTypeScriptFunction(
1651 const char *oneliner, std::string &output, const void *name_token) {
1652 StringList input;
1653 input.SplitIntoLines(oneliner, strlen(oneliner));
1654 return GenerateTypeScriptFunction(input, output, name_token);
1655}
1656
1657bool ScriptInterpreterPythonImpl::GenerateTypeSynthClass(
1658 const char *oneliner, std::string &output, const void *name_token) {
1659 StringList input;
1660 input.SplitIntoLines(oneliner, strlen(oneliner));
1661 return GenerateTypeSynthClass(input, output, name_token);
1662}
1663
1664Status ScriptInterpreterPythonImpl::GenerateBreakpointCommandCallbackData(
1665 StringList &user_input, std::string &output, bool has_extra_args,
1666 bool is_callback) {
1667 static uint32_t num_created_functions = 0;
1668 user_input.RemoveBlankLines();
1669 StreamString sstr;
1670 Status error;
1671 if (user_input.GetSize() == 0) {
1672 error = Status::FromErrorString("No input data.");
1673 return error;
1674 }
1675
1676 std::string auto_generated_function_name(GenerateUniqueName(
1677 "lldb_autogen_python_bp_callback_func_", num_created_functions));
1678 if (has_extra_args)
1679 sstr.Printf("def %s (frame, bp_loc, extra_args, internal_dict):",
1680 auto_generated_function_name.c_str());
1681 else
1682 sstr.Printf("def %s (frame, bp_loc, internal_dict):",
1683 auto_generated_function_name.c_str());
1684
1685 error = GenerateFunction(sstr.GetData(), user_input, is_callback);
1686 if (!error.Success())
1687 return error;
1688
1689 // Store the name of the auto-generated function to be called.
1690 output.assign(auto_generated_function_name);
1691 return error;
1692}
1693
1694bool ScriptInterpreterPythonImpl::GenerateWatchpointCommandCallbackData(
1695 StringList &user_input, std::string &output, bool is_callback) {
1696 static uint32_t num_created_functions = 0;
1697 user_input.RemoveBlankLines();
1698 StreamString sstr;
1699
1700 if (user_input.GetSize() == 0)
1701 return false;
1702
1703 std::string auto_generated_function_name(GenerateUniqueName(
1704 "lldb_autogen_python_wp_callback_func_", num_created_functions));
1705 sstr.Printf("def %s (frame, wp, internal_dict):",
1706 auto_generated_function_name.c_str());
1707
1708 if (!GenerateFunction(sstr.GetData(), user_input, is_callback).Success())
1709 return false;
1710
1711 // Store the name of the auto-generated function to be called.
1712 output.assign(auto_generated_function_name);
1713 return true;
1714}
1715
1716bool ScriptInterpreterPythonImpl::GetScriptedSummary(
1717 const char *python_function_name, lldb::ValueObjectSP valobj,
1718 StructuredData::ObjectSP &callee_wrapper_sp,
1719 const TypeSummaryOptions &options, std::string &retval) {
1720
1722
1723 if (!valobj.get()) {
1724 retval.assign("<no object>");
1725 return false;
1726 }
1727
1728 void *old_callee = nullptr;
1729 StructuredData::Generic *generic = nullptr;
1730 if (callee_wrapper_sp) {
1731 generic = callee_wrapper_sp->GetAsGeneric();
1732 if (generic)
1733 old_callee = generic->GetValue();
1734 }
1735 void *new_callee = old_callee;
1736
1737 bool ret_val;
1738 if (python_function_name && *python_function_name) {
1739 {
1740 Locker py_lock(this, Locker::AcquireLock | Locker::InitSession |
1741 Locker::NoSTDIN);
1742 {
1743 TypeSummaryOptionsSP options_sp(new TypeSummaryOptions(options));
1744
1745 static Timer::Category func_cat("LLDBSwigPythonCallTypeScript");
1746 Timer scoped_timer(func_cat, "LLDBSwigPythonCallTypeScript");
1747 ret_val = SWIGBridge::LLDBSwigPythonCallTypeScript(
1748 python_function_name, GetSessionDictionary().get(), valobj,
1749 &new_callee, options_sp, retval);
1750 }
1751 }
1752 } else {
1753 retval.assign("<no function name>");
1754 return false;
1755 }
1756
1757 if (new_callee && old_callee != new_callee) {
1758 Locker py_lock(this,
1759 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1760 callee_wrapper_sp = std::make_shared<StructuredPythonObject>(
1761 PythonObject(PyRefType::Borrowed, static_cast<PyObject *>(new_callee)));
1762 }
1763
1764 return ret_val;
1765}
1766
1767bool ScriptInterpreterPythonImpl::FormatterCallbackFunction(
1768 const char *python_function_name, TypeImplSP type_impl_sp) {
1769 Locker py_lock(this,
1770 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1771 return SWIGBridge::LLDBSwigPythonFormatterCallbackFunction(
1772 python_function_name, m_dictionary_name.c_str(), type_impl_sp);
1773}
1774
1775bool ScriptInterpreterPythonImpl::BreakpointCallbackFunction(
1776 void *baton, StoppointCallbackContext *context, user_id_t break_id,
1777 user_id_t break_loc_id) {
1778 CommandDataPython *bp_option_data = (CommandDataPython *)baton;
1779 const char *python_function_name = bp_option_data->script_source.c_str();
1780
1781 if (!context)
1782 return true;
1783
1784 ExecutionContext exe_ctx(context->exe_ctx_ref);
1785 Target *target = exe_ctx.GetTargetPtr();
1786
1787 if (!target)
1788 return true;
1789
1790 Debugger &debugger = target->GetDebugger();
1791 ScriptInterpreterPythonImpl *python_interpreter =
1792 GetPythonInterpreter(debugger);
1793
1794 if (!python_interpreter)
1795 return true;
1796
1797 if (python_function_name && python_function_name[0]) {
1798 const StackFrameSP stop_frame_sp(exe_ctx.GetFrameSP());
1799 BreakpointSP breakpoint_sp = target->GetBreakpointByID(break_id);
1800 if (breakpoint_sp) {
1801 const BreakpointLocationSP bp_loc_sp(
1802 breakpoint_sp->FindLocationByID(break_loc_id));
1803
1804 if (stop_frame_sp && bp_loc_sp) {
1805 bool ret_val = true;
1806 {
1807 Locker py_lock(python_interpreter, Locker::AcquireLock |
1808 Locker::InitSession |
1809 Locker::NoSTDIN);
1810 Expected<bool> maybe_ret_val =
1811 SWIGBridge::LLDBSwigPythonBreakpointCallbackFunction(
1812 python_function_name,
1813 python_interpreter->m_dictionary_name.c_str(), stop_frame_sp,
1814 bp_loc_sp, bp_option_data->m_extra_args);
1815
1816 if (!maybe_ret_val) {
1817
1818 llvm::handleAllErrors(
1819 maybe_ret_val.takeError(),
1820 [&](PythonException &E) {
1821 *debugger.GetAsyncErrorStream() << E.ReadBacktrace();
1822 },
1823 [&](const llvm::ErrorInfoBase &E) {
1824 *debugger.GetAsyncErrorStream() << E.message();
1825 });
1826
1827 } else {
1828 ret_val = maybe_ret_val.get();
1829 }
1830 }
1831 return ret_val;
1832 }
1833 }
1834 }
1835 // We currently always true so we stop in case anything goes wrong when
1836 // trying to call the script function
1837 return true;
1838}
1839
1840bool ScriptInterpreterPythonImpl::WatchpointCallbackFunction(
1841 void *baton, StoppointCallbackContext *context, user_id_t watch_id) {
1842 WatchpointOptions::CommandData *wp_option_data =
1844 const char *python_function_name = wp_option_data->script_source.c_str();
1845
1846 if (!context)
1847 return true;
1848
1849 ExecutionContext exe_ctx(context->exe_ctx_ref);
1850 Target *target = exe_ctx.GetTargetPtr();
1851
1852 if (!target)
1853 return true;
1854
1855 Debugger &debugger = target->GetDebugger();
1856 ScriptInterpreterPythonImpl *python_interpreter =
1857 GetPythonInterpreter(debugger);
1858
1859 if (!python_interpreter)
1860 return true;
1861
1862 if (python_function_name && python_function_name[0]) {
1863 const StackFrameSP stop_frame_sp(exe_ctx.GetFrameSP());
1864 WatchpointSP wp_sp = target->GetWatchpointList().FindByID(watch_id);
1865 if (wp_sp) {
1866 if (stop_frame_sp && wp_sp) {
1867 bool ret_val = true;
1868 {
1869 Locker py_lock(python_interpreter, Locker::AcquireLock |
1870 Locker::InitSession |
1871 Locker::NoSTDIN);
1872 ret_val = SWIGBridge::LLDBSwigPythonWatchpointCallbackFunction(
1873 python_function_name,
1874 python_interpreter->m_dictionary_name.c_str(), stop_frame_sp,
1875 wp_sp);
1876 }
1877 return ret_val;
1878 }
1879 }
1880 }
1881 // We currently always true so we stop in case anything goes wrong when
1882 // trying to call the script function
1883 return true;
1884}
1885
1886size_t ScriptInterpreterPythonImpl::CalculateNumChildren(
1887 const StructuredData::ObjectSP &implementor_sp, uint32_t max) {
1888 if (!implementor_sp)
1889 return 0;
1890 StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
1891 if (!generic)
1892 return 0;
1893 auto *implementor = static_cast<PyObject *>(generic->GetValue());
1894 if (!implementor)
1895 return 0;
1896
1897 size_t ret_val = 0;
1898
1899 {
1900 Locker py_lock(this,
1901 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1902 ret_val = SWIGBridge::LLDBSwigPython_CalculateNumChildren(implementor, max);
1903 }
1904
1905 return ret_val;
1906}
1907
1908lldb::ValueObjectSP ScriptInterpreterPythonImpl::GetChildAtIndex(
1909 const StructuredData::ObjectSP &implementor_sp, uint32_t idx) {
1910 if (!implementor_sp)
1911 return lldb::ValueObjectSP();
1912
1913 StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
1914 if (!generic)
1915 return lldb::ValueObjectSP();
1916 auto *implementor = static_cast<PyObject *>(generic->GetValue());
1917 if (!implementor)
1918 return lldb::ValueObjectSP();
1919
1920 lldb::ValueObjectSP ret_val;
1921 {
1922 Locker py_lock(this,
1923 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1924 PyObject *child_ptr =
1925 SWIGBridge::LLDBSwigPython_GetChildAtIndex(implementor, idx);
1926 if (child_ptr != nullptr && child_ptr != Py_None) {
1927 lldb::SBValue *sb_value_ptr =
1928 (lldb::SBValue *)LLDBSWIGPython_CastPyObjectToSBValue(child_ptr);
1929 if (sb_value_ptr == nullptr)
1930 Py_XDECREF(child_ptr);
1931 else
1932 ret_val = SWIGBridge::LLDBSWIGPython_GetValueObjectSPFromSBValue(
1933 sb_value_ptr);
1934 } else {
1935 Py_XDECREF(child_ptr);
1936 }
1937 }
1938
1939 return ret_val;
1940}
1941
1942llvm::Expected<int> ScriptInterpreterPythonImpl::GetIndexOfChildWithName(
1943 const StructuredData::ObjectSP &implementor_sp, const char *child_name) {
1944 if (!implementor_sp)
1945 return llvm::createStringError("Type has no child named '%s'", child_name);
1946
1947 StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
1948 if (!generic)
1949 return llvm::createStringError("Type has no child named '%s'", child_name);
1950 auto *implementor = static_cast<PyObject *>(generic->GetValue());
1951 if (!implementor)
1952 return llvm::createStringError("Type has no child named '%s'", child_name);
1953
1954 int ret_val = INT32_MAX;
1955
1956 {
1957 Locker py_lock(this,
1958 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1959 ret_val = SWIGBridge::LLDBSwigPython_GetIndexOfChildWithName(implementor,
1960 child_name);
1961 }
1962
1963 if (ret_val == INT32_MAX)
1964 return llvm::createStringError("Type has no child named '%s'", child_name);
1965 return ret_val;
1966}
1967
1968bool ScriptInterpreterPythonImpl::UpdateSynthProviderInstance(
1969 const StructuredData::ObjectSP &implementor_sp) {
1970 bool ret_val = false;
1971
1972 if (!implementor_sp)
1973 return ret_val;
1974
1975 StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
1976 if (!generic)
1977 return ret_val;
1978 auto *implementor = static_cast<PyObject *>(generic->GetValue());
1979 if (!implementor)
1980 return ret_val;
1981
1982 {
1983 Locker py_lock(this,
1984 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1985 ret_val =
1986 SWIGBridge::LLDBSwigPython_UpdateSynthProviderInstance(implementor);
1987 }
1988
1989 return ret_val;
1990}
1991
1992bool ScriptInterpreterPythonImpl::MightHaveChildrenSynthProviderInstance(
1993 const StructuredData::ObjectSP &implementor_sp) {
1994 bool ret_val = false;
1995
1996 if (!implementor_sp)
1997 return ret_val;
1998
1999 StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
2000 if (!generic)
2001 return ret_val;
2002 auto *implementor = static_cast<PyObject *>(generic->GetValue());
2003 if (!implementor)
2004 return ret_val;
2005
2006 {
2007 Locker py_lock(this,
2008 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2009 ret_val = SWIGBridge::LLDBSwigPython_MightHaveChildrenSynthProviderInstance(
2010 implementor);
2011 }
2012
2013 return ret_val;
2014}
2015
2016lldb::ValueObjectSP ScriptInterpreterPythonImpl::GetSyntheticValue(
2017 const StructuredData::ObjectSP &implementor_sp) {
2018 lldb::ValueObjectSP ret_val(nullptr);
2019
2020 if (!implementor_sp)
2021 return ret_val;
2022
2023 StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
2024 if (!generic)
2025 return ret_val;
2026 auto *implementor = static_cast<PyObject *>(generic->GetValue());
2027 if (!implementor)
2028 return ret_val;
2029
2030 {
2031 Locker py_lock(this,
2032 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2033 PyObject *child_ptr =
2034 SWIGBridge::LLDBSwigPython_GetValueSynthProviderInstance(implementor);
2035 if (child_ptr != nullptr && child_ptr != Py_None) {
2036 lldb::SBValue *sb_value_ptr =
2037 (lldb::SBValue *)LLDBSWIGPython_CastPyObjectToSBValue(child_ptr);
2038 if (sb_value_ptr == nullptr)
2039 Py_XDECREF(child_ptr);
2040 else
2041 ret_val = SWIGBridge::LLDBSWIGPython_GetValueObjectSPFromSBValue(
2042 sb_value_ptr);
2043 } else {
2044 Py_XDECREF(child_ptr);
2045 }
2046 }
2047
2048 return ret_val;
2049}
2050
2051ConstString ScriptInterpreterPythonImpl::GetSyntheticTypeName(
2052 const StructuredData::ObjectSP &implementor_sp) {
2053 Locker py_lock(this,
2054 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2055
2056 if (!implementor_sp)
2057 return {};
2058
2059 StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
2060 if (!generic)
2061 return {};
2062
2063 PythonObject implementor(PyRefType::Borrowed,
2064 (PyObject *)generic->GetValue());
2065 if (!implementor.IsAllocated())
2066 return {};
2067
2068 llvm::Expected<PythonObject> expected_py_return =
2069 implementor.CallMethod("get_type_name");
2070
2071 if (!expected_py_return) {
2072 llvm::consumeError(expected_py_return.takeError());
2073 return {};
2074 }
2075
2076 PythonObject py_return = std::move(expected_py_return.get());
2077 if (!py_return.IsAllocated() || !PythonString::Check(py_return.get()))
2078 return {};
2079
2080 PythonString type_name(PyRefType::Borrowed, py_return.get());
2081 return ConstString(type_name.GetString());
2082}
2083
2084bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
2085 const char *impl_function, Process *process, std::string &output,
2086 Status &error) {
2087 bool ret_val;
2088 if (!process) {
2089 error = Status::FromErrorString("no process");
2090 return false;
2091 }
2092 if (!impl_function || !impl_function[0]) {
2093 error = Status::FromErrorString("no function to execute");
2094 return false;
2095 }
2096
2097 {
2098 Locker py_lock(this,
2099 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2100 ret_val = SWIGBridge::LLDBSWIGPythonRunScriptKeywordProcess(
2101 impl_function, m_dictionary_name.c_str(), process->shared_from_this(),
2102 output);
2103 if (!ret_val)
2104 error = Status::FromErrorString("python script evaluation failed");
2105 }
2106 return ret_val;
2107}
2108
2109bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
2110 const char *impl_function, Thread *thread, std::string &output,
2111 Status &error) {
2112 if (!thread) {
2113 error = Status::FromErrorString("no thread");
2114 return false;
2115 }
2116 if (!impl_function || !impl_function[0]) {
2117 error = Status::FromErrorString("no function to execute");
2118 return false;
2119 }
2120
2121 Locker py_lock(this,
2122 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2123 if (std::optional<std::string> result =
2124 SWIGBridge::LLDBSWIGPythonRunScriptKeywordThread(
2125 impl_function, m_dictionary_name.c_str(),
2126 thread->shared_from_this())) {
2127 output = std::move(*result);
2128 return true;
2129 }
2130 error = Status::FromErrorString("python script evaluation failed");
2131 return false;
2132}
2133
2134bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
2135 const char *impl_function, Target *target, std::string &output,
2136 Status &error) {
2137 bool ret_val;
2138 if (!target) {
2139 error = Status::FromErrorString("no thread");
2140 return false;
2141 }
2142 if (!impl_function || !impl_function[0]) {
2143 error = Status::FromErrorString("no function to execute");
2144 return false;
2145 }
2146
2147 {
2148 TargetSP target_sp(target->shared_from_this());
2149 Locker py_lock(this,
2150 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2151 ret_val = SWIGBridge::LLDBSWIGPythonRunScriptKeywordTarget(
2152 impl_function, m_dictionary_name.c_str(), target_sp, output);
2153 if (!ret_val)
2154 error = Status::FromErrorString("python script evaluation failed");
2155 }
2156 return ret_val;
2157}
2158
2159bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
2160 const char *impl_function, StackFrame *frame, std::string &output,
2161 Status &error) {
2162 if (!frame) {
2163 error = Status::FromErrorString("no frame");
2164 return false;
2165 }
2166 if (!impl_function || !impl_function[0]) {
2167 error = Status::FromErrorString("no function to execute");
2168 return false;
2169 }
2170
2171 Locker py_lock(this,
2172 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2173 if (std::optional<std::string> result =
2174 SWIGBridge::LLDBSWIGPythonRunScriptKeywordFrame(
2175 impl_function, m_dictionary_name.c_str(),
2176 frame->shared_from_this())) {
2177 output = std::move(*result);
2178 return true;
2179 }
2180 error = Status::FromErrorString("python script evaluation failed");
2181 return false;
2182}
2183
2184bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
2185 const char *impl_function, ValueObject *value, std::string &output,
2186 Status &error) {
2187 bool ret_val;
2188 if (!value) {
2189 error = Status::FromErrorString("no value");
2190 return false;
2191 }
2192 if (!impl_function || !impl_function[0]) {
2193 error = Status::FromErrorString("no function to execute");
2194 return false;
2195 }
2196
2197 {
2198 Locker py_lock(this,
2199 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2200 ret_val = SWIGBridge::LLDBSWIGPythonRunScriptKeywordValue(
2201 impl_function, m_dictionary_name.c_str(), value->GetSP(), output);
2202 if (!ret_val)
2203 error = Status::FromErrorString("python script evaluation failed");
2204 }
2205 return ret_val;
2206}
2207
2208uint64_t replace_all(std::string &str, const std::string &oldStr,
2209 const std::string &newStr) {
2210 size_t pos = 0;
2211 uint64_t matches = 0;
2212 while ((pos = str.find(oldStr, pos)) != std::string::npos) {
2213 matches++;
2214 str.replace(pos, oldStr.length(), newStr);
2215 pos += newStr.length();
2216 }
2217 return matches;
2218}
2219
2220bool ScriptInterpreterPythonImpl::LoadScriptingModule(
2221 const char *pathname, const LoadScriptOptions &options,
2223 FileSpec extra_search_dir, lldb::TargetSP target_sp) {
2224 namespace fs = llvm::sys::fs;
2225 namespace path = llvm::sys::path;
2226
2228 .SetEnableIO(!options.GetSilent())
2229 .SetSetLLDBGlobals(false);
2230
2231 if (!pathname || !pathname[0]) {
2232 error = Status::FromErrorString("empty path");
2233 return false;
2234 }
2235
2236 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
2237 io_redirect_or_error = ScriptInterpreterIORedirect::Create(
2238 exc_options.GetEnableIO(), m_debugger, /*result=*/nullptr);
2239
2240 if (!io_redirect_or_error) {
2241 error = Status::FromError(io_redirect_or_error.takeError());
2242 return false;
2243 }
2244
2245 ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
2246
2247 // Before executing Python code, lock the GIL.
2248 Locker py_lock(this,
2249 Locker::AcquireLock |
2250 (options.GetInitSession() ? Locker::InitSession : 0) |
2251 Locker::NoSTDIN,
2252 Locker::FreeAcquiredLock |
2253 (options.GetInitSession() ? Locker::TearDownSession : 0),
2254 io_redirect.GetInputFile(), io_redirect.GetOutputFile(),
2255 io_redirect.GetErrorFile());
2256
2257 auto ExtendSysPath = [&](std::string directory) -> llvm::Error {
2258 if (directory.empty()) {
2259 return llvm::createStringError("invalid directory name");
2260 }
2261
2262 replace_all(directory, "\\", "\\\\");
2263 replace_all(directory, "'", "\\'");
2264
2265 // Make sure that Python has "directory" in the search path.
2266 StreamString command_stream;
2267 command_stream.Printf("if not (sys.path.__contains__('%s')):\n "
2268 "sys.path.insert(1,'%s');\n\n",
2269 directory.c_str(), directory.c_str());
2270 bool syspath_retval =
2271 ExecuteMultipleLines(command_stream.GetData(), exc_options).Success();
2272 if (!syspath_retval)
2273 return llvm::createStringError("Python sys.path handling failed");
2274
2275 return llvm::Error::success();
2276 };
2277
2278 std::string module_name(pathname);
2279 bool possible_package = false;
2280
2281 if (extra_search_dir) {
2282 if (llvm::Error e = ExtendSysPath(extra_search_dir.GetPath())) {
2283 error = Status::FromError(std::move(e));
2284 return false;
2285 }
2286 } else {
2287 FileSpec module_file(pathname);
2288 FileSystem::Instance().Resolve(module_file);
2289
2290 fs::file_status st;
2291 std::error_code ec = status(module_file.GetPath(), st);
2292
2293 if (ec || st.type() == fs::file_type::status_error ||
2294 st.type() == fs::file_type::type_unknown ||
2295 st.type() == fs::file_type::file_not_found) {
2296 // if not a valid file of any sort, check if it might be a filename still
2297 // dot can't be used but / and \ can, and if either is found, reject
2298 if (strchr(pathname, '\\') || strchr(pathname, '/')) {
2299 error = Status::FromErrorStringWithFormatv("invalid pathname '{0}'",
2300 pathname);
2301 return false;
2302 }
2303 // Not a filename, probably a package of some sort, let it go through.
2304 possible_package = true;
2305 } else if (is_directory(st) || is_regular_file(st)) {
2306 if (module_file.GetDirectory().IsEmpty()) {
2308 "invalid directory name '{0}'", pathname);
2309 return false;
2310 }
2311 if (llvm::Error e =
2312 ExtendSysPath(module_file.GetDirectory().GetCString())) {
2313 error = Status::FromError(std::move(e));
2314 return false;
2315 }
2316 module_name = module_file.GetFilename().GetCString();
2317 } else {
2319 "no known way to import this module specification");
2320 return false;
2321 }
2322 }
2323
2324 // Strip .py or .pyc extension
2325 llvm::StringRef extension = llvm::sys::path::extension(module_name);
2326 if (!extension.empty()) {
2327 if (extension == ".py")
2328 module_name.resize(module_name.length() - 3);
2329 else if (extension == ".pyc")
2330 module_name.resize(module_name.length() - 4);
2331 }
2332
2333 if (!possible_package && module_name.find('.') != llvm::StringRef::npos) {
2335 "Python does not allow dots in module names: %s", module_name.c_str());
2336 return false;
2337 }
2338
2339 if (module_name.find('-') != llvm::StringRef::npos) {
2341 "Python discourages dashes in module names: %s", module_name.c_str());
2342 return false;
2343 }
2344
2345 // Check if the module is already imported.
2346 StreamString command_stream;
2347 command_stream.Clear();
2348 command_stream.Printf("sys.modules.__contains__('%s')", module_name.c_str());
2349 bool does_contain = false;
2350 // This call will succeed if the module was ever imported in any Debugger in
2351 // the lifetime of the process in which this LLDB framework is living.
2352 const bool does_contain_executed = ExecuteOneLineWithReturn(
2353 command_stream.GetData(),
2354 ScriptInterpreterPythonImpl::eScriptReturnTypeBool, &does_contain,
2355 exc_options);
2356
2357 const bool was_imported_globally = does_contain_executed && does_contain;
2358 const bool was_imported_locally =
2359 GetSessionDictionary()
2360 .GetItemForKey(PythonString(module_name))
2361 .IsAllocated();
2362
2363 // now actually do the import
2364 command_stream.Clear();
2365
2366 if (was_imported_globally || was_imported_locally) {
2367 if (!was_imported_locally)
2368 command_stream.Printf("import %s ; reload_module(%s)",
2369 module_name.c_str(), module_name.c_str());
2370 else
2371 command_stream.Printf("reload_module(%s)", module_name.c_str());
2372 } else
2373 command_stream.Printf("import %s", module_name.c_str());
2374
2375 error = ExecuteMultipleLines(command_stream.GetData(), exc_options);
2376 if (error.Fail())
2377 return false;
2378
2379 // if we are here, everything worked
2380 // call __lldb_init_module(debugger,dict)
2381 if (!SWIGBridge::LLDBSwigPythonCallModuleInit(
2382 module_name.c_str(), m_dictionary_name.c_str(),
2383 m_debugger.shared_from_this())) {
2384 error = Status::FromErrorString("calling __lldb_init_module failed");
2385 return false;
2386 }
2387
2388 if (module_sp) {
2389 // everything went just great, now set the module object
2390 command_stream.Clear();
2391 command_stream.Printf("%s", module_name.c_str());
2392 void *module_pyobj = nullptr;
2393 if (ExecuteOneLineWithReturn(
2394 command_stream.GetData(),
2396 exc_options) &&
2397 module_pyobj)
2398 *module_sp = std::make_shared<StructuredPythonObject>(PythonObject(
2399 PyRefType::Owned, static_cast<PyObject *>(module_pyobj)));
2400 }
2401
2402 // Finally, if we got a target passed in, then we should tell the new module
2403 // about this target:
2404 if (target_sp)
2405 return SWIGBridge::LLDBSwigPythonCallModuleNewTarget(
2406 module_name.c_str(), m_dictionary_name.c_str(), target_sp);
2407
2408 return true;
2409}
2410
2411bool ScriptInterpreterPythonImpl::IsReservedWord(const char *word) {
2412 if (!word || !word[0])
2413 return false;
2414
2415 llvm::StringRef word_sr(word);
2416
2417 // filter out a few characters that would just confuse us and that are
2418 // clearly not keyword material anyway
2419 if (word_sr.find('"') != llvm::StringRef::npos ||
2420 word_sr.find('\'') != llvm::StringRef::npos)
2421 return false;
2422
2423 StreamString command_stream;
2424 command_stream.Printf("keyword.iskeyword('%s')", word);
2425 bool result;
2426 ExecuteScriptOptions options;
2427 options.SetEnableIO(false);
2428 options.SetMaskoutErrors(true);
2429 options.SetSetLLDBGlobals(false);
2430 if (ExecuteOneLineWithReturn(command_stream.GetData(),
2432 &result, options))
2433 return result;
2434 return false;
2435}
2436
2437ScriptInterpreterPythonImpl::SynchronicityHandler::SynchronicityHandler(
2438 lldb::DebuggerSP debugger_sp, ScriptedCommandSynchronicity synchro)
2439 : m_debugger_sp(debugger_sp), m_synch_wanted(synchro),
2440 m_old_asynch(debugger_sp->GetAsyncExecution()) {
2441 if (m_synch_wanted == eScriptedCommandSynchronicitySynchronous)
2442 m_debugger_sp->SetAsyncExecution(false);
2443 else if (m_synch_wanted == eScriptedCommandSynchronicityAsynchronous)
2444 m_debugger_sp->SetAsyncExecution(true);
2445}
2446
2447ScriptInterpreterPythonImpl::SynchronicityHandler::~SynchronicityHandler() {
2448 if (m_synch_wanted != eScriptedCommandSynchronicityCurrentValue)
2449 m_debugger_sp->SetAsyncExecution(m_old_asynch);
2450}
2451
2452bool ScriptInterpreterPythonImpl::RunScriptBasedCommand(
2453 const char *impl_function, llvm::StringRef args,
2454 ScriptedCommandSynchronicity synchronicity,
2456 const lldb_private::ExecutionContext &exe_ctx) {
2457 if (!impl_function) {
2458 error = Status::FromErrorString("no function to execute");
2459 return false;
2460 }
2461
2462 lldb::DebuggerSP debugger_sp = m_debugger.shared_from_this();
2463 lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx));
2464
2465 if (!debugger_sp.get()) {
2466 error = Status::FromErrorString("invalid Debugger pointer");
2467 return false;
2468 }
2469
2470 bool ret_val = false;
2471
2472 {
2473 Locker py_lock(this,
2474 Locker::AcquireLock | Locker::InitSession |
2475 (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN),
2476 Locker::FreeLock | Locker::TearDownSession);
2477
2478 SynchronicityHandler synch_handler(debugger_sp, synchronicity);
2479
2480 std::string args_str = args.str();
2481 ret_val = SWIGBridge::LLDBSwigPythonCallCommand(
2482 impl_function, m_dictionary_name.c_str(), debugger_sp, args_str.c_str(),
2483 cmd_retobj, exe_ctx_ref_sp);
2484 }
2485
2486 if (!ret_val)
2487 error = Status::FromErrorString("unable to execute script function");
2488 else if (cmd_retobj.GetStatus() == eReturnStatusFailed)
2489 return false;
2490
2491 error.Clear();
2492 return ret_val;
2493}
2494
2495bool ScriptInterpreterPythonImpl::RunScriptBasedCommand(
2496 StructuredData::GenericSP impl_obj_sp, llvm::StringRef args,
2497 ScriptedCommandSynchronicity synchronicity,
2499 const lldb_private::ExecutionContext &exe_ctx) {
2500 if (!impl_obj_sp || !impl_obj_sp->IsValid()) {
2501 error = Status::FromErrorString("no function to execute");
2502 return false;
2503 }
2504
2505 lldb::DebuggerSP debugger_sp = m_debugger.shared_from_this();
2506 lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx));
2507
2508 if (!debugger_sp.get()) {
2509 error = Status::FromErrorString("invalid Debugger pointer");
2510 return false;
2511 }
2512
2513 bool ret_val = false;
2514
2515 {
2516 Locker py_lock(this,
2517 Locker::AcquireLock | Locker::InitSession |
2518 (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN),
2519 Locker::FreeLock | Locker::TearDownSession);
2520
2521 SynchronicityHandler synch_handler(debugger_sp, synchronicity);
2522
2523 std::string args_str = args.str();
2524 ret_val = SWIGBridge::LLDBSwigPythonCallCommandObject(
2525 static_cast<PyObject *>(impl_obj_sp->GetValue()), debugger_sp,
2526 args_str.c_str(), cmd_retobj, exe_ctx_ref_sp);
2527 }
2528
2529 if (!ret_val)
2530 error = Status::FromErrorString("unable to execute script function");
2531 else if (cmd_retobj.GetStatus() == eReturnStatusFailed)
2532 return false;
2533
2534 error.Clear();
2535 return ret_val;
2536}
2537
2538bool ScriptInterpreterPythonImpl::RunScriptBasedParsedCommand(
2539 StructuredData::GenericSP impl_obj_sp, Args &args,
2540 ScriptedCommandSynchronicity synchronicity,
2542 const lldb_private::ExecutionContext &exe_ctx) {
2543 if (!impl_obj_sp || !impl_obj_sp->IsValid()) {
2544 error = Status::FromErrorString("no function to execute");
2545 return false;
2546 }
2547
2548 lldb::DebuggerSP debugger_sp = m_debugger.shared_from_this();
2549 lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx));
2550
2551 if (!debugger_sp.get()) {
2552 error = Status::FromErrorString("invalid Debugger pointer");
2553 return false;
2554 }
2555
2556 bool ret_val = false;
2557
2558 {
2559 Locker py_lock(this,
2560 Locker::AcquireLock | Locker::InitSession |
2561 (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN),
2562 Locker::FreeLock | Locker::TearDownSession);
2563
2564 SynchronicityHandler synch_handler(debugger_sp, synchronicity);
2565
2567
2568 for (const Args::ArgEntry &entry : args) {
2569 args_arr_sp->AddStringItem(entry.ref());
2570 }
2571 StructuredDataImpl args_impl(args_arr_sp);
2572
2573 ret_val = SWIGBridge::LLDBSwigPythonCallParsedCommandObject(
2574 static_cast<PyObject *>(impl_obj_sp->GetValue()), debugger_sp,
2575 args_impl, cmd_retobj, exe_ctx_ref_sp);
2576 }
2577
2578 if (!ret_val)
2579 error = Status::FromErrorString("unable to execute script function");
2580 else if (cmd_retobj.GetStatus() == eReturnStatusFailed)
2581 return false;
2582
2583 error.Clear();
2584 return ret_val;
2585}
2586
2587std::optional<std::string>
2588ScriptInterpreterPythonImpl::GetRepeatCommandForScriptedCommand(
2589 StructuredData::GenericSP impl_obj_sp, Args &args) {
2590 if (!impl_obj_sp || !impl_obj_sp->IsValid())
2591 return std::nullopt;
2592
2593 lldb::DebuggerSP debugger_sp = m_debugger.shared_from_this();
2594
2595 if (!debugger_sp.get())
2596 return std::nullopt;
2597
2598 std::optional<std::string> ret_val;
2599
2600 {
2601 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN,
2602 Locker::FreeLock);
2603
2605
2606 // For scripting commands, we send the command string:
2607 std::string command;
2608 args.GetQuotedCommandString(command);
2609 ret_val = SWIGBridge::LLDBSwigPythonGetRepeatCommandForScriptedCommand(
2610 static_cast<PyObject *>(impl_obj_sp->GetValue()), command);
2611 }
2612 return ret_val;
2613}
2614
2616ScriptInterpreterPythonImpl::HandleArgumentCompletionForScriptedCommand(
2617 StructuredData::GenericSP impl_obj_sp, std::vector<llvm::StringRef> &args,
2618 size_t args_pos, size_t char_in_arg) {
2619 StructuredData::DictionarySP completion_dict_sp;
2620 if (!impl_obj_sp || !impl_obj_sp->IsValid())
2621 return completion_dict_sp;
2622
2623 {
2624 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN,
2625 Locker::FreeLock);
2626
2627 completion_dict_sp =
2628 SWIGBridge::LLDBSwigPythonHandleArgumentCompletionForScriptedCommand(
2629 static_cast<PyObject *>(impl_obj_sp->GetValue()), args, args_pos,
2630 char_in_arg);
2631 }
2632 return completion_dict_sp;
2633}
2634
2636ScriptInterpreterPythonImpl::HandleOptionArgumentCompletionForScriptedCommand(
2637 StructuredData::GenericSP impl_obj_sp, llvm::StringRef &long_option,
2638 size_t char_in_arg) {
2639 StructuredData::DictionarySP completion_dict_sp;
2640 if (!impl_obj_sp || !impl_obj_sp->IsValid())
2641 return completion_dict_sp;
2642
2643 {
2644 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN,
2645 Locker::FreeLock);
2646
2647 completion_dict_sp = SWIGBridge::
2648 LLDBSwigPythonHandleOptionArgumentCompletionForScriptedCommand(
2649 static_cast<PyObject *>(impl_obj_sp->GetValue()), long_option,
2650 char_in_arg);
2651 }
2652 return completion_dict_sp;
2653}
2654
2655/// In Python, a special attribute __doc__ contains the docstring for an object
2656/// (function, method, class, ...) if any is defined Otherwise, the attribute's
2657/// value is None.
2658bool ScriptInterpreterPythonImpl::GetDocumentationForItem(const char *item,
2659 std::string &dest) {
2660 dest.clear();
2661
2662 if (!item || !*item)
2663 return false;
2664
2665 std::string command(item);
2666 command += ".__doc__";
2667
2668 // Python is going to point this to valid data if ExecuteOneLineWithReturn
2669 // returns successfully.
2670 char *result_ptr = nullptr;
2671
2672 if (ExecuteOneLineWithReturn(
2674 &result_ptr, ExecuteScriptOptions().SetEnableIO(false))) {
2675 if (result_ptr)
2676 dest.assign(result_ptr);
2677 return true;
2678 }
2679
2680 StreamString str_stream;
2681 str_stream << "Function " << item
2682 << " was not found. Containing module might be missing.";
2683 dest = std::string(str_stream.GetString());
2684
2685 return false;
2686}
2687
2688bool ScriptInterpreterPythonImpl::GetShortHelpForCommandObject(
2689 StructuredData::GenericSP cmd_obj_sp, std::string &dest) {
2690 dest.clear();
2691
2692 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
2693
2694 if (!cmd_obj_sp)
2695 return false;
2696
2697 PythonObject implementor(PyRefType::Borrowed,
2698 (PyObject *)cmd_obj_sp->GetValue());
2699
2700 if (!implementor.IsAllocated())
2701 return false;
2702
2703 llvm::Expected<PythonObject> expected_py_return =
2704 implementor.CallMethod("get_short_help");
2705
2706 if (!expected_py_return) {
2707 llvm::consumeError(expected_py_return.takeError());
2708 return false;
2709 }
2710
2711 PythonObject py_return = std::move(expected_py_return.get());
2712
2713 if (py_return.IsAllocated() && PythonString::Check(py_return.get())) {
2714 PythonString py_string(PyRefType::Borrowed, py_return.get());
2715 llvm::StringRef return_data(py_string.GetString());
2716 dest.assign(return_data.data(), return_data.size());
2717 return true;
2718 }
2719
2720 return false;
2721}
2722
2723uint32_t ScriptInterpreterPythonImpl::GetFlagsForCommandObject(
2724 StructuredData::GenericSP cmd_obj_sp) {
2725 uint32_t result = 0;
2726
2727 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
2728
2729 static char callee_name[] = "get_flags";
2730
2731 if (!cmd_obj_sp)
2732 return result;
2733
2734 PythonObject implementor(PyRefType::Borrowed,
2735 (PyObject *)cmd_obj_sp->GetValue());
2736
2737 if (!implementor.IsAllocated())
2738 return result;
2739
2740 PythonObject pmeth(PyRefType::Owned,
2741 PyObject_GetAttrString(implementor.get(), callee_name));
2742
2743 if (PyErr_Occurred())
2744 PyErr_Clear();
2745
2746 if (!pmeth.IsAllocated())
2747 return result;
2748
2749 if (PyCallable_Check(pmeth.get()) == 0) {
2750 if (PyErr_Occurred())
2751 PyErr_Clear();
2752 return result;
2753 }
2754
2755 if (PyErr_Occurred())
2756 PyErr_Clear();
2757
2758 long long py_return = unwrapOrSetPythonException(
2759 As<long long>(implementor.CallMethod(callee_name)));
2760
2761 // if it fails, print the error but otherwise go on
2762 if (PyErr_Occurred()) {
2763 PyErr_Print();
2764 PyErr_Clear();
2765 } else {
2766 result = py_return;
2767 }
2768
2769 return result;
2770}
2771
2773ScriptInterpreterPythonImpl::GetOptionsForCommandObject(
2774 StructuredData::GenericSP cmd_obj_sp) {
2775 StructuredData::ObjectSP result = {};
2776
2777 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
2778
2779 static char callee_name[] = "get_options_definition";
2780
2781 if (!cmd_obj_sp)
2782 return result;
2783
2784 PythonObject implementor(PyRefType::Borrowed,
2785 (PyObject *)cmd_obj_sp->GetValue());
2786
2787 if (!implementor.IsAllocated())
2788 return result;
2789
2790 PythonObject pmeth(PyRefType::Owned,
2791 PyObject_GetAttrString(implementor.get(), callee_name));
2792
2793 if (PyErr_Occurred())
2794 PyErr_Clear();
2795
2796 if (!pmeth.IsAllocated())
2797 return result;
2798
2799 if (PyCallable_Check(pmeth.get()) == 0) {
2800 if (PyErr_Occurred())
2801 PyErr_Clear();
2802 return result;
2803 }
2804
2805 if (PyErr_Occurred())
2806 PyErr_Clear();
2807
2808 PythonDictionary py_return = unwrapOrSetPythonException(
2809 As<PythonDictionary>(implementor.CallMethod(callee_name)));
2810
2811 // if it fails, print the error but otherwise go on
2812 if (PyErr_Occurred()) {
2813 PyErr_Print();
2814 PyErr_Clear();
2815 return {};
2816 }
2817 return py_return.CreateStructuredObject();
2818}
2819
2821ScriptInterpreterPythonImpl::GetArgumentsForCommandObject(
2822 StructuredData::GenericSP cmd_obj_sp) {
2823 StructuredData::ObjectSP result = {};
2824
2825 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
2826
2827 static char callee_name[] = "get_args_definition";
2828
2829 if (!cmd_obj_sp)
2830 return result;
2831
2832 PythonObject implementor(PyRefType::Borrowed,
2833 (PyObject *)cmd_obj_sp->GetValue());
2834
2835 if (!implementor.IsAllocated())
2836 return result;
2837
2838 PythonObject pmeth(PyRefType::Owned,
2839 PyObject_GetAttrString(implementor.get(), callee_name));
2840
2841 if (PyErr_Occurred())
2842 PyErr_Clear();
2843
2844 if (!pmeth.IsAllocated())
2845 return result;
2846
2847 if (PyCallable_Check(pmeth.get()) == 0) {
2848 if (PyErr_Occurred())
2849 PyErr_Clear();
2850 return result;
2851 }
2852
2853 if (PyErr_Occurred())
2854 PyErr_Clear();
2855
2856 PythonList py_return = unwrapOrSetPythonException(
2857 As<PythonList>(implementor.CallMethod(callee_name)));
2858
2859 // if it fails, print the error but otherwise go on
2860 if (PyErr_Occurred()) {
2861 PyErr_Print();
2862 PyErr_Clear();
2863 return {};
2864 }
2865 return py_return.CreateStructuredObject();
2866}
2867
2868void ScriptInterpreterPythonImpl::OptionParsingStartedForCommandObject(
2869 StructuredData::GenericSP cmd_obj_sp) {
2870
2871 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
2872
2873 static char callee_name[] = "option_parsing_started";
2874
2875 if (!cmd_obj_sp)
2876 return;
2877
2878 PythonObject implementor(PyRefType::Borrowed,
2879 (PyObject *)cmd_obj_sp->GetValue());
2880
2881 if (!implementor.IsAllocated())
2882 return;
2883
2884 PythonObject pmeth(PyRefType::Owned,
2885 PyObject_GetAttrString(implementor.get(), callee_name));
2886
2887 if (PyErr_Occurred())
2888 PyErr_Clear();
2889
2890 if (!pmeth.IsAllocated())
2891 return;
2892
2893 if (PyCallable_Check(pmeth.get()) == 0) {
2894 if (PyErr_Occurred())
2895 PyErr_Clear();
2896 return;
2897 }
2898
2899 if (PyErr_Occurred())
2900 PyErr_Clear();
2901
2902 // option_parsing_starting doesn't return anything, ignore anything but
2903 // python errors.
2904 unwrapOrSetPythonException(As<bool>(implementor.CallMethod(callee_name)));
2905
2906 // if it fails, print the error but otherwise go on
2907 if (PyErr_Occurred()) {
2908 PyErr_Print();
2909 PyErr_Clear();
2910 return;
2911 }
2912}
2913
2914bool ScriptInterpreterPythonImpl::SetOptionValueForCommandObject(
2915 StructuredData::GenericSP cmd_obj_sp, ExecutionContext *exe_ctx,
2916 llvm::StringRef long_option, llvm::StringRef value) {
2917 StructuredData::ObjectSP result = {};
2918
2919 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
2920
2921 static char callee_name[] = "set_option_value";
2922
2923 if (!cmd_obj_sp)
2924 return false;
2925
2926 PythonObject implementor(PyRefType::Borrowed,
2927 (PyObject *)cmd_obj_sp->GetValue());
2928
2929 if (!implementor.IsAllocated())
2930 return false;
2931
2932 PythonObject pmeth(PyRefType::Owned,
2933 PyObject_GetAttrString(implementor.get(), callee_name));
2934
2935 if (PyErr_Occurred())
2936 PyErr_Clear();
2937
2938 if (!pmeth.IsAllocated())
2939 return false;
2940
2941 if (PyCallable_Check(pmeth.get()) == 0) {
2942 if (PyErr_Occurred())
2943 PyErr_Clear();
2944 return false;
2945 }
2946
2947 if (PyErr_Occurred())
2948 PyErr_Clear();
2949
2950 lldb::ExecutionContextRefSP exe_ctx_ref_sp;
2951 if (exe_ctx)
2952 exe_ctx_ref_sp = std::make_shared<ExecutionContextRef>(exe_ctx);
2953 PythonObject ctx_ref_obj = SWIGBridge::ToSWIGWrapper(exe_ctx_ref_sp);
2954
2955 bool py_return = unwrapOrSetPythonException(As<bool>(
2956 implementor.CallMethod(callee_name, ctx_ref_obj,
2957 long_option.str().c_str(), value.str().c_str())));
2958
2959 // if it fails, print the error but otherwise go on
2960 if (PyErr_Occurred()) {
2961 PyErr_Print();
2962 PyErr_Clear();
2963 return false;
2964 }
2965 return py_return;
2966}
2967
2968bool ScriptInterpreterPythonImpl::GetLongHelpForCommandObject(
2969 StructuredData::GenericSP cmd_obj_sp, std::string &dest) {
2970 dest.clear();
2971
2972 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
2973
2974 if (!cmd_obj_sp)
2975 return false;
2976
2977 PythonObject implementor(PyRefType::Borrowed,
2978 (PyObject *)cmd_obj_sp->GetValue());
2979
2980 if (!implementor.IsAllocated())
2981 return false;
2982
2983 llvm::Expected<PythonObject> expected_py_return =
2984 implementor.CallMethod("get_long_help");
2985
2986 if (!expected_py_return) {
2987 llvm::consumeError(expected_py_return.takeError());
2988 return false;
2989 }
2990
2991 PythonObject py_return = std::move(expected_py_return.get());
2992
2993 bool got_string = false;
2994 if (py_return.IsAllocated() && PythonString::Check(py_return.get())) {
2995 PythonString str(PyRefType::Borrowed, py_return.get());
2996 llvm::StringRef str_data(str.GetString());
2997 dest.assign(str_data.data(), str_data.size());
2998 got_string = true;
2999 }
3000
3001 return got_string;
3002}
3003
3004std::unique_ptr<ScriptInterpreterLocker>
3005ScriptInterpreterPythonImpl::AcquireInterpreterLock() {
3006 std::unique_ptr<ScriptInterpreterLocker> py_lock(new Locker(
3007 this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN,
3008 Locker::FreeLock | Locker::TearDownSession));
3009 return py_lock;
3010}
3011
3012void ScriptInterpreterPythonImpl::Initialize() {
3014
3015 // RAII-based initialization which correctly handles multiple-initialization,
3016 // version- specific differences among Python 2 and Python 3, and saving and
3017 // restoring various other pieces of state that can get mucked with during
3018 // initialization.
3019 InitializePythonRAII initialize_guard;
3020
3021 LLDBSwigPyInit();
3022
3023 // Update the path python uses to search for modules to include the current
3024 // directory.
3025
3026 RunSimpleString("import sys");
3027 AddToSysPath(AddLocation::End, ".");
3028
3029 // Don't denormalize paths when calling file_spec.GetPath(). On platforms
3030 // that use a backslash as the path separator, this will result in executing
3031 // python code containing paths with unescaped backslashes. But Python also
3032 // accepts forward slashes, so to make life easier we just use that.
3033 if (FileSpec file_spec = GetPythonDir())
3034 AddToSysPath(AddLocation::Beginning, file_spec.GetPath(false));
3035 if (FileSpec file_spec = HostInfo::GetShlibDir())
3036 AddToSysPath(AddLocation::Beginning, file_spec.GetPath(false));
3037
3038 RunSimpleString("sys.dont_write_bytecode = 1; import "
3039 "lldb.embedded_interpreter; from "
3040 "lldb.embedded_interpreter import run_python_interpreter; "
3041 "from lldb.embedded_interpreter import run_one_line");
3042
3043#if LLDB_USE_PYTHON_SET_INTERRUPT
3044 // Python will not just overwrite its internal SIGINT handler but also the
3045 // one from the process. Backup the current SIGINT handler to prevent that
3046 // Python deletes it.
3047 RestoreSignalHandlerScope save_sigint(SIGINT);
3048
3049 // Setup a default SIGINT signal handler that works the same way as the
3050 // normal Python REPL signal handler which raises a KeyboardInterrupt.
3051 // Also make sure to not pollute the user's REPL with the signal module nor
3052 // our utility function.
3053 RunSimpleString("def lldb_setup_sigint_handler():\n"
3054 " import signal;\n"
3055 " def signal_handler(sig, frame):\n"
3056 " raise KeyboardInterrupt()\n"
3057 " signal.signal(signal.SIGINT, signal_handler);\n"
3058 "lldb_setup_sigint_handler();\n"
3059 "del lldb_setup_sigint_handler\n");
3060#endif
3061}
3062
3063void ScriptInterpreterPythonImpl::AddToSysPath(AddLocation location,
3064 std::string path) {
3065 std::string statement;
3066 if (location == AddLocation::Beginning) {
3067 statement.assign("sys.path.insert(0,\"");
3068 statement.append(path);
3069 statement.append("\")");
3070 } else {
3071 statement.assign("sys.path.append(\"");
3072 statement.append(path);
3073 statement.append("\")");
3074 }
3075 RunSimpleString(statement.c_str());
3076}
3077
3078// We are intentionally NOT calling Py_Finalize here (this would be the logical
3079// place to call it). Calling Py_Finalize here causes test suite runs to seg
3080// fault: The test suite runs in Python. It registers SBDebugger::Terminate to
3081// be called 'at_exit'. When the test suite Python harness finishes up, it
3082// calls Py_Finalize, which calls all the 'at_exit' registered functions.
3083// SBDebugger::Terminate calls Debugger::Terminate, which calls lldb::Terminate,
3084// which calls ScriptInterpreter::Terminate, which calls
3085// ScriptInterpreterPythonImpl::Terminate. So if we call Py_Finalize here, we
3086// end up with Py_Finalize being called from within Py_Finalize, which results
3087// in a seg fault. Since this function only gets called when lldb is shutting
3088// down and going away anyway, the fact that we don't actually call Py_Finalize
3089// should not cause any problems (everything should shut down/go away anyway
3090// when the process exits).
3091//
3092// void ScriptInterpreterPythonImpl::Terminate() { Py_Finalize (); }
3093
3094#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:114
virtual Status Flush()
Flush the current stream.
Definition File.cpp:157
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:357
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:414
Debugger & GetDebugger() const
Definition Target.h:1097
WatchpointList & GetWatchpointList()
Definition Target.h:807
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 INT32_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
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