blob: 330cee8711dc31b76c17dbe4b142d71442829974 [file] [log] [blame]
Jim Inghame19adf52018-09-13 21:59:16 +00001//===-- BreakpointResolverScripted.cpp ---------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Jim Inghame19adf52018-09-13 21:59:16 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "lldb/Breakpoint/BreakpointResolverScripted.h"
10
Jim Inghame19adf52018-09-13 21:59:16 +000011
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"
23
24using namespace lldb;
25using namespace lldb_private;
26
27//----------------------------------------------------------------------
28// BreakpointResolverScripted:
29//----------------------------------------------------------------------
30BreakpointResolverScripted::BreakpointResolverScripted(
31 Breakpoint *bkpt,
32 const llvm::StringRef class_name,
33 lldb::SearchDepth depth,
34 StructuredDataImpl *args_data,
35 ScriptInterpreter &script_interp)
36 : BreakpointResolver(bkpt, BreakpointResolver::PythonResolver),
37 m_class_name(class_name), m_depth(depth), m_args_ptr(args_data) {
38 CreateImplementationIfNeeded();
39}
40
41void BreakpointResolverScripted::CreateImplementationIfNeeded() {
42 if (m_implementation_sp)
43 return;
44
45 if (m_class_name.empty())
46 return;
47
48 if (m_breakpoint) {
49 TargetSP target_sp = m_breakpoint->GetTargetSP();
50 ScriptInterpreter *script_interp = target_sp->GetDebugger()
51 .GetCommandInterpreter()
52 .GetScriptInterpreter();
53 if (!script_interp)
54 return;
55 lldb::BreakpointSP bkpt_sp(m_breakpoint->shared_from_this());
56 m_implementation_sp = script_interp->CreateScriptedBreakpointResolver(
57 m_class_name.c_str(), m_args_ptr, bkpt_sp);
58 }
59}
60
61void BreakpointResolverScripted::NotifyBreakpointSet() {
62 CreateImplementationIfNeeded();
63}
64
65BreakpointResolverScripted::~BreakpointResolverScripted() {}
66
67BreakpointResolver *
68BreakpointResolverScripted::CreateFromStructuredData(
69 Breakpoint *bkpt, const StructuredData::Dictionary &options_dict,
70 Status &error) {
71 llvm::StringRef class_name;
72 bool success;
73
74 if (!bkpt)
75 return nullptr;
76
77 success = options_dict.GetValueForKeyAsString(
78 GetKey(OptionNames::PythonClassName), class_name);
79 if (!success) {
80 error.SetErrorString("BRFL::CFSD: Couldn't find class name entry.");
81 return nullptr;
82 }
83 lldb::SearchDepth depth;
84 int depth_as_int;
85 success = options_dict.GetValueForKeyAsInteger(
86 GetKey(OptionNames::SearchDepth), depth_as_int);
87 if (!success) {
88 error.SetErrorString("BRFL::CFSD: Couldn't find class name entry.");
89 return nullptr;
90 }
91 if (depth_as_int >= (int) OptionNames::LastOptionName) {
92 error.SetErrorString("BRFL::CFSD: Invalid value for search depth.");
93 return nullptr;
94 }
95 depth = (lldb::SearchDepth) depth_as_int;
96
97 StructuredDataImpl *args_data_impl = new StructuredDataImpl();
98 StructuredData::Dictionary *args_dict = new StructuredData::Dictionary();
99 success = options_dict.GetValueForKeyAsDictionary(
100 GetKey(OptionNames::ScriptArgs), args_dict);
101 if (success) {
102 // FIXME: The resolver needs a copy of the ARGS dict that it can own,
103 // so I need to make a copy constructor for the Dictionary so I can pass
104 // that to it here. For now the args are empty.
105 //StructuredData::Dictionary *dict_copy = new StructuredData::Dictionary(args_dict);
106
107 }
108 ScriptInterpreter *script_interp = bkpt->GetTarget()
109 .GetDebugger()
110 .GetCommandInterpreter()
111 .GetScriptInterpreter();
112 return new BreakpointResolverScripted(bkpt, class_name, depth, args_data_impl,
113 *script_interp);
114}
115
116StructuredData::ObjectSP
117BreakpointResolverScripted::SerializeToStructuredData() {
118 StructuredData::DictionarySP options_dict_sp(
119 new StructuredData::Dictionary());
120
121 options_dict_sp->AddStringItem(GetKey(OptionNames::PythonClassName),
122 m_class_name);
123 return WrapOptionsDict(options_dict_sp);
124}
125
126ScriptInterpreter *BreakpointResolverScripted::GetScriptInterpreter() {
127 return m_breakpoint->GetTarget().GetDebugger().GetCommandInterpreter()
128 .GetScriptInterpreter();
129}
130
131Searcher::CallbackReturn
132BreakpointResolverScripted::SearchCallback(SearchFilter &filter,
133 SymbolContext &context, Address *addr,
134 bool containing) {
135 assert(m_breakpoint != NULL);
136 bool should_continue = true;
137 if (!m_implementation_sp)
138 return Searcher::eCallbackReturnStop;
139
140 ScriptInterpreter *interp = GetScriptInterpreter();
141 should_continue = interp->ScriptedBreakpointResolverSearchCallback(
142 m_implementation_sp,
143 &context);
144 if (should_continue)
145 return Searcher::eCallbackReturnContinue;
146 else
147 return Searcher::eCallbackReturnStop;
148}
149
150lldb::SearchDepth
151BreakpointResolverScripted::GetDepth() {
152 assert(m_breakpoint != NULL);
153 lldb::SearchDepth depth = lldb::eSearchDepthModule;
154 if (m_implementation_sp) {
155 ScriptInterpreter *interp = GetScriptInterpreter();
156 depth = interp->ScriptedBreakpointResolverSearchDepth(
157 m_implementation_sp);
158 }
159 return depth;
160}
161
162void BreakpointResolverScripted::GetDescription(Stream *s) {
163 StructuredData::GenericSP generic_sp;
164 std::string short_help;
165
166 if (m_implementation_sp) {
167 ScriptInterpreter *interp = GetScriptInterpreter();
168 interp->GetShortHelpForCommandObject(m_implementation_sp,
169 short_help);
170 }
171 if (!short_help.empty())
172 s->PutCString(short_help.c_str());
173 else
174 s->Printf("python class = %s", m_class_name.c_str());
175}
176
177void BreakpointResolverScripted::Dump(Stream *s) const {}
178
179lldb::BreakpointResolverSP
180BreakpointResolverScripted::CopyForBreakpoint(Breakpoint &breakpoint) {
181 ScriptInterpreter *script_interp = GetScriptInterpreter();
182 // FIXME: Have to make a copy of the arguments from the m_args_ptr and then
183 // pass that to the new resolver.
184 lldb::BreakpointResolverSP ret_sp(
185 new BreakpointResolverScripted(&breakpoint, m_class_name,
186 m_depth, nullptr, *script_interp));
187 return ret_sp;
188}