blob: f61af071e3e452b468a58a5ce32b48a3519fb426 [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) :
Eugene Zelenko9394d7722016-02-18 00:10:17 +000032 SearchFilter(target_sp),
33 m_language(language),
34 m_language_runtime(nullptr),
35 m_filter_sp()
Greg Claytonbff78252013-03-11 18:42:51 +000036 {
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;
Eugene Zelenko9394d7722016-02-18 00:10:17 +000095 if (m_language_runtime == nullptr)
Greg Claytonbff78252013-03-11 18:42:51 +000096 {
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();
Eugene Zelenko9394d7722016-02-18 00:10:17 +0000118 m_language_runtime = nullptr;
Greg Claytonbff78252013-03-11 18:42:51 +0000119 }
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) :
Eugene Zelenko9394d7722016-02-18 00:10:17 +0000131 BreakpointResolver(nullptr, BreakpointResolver::ExceptionResolver),
132 m_language(language),
133 m_language_runtime(nullptr),
134 m_catch_bp(catch_bp),
135 m_throw_bp(throw_bp)
Greg Claytonbff78252013-03-11 18:42:51 +0000136 {
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;
Eugene Zelenko9394d7722016-02-18 00:10:17 +0000210 if (m_language_runtime == nullptr)
Greg Claytonbff78252013-03-11 18:42:51 +0000211 {
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();
Eugene Zelenko9394d7722016-02-18 00:10:17 +0000233 m_language_runtime = nullptr;
Greg Claytonbff78252013-03-11 18:42:51 +0000234 }
235 }
236 else
237 {
238 m_actual_resolver_sp.reset();
Eugene Zelenko9394d7722016-02-18 00:10:17 +0000239 m_language_runtime = nullptr;
Greg Claytonbff78252013-03-11 18:42:51 +0000240 }
241 return (bool)m_actual_resolver_sp;
242 }
Eugene Zelenko9394d7722016-02-18 00:10:17 +0000243
Greg Claytonbff78252013-03-11 18:42:51 +0000244 lldb::BreakpointResolverSP m_actual_resolver_sp;
245 lldb::LanguageType m_language;
246 LanguageRuntime *m_language_runtime;
247 bool m_catch_bp;
248 bool m_throw_bp;
249};
250
Jim Ingham22777012010-09-23 02:01:19 +0000251LanguageRuntime*
252LanguageRuntime::FindPlugin (Process *process, lldb::LanguageType language)
253{
Greg Clayton7b0992d2013-04-18 22:45:39 +0000254 std::unique_ptr<LanguageRuntime> language_runtime_ap;
Jim Ingham22777012010-09-23 02:01:19 +0000255 LanguageRuntimeCreateInstance create_callback;
256
257 for (uint32_t idx = 0;
Eugene Zelenko9394d7722016-02-18 00:10:17 +0000258 (create_callback = PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) != nullptr;
Jim Ingham22777012010-09-23 02:01:19 +0000259 ++idx)
260 {
261 language_runtime_ap.reset (create_callback(process, language));
262
Eugene Zelenko9394d7722016-02-18 00:10:17 +0000263 if (language_runtime_ap)
Jim Ingham22777012010-09-23 02:01:19 +0000264 return language_runtime_ap.release();
265 }
266
Eugene Zelenko9394d7722016-02-18 00:10:17 +0000267 return nullptr;
Jim Ingham22777012010-09-23 02:01:19 +0000268}
269
Jim Ingham5a369122010-09-28 01:25:32 +0000270LanguageRuntime::LanguageRuntime(Process *process) :
271 m_process (process)
Jim Ingham22777012010-09-23 02:01:19 +0000272{
273}
274
Eugene Zelenko8f30a652015-10-23 18:39:37 +0000275LanguageRuntime::~LanguageRuntime() = default;
Jim Ingham219ba192012-03-05 04:47:34 +0000276
Jim Inghama72b31c2015-04-22 19:42:18 +0000277Breakpoint::BreakpointPreconditionSP
278LanguageRuntime::CreateExceptionPrecondition (lldb::LanguageType language,
279 bool catch_bp,
280 bool throw_bp)
281{
282 switch (language)
283 {
284 case eLanguageTypeObjC:
285 if (throw_bp)
286 return Breakpoint::BreakpointPreconditionSP(new ObjCLanguageRuntime::ObjCExceptionPrecondition ());
287 break;
288 default:
289 break;
290 }
291 return Breakpoint::BreakpointPreconditionSP();
292}
293
Jim Ingham219ba192012-03-05 04:47:34 +0000294BreakpointSP
Greg Claytonbff78252013-03-11 18:42:51 +0000295LanguageRuntime::CreateExceptionBreakpoint (Target &target,
296 lldb::LanguageType language,
297 bool catch_bp,
298 bool throw_bp,
299 bool is_internal)
Jim Ingham219ba192012-03-05 04:47:34 +0000300{
Greg Claytonbff78252013-03-11 18:42:51 +0000301 BreakpointResolverSP resolver_sp(new ExceptionBreakpointResolver(language, catch_bp, throw_bp));
302 SearchFilterSP filter_sp(new ExceptionSearchFilter(target.shared_from_this(), language));
Greg Claytoneb023e72013-10-11 19:48:25 +0000303 bool hardware = false;
Jim Ingham1460e4b2014-01-10 23:46:59 +0000304 bool resolve_indirect_functions = false;
305 BreakpointSP exc_breakpt_sp (target.CreateBreakpoint (filter_sp, resolver_sp, is_internal, hardware, resolve_indirect_functions));
Jim Inghama72b31c2015-04-22 19:42:18 +0000306 if (exc_breakpt_sp)
307 {
308 Breakpoint::BreakpointPreconditionSP precondition_sp = CreateExceptionPrecondition(language, catch_bp, throw_bp);
309 if (precondition_sp)
310 exc_breakpt_sp->SetPrecondition(precondition_sp);
311
312 if (is_internal)
313 exc_breakpt_sp->SetBreakpointKind("exception");
314 }
Jim Ingham219ba192012-03-05 04:47:34 +0000315
316 return exc_breakpt_sp;
317}
318
Colin Rileyc9c55a22015-05-04 18:39:38 +0000319void
320LanguageRuntime::InitializeCommands (CommandObject* parent)
321{
322 if (!parent)
323 return;
324
325 if (!parent->IsMultiwordObject())
326 return;
327
328 LanguageRuntimeCreateInstance create_callback;
329
330 for (uint32_t idx = 0;
331 (create_callback = PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) != nullptr;
332 ++idx)
333 {
334 if (LanguageRuntimeGetCommandObject command_callback =
335 PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(idx))
336 {
337 CommandObjectSP command = command_callback(parent->GetCommandInterpreter());
338 if (command)
339 {
Enrico Granata0a66e2f2016-02-06 00:43:07 +0000340 // the CommandObject vended by a Language plugin cannot be created once and cached because
341 // we may create multiple debuggers and need one instance of the command each - the implementing function
342 // is meant to create a new instance of the command each time it is invoked
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{
Eugene Zelenko9394d7722016-02-18 00:10:17 +0000352 return m_process->GetTarget().GetSearchFilterForModule(nullptr);
Greg Claytonbff78252013-03-11 18:42:51 +0000353}