LLDB  mainline
ScriptInterpreterPythonImpl.h
Go to the documentation of this file.
1 //===-- ScriptInterpreterPythonImpl.h ---------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifdef LLDB_DISABLE_PYTHON
10 
11 // Python is disabled in this build
12 
13 #else
14 
15 #include "lldb-python.h"
16 
17 #include "PythonDataObjects.h"
19 
20 #include "lldb/Host/Terminal.h"
22 
23 #include "llvm/ADT/STLExtras.h"
24 #include "llvm/ADT/StringRef.h"
25 
26 namespace lldb_private {
27 class IOHandlerPythonInterpreter;
29 public:
31 
33 
35 
36  bool Interrupt() override;
37 
38  bool ExecuteOneLine(
39  llvm::StringRef command, CommandReturnObject *result,
40  const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
41 
42  void ExecuteInterpreterLoop() override;
43 
45  llvm::StringRef in_string,
46  ScriptInterpreter::ScriptReturnType return_type, void *ret_value,
47  const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
48 
50  const char *in_string,
51  const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
52 
53  Status
54  ExportFunctionDefinitionToInterpreter(StringList &function_def) override;
55 
56  bool GenerateTypeScriptFunction(StringList &input, std::string &output,
57  const void *name_token = nullptr) override;
58 
59  bool GenerateTypeSynthClass(StringList &input, std::string &output,
60  const void *name_token = nullptr) override;
61 
62  bool GenerateTypeSynthClass(const char *oneliner, std::string &output,
63  const void *name_token = nullptr) override;
64 
65  // use this if the function code is just a one-liner script
66  bool GenerateTypeScriptFunction(const char *oneliner, std::string &output,
67  const void *name_token = nullptr) override;
68 
70  std::string &output) override;
71 
73  CreateSyntheticScriptedProvider(const char *class_name,
74  lldb::ValueObjectSP valobj) override;
75 
77  CreateScriptCommandObject(const char *class_name) override;
78 
80  CreateScriptedThreadPlan(const char *class_name,
81  lldb::ThreadPlanSP thread_plan) override;
82 
84  Event *event,
85  bool &script_error) override;
86 
88  Event *event, bool &script_error) override;
89 
91  bool &script_error) override;
92 
95  bool &script_error) override;
96 
98  CreateScriptedBreakpointResolver(const char *class_name,
99  StructuredDataImpl *args_data,
100  lldb::BreakpointSP &bkpt_sp) override;
102  StructuredData::GenericSP implementor_sp,
103  SymbolContext *sym_ctx) override;
104 
106  StructuredData::GenericSP implementor_sp) override;
107 
109  CreateFrameRecognizer(const char *class_name) override;
110 
111  lldb::ValueObjectListSP
113  lldb::StackFrameSP frame_sp) override;
114 
116  OSPlugin_CreatePluginObject(const char *class_name,
117  lldb::ProcessSP process_sp) override;
118 
120  OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) override;
121 
123  OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp) override;
124 
127  lldb::tid_t thread_id) override;
128 
131  lldb::tid_t tid, lldb::addr_t context) override;
132 
134  LoadPluginModule(const FileSpec &file_spec,
135  lldb_private::Status &error) override;
136 
138  GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target,
139  const char *setting_name,
140  lldb_private::Status &error) override;
141 
142  size_t CalculateNumChildren(const StructuredData::ObjectSP &implementor,
143  uint32_t max) override;
144 
145  lldb::ValueObjectSP
146  GetChildAtIndex(const StructuredData::ObjectSP &implementor,
147  uint32_t idx) override;
148 
149  int GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor,
150  const char *child_name) override;
151 
153  const StructuredData::ObjectSP &implementor) override;
154 
156  const StructuredData::ObjectSP &implementor) override;
157 
158  lldb::ValueObjectSP
159  GetSyntheticValue(const StructuredData::ObjectSP &implementor) override;
160 
162  GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) override;
163 
164  bool
165  RunScriptBasedCommand(const char *impl_function, llvm::StringRef args,
166  ScriptedCommandSynchronicity synchronicity,
168  Status &error,
169  const lldb_private::ExecutionContext &exe_ctx) override;
170 
172  StructuredData::GenericSP impl_obj_sp, llvm::StringRef args,
173  ScriptedCommandSynchronicity synchronicity,
174  lldb_private::CommandReturnObject &cmd_retobj, Status &error,
175  const lldb_private::ExecutionContext &exe_ctx) override;
176 
177  Status GenerateFunction(const char *signature,
178  const StringList &input) override;
179 
181  std::string &output) override;
182 
184  std::string &output) override;
185 
186  bool GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj,
187  StructuredData::ObjectSP &callee_wrapper_sp,
188  const TypeSummaryOptions &options,
189  std::string &retval) override;
190 
191  void Clear() override;
192 
193  bool GetDocumentationForItem(const char *item, std::string &dest) override;
194 
196  std::string &dest) override;
197 
198  uint32_t
200 
202  std::string &dest) override;
203 
204  bool CheckObjectExists(const char *name) override {
205  if (!name || !name[0])
206  return false;
207  std::string temp;
208  return GetDocumentationForItem(name, temp);
209  }
210 
211  bool RunScriptFormatKeyword(const char *impl_function, Process *process,
212  std::string &output, Status &error) override;
213 
214  bool RunScriptFormatKeyword(const char *impl_function, Thread *thread,
215  std::string &output, Status &error) override;
216 
217  bool RunScriptFormatKeyword(const char *impl_function, Target *target,
218  std::string &output, Status &error) override;
219 
220  bool RunScriptFormatKeyword(const char *impl_function, StackFrame *frame,
221  std::string &output, Status &error) override;
222 
223  bool RunScriptFormatKeyword(const char *impl_function, ValueObject *value,
224  std::string &output, Status &error) override;
225 
226  bool
227  LoadScriptingModule(const char *filename, bool can_reload, bool init_session,
228  lldb_private::Status &error,
229  StructuredData::ObjectSP *module_sp = nullptr) override;
230 
231  bool IsReservedWord(const char *word) override;
232 
233  std::unique_ptr<ScriptInterpreterLocker> AcquireInterpreterLock() override;
234 
236  std::vector<BreakpointOptions *> &bp_options_vec,
237  CommandReturnObject &result) override;
238 
239  void
241  CommandReturnObject &result) override;
242 
243  /// Set the callback body text into the callback for the breakpoint.
245  const char *callback_body) override;
246 
248  const char *function_name) override;
249 
250  /// This one is for deserialization:
252  BreakpointOptions *bp_options,
253  std::unique_ptr<BreakpointOptions::CommandData> &data_up) override;
254 
255  /// Set a one-liner as the callback for the watchpoint.
257  const char *oneliner) override;
258 
259  void ResetOutputFileHandle(FILE *new_fh) override;
260 
261  const char *GetDictionaryName() { return m_dictionary_name.c_str(); }
262 
263  PyThreadState *GetThreadState() { return m_command_thread_state; }
264 
265  void SetThreadState(PyThreadState *s) {
266  if (s)
268  }
269 
270  // IOHandlerDelegate
271  void IOHandlerActivated(IOHandler &io_handler, bool interactive) override;
272 
273  void IOHandlerInputComplete(IOHandler &io_handler,
274  std::string &data) override;
275 
276  static lldb::ScriptInterpreterSP CreateInstance(Debugger &debugger);
277 
278  // PluginInterface protocol
280 
281  uint32_t GetPluginVersion() override;
282 
284  public:
285  enum OnEntry {
286  AcquireLock = 0x0001,
287  InitSession = 0x0002,
288  InitGlobals = 0x0004,
289  NoSTDIN = 0x0008
290  };
291 
292  enum OnLeave {
293  FreeLock = 0x0001,
294  FreeAcquiredLock = 0x0002, // do not free the lock if we already held it
295  // when calling constructor
297  };
298 
299  Locker(ScriptInterpreterPythonImpl *py_interpreter = nullptr,
300  uint16_t on_entry = AcquireLock | InitSession,
301  uint16_t on_leave = FreeLock | TearDownSession, FILE *in = nullptr,
302  FILE *out = nullptr, FILE *err = nullptr);
303 
304  ~Locker() override;
305 
306  private:
307  bool DoAcquireLock();
308 
309  bool DoInitSession(uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err);
310 
311  bool DoFreeLock();
312 
313  bool DoTearDownSession();
314 
315  bool m_teardown_session;
316  ScriptInterpreterPythonImpl *m_python_interpreter;
317  // FILE* m_tmp_fh;
318  PyGILState_STATE m_GILState;
319  };
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  static bool WatchpointCallbackFunction(void *baton,
326  StoppointCallbackContext *context,
327  lldb::user_id_t watch_id);
328  static void InitializePrivate();
329 
331  private:
332  lldb::DebuggerSP m_debugger_sp;
333  ScriptedCommandSynchronicity m_synch_wanted;
334  bool m_old_asynch;
335 
336  public:
338 
340  };
341 
342  enum class AddLocation { Beginning, End };
343 
344  static void AddToSysPath(AddLocation location, std::string path);
345 
346  bool EnterSession(uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err);
347 
348  void LeaveSession();
349 
350  void SaveTerminalState(int fd);
351 
352  void RestoreTerminalState();
353 
354  uint32_t IsExecutingPython() const { return m_lock_count > 0; }
355 
357 
359  if (m_lock_count > 0)
360  --m_lock_count;
361  return m_lock_count;
362  }
363 
368  };
369 
371 
373 
375 
377 
378  bool SetStdHandle(File &file, const char *py_name, PythonFile &save_file,
379  const char *mode);
380 
389  std::string m_dictionary_name;
390  TerminalState m_terminal_state;
396  PyThreadState *m_command_thread_state;
397 };
398 
400 public:
403  : IOHandler(debugger, IOHandler::Type::PythonInterpreter),
404  m_python(python) {}
405 
407 
408  ConstString GetControlSequence(char ch) override {
409  if (ch == 'd')
410  return ConstString("quit()\n");
411  return ConstString();
412  }
413 
414  void Run() override {
415  if (m_python) {
416  int stdin_fd = GetInputFD();
417  if (stdin_fd >= 0) {
418  Terminal terminal(stdin_fd);
419  TerminalState terminal_state;
420  const bool is_a_tty = terminal.IsATerminal();
421 
422  if (is_a_tty) {
423  terminal_state.Save(stdin_fd, false);
424  terminal.SetCanonical(false);
425  terminal.SetEcho(true);
426  }
427 
429  m_python,
435 
436  // The following call drops into the embedded interpreter loop and
437  // stays there until the user chooses to exit from the Python
438  // interpreter. This embedded interpreter will, as any Python code that
439  // performs I/O, unlock the GIL before a system call that can hang, and
440  // lock it when the syscall has returned.
441 
442  // We need to surround the call to the embedded interpreter with calls
443  // to PyGILState_Ensure and PyGILState_Release (using the Locker
444  // above). This is because Python has a global lock which must be held
445  // whenever we want to touch any Python objects. Otherwise, if the user
446  // calls Python code, the interpreter state will be off, and things
447  // could hang (it's happened before).
448 
449  StreamString run_string;
450  run_string.Printf("run_python_interpreter (%s)",
451  m_python->GetDictionaryName());
452  PyRun_SimpleString(run_string.GetData());
453 
454  if (is_a_tty)
455  terminal_state.Restore();
456  }
457  }
458  SetIsDone(true);
459  }
460 
461  void Cancel() override {}
462 
463  bool Interrupt() override { return m_python->Interrupt(); }
464 
465  void GotEOF() override {}
466 
467 protected:
469 };
470 
471 } // namespace lldb_private
472 
473 #endif
bool GenerateTypeSynthClass(StringList &input, std::string &output, const void *name_token=nullptr) override
A class to manage flag bits.
Definition: Debugger.h:82
void CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options, CommandReturnObject &result) override
ConstString GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) override
Status GenerateFunction(const char *signature, const StringList &input) override
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
std::shared_ptr< Array > ArraySP
bool LoadScriptingModule(const char *filename, bool can_reload, bool init_session, lldb_private::Status &error, StructuredData::ObjectSP *module_sp=nullptr) override
lldb::ValueObjectSP GetChildAtIndex(const StructuredData::ObjectSP &implementor, uint32_t idx) override
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:33
void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override
Called when a line or lines have been retrieved.
StructuredData::GenericSP OSPlugin_CreatePluginObject(const char *class_name, lldb::ProcessSP process_sp) override
bool ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) override
lldb::StateType ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp, bool &script_error) override
StructuredData::DictionarySP OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid, lldb::addr_t context) override
StructuredData::ObjectSP LoadPluginModule(const FileSpec &file_spec, lldb_private::Status &error) override
StructuredData::DictionarySP GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target, const char *setting_name, lldb_private::Status &error) override
bool GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, std::string &dest) override
Status SetBreakpointCommandCallback(BreakpointOptions *bp_options, const char *callback_body) override
Set the callback body text into the callback for the breakpoint.
uint32_t GetFlagsForCommandObject(StructuredData::GenericSP cmd_obj_sp) override
A file utility class.
Definition: FileSpec.h:55
Status GenerateBreakpointCommandCallbackData(StringList &input, std::string &output) override
Abstract interface for the Python script interpreter.
StructuredData::ObjectSP CreateSyntheticScriptedProvider(const char *class_name, lldb::ValueObjectSP valobj) override
bool GenerateTypeScriptFunction(StringList &input, std::string &output, const void *name_token=nullptr) override
bool GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj, StructuredData::ObjectSP &callee_wrapper_sp, const TypeSummaryOptions &options, std::string &retval) override
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
StructuredData::GenericSP CreateScriptCommandObject(const char *class_name) override
const char * GetData() const
Definition: StreamString.h:43
bool ExecuteOneLine(llvm::StringRef command, CommandReturnObject *result, const ExecuteScriptOptions &options=ExecuteScriptOptions()) override
lldb::SearchDepth ScriptedBreakpointResolverSearchDepth(StructuredData::GenericSP implementor_sp) override
bool GenerateWatchpointCommandCallbackData(StringList &input, std::string &output) override
A file class.
Definition: File.h:29
size_t CalculateNumChildren(const StructuredData::ObjectSP &implementor, uint32_t max) override
std::shared_ptr< Dictionary > DictionarySP
bool GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, std::string &dest) override
StructuredData::ObjectSP CreateScriptedThreadPlan(const char *class_name, lldb::ThreadPlanSP thread_plan) override
bool SetStdHandle(File &file, const char *py_name, PythonFile &save_file, const char *mode)
uint64_t user_id_t
Definition: lldb-types.h:84
lldb::ValueObjectSP GetSyntheticValue(const StructuredData::ObjectSP &implementor) override
bool ScriptedBreakpointResolverSearchCallback(StructuredData::GenericSP implementor_sp, SymbolContext *sym_ctx) override
static bool WatchpointCallbackFunction(void *baton, StoppointCallbackContext *context, lldb::user_id_t watch_id)
StructuredData::DictionarySP OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) override
bool GenerateScriptAliasFunction(StringList &input, std::string &output) override
bool MightHaveChildrenSynthProviderInstance(const StructuredData::ObjectSP &implementor) override
uint64_t tid_t
Definition: lldb-types.h:86
IOHandlerPythonInterpreter(Debugger &debugger, ScriptInterpreterPythonImpl *python)
A plug-in interface definition class for debugging a process.
Definition: Process.h:353
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:106
void SetWatchpointCommandCallback(WatchpointOptions *wp_options, const char *oneliner) override
Set a one-liner as the callback for the watchpoint.
Status ExportFunctionDefinitionToInterpreter(StringList &function_def) override
StructuredData::ArraySP OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp) override
static bool BreakpointCallbackFunction(void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
bool ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp, bool &script_error) override
std::shared_ptr< String > StringSP
Locker(ScriptInterpreterPythonImpl *py_interpreter=nullptr, uint16_t on_entry=AcquireLock|InitSession, uint16_t on_leave=FreeLock|TearDownSession, FILE *in=nullptr, FILE *out=nullptr, FILE *err=nullptr)
bool RunScriptFormatKeyword(const char *impl_function, Process *process, std::string &output, Status &error) override
"lldb/Breakpoint/WatchpointOptions.h" Class that manages the options on a watchpoint.
StructuredData::StringSP OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t thread_id) override
uint64_t addr_t
Definition: lldb-types.h:83
bool RunScriptBasedCommand(const char *impl_function, llvm::StringRef args, ScriptedCommandSynchronicity synchronicity, lldb_private::CommandReturnObject &cmd_retobj, Status &error, const lldb_private::ExecutionContext &exe_ctx) override
A uniqued constant string class.
Definition: ConstString.h:38
int GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor, const char *child_name) override
StructuredData::GenericSP CreateFrameRecognizer(const char *class_name) override
lldb_private::Status ExecuteMultipleLines(const char *in_string, const ExecuteScriptOptions &options=ExecuteScriptOptions()) override
"lldb/Breakpoint/BreakpointOptions.h" Class that manages the options on a breakpoint or breakpoint lo...
void SetBreakpointCommandCallbackFunction(BreakpointOptions *bp_options, const char *function_name) override
Set a one-liner as the callback for the breakpoint.
std::unique_ptr< ScriptInterpreterLocker > AcquireInterpreterLock() override
bool GetDocumentationForItem(const char *item, std::string &dest) override
void CollectDataForBreakpointCommandCallback(std::vector< BreakpointOptions *> &bp_options_vec, CommandReturnObject &result) override
std::shared_ptr< Object > ObjectSP
bool UpdateSynthProviderInstance(const StructuredData::ObjectSP &implementor) override
lldb_private::ConstString GetPluginName() override
static void AddToSysPath(AddLocation location, std::string path)
General Outline: When we hit a breakpoint we need to package up whatever information is needed to eva...
bool EnterSession(uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err)
bool ExecuteOneLineWithReturn(llvm::StringRef in_string, ScriptInterpreter::ScriptReturnType return_type, void *ret_value, const ExecuteScriptOptions &options=ExecuteScriptOptions()) override
std::shared_ptr< Generic > GenericSP
This base class provides an interface to stack frames.
Definition: StackFrame.h:40
bool ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) override
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
static lldb::ScriptInterpreterSP CreateInstance(Debugger &debugger)
StructuredData::GenericSP CreateScriptedBreakpointResolver(const char *class_name, StructuredDataImpl *args_data, lldb::BreakpointSP &bkpt_sp) override
An error handling class.
Definition: Status.h:44
lldb::ValueObjectListSP GetRecognizedArguments(const StructuredData::ObjectSP &implementor, lldb::StackFrameSP frame_sp) override