blob: 7f386162d163d9c00bdbc1b0a6086a344745c53f [file] [log] [blame]
Eugene Zelenko8f30a652015-10-23 18:39:37 +00001//===-- LanguageRuntime.cpp -------------------------------------*- C++ -*-===//
Jim Ingham22777012010-09-23 02:01:19 +00002//
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
Eugene Zelenko8f30a652015-10-23 18:39:37 +000010// C Includes
11// C++ Includes
12// Other libraries and framework includes
13// Project includes
Jim Ingham22777012010-09-23 02:01:19 +000014#include "lldb/Target/LanguageRuntime.h"
Jim Ingham0fcdac32015-11-06 22:48:59 +000015#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
16#include "Plugins/Language/ObjC/ObjCLanguage.h"
Jim Inghama72b31c2015-04-22 19:42:18 +000017#include "lldb/Target/ObjCLanguageRuntime.h"
Jim Ingham219ba192012-03-05 04:47:34 +000018#include "lldb/Target/Target.h"
Jim Ingham22777012010-09-23 02:01:19 +000019#include "lldb/Core/PluginManager.h"
Jim Ingham33df7cd2014-12-06 01:28:03 +000020#include "lldb/Core/SearchFilter.h"
Colin Rileyc9c55a22015-05-04 18:39:38 +000021#include "lldb/Interpreter/CommandInterpreter.h"
Jim Ingham22777012010-09-23 02:01:19 +000022
23using namespace lldb;
24using namespace lldb_private;
25
Greg Claytonbff78252013-03-11 18:42:51 +000026class ExceptionSearchFilter : public SearchFilter
27{
28public:
29 ExceptionSearchFilter (const lldb::TargetSP &target_sp,
Jim Ingham33df7cd2014-12-06 01:28:03 +000030 lldb::LanguageType language,
31 bool update_module_list = true) :
Greg Claytonbff78252013-03-11 18:42:51 +000032 SearchFilter (target_sp),
33 m_language (language),
34 m_language_runtime (NULL),
35 m_filter_sp ()
36 {
Jim Ingham33df7cd2014-12-06 01:28:03 +000037 if (update_module_list)
38 UpdateModuleListIfNeeded ();
Greg Claytonbff78252013-03-11 18:42:51 +000039 }
Jim Ingham33df7cd2014-12-06 01:28:03 +000040
Eugene Zelenko8f30a652015-10-23 18:39:37 +000041 ~ExceptionSearchFilter() override = default;
Jim Ingham33df7cd2014-12-06 01:28:03 +000042
Eric Christopher2325e382014-12-10 22:29:58 +000043 bool
44 ModulePasses (const lldb::ModuleSP &module_sp) override
Greg Claytonbff78252013-03-11 18:42:51 +000045 {
46 UpdateModuleListIfNeeded ();
47 if (m_filter_sp)
48 return m_filter_sp->ModulePasses (module_sp);
49 return false;
50 }
51
Eric Christopher2325e382014-12-10 22:29:58 +000052 bool
53 ModulePasses (const FileSpec &spec) override
Greg Claytonbff78252013-03-11 18:42:51 +000054 {
55 UpdateModuleListIfNeeded ();
56 if (m_filter_sp)
57 return m_filter_sp->ModulePasses (spec);
58 return false;
Greg Claytonbff78252013-03-11 18:42:51 +000059 }
60
Eric Christopher2325e382014-12-10 22:29:58 +000061 void
62 Search (Searcher &searcher) override
Greg Claytonbff78252013-03-11 18:42:51 +000063 {
64 UpdateModuleListIfNeeded ();
65 if (m_filter_sp)
66 m_filter_sp->Search (searcher);
67 }
68
Eric Christopher2325e382014-12-10 22:29:58 +000069 void
70 GetDescription (Stream *s) override
Greg Claytonbff78252013-03-11 18:42:51 +000071 {
72 UpdateModuleListIfNeeded ();
73 if (m_filter_sp)
74 m_filter_sp->GetDescription (s);
75 }
76
77protected:
78 LanguageType m_language;
79 LanguageRuntime *m_language_runtime;
80 SearchFilterSP m_filter_sp;
81
Jim Ingham33df7cd2014-12-06 01:28:03 +000082 SearchFilterSP
83 DoCopyForBreakpoint(Breakpoint &breakpoint) override
84 {
85 return SearchFilterSP(new ExceptionSearchFilter(TargetSP(), m_language, false));
86 }
87
Greg Claytonbff78252013-03-11 18:42:51 +000088 void
89 UpdateModuleListIfNeeded ()
90 {
91 ProcessSP process_sp (m_target_sp->GetProcessSP());
92 if (process_sp)
93 {
94 bool refreash_filter = !m_filter_sp;
95 if (m_language_runtime == NULL)
96 {
97 m_language_runtime = process_sp->GetLanguageRuntime(m_language);
98 refreash_filter = true;
99 }
100 else
101 {
102 LanguageRuntime *language_runtime = process_sp->GetLanguageRuntime(m_language);
103 if (m_language_runtime != language_runtime)
104 {
105 m_language_runtime = language_runtime;
106 refreash_filter = true;
107 }
108 }
109
110 if (refreash_filter && m_language_runtime)
111 {
112 m_filter_sp = m_language_runtime->CreateExceptionSearchFilter ();
113 }
114 }
115 else
116 {
117 m_filter_sp.reset();
118 m_language_runtime = NULL;
119 }
120 }
121};
122
123// The Target is the one that knows how to create breakpoints, so this function
124// is meant to be used either by the target or internally in Set/ClearExceptionBreakpoints.
125class ExceptionBreakpointResolver : public BreakpointResolver
126{
127public:
128 ExceptionBreakpointResolver (lldb::LanguageType language,
129 bool catch_bp,
130 bool throw_bp) :
131 BreakpointResolver (NULL, BreakpointResolver::ExceptionResolver),
132 m_language (language),
133 m_language_runtime (NULL),
134 m_catch_bp (catch_bp),
135 m_throw_bp (throw_bp)
136 {
137 }
138
Eugene Zelenko8f30a652015-10-23 18:39:37 +0000139 ~ExceptionBreakpointResolver() override = default;
140
Eric Christopher2325e382014-12-10 22:29:58 +0000141 Searcher::CallbackReturn
Greg Claytonbff78252013-03-11 18:42:51 +0000142 SearchCallback (SearchFilter &filter,
143 SymbolContext &context,
144 Address *addr,
Eric Christopher2325e382014-12-10 22:29:58 +0000145 bool containing) override
Greg Claytonbff78252013-03-11 18:42:51 +0000146 {
147
148 if (SetActualResolver())
149 return m_actual_resolver_sp->SearchCallback (filter, context, addr, containing);
150 else
151 return eCallbackReturnStop;
152 }
153
Eric Christopher2325e382014-12-10 22:29:58 +0000154 Searcher::Depth
155 GetDepth () override
Greg Claytonbff78252013-03-11 18:42:51 +0000156 {
157 if (SetActualResolver())
158 return m_actual_resolver_sp->GetDepth();
159 else
160 return eDepthTarget;
161 }
162
Eric Christopher2325e382014-12-10 22:29:58 +0000163 void
164 GetDescription (Stream *s) override
Greg Claytonbff78252013-03-11 18:42:51 +0000165 {
Jim Inghama2023572015-12-18 02:14:04 +0000166 Language *language_plugin = Language::FindPlugin(m_language);
167 if (language_plugin)
168 language_plugin->GetExceptionResolverDescription(m_catch_bp, m_throw_bp, *s);
169 else
170 Language::GetDefaultExceptionResolverDescription(m_catch_bp, m_throw_bp, *s);
171
Greg Claytonbff78252013-03-11 18:42:51 +0000172 SetActualResolver();
173 if (m_actual_resolver_sp)
174 {
175 s->Printf (" using: ");
176 m_actual_resolver_sp->GetDescription (s);
177 }
178 else
179 s->Printf (" the correct runtime exception handler will be determined when you run");
180 }
181
Eric Christopher2325e382014-12-10 22:29:58 +0000182 void
183 Dump (Stream *s) const override
Greg Claytonbff78252013-03-11 18:42:51 +0000184 {
185 }
186
187 /// Methods for support type inquiry through isa, cast, and dyn_cast:
188 static inline bool classof(const BreakpointResolverName *) { return true; }
189 static inline bool classof(const BreakpointResolver *V) {
190 return V->getResolverID() == BreakpointResolver::ExceptionResolver;
191 }
Eugene Zelenko8f30a652015-10-23 18:39:37 +0000192
Greg Claytonbff78252013-03-11 18:42:51 +0000193protected:
Jim Ingham33df7cd2014-12-06 01:28:03 +0000194 BreakpointResolverSP
195 CopyForBreakpoint (Breakpoint &breakpoint) override
196 {
197 return BreakpointResolverSP(new ExceptionBreakpointResolver(m_language, m_catch_bp, m_throw_bp));
198 }
199
Greg Claytonbff78252013-03-11 18:42:51 +0000200 bool
201 SetActualResolver()
202 {
203 ProcessSP process_sp;
204 if (m_breakpoint)
205 {
206 process_sp = m_breakpoint->GetTarget().GetProcessSP();
207 if (process_sp)
208 {
209 bool refreash_resolver = !m_actual_resolver_sp;
210 if (m_language_runtime == NULL)
211 {
212 m_language_runtime = process_sp->GetLanguageRuntime(m_language);
213 refreash_resolver = true;
214 }
215 else
216 {
217 LanguageRuntime *language_runtime = process_sp->GetLanguageRuntime(m_language);
218 if (m_language_runtime != language_runtime)
219 {
220 m_language_runtime = language_runtime;
221 refreash_resolver = true;
222 }
223 }
224
225 if (refreash_resolver && m_language_runtime)
226 {
227 m_actual_resolver_sp = m_language_runtime->CreateExceptionResolver (m_breakpoint, m_catch_bp, m_throw_bp);
228 }
229 }
230 else
231 {
232 m_actual_resolver_sp.reset();
233 m_language_runtime = NULL;
234 }
235 }
236 else
237 {
238 m_actual_resolver_sp.reset();
239 m_language_runtime = NULL;
240 }
241 return (bool)m_actual_resolver_sp;
242 }
243 lldb::BreakpointResolverSP m_actual_resolver_sp;
244 lldb::LanguageType m_language;
245 LanguageRuntime *m_language_runtime;
246 bool m_catch_bp;
247 bool m_throw_bp;
248};
249
Jim Ingham22777012010-09-23 02:01:19 +0000250LanguageRuntime*
251LanguageRuntime::FindPlugin (Process *process, lldb::LanguageType language)
252{
Greg Clayton7b0992d2013-04-18 22:45:39 +0000253 std::unique_ptr<LanguageRuntime> language_runtime_ap;
Jim Ingham22777012010-09-23 02:01:19 +0000254 LanguageRuntimeCreateInstance create_callback;
255
256 for (uint32_t idx = 0;
257 (create_callback = PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) != NULL;
258 ++idx)
259 {
260 language_runtime_ap.reset (create_callback(process, language));
261
262 if (language_runtime_ap.get())
263 return language_runtime_ap.release();
264 }
265
266 return NULL;
267}
268
Jim Ingham5a369122010-09-28 01:25:32 +0000269LanguageRuntime::LanguageRuntime(Process *process) :
270 m_process (process)
Jim Ingham22777012010-09-23 02:01:19 +0000271{
272}
273
Eugene Zelenko8f30a652015-10-23 18:39:37 +0000274LanguageRuntime::~LanguageRuntime() = default;
Jim Ingham219ba192012-03-05 04:47:34 +0000275
Jim Inghama72b31c2015-04-22 19:42:18 +0000276Breakpoint::BreakpointPreconditionSP
277LanguageRuntime::CreateExceptionPrecondition (lldb::LanguageType language,
278 bool catch_bp,
279 bool throw_bp)
280{
281 switch (language)
282 {
283 case eLanguageTypeObjC:
284 if (throw_bp)
285 return Breakpoint::BreakpointPreconditionSP(new ObjCLanguageRuntime::ObjCExceptionPrecondition ());
286 break;
287 default:
288 break;
289 }
290 return Breakpoint::BreakpointPreconditionSP();
291}
292
Jim Ingham219ba192012-03-05 04:47:34 +0000293BreakpointSP
Greg Claytonbff78252013-03-11 18:42:51 +0000294LanguageRuntime::CreateExceptionBreakpoint (Target &target,
295 lldb::LanguageType language,
296 bool catch_bp,
297 bool throw_bp,
298 bool is_internal)
Jim Ingham219ba192012-03-05 04:47:34 +0000299{
Greg Claytonbff78252013-03-11 18:42:51 +0000300 BreakpointResolverSP resolver_sp(new ExceptionBreakpointResolver(language, catch_bp, throw_bp));
301 SearchFilterSP filter_sp(new ExceptionSearchFilter(target.shared_from_this(), language));
Greg Claytoneb023e72013-10-11 19:48:25 +0000302 bool hardware = false;
Jim Ingham1460e4b2014-01-10 23:46:59 +0000303 bool resolve_indirect_functions = false;
304 BreakpointSP exc_breakpt_sp (target.CreateBreakpoint (filter_sp, resolver_sp, is_internal, hardware, resolve_indirect_functions));
Jim Inghama72b31c2015-04-22 19:42:18 +0000305 if (exc_breakpt_sp)
306 {
307 Breakpoint::BreakpointPreconditionSP precondition_sp = CreateExceptionPrecondition(language, catch_bp, throw_bp);
308 if (precondition_sp)
309 exc_breakpt_sp->SetPrecondition(precondition_sp);
310
311 if (is_internal)
312 exc_breakpt_sp->SetBreakpointKind("exception");
313 }
Jim Ingham219ba192012-03-05 04:47:34 +0000314
315 return exc_breakpt_sp;
316}
317
Colin Rileyc9c55a22015-05-04 18:39:38 +0000318void
319LanguageRuntime::InitializeCommands (CommandObject* parent)
320{
321 if (!parent)
322 return;
323
324 if (!parent->IsMultiwordObject())
325 return;
326
327 LanguageRuntimeCreateInstance create_callback;
328
329 for (uint32_t idx = 0;
330 (create_callback = PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) != nullptr;
331 ++idx)
332 {
333 if (LanguageRuntimeGetCommandObject command_callback =
334 PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(idx))
335 {
336 CommandObjectSP command = command_callback(parent->GetCommandInterpreter());
337 if (command)
338 {
Enrico Granata0a66e2f2016-02-06 00:43:07 +0000339 // the CommandObject vended by a Language plugin cannot be created once and cached because
340 // we may create multiple debuggers and need one instance of the command each - the implementing function
341 // is meant to create a new instance of the command each time it is invoked
342 assert(&command->GetCommandInterpreter() == &parent->GetCommandInterpreter() && "language plugin returned command for a mismatched CommandInterpreter");
Colin Rileyc9c55a22015-05-04 18:39:38 +0000343 parent->LoadSubCommand(command->GetCommandName(), command);
344 }
345 }
346 }
347}
348
Greg Claytonbff78252013-03-11 18:42:51 +0000349lldb::SearchFilterSP
350LanguageRuntime::CreateExceptionSearchFilter ()
351{
352 return m_process->GetTarget().GetSearchFilterForModule(NULL);
353}