ScriptInterpreter.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. //===-- ScriptInterpreter.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. #ifndef LLDB_INTERPRETER_SCRIPTINTERPRETER_H
  9. #define LLDB_INTERPRETER_SCRIPTINTERPRETER_H
  10. #include "lldb/API/SBData.h"
  11. #include "lldb/API/SBError.h"
  12. #include "lldb/Breakpoint/BreakpointOptions.h"
  13. #include "lldb/Core/Communication.h"
  14. #include "lldb/Core/PluginInterface.h"
  15. #include "lldb/Core/SearchFilter.h"
  16. #include "lldb/Core/StreamFile.h"
  17. #include "lldb/Host/PseudoTerminal.h"
  18. #include "lldb/Interpreter/ScriptedProcessInterface.h"
  19. #include "lldb/Utility/Broadcaster.h"
  20. #include "lldb/Utility/Status.h"
  21. #include "lldb/Utility/StructuredData.h"
  22. #include "lldb/lldb-private.h"
  23. namespace lldb_private {
  24. class ScriptInterpreterLocker {
  25. public:
  26. ScriptInterpreterLocker() = default;
  27. virtual ~ScriptInterpreterLocker() = default;
  28. private:
  29. ScriptInterpreterLocker(const ScriptInterpreterLocker &) = delete;
  30. const ScriptInterpreterLocker &
  31. operator=(const ScriptInterpreterLocker &) = delete;
  32. };
  33. class ScriptInterpreterIORedirect {
  34. public:
  35. /// Create an IO redirect. If IO is enabled, this will redirects the output
  36. /// to the command return object if set or to the debugger otherwise. If IO
  37. /// is disabled, it will redirect all IO to /dev/null.
  38. static llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
  39. Create(bool enable_io, Debugger &debugger, CommandReturnObject *result);
  40. ~ScriptInterpreterIORedirect();
  41. lldb::FileSP GetInputFile() const { return m_input_file_sp; }
  42. lldb::FileSP GetOutputFile() const { return m_output_file_sp->GetFileSP(); }
  43. lldb::FileSP GetErrorFile() const { return m_error_file_sp->GetFileSP(); }
  44. /// Flush our output and error file handles.
  45. void Flush();
  46. private:
  47. ScriptInterpreterIORedirect(std::unique_ptr<File> input,
  48. std::unique_ptr<File> output);
  49. ScriptInterpreterIORedirect(Debugger &debugger, CommandReturnObject *result);
  50. lldb::FileSP m_input_file_sp;
  51. lldb::StreamFileSP m_output_file_sp;
  52. lldb::StreamFileSP m_error_file_sp;
  53. Communication m_communication;
  54. bool m_disconnect;
  55. };
  56. class ScriptInterpreter : public PluginInterface {
  57. public:
  58. enum ScriptReturnType {
  59. eScriptReturnTypeCharPtr,
  60. eScriptReturnTypeBool,
  61. eScriptReturnTypeShortInt,
  62. eScriptReturnTypeShortIntUnsigned,
  63. eScriptReturnTypeInt,
  64. eScriptReturnTypeIntUnsigned,
  65. eScriptReturnTypeLongInt,
  66. eScriptReturnTypeLongIntUnsigned,
  67. eScriptReturnTypeLongLong,
  68. eScriptReturnTypeLongLongUnsigned,
  69. eScriptReturnTypeFloat,
  70. eScriptReturnTypeDouble,
  71. eScriptReturnTypeChar,
  72. eScriptReturnTypeCharStrOrNone,
  73. eScriptReturnTypeOpaqueObject
  74. };
  75. ScriptInterpreter(
  76. Debugger &debugger, lldb::ScriptLanguage script_lang,
  77. lldb::ScriptedProcessInterfaceUP scripted_process_interface_up = {});
  78. ~ScriptInterpreter() override = default;
  79. struct ExecuteScriptOptions {
  80. public:
  81. ExecuteScriptOptions()
  82. : m_enable_io(true), m_set_lldb_globals(true), m_maskout_errors(true) {}
  83. bool GetEnableIO() const { return m_enable_io; }
  84. bool GetSetLLDBGlobals() const { return m_set_lldb_globals; }
  85. // If this is true then any exceptions raised by the script will be
  86. // cleared with PyErr_Clear(). If false then they will be left for
  87. // the caller to clean up
  88. bool GetMaskoutErrors() const { return m_maskout_errors; }
  89. ExecuteScriptOptions &SetEnableIO(bool enable) {
  90. m_enable_io = enable;
  91. return *this;
  92. }
  93. ExecuteScriptOptions &SetSetLLDBGlobals(bool set) {
  94. m_set_lldb_globals = set;
  95. return *this;
  96. }
  97. ExecuteScriptOptions &SetMaskoutErrors(bool maskout) {
  98. m_maskout_errors = maskout;
  99. return *this;
  100. }
  101. private:
  102. bool m_enable_io;
  103. bool m_set_lldb_globals;
  104. bool m_maskout_errors;
  105. };
  106. virtual bool Interrupt() { return false; }
  107. virtual bool ExecuteOneLine(
  108. llvm::StringRef command, CommandReturnObject *result,
  109. const ExecuteScriptOptions &options = ExecuteScriptOptions()) = 0;
  110. virtual void ExecuteInterpreterLoop() = 0;
  111. virtual bool ExecuteOneLineWithReturn(
  112. llvm::StringRef in_string, ScriptReturnType return_type, void *ret_value,
  113. const ExecuteScriptOptions &options = ExecuteScriptOptions()) {
  114. return true;
  115. }
  116. virtual Status ExecuteMultipleLines(
  117. const char *in_string,
  118. const ExecuteScriptOptions &options = ExecuteScriptOptions()) {
  119. Status error;
  120. error.SetErrorString("not implemented");
  121. return error;
  122. }
  123. virtual Status
  124. ExportFunctionDefinitionToInterpreter(StringList &function_def) {
  125. Status error;
  126. error.SetErrorString("not implemented");
  127. return error;
  128. }
  129. virtual Status GenerateBreakpointCommandCallbackData(
  130. StringList &input,
  131. std::string &output,
  132. bool has_extra_args) {
  133. Status error;
  134. error.SetErrorString("not implemented");
  135. return error;
  136. }
  137. virtual bool GenerateWatchpointCommandCallbackData(StringList &input,
  138. std::string &output) {
  139. return false;
  140. }
  141. virtual bool GenerateTypeScriptFunction(const char *oneliner,
  142. std::string &output,
  143. const void *name_token = nullptr) {
  144. return false;
  145. }
  146. virtual bool GenerateTypeScriptFunction(StringList &input,
  147. std::string &output,
  148. const void *name_token = nullptr) {
  149. return false;
  150. }
  151. virtual bool GenerateScriptAliasFunction(StringList &input,
  152. std::string &output) {
  153. return false;
  154. }
  155. virtual bool GenerateTypeSynthClass(StringList &input, std::string &output,
  156. const void *name_token = nullptr) {
  157. return false;
  158. }
  159. virtual bool GenerateTypeSynthClass(const char *oneliner, std::string &output,
  160. const void *name_token = nullptr) {
  161. return false;
  162. }
  163. virtual StructuredData::ObjectSP
  164. CreateSyntheticScriptedProvider(const char *class_name,
  165. lldb::ValueObjectSP valobj) {
  166. return StructuredData::ObjectSP();
  167. }
  168. virtual StructuredData::GenericSP
  169. CreateScriptCommandObject(const char *class_name) {
  170. return StructuredData::GenericSP();
  171. }
  172. virtual StructuredData::GenericSP
  173. CreateFrameRecognizer(const char *class_name) {
  174. return StructuredData::GenericSP();
  175. }
  176. virtual lldb::ValueObjectListSP GetRecognizedArguments(
  177. const StructuredData::ObjectSP &implementor,
  178. lldb::StackFrameSP frame_sp) {
  179. return lldb::ValueObjectListSP();
  180. }
  181. virtual StructuredData::GenericSP
  182. OSPlugin_CreatePluginObject(const char *class_name,
  183. lldb::ProcessSP process_sp) {
  184. return StructuredData::GenericSP();
  185. }
  186. virtual StructuredData::DictionarySP
  187. OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) {
  188. return StructuredData::DictionarySP();
  189. }
  190. virtual StructuredData::ArraySP
  191. OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp) {
  192. return StructuredData::ArraySP();
  193. }
  194. virtual StructuredData::StringSP
  195. OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp,
  196. lldb::tid_t thread_id) {
  197. return StructuredData::StringSP();
  198. }
  199. virtual StructuredData::DictionarySP
  200. OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp,
  201. lldb::tid_t tid, lldb::addr_t context) {
  202. return StructuredData::DictionarySP();
  203. }
  204. virtual StructuredData::ObjectSP
  205. CreateScriptedThreadPlan(const char *class_name,
  206. StructuredDataImpl *args_data,
  207. std::string &error_str,
  208. lldb::ThreadPlanSP thread_plan_sp) {
  209. return StructuredData::ObjectSP();
  210. }
  211. virtual bool
  212. ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp,
  213. Event *event, bool &script_error) {
  214. script_error = true;
  215. return true;
  216. }
  217. virtual bool
  218. ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp,
  219. Event *event, bool &script_error) {
  220. script_error = true;
  221. return true;
  222. }
  223. virtual bool
  224. ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp,
  225. bool &script_error) {
  226. script_error = true;
  227. return true;
  228. }
  229. virtual lldb::StateType
  230. ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp,
  231. bool &script_error) {
  232. script_error = true;
  233. return lldb::eStateStepping;
  234. }
  235. virtual StructuredData::GenericSP
  236. CreateScriptedBreakpointResolver(const char *class_name,
  237. StructuredDataImpl *args_data,
  238. lldb::BreakpointSP &bkpt_sp) {
  239. return StructuredData::GenericSP();
  240. }
  241. virtual bool
  242. ScriptedBreakpointResolverSearchCallback(StructuredData::GenericSP implementor_sp,
  243. SymbolContext *sym_ctx)
  244. {
  245. return false;
  246. }
  247. virtual lldb::SearchDepth
  248. ScriptedBreakpointResolverSearchDepth(StructuredData::GenericSP implementor_sp)
  249. {
  250. return lldb::eSearchDepthModule;
  251. }
  252. virtual StructuredData::GenericSP
  253. CreateScriptedStopHook(lldb::TargetSP target_sp, const char *class_name,
  254. StructuredDataImpl *args_data, Status &error) {
  255. error.SetErrorString("Creating scripted stop-hooks with the current "
  256. "script interpreter is not supported.");
  257. return StructuredData::GenericSP();
  258. }
  259. // This dispatches to the handle_stop method of the stop-hook class. It
  260. // returns a "should_stop" bool.
  261. virtual bool
  262. ScriptedStopHookHandleStop(StructuredData::GenericSP implementor_sp,
  263. ExecutionContext &exc_ctx,
  264. lldb::StreamSP stream_sp) {
  265. return true;
  266. }
  267. virtual StructuredData::ObjectSP
  268. LoadPluginModule(const FileSpec &file_spec, lldb_private::Status &error) {
  269. return StructuredData::ObjectSP();
  270. }
  271. virtual StructuredData::DictionarySP
  272. GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target,
  273. const char *setting_name, lldb_private::Status &error) {
  274. return StructuredData::DictionarySP();
  275. }
  276. virtual Status GenerateFunction(const char *signature,
  277. const StringList &input) {
  278. Status error;
  279. error.SetErrorString("unimplemented");
  280. return error;
  281. }
  282. virtual void CollectDataForBreakpointCommandCallback(
  283. std::vector<BreakpointOptions *> &options, CommandReturnObject &result);
  284. virtual void
  285. CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options,
  286. CommandReturnObject &result);
  287. /// Set the specified text as the callback for the breakpoint.
  288. Status
  289. SetBreakpointCommandCallback(std::vector<BreakpointOptions *> &bp_options_vec,
  290. const char *callback_text);
  291. virtual Status SetBreakpointCommandCallback(BreakpointOptions *bp_options,
  292. const char *callback_text) {
  293. Status error;
  294. error.SetErrorString("unimplemented");
  295. return error;
  296. }
  297. /// This one is for deserialization:
  298. virtual Status SetBreakpointCommandCallback(
  299. BreakpointOptions *bp_options,
  300. std::unique_ptr<BreakpointOptions::CommandData> &data_up) {
  301. Status error;
  302. error.SetErrorString("unimplemented");
  303. return error;
  304. }
  305. Status SetBreakpointCommandCallbackFunction(
  306. std::vector<BreakpointOptions *> &bp_options_vec,
  307. const char *function_name, StructuredData::ObjectSP extra_args_sp);
  308. /// Set a script function as the callback for the breakpoint.
  309. virtual Status
  310. SetBreakpointCommandCallbackFunction(
  311. BreakpointOptions *bp_options,
  312. const char *function_name,
  313. StructuredData::ObjectSP extra_args_sp) {
  314. Status error;
  315. error.SetErrorString("unimplemented");
  316. return error;
  317. }
  318. /// Set a one-liner as the callback for the watchpoint.
  319. virtual void SetWatchpointCommandCallback(WatchpointOptions *wp_options,
  320. const char *oneliner) {}
  321. virtual bool GetScriptedSummary(const char *function_name,
  322. lldb::ValueObjectSP valobj,
  323. StructuredData::ObjectSP &callee_wrapper_sp,
  324. const TypeSummaryOptions &options,
  325. std::string &retval) {
  326. return false;
  327. }
  328. virtual void Clear() {
  329. // Clean up any ref counts to SBObjects that might be in global variables
  330. }
  331. virtual size_t
  332. CalculateNumChildren(const StructuredData::ObjectSP &implementor,
  333. uint32_t max) {
  334. return 0;
  335. }
  336. virtual lldb::ValueObjectSP
  337. GetChildAtIndex(const StructuredData::ObjectSP &implementor, uint32_t idx) {
  338. return lldb::ValueObjectSP();
  339. }
  340. virtual int
  341. GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor,
  342. const char *child_name) {
  343. return UINT32_MAX;
  344. }
  345. virtual bool
  346. UpdateSynthProviderInstance(const StructuredData::ObjectSP &implementor) {
  347. return false;
  348. }
  349. virtual bool MightHaveChildrenSynthProviderInstance(
  350. const StructuredData::ObjectSP &implementor) {
  351. return true;
  352. }
  353. virtual lldb::ValueObjectSP
  354. GetSyntheticValue(const StructuredData::ObjectSP &implementor) {
  355. return nullptr;
  356. }
  357. virtual ConstString
  358. GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) {
  359. return ConstString();
  360. }
  361. virtual bool
  362. RunScriptBasedCommand(const char *impl_function, llvm::StringRef args,
  363. ScriptedCommandSynchronicity synchronicity,
  364. lldb_private::CommandReturnObject &cmd_retobj,
  365. Status &error,
  366. const lldb_private::ExecutionContext &exe_ctx) {
  367. return false;
  368. }
  369. virtual bool RunScriptBasedCommand(
  370. StructuredData::GenericSP impl_obj_sp, llvm::StringRef args,
  371. ScriptedCommandSynchronicity synchronicity,
  372. lldb_private::CommandReturnObject &cmd_retobj, Status &error,
  373. const lldb_private::ExecutionContext &exe_ctx) {
  374. return false;
  375. }
  376. virtual bool RunScriptFormatKeyword(const char *impl_function,
  377. Process *process, std::string &output,
  378. Status &error) {
  379. error.SetErrorString("unimplemented");
  380. return false;
  381. }
  382. virtual bool RunScriptFormatKeyword(const char *impl_function, Thread *thread,
  383. std::string &output, Status &error) {
  384. error.SetErrorString("unimplemented");
  385. return false;
  386. }
  387. virtual bool RunScriptFormatKeyword(const char *impl_function, Target *target,
  388. std::string &output, Status &error) {
  389. error.SetErrorString("unimplemented");
  390. return false;
  391. }
  392. virtual bool RunScriptFormatKeyword(const char *impl_function,
  393. StackFrame *frame, std::string &output,
  394. Status &error) {
  395. error.SetErrorString("unimplemented");
  396. return false;
  397. }
  398. virtual bool RunScriptFormatKeyword(const char *impl_function,
  399. ValueObject *value, std::string &output,
  400. Status &error) {
  401. error.SetErrorString("unimplemented");
  402. return false;
  403. }
  404. virtual bool GetDocumentationForItem(const char *item, std::string &dest) {
  405. dest.clear();
  406. return false;
  407. }
  408. virtual bool
  409. GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,
  410. std::string &dest) {
  411. dest.clear();
  412. return false;
  413. }
  414. virtual uint32_t
  415. GetFlagsForCommandObject(StructuredData::GenericSP cmd_obj_sp) {
  416. return 0;
  417. }
  418. virtual bool GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,
  419. std::string &dest) {
  420. dest.clear();
  421. return false;
  422. }
  423. virtual bool CheckObjectExists(const char *name) { return false; }
  424. virtual bool
  425. LoadScriptingModule(const char *filename, bool init_session,
  426. lldb_private::Status &error,
  427. StructuredData::ObjectSP *module_sp = nullptr,
  428. FileSpec extra_search_dir = {});
  429. virtual bool IsReservedWord(const char *word) { return false; }
  430. virtual std::unique_ptr<ScriptInterpreterLocker> AcquireInterpreterLock();
  431. const char *GetScriptInterpreterPtyName();
  432. virtual llvm::Expected<unsigned>
  433. GetMaxPositionalArgumentsForCallable(const llvm::StringRef &callable_name) {
  434. return llvm::createStringError(
  435. llvm::inconvertibleErrorCode(), "Unimplemented function");
  436. }
  437. static std::string LanguageToString(lldb::ScriptLanguage language);
  438. static lldb::ScriptLanguage StringToLanguage(const llvm::StringRef &string);
  439. lldb::ScriptLanguage GetLanguage() { return m_script_lang; }
  440. ScriptedProcessInterface &GetScriptedProcessInterface() {
  441. return *m_scripted_process_interface_up;
  442. }
  443. lldb::DataExtractorSP
  444. GetDataExtractorFromSBData(const lldb::SBData &data) const;
  445. Status GetStatusFromSBError(const lldb::SBError &error) const;
  446. protected:
  447. Debugger &m_debugger;
  448. lldb::ScriptLanguage m_script_lang;
  449. lldb::ScriptedProcessInterfaceUP m_scripted_process_interface_up;
  450. };
  451. } // namespace lldb_private
  452. #endif // LLDB_INTERPRETER_SCRIPTINTERPRETER_H