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