1 //===-- BreakpointResolverScripted.cpp ---------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "lldb/Breakpoint/BreakpointResolverScripted.h"
12 #include "lldb/Breakpoint/BreakpointLocation.h"
13 #include "lldb/Core/Debugger.h"
14 #include "lldb/Core/Module.h"
15 #include "lldb/Core/Section.h"
16 #include "lldb/Core/StructuredDataImpl.h"
17 #include "lldb/Interpreter/CommandInterpreter.h"
18 #include "lldb/Interpreter/ScriptInterpreter.h"
19 #include "lldb/Target/Process.h"
20 #include "lldb/Target/Target.h"
21 #include "lldb/Utility/Log.h"
22 #include "lldb/Utility/StreamString.h"
25 using namespace lldb_private;
27 // BreakpointResolverScripted:
28 BreakpointResolverScripted::BreakpointResolverScripted(
30 const llvm::StringRef class_name,
31 lldb::SearchDepth depth,
32 StructuredDataImpl *args_data,
33 ScriptInterpreter &script_interp)
34 : BreakpointResolver(bkpt, BreakpointResolver::PythonResolver),
35 m_class_name(class_name), m_depth(depth), m_args_ptr(args_data) {
36 CreateImplementationIfNeeded();
39 void BreakpointResolverScripted::CreateImplementationIfNeeded() {
40 if (m_implementation_sp)
43 if (m_class_name.empty())
47 TargetSP target_sp = m_breakpoint->GetTargetSP();
48 ScriptInterpreter *script_interp = target_sp->GetDebugger()
49 .GetScriptInterpreter();
52 lldb::BreakpointSP bkpt_sp(m_breakpoint->shared_from_this());
53 m_implementation_sp = script_interp->CreateScriptedBreakpointResolver(
54 m_class_name.c_str(), m_args_ptr, bkpt_sp);
58 void BreakpointResolverScripted::NotifyBreakpointSet() {
59 CreateImplementationIfNeeded();
62 BreakpointResolverScripted::~BreakpointResolverScripted() {}
65 BreakpointResolverScripted::CreateFromStructuredData(
66 Breakpoint *bkpt, const StructuredData::Dictionary &options_dict,
68 llvm::StringRef class_name;
74 success = options_dict.GetValueForKeyAsString(
75 GetKey(OptionNames::PythonClassName), class_name);
77 error.SetErrorString("BRFL::CFSD: Couldn't find class name entry.");
80 lldb::SearchDepth depth;
82 success = options_dict.GetValueForKeyAsInteger(
83 GetKey(OptionNames::SearchDepth), depth_as_int);
85 error.SetErrorString("BRFL::CFSD: Couldn't find class name entry.");
88 if (depth_as_int >= (int) OptionNames::LastOptionName) {
89 error.SetErrorString("BRFL::CFSD: Invalid value for search depth.");
92 depth = (lldb::SearchDepth) depth_as_int;
94 StructuredDataImpl *args_data_impl = new StructuredDataImpl();
95 StructuredData::Dictionary *args_dict = new StructuredData::Dictionary();
96 success = options_dict.GetValueForKeyAsDictionary(
97 GetKey(OptionNames::ScriptArgs), args_dict);
99 // FIXME: The resolver needs a copy of the ARGS dict that it can own,
100 // so I need to make a copy constructor for the Dictionary so I can pass
101 // that to it here. For now the args are empty.
102 //StructuredData::Dictionary *dict_copy = new StructuredData::Dictionary(args_dict);
105 ScriptInterpreter *script_interp = bkpt->GetTarget()
107 .GetScriptInterpreter();
108 return new BreakpointResolverScripted(bkpt, class_name, depth, args_data_impl,
112 StructuredData::ObjectSP
113 BreakpointResolverScripted::SerializeToStructuredData() {
114 StructuredData::DictionarySP options_dict_sp(
115 new StructuredData::Dictionary());
117 options_dict_sp->AddStringItem(GetKey(OptionNames::PythonClassName),
119 return WrapOptionsDict(options_dict_sp);
122 ScriptInterpreter *BreakpointResolverScripted::GetScriptInterpreter() {
123 return m_breakpoint->GetTarget().GetDebugger().GetScriptInterpreter();
126 Searcher::CallbackReturn
127 BreakpointResolverScripted::SearchCallback(SearchFilter &filter,
128 SymbolContext &context, Address *addr,
130 assert(m_breakpoint != nullptr);
131 bool should_continue = true;
132 if (!m_implementation_sp)
133 return Searcher::eCallbackReturnStop;
135 ScriptInterpreter *interp = GetScriptInterpreter();
136 should_continue = interp->ScriptedBreakpointResolverSearchCallback(
140 return Searcher::eCallbackReturnContinue;
142 return Searcher::eCallbackReturnStop;
146 BreakpointResolverScripted::GetDepth() {
147 assert(m_breakpoint != nullptr);
148 lldb::SearchDepth depth = lldb::eSearchDepthModule;
149 if (m_implementation_sp) {
150 ScriptInterpreter *interp = GetScriptInterpreter();
151 depth = interp->ScriptedBreakpointResolverSearchDepth(
152 m_implementation_sp);
157 void BreakpointResolverScripted::GetDescription(Stream *s) {
158 StructuredData::GenericSP generic_sp;
159 std::string short_help;
161 if (m_implementation_sp) {
162 ScriptInterpreter *interp = GetScriptInterpreter();
163 interp->GetShortHelpForCommandObject(m_implementation_sp,
166 if (!short_help.empty())
167 s->PutCString(short_help.c_str());
169 s->Printf("python class = %s", m_class_name.c_str());
172 void BreakpointResolverScripted::Dump(Stream *s) const {}
174 lldb::BreakpointResolverSP
175 BreakpointResolverScripted::CopyForBreakpoint(Breakpoint &breakpoint) {
176 ScriptInterpreter *script_interp = GetScriptInterpreter();
177 // FIXME: Have to make a copy of the arguments from the m_args_ptr and then
178 // pass that to the new resolver.
179 lldb::BreakpointResolverSP ret_sp(
180 new BreakpointResolverScripted(&breakpoint, m_class_name,
181 m_depth, nullptr, *script_interp));