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