blob: 7bcb75306ab6d2dbe46950df1e40a03532d45df8 [file] [log] [blame]
Jim Ingham151c0322015-09-15 21:13:50 +00001//===-- UserExpression.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 <stdio.h>
11#if HAVE_SYS_TYPES_H
12# include <sys/types.h>
13#endif
14
15#include <cstdlib>
16#include <string>
17#include <map>
18
19#include "lldb/Core/ConstString.h"
20#include "lldb/Core/Log.h"
21#include "lldb/Core/Module.h"
22#include "lldb/Core/StreamFile.h"
23#include "lldb/Core/StreamString.h"
24#include "lldb/Core/ValueObjectConstResult.h"
Jim Ingham151c0322015-09-15 21:13:50 +000025#include "lldb/Expression/ExpressionSourceCode.h"
26#include "lldb/Expression/IRExecutionUnit.h"
27#include "lldb/Expression/IRInterpreter.h"
28#include "lldb/Expression/Materializer.h"
29#include "lldb/Expression/UserExpression.h"
Sean Callanan4dbb2712015-09-25 20:35:58 +000030#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
Jim Ingham151c0322015-09-15 21:13:50 +000031#include "lldb/Host/HostInfo.h"
32#include "lldb/Symbol/Block.h"
Jim Ingham151c0322015-09-15 21:13:50 +000033#include "lldb/Symbol/Function.h"
34#include "lldb/Symbol/ObjectFile.h"
35#include "lldb/Symbol/SymbolVendor.h"
36#include "lldb/Symbol/Type.h"
Sean Callanan8f1f9a12015-09-30 19:57:57 +000037#include "lldb/Symbol/TypeSystem.h"
Jim Ingham151c0322015-09-15 21:13:50 +000038#include "lldb/Symbol/VariableList.h"
39#include "lldb/Target/ExecutionContext.h"
40#include "lldb/Target/Process.h"
41#include "lldb/Target/StackFrame.h"
42#include "lldb/Target/Target.h"
43#include "lldb/Target/ThreadPlan.h"
44#include "lldb/Target/ThreadPlanCallUserExpression.h"
45
Jim Ingham151c0322015-09-15 21:13:50 +000046using namespace lldb_private;
47
48UserExpression::UserExpression (ExecutionContextScope &exe_scope,
49 const char *expr,
50 const char *expr_prefix,
51 lldb::LanguageType language,
52 ResultType desired_type) :
53 Expression (exe_scope),
54 m_stack_frame_bottom (LLDB_INVALID_ADDRESS),
55 m_stack_frame_top (LLDB_INVALID_ADDRESS),
56 m_expr_text (expr),
57 m_expr_prefix (expr_prefix ? expr_prefix : ""),
58 m_language (language),
59 m_transformed_text (),
60 m_desired_type (desired_type),
61 m_execution_unit_sp(),
62 m_materializer_ap(),
63 m_jit_module_wp(),
64 m_enforce_valid_object (true),
65 m_in_cplusplus_method (false),
66 m_in_objectivec_method (false),
67 m_in_static_method(false),
68 m_needs_object_ptr (false),
69 m_const_object (false),
70 m_target (NULL),
71 m_can_interpret (false),
72 m_materialized_address (LLDB_INVALID_ADDRESS)
73{
74}
75
76UserExpression::~UserExpression ()
77{
78 if (m_target)
79 {
80 lldb::ModuleSP jit_module_sp (m_jit_module_wp.lock());
81 if (jit_module_sp)
82 m_target->GetImages().Remove(jit_module_sp);
83 }
84}
85
86void
87UserExpression::InstallContext (ExecutionContext &exe_ctx)
88{
89 m_jit_process_wp = exe_ctx.GetProcessSP();
90
91 lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
92
93 if (frame_sp)
94 m_address = frame_sp->GetFrameCodeAddress();
95}
96
97bool
98UserExpression::LockAndCheckContext (ExecutionContext &exe_ctx,
99 lldb::TargetSP &target_sp,
100 lldb::ProcessSP &process_sp,
101 lldb::StackFrameSP &frame_sp)
102{
103 lldb::ProcessSP expected_process_sp = m_jit_process_wp.lock();
104 process_sp = exe_ctx.GetProcessSP();
105
106 if (process_sp != expected_process_sp)
107 return false;
108
109 process_sp = exe_ctx.GetProcessSP();
110 target_sp = exe_ctx.GetTargetSP();
111 frame_sp = exe_ctx.GetFrameSP();
112
113 if (m_address.IsValid())
114 {
115 if (!frame_sp)
116 return false;
117 else
118 return (0 == Address::CompareLoadAddress(m_address, frame_sp->GetFrameCodeAddress(), target_sp.get()));
119 }
120
121 return true;
122}
123
124bool
125UserExpression::MatchesContext (ExecutionContext &exe_ctx)
126{
127 lldb::TargetSP target_sp;
128 lldb::ProcessSP process_sp;
129 lldb::StackFrameSP frame_sp;
130
131 return LockAndCheckContext(exe_ctx, target_sp, process_sp, frame_sp);
132}
133
134lldb::addr_t
135UserExpression::GetObjectPointer (lldb::StackFrameSP frame_sp,
136 ConstString &object_name,
137 Error &err)
138{
139 err.Clear();
140
141 if (!frame_sp)
142 {
143 err.SetErrorStringWithFormat("Couldn't load '%s' because the context is incomplete", object_name.AsCString());
144 return LLDB_INVALID_ADDRESS;
145 }
146
147 lldb::VariableSP var_sp;
148 lldb::ValueObjectSP valobj_sp;
149
150 valobj_sp = frame_sp->GetValueForVariableExpressionPath(object_name.AsCString(),
151 lldb::eNoDynamicValues,
152 StackFrame::eExpressionPathOptionCheckPtrVsMember |
153 StackFrame::eExpressionPathOptionsNoFragileObjcIvar |
154 StackFrame::eExpressionPathOptionsNoSyntheticChildren |
155 StackFrame::eExpressionPathOptionsNoSyntheticArrayRange,
156 var_sp,
157 err);
158
159 if (!err.Success() || !valobj_sp.get())
160 return LLDB_INVALID_ADDRESS;
161
162 lldb::addr_t ret = valobj_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
163
164 if (ret == LLDB_INVALID_ADDRESS)
165 {
166 err.SetErrorStringWithFormat("Couldn't load '%s' because its value couldn't be evaluated", object_name.AsCString());
167 return LLDB_INVALID_ADDRESS;
168 }
169
170 return ret;
171}
172
173bool
174UserExpression::PrepareToExecuteJITExpression (Stream &error_stream,
175 ExecutionContext &exe_ctx,
176 lldb::addr_t &struct_address)
177{
178 lldb::TargetSP target;
179 lldb::ProcessSP process;
180 lldb::StackFrameSP frame;
181
182 if (!LockAndCheckContext(exe_ctx,
183 target,
184 process,
185 frame))
186 {
187 error_stream.Printf("The context has changed before we could JIT the expression!\n");
188 return false;
189 }
190
191 if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
192 {
193 if (m_materialized_address == LLDB_INVALID_ADDRESS)
194 {
195 Error alloc_error;
196
197 IRMemoryMap::AllocationPolicy policy = m_can_interpret ? IRMemoryMap::eAllocationPolicyHostOnly : IRMemoryMap::eAllocationPolicyMirror;
198
199 m_materialized_address = m_execution_unit_sp->Malloc(m_materializer_ap->GetStructByteSize(),
200 m_materializer_ap->GetStructAlignment(),
201 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
202 policy,
203 alloc_error);
204
205 if (!alloc_error.Success())
206 {
207 error_stream.Printf("Couldn't allocate space for materialized struct: %s\n", alloc_error.AsCString());
208 return false;
209 }
210 }
211
212 struct_address = m_materialized_address;
213
214 if (m_can_interpret && m_stack_frame_bottom == LLDB_INVALID_ADDRESS)
215 {
216 Error alloc_error;
217
218 const size_t stack_frame_size = 512 * 1024;
219
220 m_stack_frame_bottom = m_execution_unit_sp->Malloc(stack_frame_size,
221 8,
222 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
223 IRMemoryMap::eAllocationPolicyHostOnly,
224 alloc_error);
225
226 m_stack_frame_top = m_stack_frame_bottom + stack_frame_size;
227
228 if (!alloc_error.Success())
229 {
230 error_stream.Printf("Couldn't allocate space for the stack frame: %s\n", alloc_error.AsCString());
231 return false;
232 }
233 }
234
235 Error materialize_error;
236
237 m_dematerializer_sp = m_materializer_ap->Materialize(frame, *m_execution_unit_sp, struct_address, materialize_error);
238
239 if (!materialize_error.Success())
240 {
241 error_stream.Printf("Couldn't materialize: %s\n", materialize_error.AsCString());
242 return false;
243 }
244 }
245 return true;
246}
247
248bool
249UserExpression::FinalizeJITExecution (Stream &error_stream,
250 ExecutionContext &exe_ctx,
251 lldb::ExpressionVariableSP &result,
252 lldb::addr_t function_stack_bottom,
253 lldb::addr_t function_stack_top)
254{
255 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
256
257 if (log)
258 log->Printf("-- [UserExpression::FinalizeJITExecution] Dematerializing after execution --");
259
260 if (!m_dematerializer_sp)
261 {
262 error_stream.Printf ("Couldn't apply expression side effects : no dematerializer is present");
263 return false;
264 }
265
266 Error dematerialize_error;
267
Sean Callanan9fda9d22015-10-03 09:09:01 +0000268 m_dematerializer_sp->Dematerialize(dematerialize_error, function_stack_bottom, function_stack_top);
Jim Ingham151c0322015-09-15 21:13:50 +0000269
270 if (!dematerialize_error.Success())
271 {
272 error_stream.Printf ("Couldn't apply expression side effects : %s\n", dematerialize_error.AsCString("unknown error"));
273 return false;
274 }
275
Sean Callanan9fda9d22015-10-03 09:09:01 +0000276 result = GetResultAfterDematerialization(exe_ctx.GetBestExecutionContextScope());
277
Jim Ingham151c0322015-09-15 21:13:50 +0000278 if (result)
279 result->TransferAddress();
280
281 m_dematerializer_sp.reset();
282
283 return true;
284}
285
286lldb::ExpressionResults
287UserExpression::Execute (Stream &error_stream,
288 ExecutionContext &exe_ctx,
289 const EvaluateExpressionOptions& options,
290 lldb::UserExpressionSP &shared_ptr_to_me,
291 lldb::ExpressionVariableSP &result)
292{
293 // The expression log is quite verbose, and if you're just tracking the execution of the
294 // expression, it's quite convenient to have these logs come out with the STEP log as well.
295 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
296
297 if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
298 {
299 lldb::addr_t struct_address = LLDB_INVALID_ADDRESS;
300
301 if (!PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address))
302 {
303 error_stream.Printf("Errored out in %s, couldn't PrepareToExecuteJITExpression", __FUNCTION__);
304 return lldb::eExpressionSetupError;
305 }
306
307 lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS;
308 lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS;
309
310 if (m_can_interpret)
311 {
312 llvm::Module *module = m_execution_unit_sp->GetModule();
313 llvm::Function *function = m_execution_unit_sp->GetFunction();
314
315 if (!module || !function)
316 {
317 error_stream.Printf("Supposed to interpret, but nothing is there");
318 return lldb::eExpressionSetupError;
319 }
320
321 Error interpreter_error;
322
323 std::vector<lldb::addr_t> args;
324
325 if (!AddInitialArguments(exe_ctx, args, error_stream))
326 {
327 error_stream.Printf ("Errored out in %s, couldn't AddInitialArguments", __FUNCTION__);
328 return lldb::eExpressionSetupError;
329 }
330
331 args.push_back(struct_address);
332
333 function_stack_bottom = m_stack_frame_bottom;
334 function_stack_top = m_stack_frame_top;
335
336 IRInterpreter::Interpret (*module,
337 *function,
338 args,
339 *m_execution_unit_sp.get(),
340 interpreter_error,
341 function_stack_bottom,
342 function_stack_top,
343 exe_ctx);
344
345 if (!interpreter_error.Success())
346 {
347 error_stream.Printf("Supposed to interpret, but failed: %s", interpreter_error.AsCString());
348 return lldb::eExpressionDiscarded;
349 }
350 }
351 else
352 {
353 if (!exe_ctx.HasThreadScope())
354 {
355 error_stream.Printf("UserExpression::Execute called with no thread selected.");
356 return lldb::eExpressionSetupError;
357 }
358
359 Address wrapper_address (m_jit_start_addr);
360
361 std::vector<lldb::addr_t> args;
362
363 if (!AddInitialArguments(exe_ctx, args, error_stream))
364 {
365 error_stream.Printf ("Errored out in %s, couldn't AddInitialArguments", __FUNCTION__);
366 return lldb::eExpressionSetupError;
367 }
368
369 args.push_back(struct_address);
370
371 lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(),
372 wrapper_address,
373 args,
374 options,
375 shared_ptr_to_me));
376
377 if (!call_plan_sp || !call_plan_sp->ValidatePlan (&error_stream))
378 return lldb::eExpressionSetupError;
379
380 ThreadPlanCallUserExpression *user_expression_plan = static_cast<ThreadPlanCallUserExpression *>(call_plan_sp.get());
381
382 lldb::addr_t function_stack_pointer = user_expression_plan->GetFunctionStackPointer();
383
384 function_stack_bottom = function_stack_pointer - HostInfo::GetPageSize();
385 function_stack_top = function_stack_pointer;
386
387 if (log)
388 log->Printf("-- [UserExpression::Execute] Execution of expression begins --");
389
390 if (exe_ctx.GetProcessPtr())
391 exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
392
393 lldb::ExpressionResults execution_result = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx,
394 call_plan_sp,
395 options,
396 error_stream);
397
398 if (exe_ctx.GetProcessPtr())
399 exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
400
401 if (log)
402 log->Printf("-- [UserExpression::Execute] Execution of expression completed --");
403
404 if (execution_result == lldb::eExpressionInterrupted || execution_result == lldb::eExpressionHitBreakpoint)
405 {
406 const char *error_desc = NULL;
407
408 if (call_plan_sp)
409 {
410 lldb::StopInfoSP real_stop_info_sp = call_plan_sp->GetRealStopInfo();
411 if (real_stop_info_sp)
412 error_desc = real_stop_info_sp->GetDescription();
413 }
414 if (error_desc)
415 error_stream.Printf ("Execution was interrupted, reason: %s.", error_desc);
416 else
417 error_stream.PutCString ("Execution was interrupted.");
418
419 if ((execution_result == lldb::eExpressionInterrupted && options.DoesUnwindOnError())
420 || (execution_result == lldb::eExpressionHitBreakpoint && options.DoesIgnoreBreakpoints()))
421 error_stream.PutCString ("\nThe process has been returned to the state before expression evaluation.");
422 else
423 {
424 if (execution_result == lldb::eExpressionHitBreakpoint)
425 user_expression_plan->TransferExpressionOwnership();
426 error_stream.PutCString ("\nThe process has been left at the point where it was interrupted, "
427 "use \"thread return -x\" to return to the state before expression evaluation.");
428 }
429
430 return execution_result;
431 }
432 else if (execution_result == lldb::eExpressionStoppedForDebug)
433 {
434 error_stream.PutCString ("Execution was halted at the first instruction of the expression "
435 "function because \"debug\" was requested.\n"
436 "Use \"thread return -x\" to return to the state before expression evaluation.");
437 return execution_result;
438 }
439 else if (execution_result != lldb::eExpressionCompleted)
440 {
441 error_stream.Printf ("Couldn't execute function; result was %s\n", Process::ExecutionResultAsCString (execution_result));
442 return execution_result;
443 }
444 }
445
446 if (FinalizeJITExecution (error_stream, exe_ctx, result, function_stack_bottom, function_stack_top))
447 {
448 return lldb::eExpressionCompleted;
449 }
450 else
451 {
452 return lldb::eExpressionResultUnavailable;
453 }
454 }
455 else
456 {
457 error_stream.Printf("Expression can't be run, because there is no JIT compiled function");
458 return lldb::eExpressionSetupError;
459 }
460}
461
462lldb::ExpressionResults
463UserExpression::Evaluate (ExecutionContext &exe_ctx,
464 const EvaluateExpressionOptions& options,
465 const char *expr_cstr,
466 const char *expr_prefix,
467 lldb::ValueObjectSP &result_valobj_sp,
Sean Callanan66810412015-10-19 23:11:07 +0000468 Error &error,
469 uint32_t line_offset,
470 lldb::ModuleSP *jit_module_sp_ptr)
Jim Ingham151c0322015-09-15 21:13:50 +0000471{
472 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
473
474 lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy();
Dawn Perchik1bbaede2015-10-07 22:01:12 +0000475 lldb::LanguageType language = options.GetLanguage();
Jim Ingham151c0322015-09-15 21:13:50 +0000476 const ResultType desired_type = options.DoesCoerceToId() ? UserExpression::eResultTypeId : UserExpression::eResultTypeAny;
477 lldb::ExpressionResults execution_results = lldb::eExpressionSetupError;
478
479 Target *target = exe_ctx.GetTargetPtr();
480 if (!target)
481 {
482 if (log)
483 log->Printf("== [UserExpression::Evaluate] Passed a NULL target, can't run expressions.");
484 return lldb::eExpressionSetupError;
485 }
486
487 Process *process = exe_ctx.GetProcessPtr();
488
489 if (process == NULL || process->GetState() != lldb::eStateStopped)
490 {
491 if (execution_policy == eExecutionPolicyAlways)
492 {
493 if (log)
494 log->Printf("== [UserExpression::Evaluate] Expression may not run, but is not constant ==");
495
496 error.SetErrorString ("expression needed to run but couldn't");
497
498 return execution_results;
499 }
500 }
501
502 if (process == NULL || !process->CanJIT())
503 execution_policy = eExecutionPolicyNever;
504
505 const char *full_prefix = NULL;
506 const char *option_prefix = options.GetPrefix();
507 std::string full_prefix_storage;
508 if (expr_prefix && option_prefix)
509 {
510 full_prefix_storage.assign(expr_prefix);
511 full_prefix_storage.append(option_prefix);
512 if (!full_prefix_storage.empty())
513 full_prefix = full_prefix_storage.c_str();
514 }
515 else if (expr_prefix)
516 full_prefix = expr_prefix;
517 else
518 full_prefix = option_prefix;
519
Dawn Perchik1bbaede2015-10-07 22:01:12 +0000520 // If the language was not specified in the expression command,
521 // set it to the language in the target's properties if
522 // specified, else default to the langage for the frame.
523 if (language == lldb::eLanguageTypeUnknown)
524 {
525 if (target->GetLanguage() != lldb::eLanguageTypeUnknown)
526 language = target->GetLanguage();
527 else if (StackFrame *frame = exe_ctx.GetFramePtr())
528 language = frame->GetLanguage();
529 }
530
Jim Ingham151c0322015-09-15 21:13:50 +0000531 lldb::UserExpressionSP user_expression_sp(target->GetUserExpressionForLanguage (expr_cstr,
532 full_prefix,
533 language,
534 desired_type,
535 error));
536 if (error.Fail())
537 {
538 if (log)
539 log->Printf ("== [UserExpression::Evaluate] Getting expression: %s ==", error.AsCString());
540 return lldb::eExpressionSetupError;
541 }
542
543 StreamString error_stream;
544
545 if (log)
546 log->Printf("== [UserExpression::Evaluate] Parsing expression %s ==", expr_cstr);
547
548 const bool keep_expression_in_memory = true;
549 const bool generate_debug_info = options.GetGenerateDebugInfo();
550
551 if (options.InvokeCancelCallback (lldb::eExpressionEvaluationParse))
552 {
553 error.SetErrorString ("expression interrupted by callback before parse");
554 result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
555 return lldb::eExpressionInterrupted;
556 }
557
558 if (!user_expression_sp->Parse (error_stream,
559 exe_ctx,
560 execution_policy,
561 keep_expression_in_memory,
562 generate_debug_info))
563 {
564 execution_results = lldb::eExpressionParseError;
565 if (error_stream.GetString().empty())
566 error.SetExpressionError (execution_results, "expression failed to parse, unknown error");
567 else
568 error.SetExpressionError (execution_results, error_stream.GetString().c_str());
569 }
570 else
571 {
Sean Callanan66810412015-10-19 23:11:07 +0000572 // If a pointer to a lldb::ModuleSP was passed in, return the JIT'ed module if one was created
573 if (jit_module_sp_ptr && user_expression_sp->m_execution_unit_sp)
574 *jit_module_sp_ptr = user_expression_sp->m_execution_unit_sp->GetJITModule();
575
Jim Ingham151c0322015-09-15 21:13:50 +0000576 lldb::ExpressionVariableSP expr_result;
577
578 if (execution_policy == eExecutionPolicyNever &&
579 !user_expression_sp->CanInterpret())
580 {
581 if (log)
582 log->Printf("== [UserExpression::Evaluate] Expression may not run, but is not constant ==");
583
584 if (error_stream.GetString().empty())
585 error.SetExpressionError (lldb::eExpressionSetupError, "expression needed to run but couldn't");
586 }
587 else
588 {
589 if (options.InvokeCancelCallback (lldb::eExpressionEvaluationExecution))
590 {
591 error.SetExpressionError (lldb::eExpressionInterrupted, "expression interrupted by callback before execution");
592 result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
593 return lldb::eExpressionInterrupted;
594 }
595
596 error_stream.GetString().clear();
597
598 if (log)
599 log->Printf("== [UserExpression::Evaluate] Executing expression ==");
600
601 execution_results = user_expression_sp->Execute (error_stream,
602 exe_ctx,
603 options,
604 user_expression_sp,
605 expr_result);
606
607 if (options.GetResultIsInternal() && expr_result && process)
608 {
Sean Callananb92bd752015-10-01 16:28:02 +0000609 process->GetTarget().GetPersistentExpressionStateForLanguage(language)->RemovePersistentVariable (expr_result);
Jim Ingham151c0322015-09-15 21:13:50 +0000610 }
611
612 if (execution_results != lldb::eExpressionCompleted)
613 {
614 if (log)
615 log->Printf("== [UserExpression::Evaluate] Execution completed abnormally ==");
616
617 if (error_stream.GetString().empty())
618 error.SetExpressionError (execution_results, "expression failed to execute, unknown error");
619 else
620 error.SetExpressionError (execution_results, error_stream.GetString().c_str());
621 }
622 else
623 {
624 if (expr_result)
625 {
626 result_valobj_sp = expr_result->GetValueObject();
627
628 if (log)
629 log->Printf("== [UserExpression::Evaluate] Execution completed normally with result %s ==",
630 result_valobj_sp->GetValueAsCString());
631 }
632 else
633 {
634 if (log)
635 log->Printf("== [UserExpression::Evaluate] Execution completed normally with no result ==");
636
637 error.SetError(UserExpression::kNoResult, lldb::eErrorTypeGeneric);
638 }
639 }
640 }
641 }
642
643 if (options.InvokeCancelCallback(lldb::eExpressionEvaluationComplete))
644 {
645 error.SetExpressionError (lldb::eExpressionInterrupted, "expression interrupted by callback after complete");
646 return lldb::eExpressionInterrupted;
647 }
648
649 if (result_valobj_sp.get() == NULL)
650 {
651 result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
652 }
653
654 return execution_results;
655}