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