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
9#ifndef LLDB_INTERPRETER_SCRIPTINTERPRETER_H
10#define LLDB_INTERPRETER_SCRIPTINTERPRETER_H
11
12#include "lldb/API/SBAttachInfo.h"
13#include "lldb/API/SBBreakpoint.h"
14#include "lldb/API/SBData.h"
15#include "lldb/API/SBError.h"
16#include "lldb/API/SBLaunchInfo.h"
17#include "lldb/API/SBMemoryRegionInfo.h"
18#include "lldb/Breakpoint/BreakpointOptions.h"
19#include "lldb/Core/PluginInterface.h"
20#include "lldb/Core/SearchFilter.h"
21#include "lldb/Core/ThreadedCommunication.h"
22#include "lldb/Host/PseudoTerminal.h"
23#include "lldb/Host/StreamFile.h"
24#include "lldb/Interpreter/Interfaces/OperatingSystemInterface.h"
25#include "lldb/Interpreter/Interfaces/ScriptedPlatformInterface.h"
26#include "lldb/Interpreter/Interfaces/ScriptedProcessInterface.h"
27#include "lldb/Interpreter/Interfaces/ScriptedThreadInterface.h"
28#include "lldb/Interpreter/ScriptObject.h"
29#include "lldb/Utility/Broadcaster.h"
30#include "lldb/Utility/Status.h"
31#include "lldb/Utility/StructuredData.h"
32#include "lldb/lldb-private.h"
33#include <optional>
34
35namespace lldb_private {
36
37class ScriptInterpreterLocker {
38public:
39 ScriptInterpreterLocker() = default;
40
41 virtual ~ScriptInterpreterLocker() = default;
42
43private:
44 ScriptInterpreterLocker(const ScriptInterpreterLocker &) = delete;
45 const ScriptInterpreterLocker &
46 operator=(const ScriptInterpreterLocker &) = delete;
47};
48
49class ExecuteScriptOptions {
50public:
51 ExecuteScriptOptions() = default;
52
53 bool GetEnableIO() const { return m_enable_io; }
54
55 bool GetSetLLDBGlobals() const { return m_set_lldb_globals; }
56
57 // If this is true then any exceptions raised by the script will be
58 // cleared with PyErr_Clear(). If false then they will be left for
59 // the caller to clean up
60 bool GetMaskoutErrors() const { return m_maskout_errors; }
61
62 ExecuteScriptOptions &SetEnableIO(bool enable) {
63 m_enable_io = enable;
64 return *this;
65 }
66
67 ExecuteScriptOptions &SetSetLLDBGlobals(bool set) {
68 m_set_lldb_globals = set;
69 return *this;
70 }
71
72 ExecuteScriptOptions &SetMaskoutErrors(bool maskout) {
73 m_maskout_errors = maskout;
74 return *this;
75 }
76
77private:
78 bool m_enable_io = true;
79 bool m_set_lldb_globals = true;
80 bool m_maskout_errors = true;
81};
82
83class LoadScriptOptions {
84public:
85 LoadScriptOptions() = default;
86
87 bool GetInitSession() const { return m_init_session; }
88 bool GetSilent() const { return m_silent; }
89
90 LoadScriptOptions &SetInitSession(bool b) {
91 m_init_session = b;
92 return *this;
93 }
94
95 LoadScriptOptions &SetSilent(bool b) {
96 m_silent = b;
97 return *this;
98 }
99
100private:
101 bool m_init_session = false;
102 bool m_silent = false;
103};
104
105class ScriptInterpreterIORedirect {
106public:
107 /// Create an IO redirect. If IO is enabled, this will redirects the output
108 /// to the command return object if set or to the debugger otherwise. If IO
109 /// is disabled, it will redirect all IO to /dev/null.
110 static llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
111 Create(bool enable_io, Debugger &debugger, CommandReturnObject *result);
112
113 ~ScriptInterpreterIORedirect();
114
115 lldb::FileSP GetInputFile() const { return m_input_file_sp; }
116 lldb::FileSP GetOutputFile() const { return m_output_file_sp->GetFileSP(); }
117 lldb::FileSP GetErrorFile() const { return m_error_file_sp->GetFileSP(); }
118
119 /// Flush our output and error file handles.
120 void Flush();
121
122private:
123 ScriptInterpreterIORedirect(std::unique_ptr<File> input,
124 std::unique_ptr<File> output);
125 ScriptInterpreterIORedirect(Debugger &debugger, CommandReturnObject *result);
126
127 lldb::FileSP m_input_file_sp;
128 lldb::StreamFileSP m_output_file_sp;
129 lldb::StreamFileSP m_error_file_sp;
130 ThreadedCommunication m_communication;
131 bool m_disconnect;
132};
133
134class ScriptInterpreter : public PluginInterface {
135public:
136 enum ScriptReturnType {
137 eScriptReturnTypeCharPtr,
138 eScriptReturnTypeBool,
139 eScriptReturnTypeShortInt,
140 eScriptReturnTypeShortIntUnsigned,
141 eScriptReturnTypeInt,
142 eScriptReturnTypeIntUnsigned,
143 eScriptReturnTypeLongInt,
144 eScriptReturnTypeLongIntUnsigned,
145 eScriptReturnTypeLongLong,
146 eScriptReturnTypeLongLongUnsigned,
147 eScriptReturnTypeFloat,
148 eScriptReturnTypeDouble,
149 eScriptReturnTypeChar,
150 eScriptReturnTypeCharStrOrNone,
151 eScriptReturnTypeOpaqueObject
152 };
153
154 ScriptInterpreter(Debugger &debugger, lldb::ScriptLanguage script_lang);
155
156 virtual StructuredData::DictionarySP GetInterpreterInfo();
157
158 ~ScriptInterpreter() override = default;
159
160 virtual bool Interrupt() { return false; }
161
162 virtual bool ExecuteOneLine(
163 llvm::StringRef command, CommandReturnObject *result,
164 const ExecuteScriptOptions &options = ExecuteScriptOptions()) = 0;
165
166 virtual void ExecuteInterpreterLoop() = 0;
167
168 virtual bool ExecuteOneLineWithReturn(
169 llvm::StringRef in_string, ScriptReturnType return_type, void *ret_value,
170 const ExecuteScriptOptions &options = ExecuteScriptOptions()) {
171 return true;
172 }
173
174 virtual Status ExecuteMultipleLines(
175 const char *in_string,
176 const ExecuteScriptOptions &options = ExecuteScriptOptions()) {
177 Status error;
178 error.SetErrorString("not implemented");
179 return error;
180 }
181
182 virtual Status
183 ExportFunctionDefinitionToInterpreter(StringList &function_def) {
184 Status error;
185 error.SetErrorString("not implemented");
186 return error;
187 }
188
189 virtual Status GenerateBreakpointCommandCallbackData(StringList &input,
190 std::string &output,
191 bool has_extra_args,
192 bool is_callback) {
193 Status error;
194 error.SetErrorString("not implemented");
195 return error;
196 }
197
198 virtual bool GenerateWatchpointCommandCallbackData(StringList &input,
199 std::string &output,
200 bool is_callback) {
201 return false;
202 }
203
204 virtual bool GenerateTypeScriptFunction(const char *oneliner,
205 std::string &output,
206 const void *name_token = nullptr) {
207 return false;
208 }
209
210 virtual bool GenerateTypeScriptFunction(StringList &input,
211 std::string &output,
212 const void *name_token = nullptr) {
213 return false;
214 }
215
216 virtual bool GenerateScriptAliasFunction(StringList &input,
217 std::string &output) {
218 return false;
219 }
220
221 virtual bool GenerateTypeSynthClass(StringList &input, std::string &output,
222 const void *name_token = nullptr) {
223 return false;
224 }
225
226 virtual bool GenerateTypeSynthClass(const char *oneliner, std::string &output,
227 const void *name_token = nullptr) {
228 return false;
229 }
230
231 virtual StructuredData::ObjectSP
232 CreateSyntheticScriptedProvider(const char *class_name,
233 lldb::ValueObjectSP valobj) {
234 return StructuredData::ObjectSP();
235 }
236
237 virtual StructuredData::GenericSP
238 CreateScriptCommandObject(const char *class_name) {
239 return StructuredData::GenericSP();
240 }
241
242 virtual StructuredData::GenericSP
243 CreateFrameRecognizer(const char *class_name) {
244 return StructuredData::GenericSP();
245 }
246
247 virtual lldb::ValueObjectListSP GetRecognizedArguments(
248 const StructuredData::ObjectSP &implementor,
249 lldb::StackFrameSP frame_sp) {
250 return lldb::ValueObjectListSP();
251 }
252
253 virtual StructuredData::ObjectSP
254 CreateScriptedThreadPlan(const char *class_name,
255 const StructuredDataImpl &args_data,
256 std::string &error_str,
257 lldb::ThreadPlanSP thread_plan_sp) {
258 return StructuredData::ObjectSP();
259 }
260
261 virtual bool
262 ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp,
263 Event *event, bool &script_error) {
264 script_error = true;
265 return true;
266 }
267
268 virtual bool
269 ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp,
270 Event *event, bool &script_error) {
271 script_error = true;
272 return true;
273 }
274
275 virtual bool
276 ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp,
277 bool &script_error) {
278 script_error = true;
279 return true;
280 }
281
282 virtual lldb::StateType
283 ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp,
284 bool &script_error) {
285 script_error = true;
286 return lldb::eStateStepping;
287 }
288
289 virtual bool
290 ScriptedThreadPlanGetStopDescription(StructuredData::ObjectSP implementor_sp,
291 lldb_private::Stream *stream,
292 bool &script_error) {
293 script_error = true;
294 return false;
295 }
296
297 virtual StructuredData::GenericSP
298 CreateScriptedBreakpointResolver(const char *class_name,
299 const StructuredDataImpl &args_data,
300 lldb::BreakpointSP &bkpt_sp) {
301 return StructuredData::GenericSP();
302 }
303
304 virtual bool
305 ScriptedBreakpointResolverSearchCallback(StructuredData::GenericSP implementor_sp,
306 SymbolContext *sym_ctx)
307 {
308 return false;
309 }
310
311 virtual lldb::SearchDepth
312 ScriptedBreakpointResolverSearchDepth(StructuredData::GenericSP implementor_sp)
313 {
314 return lldb::eSearchDepthModule;
315 }
316
317 virtual StructuredData::GenericSP
318 CreateScriptedStopHook(lldb::TargetSP target_sp, const char *class_name,
319 const StructuredDataImpl &args_data, Status &error) {
320 error.SetErrorString("Creating scripted stop-hooks with the current "
321 "script interpreter is not supported.");
322 return StructuredData::GenericSP();
323 }
324
325 // This dispatches to the handle_stop method of the stop-hook class. It
326 // returns a "should_stop" bool.
327 virtual bool
328 ScriptedStopHookHandleStop(StructuredData::GenericSP implementor_sp,
329 ExecutionContext &exc_ctx,
330 lldb::StreamSP stream_sp) {
331 return true;
332 }
333
334 virtual StructuredData::ObjectSP
335 LoadPluginModule(const FileSpec &file_spec, lldb_private::Status &error) {
336 return StructuredData::ObjectSP();
337 }
338
339 virtual StructuredData::DictionarySP
340 GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target,
341 const char *setting_name, lldb_private::Status &error) {
342 return StructuredData::DictionarySP();
343 }
344
345 virtual Status GenerateFunction(const char *signature,
346 const StringList &input,
347 bool is_callback) {
348 Status error;
349 error.SetErrorString("unimplemented");
350 return error;
351 }
352
353 virtual void CollectDataForBreakpointCommandCallback(
354 std::vector<std::reference_wrapper<BreakpointOptions>> &options,
355 CommandReturnObject &result);
356
357 virtual void
358 CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options,
359 CommandReturnObject &result);
360
361 /// Set the specified text as the callback for the breakpoint.
362 Status SetBreakpointCommandCallback(
363 std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
364 const char *callback_text);
365
366 virtual Status SetBreakpointCommandCallback(BreakpointOptions &bp_options,
367 const char *callback_text,
368 bool is_callback) {
369 Status error;
370 error.SetErrorString("unimplemented");
371 return error;
372 }
373
374 /// This one is for deserialization:
375 virtual Status SetBreakpointCommandCallback(
376 BreakpointOptions &bp_options,
377 std::unique_ptr<BreakpointOptions::CommandData> &data_up) {
378 Status error;
379 error.SetErrorString("unimplemented");
380 return error;
381 }
382
383 Status SetBreakpointCommandCallbackFunction(
384 std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
385 const char *function_name, StructuredData::ObjectSP extra_args_sp);
386
387 /// Set a script function as the callback for the breakpoint.
388 virtual Status
389 SetBreakpointCommandCallbackFunction(BreakpointOptions &bp_options,
390 const char *function_name,
391 StructuredData::ObjectSP extra_args_sp) {
392 Status error;
393 error.SetErrorString("unimplemented");
394 return error;
395 }
396
397 /// Set a one-liner as the callback for the watchpoint.
398 virtual void SetWatchpointCommandCallback(WatchpointOptions *wp_options,
399 const char *user_input,
400 bool is_callback) {}
401
402 virtual bool GetScriptedSummary(const char *function_name,
403 lldb::ValueObjectSP valobj,
404 StructuredData::ObjectSP &callee_wrapper_sp,
405 const TypeSummaryOptions &options,
406 std::string &retval) {
407 return false;
408 }
409
410 // Calls the specified formatter matching Python function and returns its
411 // result (true if it's a match, false if we should keep looking for a
412 // matching formatter).
413 virtual bool FormatterCallbackFunction(const char *function_name,
414 lldb::TypeImplSP type_impl_sp) {
415 return true;
416 }
417
418 virtual void Clear() {
419 // Clean up any ref counts to SBObjects that might be in global variables
420 }
421
422 virtual size_t
423 CalculateNumChildren(const StructuredData::ObjectSP &implementor,
424 uint32_t max) {
425 return 0;
426 }
427
428 virtual lldb::ValueObjectSP
429 GetChildAtIndex(const StructuredData::ObjectSP &implementor, uint32_t idx) {
430 return lldb::ValueObjectSP();
431 }
432
433 virtual int
434 GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor,
435 const char *child_name) {
436 return UINT32_MAX;
437 }
438
439 virtual bool
440 UpdateSynthProviderInstance(const StructuredData::ObjectSP &implementor) {
441 return false;
442 }
443
444 virtual bool MightHaveChildrenSynthProviderInstance(
445 const StructuredData::ObjectSP &implementor) {
446 return true;
447 }
448
449 virtual lldb::ValueObjectSP
450 GetSyntheticValue(const StructuredData::ObjectSP &implementor) {
451 return nullptr;
452 }
453
454 virtual ConstString
455 GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) {
456 return ConstString();
457 }
458
459 virtual bool
460 RunScriptBasedCommand(const char *impl_function, llvm::StringRef args,
461 ScriptedCommandSynchronicity synchronicity,
462 lldb_private::CommandReturnObject &cmd_retobj,
463 Status &error,
464 const lldb_private::ExecutionContext &exe_ctx) {
465 return false;
466 }
467
468 virtual bool RunScriptBasedCommand(
469 StructuredData::GenericSP impl_obj_sp, llvm::StringRef args,
470 ScriptedCommandSynchronicity synchronicity,
471 lldb_private::CommandReturnObject &cmd_retobj, Status &error,
472 const lldb_private::ExecutionContext &exe_ctx) {
473 return false;
474 }
475
476 virtual bool RunScriptBasedParsedCommand(
477 StructuredData::GenericSP impl_obj_sp, Args& args,
478 ScriptedCommandSynchronicity synchronicity,
479 lldb_private::CommandReturnObject &cmd_retobj, Status &error,
480 const lldb_private::ExecutionContext &exe_ctx) {
481 return false;
482 }
483
484 virtual bool RunScriptFormatKeyword(const char *impl_function,
485 Process *process, std::string &output,
486 Status &error) {
487 error.SetErrorString("unimplemented");
488 return false;
489 }
490
491 virtual bool RunScriptFormatKeyword(const char *impl_function, Thread *thread,
492 std::string &output, Status &error) {
493 error.SetErrorString("unimplemented");
494 return false;
495 }
496
497 virtual bool RunScriptFormatKeyword(const char *impl_function, Target *target,
498 std::string &output, Status &error) {
499 error.SetErrorString("unimplemented");
500 return false;
501 }
502
503 virtual bool RunScriptFormatKeyword(const char *impl_function,
504 StackFrame *frame, std::string &output,
505 Status &error) {
506 error.SetErrorString("unimplemented");
507 return false;
508 }
509
510 virtual bool RunScriptFormatKeyword(const char *impl_function,
511 ValueObject *value, std::string &output,
512 Status &error) {
513 error.SetErrorString("unimplemented");
514 return false;
515 }
516
517 virtual bool GetDocumentationForItem(const char *item, std::string &dest) {
518 dest.clear();
519 return false;
520 }
521
522 virtual bool
523 GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,
524 std::string &dest) {
525 dest.clear();
526 return false;
527 }
528
529 virtual StructuredData::ObjectSP
530 GetOptionsForCommandObject(StructuredData::GenericSP cmd_obj_sp) {
531 return {};
532 }
533
534 virtual StructuredData::ObjectSP
535 GetArgumentsForCommandObject(StructuredData::GenericSP cmd_obj_sp) {
536 return {};
537 }
538
539 virtual bool SetOptionValueForCommandObject(
540 StructuredData::GenericSP cmd_obj_sp, ExecutionContext *exe_ctx,
541 llvm::StringRef long_option, llvm::StringRef value) {
542 return false;
543 }
544
545 virtual void OptionParsingStartedForCommandObject(
546 StructuredData::GenericSP cmd_obj_sp) {
547 return;
548 }
549
550 virtual uint32_t
551 GetFlagsForCommandObject(StructuredData::GenericSP cmd_obj_sp) {
552 return 0;
553 }
554
555 virtual bool GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,
556 std::string &dest) {
557 dest.clear();
558 return false;
559 }
560
561 virtual bool CheckObjectExists(const char *name) { return false; }
562
563 virtual bool
564 LoadScriptingModule(const char *filename, const LoadScriptOptions &options,
565 lldb_private::Status &error,
566 StructuredData::ObjectSP *module_sp = nullptr,
567 FileSpec extra_search_dir = {});
568
569 virtual bool IsReservedWord(const char *word) { return false; }
570
571 virtual std::unique_ptr<ScriptInterpreterLocker> AcquireInterpreterLock();
572
573 const char *GetScriptInterpreterPtyName();
574
575 virtual llvm::Expected<unsigned>
576 GetMaxPositionalArgumentsForCallable(const llvm::StringRef &callable_name) {
577 return llvm::createStringError(
578 EC: llvm::inconvertibleErrorCode(), Msg: "Unimplemented function");
579 }
580
581 static std::string LanguageToString(lldb::ScriptLanguage language);
582
583 static lldb::ScriptLanguage StringToLanguage(const llvm::StringRef &string);
584
585 lldb::ScriptLanguage GetLanguage() { return m_script_lang; }
586
587 virtual lldb::ScriptedProcessInterfaceUP CreateScriptedProcessInterface() {
588 return {};
589 }
590
591 virtual lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() {
592 return {};
593 }
594
595 virtual lldb::OperatingSystemInterfaceSP CreateOperatingSystemInterface() {
596 return {};
597 }
598
599 virtual lldb::ScriptedPlatformInterfaceUP GetScriptedPlatformInterface() {
600 return {};
601 }
602
603 virtual StructuredData::ObjectSP
604 CreateStructuredDataFromScriptObject(ScriptObject obj) {
605 return {};
606 }
607
608 lldb::DataExtractorSP
609 GetDataExtractorFromSBData(const lldb::SBData &data) const;
610
611 Status GetStatusFromSBError(const lldb::SBError &error) const;
612
613 lldb::BreakpointSP
614 GetOpaqueTypeFromSBBreakpoint(const lldb::SBBreakpoint &breakpoint) const;
615
616 lldb::ProcessAttachInfoSP
617 GetOpaqueTypeFromSBAttachInfo(const lldb::SBAttachInfo &attach_info) const;
618
619 lldb::ProcessLaunchInfoSP
620 GetOpaqueTypeFromSBLaunchInfo(const lldb::SBLaunchInfo &launch_info) const;
621
622 std::optional<MemoryRegionInfo> GetOpaqueTypeFromSBMemoryRegionInfo(
623 const lldb::SBMemoryRegionInfo &mem_region) const;
624
625protected:
626 Debugger &m_debugger;
627 lldb::ScriptLanguage m_script_lang;
628};
629
630} // namespace lldb_private
631
632#endif // LLDB_INTERPRETER_SCRIPTINTERPRETER_H
633

source code of lldb/include/lldb/Interpreter/ScriptInterpreter.h