LLDB mainline
ScriptedCommandPythonInterface.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
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#include "../lldb-python.h"
10
12#include "lldb/Core/Debugger.h"
16#include "lldb/Utility/Args.h"
19
20#include "../SWIGPythonBridge.h"
23
24using namespace lldb;
25using namespace lldb_private;
26using namespace lldb_private::python;
28
32
33llvm::Expected<StructuredData::GenericSP>
35 llvm::StringRef class_name, lldb::DebuggerSP debugger_sp) {
36 if (class_name.empty())
37 return llvm::createStringError("empty class name");
38
39 if (!debugger_sp)
40 return llvm::createStringError("invalid Debugger pointer");
41
42 m_debugger_sp = debugger_sp;
43 ScriptedMetadata scripted_metadata(class_name,
46 scripted_metadata, /*script_obj=*/nullptr, debugger_sp);
47}
48
50 llvm::StringRef args, ScriptedCommandSynchronicity synchronicity,
51 CommandReturnObject &cmd_retobj, Status &error,
52 const ExecutionContext &exe_ctx) {
53 lldb::DebuggerSP debugger_sp = m_debugger_sp;
54 if (!debugger_sp) {
55 error = Status::FromErrorString("invalid Debugger pointer");
56 return false;
57 }
58 lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx));
59
60 // Outer Locker sets up the session (with conditional NoSTDIN for
61 // interactive commands and TearDownSession on exit) that Dispatch's inner
62 // Locker doesn't provide. Nesting is only safe because Dispatch's own
63 // Locker never requests InitSession itself.
64 Locker py_lock(&m_interpreter,
66 (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN),
69 debugger_sp, synchronicity);
70
71 std::string args_str = args.str();
72 Dispatch("__call__", error, debugger_sp, args_str.c_str(), exe_ctx_ref_sp,
73 &cmd_retobj);
74
75 if (!error.Success() || cmd_retobj.GetStatus() == eReturnStatusFailed)
76 return false;
77
78 return true;
79}
80
82 Args &args, ScriptedCommandSynchronicity synchronicity,
83 CommandReturnObject &cmd_retobj, Status &error,
84 const ExecutionContext &exe_ctx) {
85 lldb::DebuggerSP debugger_sp = m_debugger_sp;
86 if (!debugger_sp) {
87 error = Status::FromErrorString("invalid Debugger pointer");
88 return false;
89 }
90 lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx));
91
92 Locker py_lock(&m_interpreter,
94 (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN),
97 debugger_sp, synchronicity);
98
100 for (const Args::ArgEntry &entry : args)
101 args_arr_sp->AddStringItem(entry.ref());
102 StructuredDataImpl args_impl(args_arr_sp);
103
104 Dispatch("__call__", error, debugger_sp, args_impl, exe_ctx_ref_sp,
105 &cmd_retobj);
106
107 if (!error.Success() || cmd_retobj.GetStatus() == eReturnStatusFailed)
108 return false;
109
110 return true;
111}
112
113std::optional<std::string>
115 std::string command;
116 args.GetQuotedCommandString(command);
119 Dispatch("get_repeat_command", error, command.c_str());
120 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
121 error))
122 return {};
123 return obj->GetStringValue().str();
124}
125
128 std::vector<std::string> &args, size_t args_pos, size_t char_in_arg) {
130 StructuredData::ObjectSP obj = Dispatch("handle_argument_completion", error,
131 args, args_pos, char_in_arg);
132 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
133 error))
134 return {};
136 if (dict_sp->GetType() == lldb::eStructuredDataTypeInvalid)
137 return {};
138 return dict_sp;
139}
140
143 llvm::StringRef &long_option, size_t char_in_arg) {
145 std::string long_option_str = long_option.str();
147 Dispatch("handle_option_argument_completion", error,
148 long_option_str.c_str(), char_in_arg);
149 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
150 error))
151 return {};
152
153 // A boolean return means: True means completion handled but no
154 // completions; False means completion not handled (fall back to default).
155 if (obj->GetType() == lldb::eStructuredDataTypeBoolean) {
156 if (!obj->GetBooleanValue())
157 return {};
159 dict_sp->AddBooleanItem("no-completion", true);
160 return dict_sp;
161 }
162
164 if (dict_sp->GetType() == lldb::eStructuredDataTypeInvalid)
165 return {};
166 return dict_sp;
167}
168
170 dest.clear();
172 StructuredData::ObjectSP obj = Dispatch("get_short_help", error);
173 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
174 error))
175 return false;
176 dest = obj->GetStringValue().str();
177 return !dest.empty();
178}
179
181 dest.clear();
183 StructuredData::ObjectSP obj = Dispatch("get_long_help", error);
184 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
185 error))
186 return false;
187 dest = obj->GetStringValue().str();
188 return !dest.empty();
189}
190
193 StructuredData::ObjectSP obj = Dispatch("get_flags", error);
194 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
195 error))
196 return 0;
197 return static_cast<uint32_t>(obj->GetUnsignedIntegerValue());
198}
199
203 return Dispatch("get_options_definition", error);
204}
205
209 return Dispatch("get_args_definition", error);
210}
211
214 Dispatch("option_parsing_started", error);
215}
216
218 llvm::StringRef long_option,
219 llvm::StringRef value) {
220 lldb::ExecutionContextRefSP exe_ctx_ref_sp;
221 if (exe_ctx)
222 exe_ctx_ref_sp = std::make_shared<ExecutionContextRef>(exe_ctx);
224 std::string long_option_str = long_option.str();
225 std::string value_str = value.str();
227 Dispatch("set_option_value", error, exe_ctx_ref_sp,
228 long_option_str.c_str(), value_str.c_str());
229 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
230 error))
231 return false;
232 return obj->GetBooleanValue();
233}
234
236 const std::vector<llvm::StringRef> ci_usages = {
237 "command script add -c <ClassName> <cmd>",
238 "command script add -p <ClassName> <cmd>"};
239 const std::vector<llvm::StringRef> api_usages = {};
242 "Implement a raw or parsed custom command backed by a Python class.",
244 ScriptedInterfaceUsages(ci_usages, api_usages));
245}
246
static llvm::raw_ostream & error(Stream &strm)
ScriptInterpreterPythonImpl::Locker Locker
A command line argument class.
Definition Args.h:33
bool GetQuotedCommandString(std::string &command) const
Definition Args.cpp:232
Execution context objects refer to objects in the execution of the program that is being debugged.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
std::optional< std::string > GetRepeatCommand(Args &args) override
llvm::Expected< StructuredData::GenericSP > CreatePluginObject(llvm::StringRef class_name, lldb::DebuggerSP debugger_sp) override
bool RunParsedCommand(Args &args, ScriptedCommandSynchronicity synchronicity, CommandReturnObject &cmd_retobj, Status &error, const ExecutionContext &exe_ctx) override
StructuredData::DictionarySP HandleArgumentCompletion(std::vector< std::string > &args, size_t args_pos, size_t char_in_arg) override
ScriptedCommandPythonInterface(ScriptInterpreterPythonImpl &interpreter)
bool RunRawCommand(llvm::StringRef args, ScriptedCommandSynchronicity synchronicity, CommandReturnObject &cmd_retobj, Status &error, const ExecutionContext &exe_ctx) override
bool SetOptionValue(ExecutionContext *exe_ctx, llvm::StringRef long_option, llvm::StringRef value) override
StructuredData::DictionarySP HandleOptionArgumentCompletion(llvm::StringRef &long_option, size_t char_in_arg) override
static bool CheckStructuredDataObject(llvm::StringRef caller, T obj, Status &error)
static bool CreateInstance(lldb::ScriptLanguage language, ScriptedInterfaceUsages usages)
ScriptInterpreterPythonImpl & m_interpreter
ScriptedPythonInterface(ScriptInterpreterPythonImpl &interpreter)
T Dispatch(llvm::StringRef method_name, Status &error, Args &&...args)
llvm::Expected< StructuredData::GenericSP > CreatePluginObject(const ScriptedMetadata &scripted_metadata, StructuredData::Generic *script_obj, Args... args)
An error handling class.
Definition Status.h:118
static Status FromErrorString(const char *str)
Definition Status.h:141
std::shared_ptr< Dictionary > DictionarySP
std::shared_ptr< Object > ObjectSP
std::shared_ptr< Array > ArraySP
A class that represents a running process on the host machine.
@ eScriptLanguagePython
@ eScriptedExtensionScriptedCommand
std::shared_ptr< lldb_private::Debugger > DebuggerSP
@ eReturnStatusFailed
@ eStructuredDataTypeInvalid
@ eStructuredDataTypeBoolean
std::shared_ptr< lldb_private::ExecutionContextRef > ExecutionContextRefSP