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