xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h (revision dda2819751e49c83612958492e38917049128b41)
1061da546Spatrick //===-- ScriptInterpreterPythonImpl.h ---------------------------*- C++ -*-===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick 
9061da546Spatrick #include "lldb/Host/Config.h"
10061da546Spatrick 
11061da546Spatrick #if LLDB_ENABLE_PYTHON
12061da546Spatrick 
13061da546Spatrick #include "lldb-python.h"
14061da546Spatrick 
15061da546Spatrick #include "PythonDataObjects.h"
16061da546Spatrick #include "ScriptInterpreterPython.h"
17061da546Spatrick 
18061da546Spatrick #include "lldb/Host/Terminal.h"
19061da546Spatrick #include "lldb/Utility/StreamString.h"
20061da546Spatrick 
21061da546Spatrick #include "llvm/ADT/STLExtras.h"
22061da546Spatrick #include "llvm/ADT/StringRef.h"
23061da546Spatrick 
24061da546Spatrick namespace lldb_private {
25061da546Spatrick class IOHandlerPythonInterpreter;
26061da546Spatrick class ScriptInterpreterPythonImpl : public ScriptInterpreterPython {
27061da546Spatrick public:
28061da546Spatrick   friend class IOHandlerPythonInterpreter;
29061da546Spatrick 
30061da546Spatrick   ScriptInterpreterPythonImpl(Debugger &debugger);
31061da546Spatrick 
32061da546Spatrick   ~ScriptInterpreterPythonImpl() override;
33061da546Spatrick 
34061da546Spatrick   bool Interrupt() override;
35061da546Spatrick 
36061da546Spatrick   bool ExecuteOneLine(
37061da546Spatrick       llvm::StringRef command, CommandReturnObject *result,
38061da546Spatrick       const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
39061da546Spatrick 
40061da546Spatrick   void ExecuteInterpreterLoop() override;
41061da546Spatrick 
42061da546Spatrick   bool ExecuteOneLineWithReturn(
43061da546Spatrick       llvm::StringRef in_string,
44061da546Spatrick       ScriptInterpreter::ScriptReturnType return_type, void *ret_value,
45061da546Spatrick       const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
46061da546Spatrick 
47061da546Spatrick   lldb_private::Status ExecuteMultipleLines(
48061da546Spatrick       const char *in_string,
49061da546Spatrick       const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
50061da546Spatrick 
51061da546Spatrick   Status
52061da546Spatrick   ExportFunctionDefinitionToInterpreter(StringList &function_def) override;
53061da546Spatrick 
54061da546Spatrick   bool GenerateTypeScriptFunction(StringList &input, std::string &output,
55061da546Spatrick                                   const void *name_token = nullptr) override;
56061da546Spatrick 
57061da546Spatrick   bool GenerateTypeSynthClass(StringList &input, std::string &output,
58061da546Spatrick                               const void *name_token = nullptr) override;
59061da546Spatrick 
60061da546Spatrick   bool GenerateTypeSynthClass(const char *oneliner, std::string &output,
61061da546Spatrick                               const void *name_token = nullptr) override;
62061da546Spatrick 
63061da546Spatrick   // use this if the function code is just a one-liner script
64061da546Spatrick   bool GenerateTypeScriptFunction(const char *oneliner, std::string &output,
65061da546Spatrick                                   const void *name_token = nullptr) override;
66061da546Spatrick 
67061da546Spatrick   bool GenerateScriptAliasFunction(StringList &input,
68061da546Spatrick                                    std::string &output) override;
69061da546Spatrick 
70061da546Spatrick   StructuredData::ObjectSP
71061da546Spatrick   CreateSyntheticScriptedProvider(const char *class_name,
72061da546Spatrick                                   lldb::ValueObjectSP valobj) override;
73061da546Spatrick 
74061da546Spatrick   StructuredData::GenericSP
75061da546Spatrick   CreateScriptCommandObject(const char *class_name) override;
76061da546Spatrick 
77061da546Spatrick   StructuredData::ObjectSP
78061da546Spatrick   CreateScriptedThreadPlan(const char *class_name,
79061da546Spatrick                            StructuredDataImpl *args_data,
80061da546Spatrick                            std::string &error_str,
81061da546Spatrick                            lldb::ThreadPlanSP thread_plan) override;
82061da546Spatrick 
83061da546Spatrick   bool ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp,
84061da546Spatrick                                       Event *event,
85061da546Spatrick                                       bool &script_error) override;
86061da546Spatrick 
87061da546Spatrick   bool ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp,
88061da546Spatrick                                     Event *event, bool &script_error) override;
89061da546Spatrick 
90061da546Spatrick   bool ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp,
91061da546Spatrick                                  bool &script_error) override;
92061da546Spatrick 
93061da546Spatrick   lldb::StateType
94061da546Spatrick   ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp,
95061da546Spatrick                                 bool &script_error) override;
96061da546Spatrick 
97061da546Spatrick   StructuredData::GenericSP
98061da546Spatrick   CreateScriptedBreakpointResolver(const char *class_name,
99061da546Spatrick                                    StructuredDataImpl *args_data,
100061da546Spatrick                                    lldb::BreakpointSP &bkpt_sp) override;
101061da546Spatrick   bool ScriptedBreakpointResolverSearchCallback(
102061da546Spatrick       StructuredData::GenericSP implementor_sp,
103061da546Spatrick       SymbolContext *sym_ctx) override;
104061da546Spatrick 
105061da546Spatrick   lldb::SearchDepth ScriptedBreakpointResolverSearchDepth(
106061da546Spatrick       StructuredData::GenericSP implementor_sp) override;
107061da546Spatrick 
108061da546Spatrick   StructuredData::GenericSP
109061da546Spatrick   CreateFrameRecognizer(const char *class_name) override;
110061da546Spatrick 
111061da546Spatrick   lldb::ValueObjectListSP
112061da546Spatrick   GetRecognizedArguments(const StructuredData::ObjectSP &implementor,
113061da546Spatrick                          lldb::StackFrameSP frame_sp) override;
114061da546Spatrick 
115061da546Spatrick   StructuredData::GenericSP
116061da546Spatrick   OSPlugin_CreatePluginObject(const char *class_name,
117061da546Spatrick                               lldb::ProcessSP process_sp) override;
118061da546Spatrick 
119061da546Spatrick   StructuredData::DictionarySP
120061da546Spatrick   OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) override;
121061da546Spatrick 
122061da546Spatrick   StructuredData::ArraySP
123061da546Spatrick   OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp) override;
124061da546Spatrick 
125061da546Spatrick   StructuredData::StringSP
126061da546Spatrick   OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp,
127061da546Spatrick                                lldb::tid_t thread_id) override;
128061da546Spatrick 
129061da546Spatrick   StructuredData::DictionarySP
130061da546Spatrick   OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp,
131061da546Spatrick                         lldb::tid_t tid, lldb::addr_t context) override;
132061da546Spatrick 
133061da546Spatrick   StructuredData::ObjectSP
134061da546Spatrick   LoadPluginModule(const FileSpec &file_spec,
135061da546Spatrick                    lldb_private::Status &error) override;
136061da546Spatrick 
137061da546Spatrick   StructuredData::DictionarySP
138061da546Spatrick   GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target,
139061da546Spatrick                      const char *setting_name,
140061da546Spatrick                      lldb_private::Status &error) override;
141061da546Spatrick 
142061da546Spatrick   size_t CalculateNumChildren(const StructuredData::ObjectSP &implementor,
143061da546Spatrick                               uint32_t max) override;
144061da546Spatrick 
145061da546Spatrick   lldb::ValueObjectSP
146061da546Spatrick   GetChildAtIndex(const StructuredData::ObjectSP &implementor,
147061da546Spatrick                   uint32_t idx) override;
148061da546Spatrick 
149061da546Spatrick   int GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor,
150061da546Spatrick                               const char *child_name) override;
151061da546Spatrick 
152061da546Spatrick   bool UpdateSynthProviderInstance(
153061da546Spatrick       const StructuredData::ObjectSP &implementor) override;
154061da546Spatrick 
155061da546Spatrick   bool MightHaveChildrenSynthProviderInstance(
156061da546Spatrick       const StructuredData::ObjectSP &implementor) override;
157061da546Spatrick 
158061da546Spatrick   lldb::ValueObjectSP
159061da546Spatrick   GetSyntheticValue(const StructuredData::ObjectSP &implementor) override;
160061da546Spatrick 
161061da546Spatrick   ConstString
162061da546Spatrick   GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) override;
163061da546Spatrick 
164061da546Spatrick   bool
165061da546Spatrick   RunScriptBasedCommand(const char *impl_function, llvm::StringRef args,
166061da546Spatrick                         ScriptedCommandSynchronicity synchronicity,
167061da546Spatrick                         lldb_private::CommandReturnObject &cmd_retobj,
168061da546Spatrick                         Status &error,
169061da546Spatrick                         const lldb_private::ExecutionContext &exe_ctx) override;
170061da546Spatrick 
171061da546Spatrick   bool RunScriptBasedCommand(
172061da546Spatrick       StructuredData::GenericSP impl_obj_sp, llvm::StringRef args,
173061da546Spatrick       ScriptedCommandSynchronicity synchronicity,
174061da546Spatrick       lldb_private::CommandReturnObject &cmd_retobj, Status &error,
175061da546Spatrick       const lldb_private::ExecutionContext &exe_ctx) override;
176061da546Spatrick 
177061da546Spatrick   Status GenerateFunction(const char *signature,
178061da546Spatrick                           const StringList &input) override;
179061da546Spatrick 
180061da546Spatrick   Status GenerateBreakpointCommandCallbackData(
181061da546Spatrick       StringList &input,
182061da546Spatrick       std::string &output,
183061da546Spatrick       bool has_extra_args) override;
184061da546Spatrick 
185061da546Spatrick   bool GenerateWatchpointCommandCallbackData(StringList &input,
186061da546Spatrick                                              std::string &output) override;
187061da546Spatrick 
188061da546Spatrick   bool GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj,
189061da546Spatrick                           StructuredData::ObjectSP &callee_wrapper_sp,
190061da546Spatrick                           const TypeSummaryOptions &options,
191061da546Spatrick                           std::string &retval) override;
192061da546Spatrick 
193061da546Spatrick   bool GetDocumentationForItem(const char *item, std::string &dest) override;
194061da546Spatrick 
195061da546Spatrick   bool GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,
196061da546Spatrick                                     std::string &dest) override;
197061da546Spatrick 
198061da546Spatrick   uint32_t
199061da546Spatrick   GetFlagsForCommandObject(StructuredData::GenericSP cmd_obj_sp) override;
200061da546Spatrick 
201061da546Spatrick   bool GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,
202061da546Spatrick                                    std::string &dest) override;
203061da546Spatrick 
204061da546Spatrick   bool CheckObjectExists(const char *name) override {
205061da546Spatrick     if (!name || !name[0])
206061da546Spatrick       return false;
207061da546Spatrick     std::string temp;
208061da546Spatrick     return GetDocumentationForItem(name, temp);
209061da546Spatrick   }
210061da546Spatrick 
211061da546Spatrick   bool RunScriptFormatKeyword(const char *impl_function, Process *process,
212061da546Spatrick                               std::string &output, Status &error) override;
213061da546Spatrick 
214061da546Spatrick   bool RunScriptFormatKeyword(const char *impl_function, Thread *thread,
215061da546Spatrick                               std::string &output, Status &error) override;
216061da546Spatrick 
217061da546Spatrick   bool RunScriptFormatKeyword(const char *impl_function, Target *target,
218061da546Spatrick                               std::string &output, Status &error) override;
219061da546Spatrick 
220061da546Spatrick   bool RunScriptFormatKeyword(const char *impl_function, StackFrame *frame,
221061da546Spatrick                               std::string &output, Status &error) override;
222061da546Spatrick 
223061da546Spatrick   bool RunScriptFormatKeyword(const char *impl_function, ValueObject *value,
224061da546Spatrick                               std::string &output, Status &error) override;
225061da546Spatrick 
226061da546Spatrick   bool
227061da546Spatrick   LoadScriptingModule(const char *filename, bool init_session,
228061da546Spatrick                       lldb_private::Status &error,
229061da546Spatrick                       StructuredData::ObjectSP *module_sp = nullptr) override;
230061da546Spatrick 
231061da546Spatrick   bool IsReservedWord(const char *word) override;
232061da546Spatrick 
233061da546Spatrick   std::unique_ptr<ScriptInterpreterLocker> AcquireInterpreterLock() override;
234061da546Spatrick 
235061da546Spatrick   void CollectDataForBreakpointCommandCallback(
236061da546Spatrick       std::vector<BreakpointOptions *> &bp_options_vec,
237061da546Spatrick       CommandReturnObject &result) override;
238061da546Spatrick 
239061da546Spatrick   void
240061da546Spatrick   CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options,
241061da546Spatrick                                           CommandReturnObject &result) override;
242061da546Spatrick 
243061da546Spatrick   /// Set the callback body text into the callback for the breakpoint.
244061da546Spatrick   Status SetBreakpointCommandCallback(BreakpointOptions *bp_options,
245061da546Spatrick                                       const char *callback_body) override;
246061da546Spatrick 
247061da546Spatrick   Status SetBreakpointCommandCallbackFunction(
248061da546Spatrick       BreakpointOptions *bp_options,
249061da546Spatrick       const char *function_name,
250061da546Spatrick       StructuredData::ObjectSP extra_args_sp) override;
251061da546Spatrick 
252061da546Spatrick   /// This one is for deserialization:
253061da546Spatrick   Status SetBreakpointCommandCallback(
254061da546Spatrick       BreakpointOptions *bp_options,
255061da546Spatrick       std::unique_ptr<BreakpointOptions::CommandData> &data_up) override;
256061da546Spatrick 
257061da546Spatrick   Status SetBreakpointCommandCallback(BreakpointOptions *bp_options,
258061da546Spatrick                                       const char *command_body_text,
259061da546Spatrick                                       StructuredData::ObjectSP extra_args_sp,
260061da546Spatrick                                       bool uses_extra_args);
261061da546Spatrick 
262061da546Spatrick   /// Set a one-liner as the callback for the watchpoint.
263061da546Spatrick   void SetWatchpointCommandCallback(WatchpointOptions *wp_options,
264061da546Spatrick                                     const char *oneliner) override;
265061da546Spatrick 
266061da546Spatrick   const char *GetDictionaryName() { return m_dictionary_name.c_str(); }
267061da546Spatrick 
268061da546Spatrick   PyThreadState *GetThreadState() { return m_command_thread_state; }
269061da546Spatrick 
270061da546Spatrick   void SetThreadState(PyThreadState *s) {
271061da546Spatrick     if (s)
272061da546Spatrick       m_command_thread_state = s;
273061da546Spatrick   }
274061da546Spatrick 
275061da546Spatrick   // IOHandlerDelegate
276061da546Spatrick   void IOHandlerActivated(IOHandler &io_handler, bool interactive) override;
277061da546Spatrick 
278061da546Spatrick   void IOHandlerInputComplete(IOHandler &io_handler,
279061da546Spatrick                               std::string &data) override;
280061da546Spatrick 
281061da546Spatrick   static lldb::ScriptInterpreterSP CreateInstance(Debugger &debugger);
282061da546Spatrick 
283061da546Spatrick   // PluginInterface protocol
284061da546Spatrick   lldb_private::ConstString GetPluginName() override;
285061da546Spatrick 
286061da546Spatrick   uint32_t GetPluginVersion() override;
287061da546Spatrick 
288061da546Spatrick   class Locker : public ScriptInterpreterLocker {
289061da546Spatrick   public:
290061da546Spatrick     enum OnEntry {
291061da546Spatrick       AcquireLock = 0x0001,
292061da546Spatrick       InitSession = 0x0002,
293061da546Spatrick       InitGlobals = 0x0004,
294061da546Spatrick       NoSTDIN = 0x0008
295061da546Spatrick     };
296061da546Spatrick 
297061da546Spatrick     enum OnLeave {
298061da546Spatrick       FreeLock = 0x0001,
299061da546Spatrick       FreeAcquiredLock = 0x0002, // do not free the lock if we already held it
300061da546Spatrick                                  // when calling constructor
301061da546Spatrick       TearDownSession = 0x0004
302061da546Spatrick     };
303061da546Spatrick 
304061da546Spatrick     Locker(ScriptInterpreterPythonImpl *py_interpreter,
305061da546Spatrick            uint16_t on_entry = AcquireLock | InitSession,
306061da546Spatrick            uint16_t on_leave = FreeLock | TearDownSession,
307061da546Spatrick            lldb::FileSP in = nullptr, lldb::FileSP out = nullptr,
308061da546Spatrick            lldb::FileSP err = nullptr);
309061da546Spatrick 
310061da546Spatrick     ~Locker() override;
311061da546Spatrick 
312061da546Spatrick   private:
313061da546Spatrick     bool DoAcquireLock();
314061da546Spatrick 
315061da546Spatrick     bool DoInitSession(uint16_t on_entry_flags, lldb::FileSP in,
316061da546Spatrick                        lldb::FileSP out, lldb::FileSP err);
317061da546Spatrick 
318061da546Spatrick     bool DoFreeLock();
319061da546Spatrick 
320061da546Spatrick     bool DoTearDownSession();
321061da546Spatrick 
322061da546Spatrick     bool m_teardown_session;
323061da546Spatrick     ScriptInterpreterPythonImpl *m_python_interpreter;
324061da546Spatrick     PyGILState_STATE m_GILState;
325061da546Spatrick   };
326061da546Spatrick 
327061da546Spatrick   static bool BreakpointCallbackFunction(void *baton,
328061da546Spatrick                                          StoppointCallbackContext *context,
329061da546Spatrick                                          lldb::user_id_t break_id,
330061da546Spatrick                                          lldb::user_id_t break_loc_id);
331061da546Spatrick   static bool WatchpointCallbackFunction(void *baton,
332061da546Spatrick                                          StoppointCallbackContext *context,
333061da546Spatrick                                          lldb::user_id_t watch_id);
334061da546Spatrick   static void InitializePrivate();
335061da546Spatrick 
336061da546Spatrick   class SynchronicityHandler {
337061da546Spatrick   private:
338061da546Spatrick     lldb::DebuggerSP m_debugger_sp;
339061da546Spatrick     ScriptedCommandSynchronicity m_synch_wanted;
340061da546Spatrick     bool m_old_asynch;
341061da546Spatrick 
342061da546Spatrick   public:
343061da546Spatrick     SynchronicityHandler(lldb::DebuggerSP, ScriptedCommandSynchronicity);
344061da546Spatrick 
345061da546Spatrick     ~SynchronicityHandler();
346061da546Spatrick   };
347061da546Spatrick 
348061da546Spatrick   enum class AddLocation { Beginning, End };
349061da546Spatrick 
350061da546Spatrick   static void AddToSysPath(AddLocation location, std::string path);
351061da546Spatrick 
352061da546Spatrick   bool EnterSession(uint16_t on_entry_flags, lldb::FileSP in, lldb::FileSP out,
353061da546Spatrick                     lldb::FileSP err);
354061da546Spatrick 
355061da546Spatrick   void LeaveSession();
356061da546Spatrick 
357061da546Spatrick   uint32_t IsExecutingPython() const { return m_lock_count > 0; }
358061da546Spatrick 
359061da546Spatrick   uint32_t IncrementLockCount() { return ++m_lock_count; }
360061da546Spatrick 
361061da546Spatrick   uint32_t DecrementLockCount() {
362061da546Spatrick     if (m_lock_count > 0)
363061da546Spatrick       --m_lock_count;
364061da546Spatrick     return m_lock_count;
365061da546Spatrick   }
366061da546Spatrick 
367061da546Spatrick   enum ActiveIOHandler {
368061da546Spatrick     eIOHandlerNone,
369061da546Spatrick     eIOHandlerBreakpoint,
370061da546Spatrick     eIOHandlerWatchpoint
371061da546Spatrick   };
372061da546Spatrick 
373061da546Spatrick   python::PythonModule &GetMainModule();
374061da546Spatrick 
375061da546Spatrick   python::PythonDictionary &GetSessionDictionary();
376061da546Spatrick 
377061da546Spatrick   python::PythonDictionary &GetSysModuleDictionary();
378061da546Spatrick 
379061da546Spatrick   llvm::Expected<unsigned> GetMaxPositionalArgumentsForCallable(
380061da546Spatrick       const llvm::StringRef &callable_name) override;
381061da546Spatrick 
382061da546Spatrick   bool GetEmbeddedInterpreterModuleObjects();
383061da546Spatrick 
384061da546Spatrick   bool SetStdHandle(lldb::FileSP file, const char *py_name,
385061da546Spatrick                     python::PythonObject &save_file, const char *mode);
386061da546Spatrick 
387061da546Spatrick   python::PythonObject m_saved_stdin;
388061da546Spatrick   python::PythonObject m_saved_stdout;
389061da546Spatrick   python::PythonObject m_saved_stderr;
390061da546Spatrick   python::PythonModule m_main_module;
391061da546Spatrick   python::PythonDictionary m_session_dict;
392061da546Spatrick   python::PythonDictionary m_sys_module_dict;
393061da546Spatrick   python::PythonObject m_run_one_line_function;
394061da546Spatrick   python::PythonObject m_run_one_line_str_global;
395061da546Spatrick   std::string m_dictionary_name;
396061da546Spatrick   ActiveIOHandler m_active_io_handler;
397061da546Spatrick   bool m_session_is_active;
398*dda28197Spatrick   bool m_pty_secondary_is_open;
399061da546Spatrick   bool m_valid_session;
400061da546Spatrick   uint32_t m_lock_count;
401061da546Spatrick   PyThreadState *m_command_thread_state;
402061da546Spatrick };
403061da546Spatrick 
404061da546Spatrick class IOHandlerPythonInterpreter : public IOHandler {
405061da546Spatrick public:
406061da546Spatrick   IOHandlerPythonInterpreter(Debugger &debugger,
407061da546Spatrick                              ScriptInterpreterPythonImpl *python)
408061da546Spatrick       : IOHandler(debugger, IOHandler::Type::PythonInterpreter),
409061da546Spatrick         m_python(python) {}
410061da546Spatrick 
411061da546Spatrick   ~IOHandlerPythonInterpreter() override {}
412061da546Spatrick 
413061da546Spatrick   ConstString GetControlSequence(char ch) override {
414061da546Spatrick     if (ch == 'd')
415061da546Spatrick       return ConstString("quit()\n");
416061da546Spatrick     return ConstString();
417061da546Spatrick   }
418061da546Spatrick 
419061da546Spatrick   void Run() override {
420061da546Spatrick     if (m_python) {
421061da546Spatrick       int stdin_fd = GetInputFD();
422061da546Spatrick       if (stdin_fd >= 0) {
423061da546Spatrick         Terminal terminal(stdin_fd);
424061da546Spatrick         TerminalState terminal_state;
425061da546Spatrick         const bool is_a_tty = terminal.IsATerminal();
426061da546Spatrick 
427061da546Spatrick         if (is_a_tty) {
428061da546Spatrick           terminal_state.Save(stdin_fd, false);
429061da546Spatrick           terminal.SetCanonical(false);
430061da546Spatrick           terminal.SetEcho(true);
431061da546Spatrick         }
432061da546Spatrick 
433061da546Spatrick         ScriptInterpreterPythonImpl::Locker locker(
434061da546Spatrick             m_python,
435061da546Spatrick             ScriptInterpreterPythonImpl::Locker::AcquireLock |
436061da546Spatrick                 ScriptInterpreterPythonImpl::Locker::InitSession |
437061da546Spatrick                 ScriptInterpreterPythonImpl::Locker::InitGlobals,
438061da546Spatrick             ScriptInterpreterPythonImpl::Locker::FreeAcquiredLock |
439061da546Spatrick                 ScriptInterpreterPythonImpl::Locker::TearDownSession);
440061da546Spatrick 
441061da546Spatrick         // The following call drops into the embedded interpreter loop and
442061da546Spatrick         // stays there until the user chooses to exit from the Python
443061da546Spatrick         // interpreter. This embedded interpreter will, as any Python code that
444061da546Spatrick         // performs I/O, unlock the GIL before a system call that can hang, and
445061da546Spatrick         // lock it when the syscall has returned.
446061da546Spatrick 
447061da546Spatrick         // We need to surround the call to the embedded interpreter with calls
448061da546Spatrick         // to PyGILState_Ensure and PyGILState_Release (using the Locker
449061da546Spatrick         // above). This is because Python has a global lock which must be held
450061da546Spatrick         // whenever we want to touch any Python objects. Otherwise, if the user
451061da546Spatrick         // calls Python code, the interpreter state will be off, and things
452061da546Spatrick         // could hang (it's happened before).
453061da546Spatrick 
454061da546Spatrick         StreamString run_string;
455061da546Spatrick         run_string.Printf("run_python_interpreter (%s)",
456061da546Spatrick                           m_python->GetDictionaryName());
457061da546Spatrick         PyRun_SimpleString(run_string.GetData());
458061da546Spatrick 
459061da546Spatrick         if (is_a_tty)
460061da546Spatrick           terminal_state.Restore();
461061da546Spatrick       }
462061da546Spatrick     }
463061da546Spatrick     SetIsDone(true);
464061da546Spatrick   }
465061da546Spatrick 
466061da546Spatrick   void Cancel() override {}
467061da546Spatrick 
468061da546Spatrick   bool Interrupt() override { return m_python->Interrupt(); }
469061da546Spatrick 
470061da546Spatrick   void GotEOF() override {}
471061da546Spatrick 
472061da546Spatrick protected:
473061da546Spatrick   ScriptInterpreterPythonImpl *m_python;
474061da546Spatrick };
475061da546Spatrick 
476061da546Spatrick } // namespace lldb_private
477061da546Spatrick 
478061da546Spatrick #endif
479