LLDB mainline
BreakpointResolverScripted.cpp
Go to the documentation of this file.
1//===-- BreakpointResolverScripted.cpp ------------------------------------===//
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
10
11
13#include "lldb/Core/Debugger.h"
14#include "lldb/Core/Module.h"
15#include "lldb/Core/Section.h"
19#include "lldb/Target/Process.h"
20#include "lldb/Target/Target.h"
21#include "lldb/Utility/Log.h"
23#include "llvm/Support/FormatVariadic.h"
24
25using namespace lldb;
26using namespace lldb_private;
27
28// BreakpointResolverScripted:
30 const BreakpointSP &bkpt, const llvm::StringRef class_name,
31 lldb::SearchDepth depth, const StructuredDataImpl &args_data)
33 m_class_name(std::string(class_name)), m_depth(depth), m_args(args_data) {
34 if (bkpt)
36}
37
39 BreakpointSP breakpoint_sp) {
40 // This version has to be called with a valid breakpoint_sp
41 // But the interface might have been made before we sent the breakpoint to
42 // the interface. If so, do that here:
43 assert(breakpoint_sp);
44 if (m_interface_sp) {
45 if (!m_breakpoint_sent) {
46 m_interface_sp->SetBreakpoint(breakpoint_sp);
47 m_breakpoint_sent = true;
48 }
49 return;
50 }
51
52 if (m_class_name.empty())
53 return;
54
55 if (!breakpoint_sp)
56 return;
57
58 TargetSP target_sp = breakpoint_sp->GetTargetSP();
59 if (target_sp)
60 CreateImplementationIfNeeded(*target_sp.get(), breakpoint_sp);
61}
62
64 Target &target, BreakpointSP breakpoint_sp) {
65 if (m_interface_sp) {
66 if (!m_breakpoint_sent && breakpoint_sp) {
67 m_interface_sp->SetBreakpoint(breakpoint_sp);
68 m_breakpoint_sent = true;
69 }
70 return;
71 }
72
73 ScriptInterpreter *script_interp =
75 if (!script_interp)
76 return;
77
78 if (!m_interface_sp)
80
81 if (!m_interface_sp) {
83 "BreakpointResolverScripted::%s () - ERROR: %s", __FUNCTION__,
84 "Script interpreter couldn't create Scripted Breakpoint Interface");
85 return;
86 }
87
88 StructuredData::ObjectSP args_obj = m_args.GetObjectSP();
90 if (args_obj && args_obj->GetType() == lldb::eStructuredDataTypeDictionary)
91 args_dict_sp =
92 std::static_pointer_cast<StructuredData::Dictionary>(args_obj);
93 ScriptedMetadata scripted_metadata(m_class_name, args_dict_sp);
94 auto obj_or_err =
95 m_interface_sp->CreatePluginObject(scripted_metadata, breakpoint_sp);
96 if (!obj_or_err) {
97 m_interface_sp.reset();
98 std::string msg = llvm::toString(obj_or_err.takeError());
100 llvm::formatv("failed to create BreakpointResolverScripted: {0}", msg)
101 .str(),
102 target.GetDebugger().GetID());
103 m_error = Status(msg);
104 return;
105 }
106 StructuredData::ObjectSP object_sp = *obj_or_err;
107 if (!object_sp || !object_sp->IsValid()) {
109 "ScriptedBreakpoint::%s () - ERROR: %s", __FUNCTION__,
110 "Failed to create valid script object");
111 }
112 if (breakpoint_sp)
113 m_breakpoint_sent = true;
114}
115
117 Target &target, BreakpointResolverSP original_sp) {
118 // At this point neither resolver has been assigned a breakpoint, so pass
119 // in an empty one.
121 if (!m_interface_sp)
122 return false;
123
124 StructuredData::ObjectSP serialized_sp =
125 original_sp->SerializeToStructuredData();
126 StructuredDataImpl impl(serialized_sp);
127 return m_interface_sp->OverridesResolver(target, impl);
128}
129
133
135 const StructuredData::Dictionary &options_dict, Status &error) {
136 llvm::StringRef class_name;
137 bool success;
138
139 success = options_dict.GetValueForKeyAsString(
141 if (!success) {
142 error =
143 Status::FromErrorString("BRFL::CFSD: Couldn't find class name entry.");
144 return nullptr;
145 }
146 // The Python function will actually provide the search depth, this is a
147 // placeholder.
149
150 StructuredDataImpl args_data_impl;
151 StructuredData::Dictionary *args_dict = nullptr;
153 args_dict))
154 args_data_impl.SetObjectSP(args_dict->shared_from_this());
155 return std::make_shared<BreakpointResolverScripted>(nullptr, class_name,
156 depth, args_data_impl);
157}
158
161 StructuredData::DictionarySP options_dict_sp(
163
164 options_dict_sp->AddStringItem(GetKey(OptionNames::PythonClassName),
166 if (m_args.IsValid())
167 options_dict_sp->AddItem(GetKey(OptionNames::ScriptArgs),
168 m_args.GetObjectSP());
169
170 return WrapOptionsDict(options_dict_sp);
171}
172
174 return GetBreakpoint()->GetTarget().GetDebugger().GetScriptInterpreter();
175}
176
178 SearchFilter &filter, SymbolContext &context, Address *addr) {
179 bool should_continue = true;
180 if (!m_interface_sp)
182
183 should_continue = m_interface_sp->ResolverCallback(context);
184 if (should_continue)
186
188}
189
193 if (m_interface_sp)
194 depth = m_interface_sp->GetDepth();
195
196 return depth;
197}
198
200 StructuredData::GenericSP generic_sp;
201 std::optional<std::string> short_help;
202
204
205 if (m_interface_sp) {
206 short_help = m_interface_sp->GetShortHelp();
207 }
208 if (short_help && !short_help->empty())
209 s->PutCString(short_help->c_str());
210 else
211 s->Printf("python class = %s", m_class_name.c_str());
212}
213
217 if (m_interface_sp)
218 return m_interface_sp->GetLocationDescription(bp_loc_sp, level);
219 return {};
220}
221
224 lldb::BreakpointLocationSP bp_loc_sp) {
225 if (m_interface_sp)
226 return m_interface_sp->WasHit(frame_sp, bp_loc_sp);
227 return {};
228}
229
231
234 return std::make_shared<BreakpointResolverScripted>(breakpoint, m_class_name,
235 m_depth, m_args);
236}
static llvm::raw_ostream & error(Stream &strm)
A section + offset based address class.
Definition Address.h:62
BreakpointResolverScripted(const lldb::BreakpointSP &bkpt, const llvm::StringRef class_name, lldb::SearchDepth depth, const StructuredDataImpl &args_data)
lldb::BreakpointResolverSP CopyForBreakpoint(lldb::BreakpointSP &breakpoint) override
std::optional< std::string > GetLocationDescription(lldb::BreakpointLocationSP bp_loc_sp, lldb::DescriptionLevel level)
void GetDescription(Stream *s) override
Prints a canonical description for the breakpoint to the stream s.
StructuredData::ObjectSP SerializeToStructuredData() override
void Dump(Stream *s) const override
Standard "Dump" method. At present it does nothing.
Searcher::CallbackReturn SearchCallback(SearchFilter &filter, SymbolContext &context, Address *addr) override
void CreateImplementationIfNeeded(lldb::BreakpointSP bkpt)
lldb::BreakpointLocationSP WasHit(lldb::StackFrameSP frame_sp, lldb::BreakpointLocationSP bp_loc_sp)
lldb::ScriptedBreakpointInterfaceSP m_interface_sp
bool OverridesResolver(Target &target, lldb::BreakpointResolverSP original_sp) override
The resolver_sp won't have had its breakpoint set by the time we are checking the Override,...
static lldb::BreakpointResolverSP CreateFromStructuredData(const StructuredData::Dictionary &options_dict, Status &error)
static const char * GetKey(OptionNames enum_value)
StructuredData::DictionarySP WrapOptionsDict(StructuredData::DictionarySP options_dict_sp)
lldb::BreakpointSP GetBreakpoint() const
This gets the breakpoint for this resolver.
BreakpointResolver(const lldb::BreakpointSP &bkpt, unsigned char resolverType, lldb::addr_t offset=0, bool offset_is_insn_count=false)
The breakpoint resolver need to have a breakpoint for "ResolveBreakpoint to make sense.
static void ReportError(std::string message, std::optional< lldb::user_id_t > debugger_id=std::nullopt, std::once_flag *once=nullptr)
Report error events.
ScriptInterpreter * GetScriptInterpreter(bool can_create=true, std::optional< lldb::ScriptLanguage > language={})
virtual lldb::ScriptedBreakpointInterfaceSP CreateScriptedBreakpointInterface()
General Outline: Provides the callback and search depth for the SearchFilter search.
An error handling class.
Definition Status.h:118
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition Status.cpp:106
static Status FromErrorString(const char *str)
Definition Status.h:141
A stream class that can stream formatted output to a file.
Definition Stream.h:28
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition Stream.cpp:63
void SetObjectSP(const StructuredData::ObjectSP &obj)
bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result) const
bool GetValueForKeyAsDictionary(llvm::StringRef key, Dictionary *&result) const
std::shared_ptr< Generic > GenericSP
std::shared_ptr< Dictionary > DictionarySP
std::shared_ptr< Object > ObjectSP
Defines a symbol context baton that can be handed other debug core functions.
Debugger & GetDebugger() const
Definition Target.h:1330
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
std::shared_ptr< lldb_private::BreakpointResolver > BreakpointResolverSP
std::shared_ptr< lldb_private::BreakpointLocation > BreakpointLocationSP
DescriptionLevel
Description levels for "void GetDescription(Stream *, DescriptionLevel)" calls.
std::shared_ptr< lldb_private::Breakpoint > BreakpointSP
std::shared_ptr< lldb_private::Target > TargetSP
@ eStructuredDataTypeDictionary
lldb::user_id_t GetID() const
Get accessor for the user ID.
Definition UserID.h:47