xref: /llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h (revision b9c1b51e45b845debb76d8658edabca70ca56079)
1 //===-- ScriptInterpreterPython.h -------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHON_H
11 #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHON_H
12 
13 #ifdef LLDB_DISABLE_PYTHON
14 
15 // Python is disabled in this build
16 
17 #else
18 
19 // C Includes
20 // C++ Includes
21 #include <memory>
22 #include <string>
23 #include <vector>
24 
25 // Other libraries and framework includes
26 // Project includes
27 #include "PythonDataObjects.h"
28 #include "lldb/Core/IOHandler.h"
29 #include "lldb/Host/Terminal.h"
30 #include "lldb/Interpreter/ScriptInterpreter.h"
31 #include "lldb/lldb-private.h"
32 
33 class IOHandlerPythonInterpreter;
34 
35 namespace lldb_private {
36 
37 class ScriptInterpreterPython : public ScriptInterpreter,
38                                 public IOHandlerDelegateMultiline {
39 public:
40 #if PY_MAJOR_VERSION >= 3
41   typedef PyObject *(*SWIGInitCallback)(void);
42 #else
43   typedef void (*SWIGInitCallback)(void);
44 #endif
45 
46   typedef bool (*SWIGBreakpointCallbackFunction)(
47       const char *python_function_name, const char *session_dictionary_name,
48       const lldb::StackFrameSP &frame_sp,
49       const lldb::BreakpointLocationSP &bp_loc_sp);
50 
51   typedef bool (*SWIGWatchpointCallbackFunction)(
52       const char *python_function_name, const char *session_dictionary_name,
53       const lldb::StackFrameSP &frame_sp, const lldb::WatchpointSP &wp_sp);
54 
55   typedef bool (*SWIGPythonTypeScriptCallbackFunction)(
56       const char *python_function_name, void *session_dictionary,
57       const lldb::ValueObjectSP &valobj_sp, void **pyfunct_wrapper,
58       const lldb::TypeSummaryOptionsSP &options, std::string &retval);
59 
60   typedef void *(*SWIGPythonCreateSyntheticProvider)(
61       const char *python_class_name, const char *session_dictionary_name,
62       const lldb::ValueObjectSP &valobj_sp);
63 
64   typedef void *(*SWIGPythonCreateCommandObject)(
65       const char *python_class_name, const char *session_dictionary_name,
66       const lldb::DebuggerSP debugger_sp);
67 
68   typedef void *(*SWIGPythonCreateScriptedThreadPlan)(
69       const char *python_class_name, const char *session_dictionary_name,
70       const lldb::ThreadPlanSP &thread_plan_sp);
71 
72   typedef bool (*SWIGPythonCallThreadPlan)(void *implementor,
73                                            const char *method_name,
74                                            Event *event_sp, bool &got_error);
75 
76   typedef void *(*SWIGPythonCreateOSPlugin)(const char *python_class_name,
77                                             const char *session_dictionary_name,
78                                             const lldb::ProcessSP &process_sp);
79 
80   typedef size_t (*SWIGPythonCalculateNumChildren)(void *implementor,
81                                                    uint32_t max);
82 
83   typedef void *(*SWIGPythonGetChildAtIndex)(void *implementor, uint32_t idx);
84 
85   typedef int (*SWIGPythonGetIndexOfChildWithName)(void *implementor,
86                                                    const char *child_name);
87 
88   typedef void *(*SWIGPythonCastPyObjectToSBValue)(void *data);
89 
90   typedef lldb::ValueObjectSP (*SWIGPythonGetValueObjectSPFromSBValue)(
91       void *data);
92 
93   typedef bool (*SWIGPythonUpdateSynthProviderInstance)(void *data);
94 
95   typedef bool (*SWIGPythonMightHaveChildrenSynthProviderInstance)(void *data);
96 
97   typedef void *(*SWIGPythonGetValueSynthProviderInstance)(void *implementor);
98 
99   typedef bool (*SWIGPythonCallCommand)(
100       const char *python_function_name, const char *session_dictionary_name,
101       lldb::DebuggerSP &debugger, const char *args,
102       lldb_private::CommandReturnObject &cmd_retobj,
103       lldb::ExecutionContextRefSP exe_ctx_ref_sp);
104 
105   typedef bool (*SWIGPythonCallCommandObject)(
106       void *implementor, lldb::DebuggerSP &debugger, const char *args,
107       lldb_private::CommandReturnObject &cmd_retobj,
108       lldb::ExecutionContextRefSP exe_ctx_ref_sp);
109 
110   typedef bool (*SWIGPythonCallModuleInit)(const char *python_module_name,
111                                            const char *session_dictionary_name,
112                                            lldb::DebuggerSP &debugger);
113 
114   typedef bool (*SWIGPythonScriptKeyword_Process)(
115       const char *python_function_name, const char *session_dictionary_name,
116       lldb::ProcessSP &process, std::string &output);
117 
118   typedef bool (*SWIGPythonScriptKeyword_Thread)(
119       const char *python_function_name, const char *session_dictionary_name,
120       lldb::ThreadSP &thread, std::string &output);
121 
122   typedef bool (*SWIGPythonScriptKeyword_Target)(
123       const char *python_function_name, const char *session_dictionary_name,
124       lldb::TargetSP &target, std::string &output);
125 
126   typedef bool (*SWIGPythonScriptKeyword_Frame)(
127       const char *python_function_name, const char *session_dictionary_name,
128       lldb::StackFrameSP &frame, std::string &output);
129 
130   typedef bool (*SWIGPythonScriptKeyword_Value)(
131       const char *python_function_name, const char *session_dictionary_name,
132       lldb::ValueObjectSP &value, std::string &output);
133 
134   typedef void *(*SWIGPython_GetDynamicSetting)(
135       void *module, const char *setting, const lldb::TargetSP &target_sp);
136 
137   friend class ::IOHandlerPythonInterpreter;
138 
139   ScriptInterpreterPython(CommandInterpreter &interpreter);
140 
141   ~ScriptInterpreterPython() override;
142 
143   bool Interrupt() override;
144 
145   bool ExecuteOneLine(
146       const char *command, CommandReturnObject *result,
147       const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
148 
149   void ExecuteInterpreterLoop() override;
150 
151   bool ExecuteOneLineWithReturn(
152       const char *in_string, ScriptInterpreter::ScriptReturnType return_type,
153       void *ret_value,
154       const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
155 
156   lldb_private::Error ExecuteMultipleLines(
157       const char *in_string,
158       const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
159 
160   Error
161   ExportFunctionDefinitionToInterpreter(StringList &function_def) override;
162 
163   bool GenerateTypeScriptFunction(StringList &input, std::string &output,
164                                   const void *name_token = nullptr) override;
165 
166   bool GenerateTypeSynthClass(StringList &input, std::string &output,
167                               const void *name_token = nullptr) override;
168 
169   bool GenerateTypeSynthClass(const char *oneliner, std::string &output,
170                               const void *name_token = nullptr) override;
171 
172   // use this if the function code is just a one-liner script
173   bool GenerateTypeScriptFunction(const char *oneliner, std::string &output,
174                                   const void *name_token = nullptr) override;
175 
176   bool GenerateScriptAliasFunction(StringList &input,
177                                    std::string &output) override;
178 
179   StructuredData::ObjectSP
180   CreateSyntheticScriptedProvider(const char *class_name,
181                                   lldb::ValueObjectSP valobj) override;
182 
183   StructuredData::GenericSP
184   CreateScriptCommandObject(const char *class_name) override;
185 
186   StructuredData::ObjectSP
187   CreateScriptedThreadPlan(const char *class_name,
188                            lldb::ThreadPlanSP thread_plan) override;
189 
190   bool ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp,
191                                       Event *event,
192                                       bool &script_error) override;
193 
194   bool ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp,
195                                     Event *event, bool &script_error) override;
196 
197   bool ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp,
198                                  bool &script_error) override;
199 
200   lldb::StateType
201   ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp,
202                                 bool &script_error) override;
203 
204   StructuredData::GenericSP
205   OSPlugin_CreatePluginObject(const char *class_name,
206                               lldb::ProcessSP process_sp) override;
207 
208   StructuredData::DictionarySP
209   OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) override;
210 
211   StructuredData::ArraySP
212   OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp) override;
213 
214   StructuredData::StringSP
215   OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp,
216                                lldb::tid_t thread_id) override;
217 
218   StructuredData::DictionarySP
219   OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp,
220                         lldb::tid_t tid, lldb::addr_t context) override;
221 
222   StructuredData::ObjectSP
223   LoadPluginModule(const FileSpec &file_spec,
224                    lldb_private::Error &error) override;
225 
226   StructuredData::DictionarySP
227   GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target,
228                      const char *setting_name,
229                      lldb_private::Error &error) override;
230 
231   size_t CalculateNumChildren(const StructuredData::ObjectSP &implementor,
232                               uint32_t max) override;
233 
234   lldb::ValueObjectSP
235   GetChildAtIndex(const StructuredData::ObjectSP &implementor,
236                   uint32_t idx) override;
237 
238   int GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor,
239                               const char *child_name) override;
240 
241   bool UpdateSynthProviderInstance(
242       const StructuredData::ObjectSP &implementor) override;
243 
244   bool MightHaveChildrenSynthProviderInstance(
245       const StructuredData::ObjectSP &implementor) override;
246 
247   lldb::ValueObjectSP
248   GetSyntheticValue(const StructuredData::ObjectSP &implementor) override;
249 
250   ConstString
251   GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) override;
252 
253   bool
254   RunScriptBasedCommand(const char *impl_function, const char *args,
255                         ScriptedCommandSynchronicity synchronicity,
256                         lldb_private::CommandReturnObject &cmd_retobj,
257                         Error &error,
258                         const lldb_private::ExecutionContext &exe_ctx) override;
259 
260   bool
261   RunScriptBasedCommand(StructuredData::GenericSP impl_obj_sp, const char *args,
262                         ScriptedCommandSynchronicity synchronicity,
263                         lldb_private::CommandReturnObject &cmd_retobj,
264                         Error &error,
265                         const lldb_private::ExecutionContext &exe_ctx) override;
266 
267   Error GenerateFunction(const char *signature,
268                          const StringList &input) override;
269 
270   Error GenerateBreakpointCommandCallbackData(StringList &input,
271                                               std::string &output) override;
272 
273   bool GenerateWatchpointCommandCallbackData(StringList &input,
274                                              std::string &output) override;
275 
276   //    static size_t
277   //    GenerateBreakpointOptionsCommandCallback (void *baton,
278   //                                              InputReader &reader,
279   //                                              lldb::InputReaderAction
280   //                                              notification,
281   //                                              const char *bytes,
282   //                                              size_t bytes_len);
283   //
284   //    static size_t
285   //    GenerateWatchpointOptionsCommandCallback (void *baton,
286   //                                              InputReader &reader,
287   //                                              lldb::InputReaderAction
288   //                                              notification,
289   //                                              const char *bytes,
290   //                                              size_t bytes_len);
291 
292   static bool BreakpointCallbackFunction(void *baton,
293                                          StoppointCallbackContext *context,
294                                          lldb::user_id_t break_id,
295                                          lldb::user_id_t break_loc_id);
296 
297   static bool WatchpointCallbackFunction(void *baton,
298                                          StoppointCallbackContext *context,
299                                          lldb::user_id_t watch_id);
300 
301   bool GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj,
302                           StructuredData::ObjectSP &callee_wrapper_sp,
303                           const TypeSummaryOptions &options,
304                           std::string &retval) override;
305 
306   void Clear() override;
307 
308   bool GetDocumentationForItem(const char *item, std::string &dest) override;
309 
310   bool GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,
311                                     std::string &dest) override;
312 
313   uint32_t
314   GetFlagsForCommandObject(StructuredData::GenericSP cmd_obj_sp) override;
315 
316   bool GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,
317                                    std::string &dest) override;
318 
319   bool CheckObjectExists(const char *name) override {
320     if (!name || !name[0])
321       return false;
322     std::string temp;
323     return GetDocumentationForItem(name, temp);
324   }
325 
326   bool RunScriptFormatKeyword(const char *impl_function, Process *process,
327                               std::string &output, Error &error) override;
328 
329   bool RunScriptFormatKeyword(const char *impl_function, Thread *thread,
330                               std::string &output, Error &error) override;
331 
332   bool RunScriptFormatKeyword(const char *impl_function, Target *target,
333                               std::string &output, Error &error) override;
334 
335   bool RunScriptFormatKeyword(const char *impl_function, StackFrame *frame,
336                               std::string &output, Error &error) override;
337 
338   bool RunScriptFormatKeyword(const char *impl_function, ValueObject *value,
339                               std::string &output, Error &error) override;
340 
341   bool
342   LoadScriptingModule(const char *filename, bool can_reload, bool init_session,
343                       lldb_private::Error &error,
344                       StructuredData::ObjectSP *module_sp = nullptr) override;
345 
346   bool IsReservedWord(const char *word) override;
347 
348   std::unique_ptr<ScriptInterpreterLocker> AcquireInterpreterLock() override;
349 
350   void CollectDataForBreakpointCommandCallback(
351       std::vector<BreakpointOptions *> &bp_options_vec,
352       CommandReturnObject &result) override;
353 
354   void
355   CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options,
356                                           CommandReturnObject &result) override;
357 
358   /// Set the callback body text into the callback for the breakpoint.
359   Error SetBreakpointCommandCallback(BreakpointOptions *bp_options,
360                                      const char *callback_body) override;
361 
362   void SetBreakpointCommandCallbackFunction(BreakpointOptions *bp_options,
363                                             const char *function_name) override;
364 
365   /// Set a one-liner as the callback for the watchpoint.
366   void SetWatchpointCommandCallback(WatchpointOptions *wp_options,
367                                     const char *oneliner) override;
368 
369   StringList ReadCommandInputFromUser(FILE *in_file);
370 
371   void ResetOutputFileHandle(FILE *new_fh) override;
372 
373   static void InitializePrivate();
374 
375   static void InitializeInterpreter(
376       SWIGInitCallback python_swig_init_callback,
377       SWIGBreakpointCallbackFunction swig_breakpoint_callback,
378       SWIGWatchpointCallbackFunction swig_watchpoint_callback,
379       SWIGPythonTypeScriptCallbackFunction swig_typescript_callback,
380       SWIGPythonCreateSyntheticProvider swig_synthetic_script,
381       SWIGPythonCreateCommandObject swig_create_cmd,
382       SWIGPythonCalculateNumChildren swig_calc_children,
383       SWIGPythonGetChildAtIndex swig_get_child_index,
384       SWIGPythonGetIndexOfChildWithName swig_get_index_child,
385       SWIGPythonCastPyObjectToSBValue swig_cast_to_sbvalue,
386       SWIGPythonGetValueObjectSPFromSBValue swig_get_valobj_sp_from_sbvalue,
387       SWIGPythonUpdateSynthProviderInstance swig_update_provider,
388       SWIGPythonMightHaveChildrenSynthProviderInstance
389           swig_mighthavechildren_provider,
390       SWIGPythonGetValueSynthProviderInstance swig_getvalue_provider,
391       SWIGPythonCallCommand swig_call_command,
392       SWIGPythonCallCommandObject swig_call_command_object,
393       SWIGPythonCallModuleInit swig_call_module_init,
394       SWIGPythonCreateOSPlugin swig_create_os_plugin,
395       SWIGPythonScriptKeyword_Process swig_run_script_keyword_process,
396       SWIGPythonScriptKeyword_Thread swig_run_script_keyword_thread,
397       SWIGPythonScriptKeyword_Target swig_run_script_keyword_target,
398       SWIGPythonScriptKeyword_Frame swig_run_script_keyword_frame,
399       SWIGPythonScriptKeyword_Value swig_run_script_keyword_value,
400       SWIGPython_GetDynamicSetting swig_plugin_get,
401       SWIGPythonCreateScriptedThreadPlan swig_thread_plan_script,
402       SWIGPythonCallThreadPlan swig_call_thread_plan);
403 
404   const char *GetDictionaryName() { return m_dictionary_name.c_str(); }
405 
406   PyThreadState *GetThreadState() { return m_command_thread_state; }
407 
408   void SetThreadState(PyThreadState *s) {
409     if (s)
410       m_command_thread_state = s;
411   }
412 
413   //----------------------------------------------------------------------
414   // IOHandlerDelegate
415   //----------------------------------------------------------------------
416   void IOHandlerActivated(IOHandler &io_handler) override;
417 
418   void IOHandlerInputComplete(IOHandler &io_handler,
419                               std::string &data) override;
420 
421   //------------------------------------------------------------------
422   // Static Functions
423   //------------------------------------------------------------------
424   static void Initialize();
425 
426   static void Terminate();
427 
428   static lldb::ScriptInterpreterSP
429   CreateInstance(CommandInterpreter &interpreter);
430 
431   static lldb_private::ConstString GetPluginNameStatic();
432 
433   static const char *GetPluginDescriptionStatic();
434 
435   //------------------------------------------------------------------
436   // PluginInterface protocol
437   //------------------------------------------------------------------
438   lldb_private::ConstString GetPluginName() override;
439 
440   uint32_t GetPluginVersion() override;
441 
442   class Locker : public ScriptInterpreterLocker {
443   public:
444     enum OnEntry {
445       AcquireLock = 0x0001,
446       InitSession = 0x0002,
447       InitGlobals = 0x0004,
448       NoSTDIN = 0x0008
449     };
450 
451     enum OnLeave {
452       FreeLock = 0x0001,
453       FreeAcquiredLock = 0x0002, // do not free the lock if we already held it
454                                  // when calling constructor
455       TearDownSession = 0x0004
456     };
457 
458     Locker(ScriptInterpreterPython *py_interpreter = nullptr,
459            uint16_t on_entry = AcquireLock | InitSession,
460            uint16_t on_leave = FreeLock | TearDownSession, FILE *in = nullptr,
461            FILE *out = nullptr, FILE *err = nullptr);
462 
463     ~Locker() override;
464 
465   private:
466     bool DoAcquireLock();
467 
468     bool DoInitSession(uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err);
469 
470     bool DoFreeLock();
471 
472     bool DoTearDownSession();
473 
474     static void ReleasePythonLock();
475 
476     bool m_teardown_session;
477     ScriptInterpreterPython *m_python_interpreter;
478     //    	FILE*                    m_tmp_fh;
479     PyGILState_STATE m_GILState;
480   };
481 
482 protected:
483   class SynchronicityHandler {
484   private:
485     lldb::DebuggerSP m_debugger_sp;
486     ScriptedCommandSynchronicity m_synch_wanted;
487     bool m_old_asynch;
488 
489   public:
490     SynchronicityHandler(lldb::DebuggerSP, ScriptedCommandSynchronicity);
491 
492     ~SynchronicityHandler();
493   };
494 
495   enum class AddLocation { Beginning, End };
496 
497   static void AddToSysPath(AddLocation location, std::string path);
498 
499   bool EnterSession(uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err);
500 
501   void LeaveSession();
502 
503   void SaveTerminalState(int fd);
504 
505   void RestoreTerminalState();
506 
507   uint32_t IsExecutingPython() const { return m_lock_count > 0; }
508 
509   uint32_t IncrementLockCount() { return ++m_lock_count; }
510 
511   uint32_t DecrementLockCount() {
512     if (m_lock_count > 0)
513       --m_lock_count;
514     return m_lock_count;
515   }
516 
517   enum ActiveIOHandler {
518     eIOHandlerNone,
519     eIOHandlerBreakpoint,
520     eIOHandlerWatchpoint
521   };
522 
523   PythonObject &GetMainModule();
524 
525   PythonDictionary &GetSessionDictionary();
526 
527   PythonDictionary &GetSysModuleDictionary();
528 
529   bool GetEmbeddedInterpreterModuleObjects();
530 
531   bool SetStdHandle(File &file, const char *py_name, PythonFile &save_file,
532                     const char *mode);
533 
534   PythonFile m_saved_stdin;
535   PythonFile m_saved_stdout;
536   PythonFile m_saved_stderr;
537   PythonObject m_main_module;
538   PythonObject m_lldb_module;
539   PythonDictionary m_session_dict;
540   PythonDictionary m_sys_module_dict;
541   PythonObject m_run_one_line_function;
542   PythonObject m_run_one_line_str_global;
543   std::string m_dictionary_name;
544   TerminalState m_terminal_state;
545   ActiveIOHandler m_active_io_handler;
546   bool m_session_is_active;
547   bool m_pty_slave_is_open;
548   bool m_valid_session;
549   uint32_t m_lock_count;
550   PyThreadState *m_command_thread_state;
551 };
552 
553 } // namespace lldb_private
554 
555 #endif // LLDB_DISABLE_PYTHON
556 
557 #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHON_H
558