9#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H
10#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H
12#include "lldb/Host/Config.h"
24#include "llvm/ADT/STLExtras.h"
25#include "llvm/ADT/StringRef.h"
28class IOHandlerPythonInterpreter;
29class ScriptInterpreterPythonImpl :
public ScriptInterpreterPython {
31 friend class IOHandlerPythonInterpreter;
33 ScriptInterpreterPythonImpl(Debugger &debugger);
35 ~ScriptInterpreterPythonImpl()
override;
37 bool Interrupt()
override;
40 llvm::StringRef command, CommandReturnObject *result,
41 const ExecuteScriptOptions &options = ExecuteScriptOptions())
override;
43 void ExecuteInterpreterLoop()
override;
45 bool ExecuteOneLineWithReturn(
46 llvm::StringRef in_string,
47 ScriptInterpreter::ScriptReturnType return_type,
void *ret_value,
48 const ExecuteScriptOptions &options = ExecuteScriptOptions())
override;
51 const char *in_string,
52 const ExecuteScriptOptions &options = ExecuteScriptOptions())
override;
55 ExportFunctionDefinitionToInterpreter(StringList &function_def)
override;
57 bool GenerateTypeScriptFunction(StringList &input, std::string &output,
58 const void *name_token =
nullptr)
override;
60 bool GenerateTypeSynthClass(StringList &input, std::string &output,
61 const void *name_token =
nullptr)
override;
63 bool GenerateTypeSynthClass(
const char *oneliner, std::string &output,
64 const void *name_token =
nullptr)
override;
67 bool GenerateTypeScriptFunction(
const char *oneliner, std::string &output,
68 const void *name_token =
nullptr)
override;
70 bool GenerateScriptAliasFunction(StringList &input,
71 std::string &output)
override;
73 StructuredData::ObjectSP
74 CreateSyntheticScriptedProvider(
const char *class_name,
77 StructuredData::GenericSP
78 CreateScriptCommandObject(
const char *class_name)
override;
80 StructuredData::ObjectSP
81 CreateStructuredDataFromScriptObject(ScriptObject obj)
override;
83 StructuredData::GenericSP
84 CreateFrameRecognizer(
const char *class_name)
override;
87 GetRecognizedArguments(
const StructuredData::ObjectSP &implementor,
90 bool ShouldHide(
const StructuredData::ObjectSP &implementor,
98 CreateScriptedBreakpointInterface()
override;
105 CreateScriptedFrameProviderInterface()
override;
108 CreateScriptedThreadPlanInterface()
override;
112 StructuredData::ObjectSP
113 LoadPluginModule(
const FileSpec &file_spec,
116 StructuredData::DictionarySP
117 GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target,
118 const char *setting_name,
122 uint32_t max)
override;
125 GetChildAtIndex(
const StructuredData::ObjectSP &implementor,
126 uint32_t idx)
override;
128 llvm::Expected<uint32_t>
129 GetIndexOfChildWithName(
const StructuredData::ObjectSP &implementor,
130 const char *child_name)
override;
132 bool UpdateSynthProviderInstance(
133 const StructuredData::ObjectSP &implementor)
override;
135 bool MightHaveChildrenSynthProviderInstance(
136 const StructuredData::ObjectSP &implementor)
override;
139 GetSyntheticValue(
const StructuredData::ObjectSP &implementor)
override;
142 GetSyntheticTypeName(
const StructuredData::ObjectSP &implementor)
override;
145 RunScriptBasedCommand(
const char *impl_function, llvm::StringRef args,
146 ScriptedCommandSynchronicity synchronicity,
147 lldb_private::CommandReturnObject &cmd_retobj,
149 const lldb_private::ExecutionContext &exe_ctx)
override;
151 bool RunScriptBasedCommand(
152 StructuredData::GenericSP impl_obj_sp, llvm::StringRef args,
153 ScriptedCommandSynchronicity synchronicity,
154 lldb_private::CommandReturnObject &cmd_retobj, Status &
error,
155 const lldb_private::ExecutionContext &exe_ctx)
override;
157 bool RunScriptBasedParsedCommand(
158 StructuredData::GenericSP impl_obj_sp, Args &args,
159 ScriptedCommandSynchronicity synchronicity,
160 lldb_private::CommandReturnObject &cmd_retobj, Status &
error,
161 const lldb_private::ExecutionContext &exe_ctx)
override;
163 std::optional<std::string>
164 GetRepeatCommandForScriptedCommand(StructuredData::GenericSP impl_obj_sp,
165 Args &args)
override;
167 StructuredData::DictionarySP HandleArgumentCompletionForScriptedCommand(
168 StructuredData::GenericSP impl_obj_sp, std::vector<llvm::StringRef> &args,
169 size_t args_pos,
size_t char_in_arg)
override;
171 StructuredData::DictionarySP HandleOptionArgumentCompletionForScriptedCommand(
172 StructuredData::GenericSP impl_obj_sp, llvm::StringRef &long_options,
173 size_t char_in_arg)
override;
175 Status GenerateFunction(
const char *signature,
const StringList &input,
176 bool is_callback)
override;
178 Status GenerateBreakpointCommandCallbackData(StringList &input,
181 bool is_callback)
override;
183 bool GenerateWatchpointCommandCallbackData(StringList &input,
185 bool is_callback)
override;
188 StructuredData::ObjectSP &callee_wrapper_sp,
189 const TypeSummaryOptions &options,
190 std::string &retval)
override;
192 bool FormatterCallbackFunction(
const char *function_name,
195 bool GetDocumentationForItem(
const char *item, std::string &dest)
override;
197 bool GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,
198 std::string &dest)
override;
201 GetFlagsForCommandObject(StructuredData::GenericSP cmd_obj_sp)
override;
203 bool GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,
204 std::string &dest)
override;
206 StructuredData::ObjectSP
207 GetOptionsForCommandObject(StructuredData::GenericSP cmd_obj_sp)
override;
209 StructuredData::ObjectSP
210 GetArgumentsForCommandObject(StructuredData::GenericSP cmd_obj_sp)
override;
212 bool SetOptionValueForCommandObject(StructuredData::GenericSP cmd_obj_sp,
213 ExecutionContext *exe_ctx,
214 llvm::StringRef long_option,
215 llvm::StringRef value)
override;
217 void OptionParsingStartedForCommandObject(
218 StructuredData::GenericSP cmd_obj_sp)
override;
220 bool CheckObjectExists(
const char *name)
override {
221 if (!name || !name[0])
224 return GetDocumentationForItem(name, temp);
228 std::string &output, Status &
error)
override;
231 std::string &output, Status &
error)
override;
234 std::string &output, Status &
error)
override;
237 std::string &output, Status &
error)
override;
240 std::string &output, Status &
error)
override;
242 bool LoadScriptingModule(
const char *filename,
243 const LoadScriptOptions &options,
245 StructuredData::ObjectSP *module_sp =
nullptr,
246 FileSpec extra_search_dir = {},
249 bool IsReservedWord(
const char *word)
override;
251 std::unique_ptr<ScriptInterpreterLocker> AcquireInterpreterLock()
override;
253 void CollectDataForBreakpointCommandCallback(
254 std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
255 CommandReturnObject &result)
override;
258 CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options,
259 CommandReturnObject &result)
override;
262 Status SetBreakpointCommandCallback(BreakpointOptions &bp_options,
263 const char *callback_body,
264 bool is_callback)
override;
266 Status SetBreakpointCommandCallbackFunction(
267 BreakpointOptions &bp_options,
const char *function_name,
268 StructuredData::ObjectSP extra_args_sp)
override;
271 Status SetBreakpointCommandCallback(
272 BreakpointOptions &bp_options,
273 std::unique_ptr<BreakpointOptions::CommandData> &data_up)
override;
275 Status SetBreakpointCommandCallback(BreakpointOptions &bp_options,
276 const char *command_body_text,
277 StructuredData::ObjectSP extra_args_sp,
278 bool uses_extra_args,
282 void SetWatchpointCommandCallback(WatchpointOptions *wp_options,
283 const char *user_input,
284 bool is_callback)
override;
286 const char *GetDictionaryName() {
return m_dictionary_name.c_str(); }
288 PyThreadState *GetThreadState() {
return m_command_thread_state; }
290 void SetThreadState(PyThreadState *s) {
292 m_command_thread_state = s;
296 void IOHandlerActivated(IOHandler &io_handler,
bool interactive)
override;
298 void IOHandlerInputComplete(IOHandler &io_handler,
299 std::string &data)
override;
304 llvm::StringRef GetPluginName()
override {
return GetPluginNameStatic(); }
306 class Locker :
public ScriptInterpreterLocker {
309 AcquireLock = 0x0001,
310 InitSession = 0x0002,
311 InitGlobals = 0x0004,
317 FreeAcquiredLock = 0x0002,
319 TearDownSession = 0x0004
322 Locker(ScriptInterpreterPythonImpl *py_interpreter,
323 uint16_t on_entry = AcquireLock | InitSession,
324 uint16_t on_leave = FreeLock | TearDownSession,
331 bool DoAcquireLock();
333 bool DoInitSession(uint16_t on_entry_flags,
lldb::FileSP in,
338 bool DoTearDownSession();
340 bool m_teardown_session;
341 ScriptInterpreterPythonImpl *m_python_interpreter;
342 PyGILState_STATE m_GILState;
345 static bool BreakpointCallbackFunction(
void *baton,
346 StoppointCallbackContext *context,
349 static bool WatchpointCallbackFunction(
void *baton,
350 StoppointCallbackContext *context,
352 static void Initialize();
354 class SynchronicityHandler {
363 ~SynchronicityHandler();
366 enum class AddLocation { Beginning, End };
368 static void AddToSysPath(AddLocation location, std::string path);
375 uint32_t IsExecutingPython() {
376 std::lock_guard<std::mutex> guard(m_mutex);
377 return m_lock_count > 0;
380 uint32_t IncrementLockCount() {
381 std::lock_guard<std::mutex> guard(m_mutex);
382 return ++m_lock_count;
385 uint32_t DecrementLockCount() {
386 std::lock_guard<std::mutex> guard(m_mutex);
387 if (m_lock_count > 0)
398 python::PythonModule &GetMainModule();
400 python::PythonDictionary &GetSessionDictionary();
402 python::PythonDictionary &GetSysModuleDictionary();
404 llvm::Expected<unsigned> GetMaxPositionalArgumentsForCallable(
405 const llvm::StringRef &callable_name)
override;
407 bool GetEmbeddedInterpreterModuleObjects();
409 bool SetStdHandle(
lldb::FileSP file,
const char *py_name,
410 python::PythonObject &save_file,
const char *mode);
412 python::PythonObject m_saved_stdin;
413 python::PythonObject m_saved_stdout;
414 python::PythonObject m_saved_stderr;
415 python::PythonModule m_main_module;
416 python::PythonDictionary m_session_dict;
417 python::PythonDictionary m_sys_module_dict;
418 python::PythonObject m_run_one_line_function;
419 python::PythonObject m_run_one_line_str_global;
420 std::string m_dictionary_name;
422 bool m_session_is_active;
423 bool m_pty_secondary_is_open;
424 bool m_valid_session;
425 uint32_t m_lock_count;
427 PyThreadState *m_command_thread_state;
430class IOHandlerPythonInterpreter :
public IOHandler {
432 IOHandlerPythonInterpreter(Debugger &debugger,
433 ScriptInterpreterPythonImpl *python)
434 : IOHandler(debugger, IOHandler::
Type::PythonInterpreter),
437 ~IOHandlerPythonInterpreter()
override =
default;
439 llvm::StringRef GetControlSequence(
char ch)
override {
440 static constexpr llvm::StringLiteral control_sequence(
"quit()\n");
442 return control_sequence;
446 void Run()
override {
448 int stdin_fd = GetInputFD();
450 Terminal terminal(stdin_fd);
451 TerminalState terminal_state(terminal);
453 if (terminal.IsATerminal()) {
455 llvm::consumeError(terminal.SetCanonical(
false));
456 llvm::consumeError(terminal.SetEcho(
true));
459 ScriptInterpreterPythonImpl::Locker locker(
461 ScriptInterpreterPythonImpl::Locker::AcquireLock |
462 ScriptInterpreterPythonImpl::Locker::InitSession |
463 ScriptInterpreterPythonImpl::Locker::InitGlobals,
464 ScriptInterpreterPythonImpl::Locker::FreeAcquiredLock |
465 ScriptInterpreterPythonImpl::Locker::TearDownSession);
480 StreamString run_string;
481 run_string.Printf(
"run_python_interpreter (%s)",
482 m_python->GetDictionaryName());
483 python::RunSimpleString(run_string.GetData());
489 void Cancel()
override {}
491 bool Interrupt()
override {
return m_python->Interrupt(); }
493 void GotEOF()
override {}
496 ScriptInterpreterPythonImpl *m_python;
static llvm::raw_ostream & error(Stream &strm)
static std::optional< size_t > CalculateNumChildren(CompilerType container_elem_type, uint64_t num_elements, CompilerType element_type)
Calculates the number of elements stored in a container (with element type 'container_elem_type') as ...
A class that represents a running process on the host machine.
ScriptedCommandSynchronicity
std::shared_ptr< lldb_private::ScriptedStopHookInterface > ScriptedStopHookInterfaceSP
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
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::OperatingSystemInterface > OperatingSystemInterfaceSP
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
std::shared_ptr< lldb_private::ScriptedFrameProviderInterface > ScriptedFrameProviderInterfaceSP
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