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