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 llvm::Expected<StructuredData::ObjectSP> obj_or_err = Dispatch(
73 "__call__", debugger_sp, args_str.c_str(), exe_ctx_ref_sp, &cmd_retobj);
74 if (!obj_or_err) {
75 error = Status::FromError(obj_or_err.takeError());
76 return false;
77 }
78
79 return cmd_retobj.GetStatus() != eReturnStatusFailed;
80}
81
83 Args &args, ScriptedCommandSynchronicity synchronicity,
84 CommandReturnObject &cmd_retobj, Status &error,
85 const ExecutionContext &exe_ctx) {
86 lldb::DebuggerSP debugger_sp = m_debugger_sp;
87 if (!debugger_sp) {
88 error = Status::FromErrorString("invalid Debugger pointer");
89 return false;
90 }
91 lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx));
92
93 Locker py_lock(&m_interpreter,
95 (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN),
98 debugger_sp, synchronicity);
99
101 for (const Args::ArgEntry &entry : args)
102 args_arr_sp->AddStringItem(entry.ref());
103 StructuredDataImpl args_impl(args_arr_sp);
104
105 llvm::Expected<StructuredData::ObjectSP> obj_or_err =
106 Dispatch("__call__", debugger_sp, args_impl, exe_ctx_ref_sp, &cmd_retobj);
107 if (!obj_or_err) {
108 error = Status::FromError(obj_or_err.takeError());
109 return false;
110 }
111
112 return cmd_retobj.GetStatus() != eReturnStatusFailed;
113}
114
115std::optional<std::string>
117 std::string command;
118 args.GetQuotedCommandString(command);
120 Dispatch("get_repeat_command", command.c_str()), LLVM_PRETTY_FUNCTION);
121 if (!obj)
122 return {};
123
124 return obj->GetStringValue().str();
125}
126
129 std::vector<std::string> &args, size_t args_pos, size_t char_in_arg) {
131 Dispatch("handle_argument_completion", args, args_pos, char_in_arg),
132 LLVM_PRETTY_FUNCTION);
133 if (!obj)
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) {
144 std::string long_option_str = long_option.str();
146 LogAndDefault(Dispatch("handle_option_argument_completion",
147 long_option_str.c_str(), char_in_arg),
148 LLVM_PRETTY_FUNCTION);
149 if (!obj)
150 return {};
151
152 // A boolean return means: True means completion handled but no
153 // completions; False means completion not handled (fall back to default).
154 if (obj->GetType() == lldb::eStructuredDataTypeBoolean) {
155 if (!obj->GetBooleanValue())
156 return {};
158 dict_sp->AddBooleanItem("no-completion", true);
159 return dict_sp;
160 }
161
163 if (dict_sp->GetType() == lldb::eStructuredDataTypeInvalid)
164 return {};
165 return dict_sp;
166}
167
169 dest.clear();
171 LogAndDefault(Dispatch("get_short_help"), LLVM_PRETTY_FUNCTION);
172 if (!obj)
173 return false;
174 dest = obj->GetStringValue().str();
175 return !dest.empty();
176}
177
179 dest.clear();
181 LogAndDefault(Dispatch("get_long_help"), LLVM_PRETTY_FUNCTION);
182 if (!obj)
183 return false;
184 dest = obj->GetStringValue().str();
185 return !dest.empty();
186}
187
190 LogAndDefault(Dispatch("get_flags"), LLVM_PRETTY_FUNCTION);
191 if (!obj)
192 return 0;
193
194 return static_cast<uint32_t>(obj->GetUnsignedIntegerValue());
195}
196
199 return LogAndDefault(Dispatch("get_options_definition"),
200 LLVM_PRETTY_FUNCTION);
201}
202
205 return LogAndDefault(Dispatch("get_args_definition"), LLVM_PRETTY_FUNCTION);
206}
207
209 LogAndDefault(Dispatch("option_parsing_started"), LLVM_PRETTY_FUNCTION);
210}
211
213 llvm::StringRef long_option,
214 llvm::StringRef value) {
215 lldb::ExecutionContextRefSP exe_ctx_ref_sp;
216 if (exe_ctx)
217 exe_ctx_ref_sp = std::make_shared<ExecutionContextRef>(exe_ctx);
218 std::string long_option_str = long_option.str();
219 std::string value_str = value.str();
221 LogAndDefault(Dispatch("set_option_value", exe_ctx_ref_sp,
222 long_option_str.c_str(), value_str.c_str()),
223 LLVM_PRETTY_FUNCTION);
224 if (!obj)
225 return false;
226 return obj->GetBooleanValue();
227}
228
230 const std::vector<llvm::StringRef> ci_usages = {
231 "command script add -c <ClassName> <cmd>",
232 "command script add -p <ClassName> <cmd>"};
233 const std::vector<llvm::StringRef> api_usages = {};
236 "Implement a raw or parsed custom command backed by a Python class.",
238 ScriptedInterfaceUsages(ci_usages, api_usages));
239}
240
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 CreateInstance(lldb::ScriptLanguage language, ScriptedInterfaceUsages usages)
ScriptInterpreterPythonImpl & m_interpreter
static T LogAndDefault(llvm::Expected< T > value_or_err, llvm::StringRef caller)
Log the failure in value_or_err and fall back to a default-constructed T.
ScriptedPythonInterface(ScriptInterpreterPythonImpl &interpreter)
llvm::Expected< T > Dispatch(llvm::StringRef method_name, Args &&...args)
Call method_name on the scripted object.
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
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
Definition Status.cpp:136
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