diff options
author | Sean Callanan <scallanan@apple.com> | 2012-01-24 22:06:48 +0000 |
---|---|---|
committer | Sean Callanan <scallanan@apple.com> | 2012-01-24 22:06:48 +0000 |
commit | 175a0d04b6981bbbd026e8720701de5636d879d3 (patch) | |
tree | 3e4b0212c805e2ddfd285879c136383b9166e956 | |
parent | 77dbd786c845cafaf40c3ec6224025f3bcc09f35 (diff) | |
download | bcm5719-llvm-175a0d04b6981bbbd026e8720701de5636d879d3.tar.gz bcm5719-llvm-175a0d04b6981bbbd026e8720701de5636d879d3.zip |
Added a mechanism for the IR interpreter to return
an error along with its boolean result. The
expression parser reports this error if the
interpreter fails and the expression could not be
run in the target.
llvm-svn: 148870
-rw-r--r-- | lldb/include/lldb/Expression/ClangExpressionParser.h | 1 | ||||
-rw-r--r-- | lldb/include/lldb/Expression/IRForTarget.h | 12 | ||||
-rw-r--r-- | lldb/include/lldb/Expression/IRInterpreter.h | 12 | ||||
-rw-r--r-- | lldb/source/Expression/ClangExpressionParser.cpp | 34 | ||||
-rw-r--r-- | lldb/source/Expression/IRForTarget.cpp | 7 | ||||
-rw-r--r-- | lldb/source/Expression/IRInterpreter.cpp | 159 |
6 files changed, 159 insertions, 66 deletions
diff --git a/lldb/include/lldb/Expression/ClangExpressionParser.h b/lldb/include/lldb/Expression/ClangExpressionParser.h index 982e67a9284..c3323b88e13 100644 --- a/lldb/include/lldb/Expression/ClangExpressionParser.h +++ b/lldb/include/lldb/Expression/ClangExpressionParser.h @@ -189,7 +189,6 @@ private: std::auto_ptr<clang::SelectorTable> m_selector_table; ///< Selector table for Objective-C methods std::auto_ptr<clang::ASTContext> m_ast_context; ///< The AST context used to hold types and names for the parser std::auto_ptr<clang::CodeGenerator> m_code_generator; ///< [owned by the Execution Engine] The Clang object that generates IR - std::auto_ptr<llvm::ExecutionEngine> m_execution_engine; ///< The LLVM JIT std::vector<JittedFunction> m_jitted_functions; ///< A vector of all functions that have been JITted into machine code (just one, if ParseExpression() was called) }; diff --git a/lldb/include/lldb/Expression/IRForTarget.h b/lldb/include/lldb/Expression/IRForTarget.h index 46fd3a6a985..d263e7de3b1 100644 --- a/lldb/include/lldb/Expression/IRForTarget.h +++ b/lldb/include/lldb/Expression/IRForTarget.h @@ -12,6 +12,7 @@ #include "lldb/lldb-public.h" #include "lldb/Core/ConstString.h" +#include "lldb/Core/Error.h" #include "lldb/Core/Stream.h" #include "lldb/Symbol/TaggedASTType.h" #include "llvm/Pass.h" @@ -115,6 +116,10 @@ public: /// $__lldb_expr, and that function is passed to the passes one by /// one. /// + /// @param[in] interpreter_error + /// An error. If the expression fails to be interpreted, this error + /// is set to a reason why. + /// /// @return /// True on success; false otherwise //------------------------------------------------------------------ @@ -146,10 +151,10 @@ public: /// /// Returns true if it did; false otherwise. //------------------------------------------------------------------ - bool - interpretSuccess () + lldb_private::Error & + getInterpreterError () { - return m_interpret_success; + return m_interpreter_error; } private: @@ -632,6 +637,7 @@ private: llvm::Constant *m_sel_registerName; ///< The address of the function sel_registerName, cast to the appropriate function pointer type lldb::ClangExpressionVariableSP &m_const_result; ///< This value should be set to the return value of the expression if it is constant and the expression has no side effects lldb_private::Stream *m_error_stream; ///< If non-NULL, the stream on which errors should be printed + lldb_private::Error m_interpreter_error; ///< The error result from the IR interpreter bool m_has_side_effects; ///< True if the function's result cannot be simply determined statically llvm::StoreInst *m_result_store; ///< If non-NULL, the store instruction that writes to the result variable. If m_has_side_effects is true, this is NULL. diff --git a/lldb/include/lldb/Expression/IRInterpreter.h b/lldb/include/lldb/Expression/IRInterpreter.h index dd4d38410df..c8d341f045f 100644 --- a/lldb/include/lldb/Expression/IRInterpreter.h +++ b/lldb/include/lldb/Expression/IRInterpreter.h @@ -79,6 +79,9 @@ public: /// @param[in] llvm_module /// The module containing the function. /// + /// @param[in] error + /// If the expression fails to interpret, a reason why. + /// /// @return /// True on success; false otherwise //------------------------------------------------------------------ @@ -87,21 +90,24 @@ public: const lldb_private::ConstString &result_name, lldb_private::TypeFromParser result_type, llvm::Function &llvm_function, - llvm::Module &llvm_module); + llvm::Module &llvm_module, + lldb_private::Error &err); private: /// Flags lldb_private::ClangExpressionDeclMap &m_decl_map; ///< The DeclMap containing the Decls lldb_private::Stream *m_error_stream; bool - supportsFunction (llvm::Function &llvm_function); + supportsFunction (llvm::Function &llvm_function, + lldb_private::Error &err); bool runOnFunction (lldb::ClangExpressionVariableSP &result, const lldb_private::ConstString &result_name, lldb_private::TypeFromParser result_type, llvm::Function &llvm_function, - llvm::Module &llvm_module); + llvm::Module &llvm_module, + lldb_private::Error &err); }; #endif diff --git a/lldb/source/Expression/ClangExpressionParser.cpp b/lldb/source/Expression/ClangExpressionParser.cpp index 7c3e6589621..625b03e28a2 100644 --- a/lldb/source/Expression/ClangExpressionParser.cpp +++ b/lldb/source/Expression/ClangExpressionParser.cpp @@ -187,7 +187,6 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope, m_expr (expr), m_compiler (), m_code_generator (NULL), - m_execution_engine (), m_jitted_functions () { // Initialize targets first, so that --version shows registered targets. @@ -447,6 +446,8 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_allocation_addr, func_end = LLDB_INVALID_ADDRESS; lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + std::auto_ptr<llvm::ExecutionEngine> execution_engine; + Error err; llvm::Module *module = m_code_generator->ReleaseModule(); @@ -498,7 +499,9 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_allocation_addr, return err; } - if (execution_policy != eExecutionPolicyAlways && ir_for_target.interpretSuccess()) + Error &interpreter_error(ir_for_target.getInterpreterError()); + + if (execution_policy != eExecutionPolicyAlways && interpreter_error.Success()) { if (const_result) const_result->TransferAddress(); @@ -512,7 +515,10 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_allocation_addr, if (!process || execution_policy == eExecutionPolicyNever) { err.SetErrorToGenericError(); - err.SetErrorString("Execution needed to run in the target, but the target can't be run"); + if (execution_policy == eExecutionPolicyAlways) + err.SetErrorString("Execution needed to run in the target, but the target can't be run"); + else + err.SetErrorStringWithFormat("Interpreting the expression locally failed: %s", interpreter_error.AsCString()); return err; } @@ -571,15 +577,6 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_allocation_addr, log->Printf ("Module being sent to JIT: \n%s", s.c_str()); } -#if defined (USE_STANDARD_JIT) - m_execution_engine.reset(llvm::ExecutionEngine::createJIT (module, - &error_string, - jit_memory_manager, - CodeGenOpt::Less, - true, - Reloc::Default, - CodeModel::Small)); -#else EngineBuilder builder(module); builder.setEngineKind(EngineKind::JIT) .setErrorStr(&error_string) @@ -589,24 +586,23 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_allocation_addr, .setAllocateGVsWithCode(true) .setCodeModel(CodeModel::Small) .setUseMCJIT(true); - m_execution_engine.reset(builder.create()); -#endif + execution_engine.reset(builder.create()); - if (!m_execution_engine.get()) + if (!execution_engine.get()) { err.SetErrorToGenericError(); err.SetErrorStringWithFormat("Couldn't JIT the function: %s", error_string.c_str()); return err; } - m_execution_engine->DisableLazyCompilation(); + execution_engine->DisableLazyCompilation(); llvm::Function *function = module->getFunction (function_name.c_str()); // We don't actually need the function pointer here, this just forces it to get resolved. - void *fun_ptr = m_execution_engine->getPointerToFunction(function); - + void *fun_ptr = execution_engine->getPointerToFunction(function); + // Errors usually cause failures in the JIT, but if we're lucky we get here. if (!function) @@ -717,6 +713,8 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_allocation_addr, } } + execution_engine.reset(); + err.Clear(); return err; } diff --git a/lldb/source/Expression/IRForTarget.cpp b/lldb/source/Expression/IRForTarget.cpp index c16e1266b91..15ba25038af 100644 --- a/lldb/source/Expression/IRForTarget.cpp +++ b/lldb/source/Expression/IRForTarget.cpp @@ -2663,11 +2663,10 @@ IRForTarget::runOnModule (Module &llvm_module) IRInterpreter interpreter (*m_decl_map, m_error_stream); - if (interpreter.maybeRunOnFunction(m_const_result, m_result_name, m_result_type, *function, llvm_module)) - { - m_interpret_success = true; + interpreter.maybeRunOnFunction(m_const_result, m_result_name, m_result_type, *function, llvm_module, m_interpreter_error); + + if (m_interpreter_error.Success()) return true; - } } if (log && log->GetVerbose()) diff --git a/lldb/source/Expression/IRInterpreter.cpp b/lldb/source/Expression/IRInterpreter.cpp index dba09799d5b..3cbe9f3bd8f 100644 --- a/lldb/source/Expression/IRInterpreter.cpp +++ b/lldb/source/Expression/IRInterpreter.cpp @@ -851,20 +851,32 @@ IRInterpreter::maybeRunOnFunction (lldb::ClangExpressionVariableSP &result, const lldb_private::ConstString &result_name, lldb_private::TypeFromParser result_type, Function &llvm_function, - Module &llvm_module) + Module &llvm_module, + lldb_private::Error &err) { - if (supportsFunction (llvm_function)) + if (supportsFunction (llvm_function, err)) return runOnFunction(result, result_name, result_type, llvm_function, - llvm_module); + llvm_module, + err); else return false; } +static const char *unsupported_opcode_error = "Interpreter doesn't handle one of the expression's opcodes"; +static const char *interpreter_initialization_error = "Interpreter couldn't be initialized"; +static const char *interpreter_internal_error = "Interpreter encountered an internal error"; +static const char *bad_value_error = "Interpreter couldn't resolve a value during execution"; +static const char *memory_allocation_error = "Interpreter couldn't allocate memory"; +static const char *memory_write_error = "Interpreter couldn't write to memory"; +static const char *memory_read_error = "Interpreter couldn't read from memory"; +static const char *infinite_loop_error = "Interpreter ran for too many cycles"; + bool -IRInterpreter::supportsFunction (Function &llvm_function) +IRInterpreter::supportsFunction (Function &llvm_function, + lldb_private::Error &err) { lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); @@ -882,6 +894,8 @@ IRInterpreter::supportsFunction (Function &llvm_function) { if (log) log->Printf("Unsupported instruction: %s", PrintValue(ii).c_str()); + err.SetErrorToGenericError(); + err.SetErrorString(unsupported_opcode_error); return false; } case Instruction::Add: @@ -895,7 +909,11 @@ IRInterpreter::supportsFunction (Function &llvm_function) ICmpInst *icmp_inst = dyn_cast<ICmpInst>(ii); if (!icmp_inst) + { + err.SetErrorToGenericError(); + err.SetErrorString(interpreter_internal_error); return false; + } switch (icmp_inst->getPredicate()) { @@ -903,6 +921,9 @@ IRInterpreter::supportsFunction (Function &llvm_function) { if (log) log->Printf("Unsupported ICmp predicate: %s", PrintValue(ii).c_str()); + + err.SetErrorToGenericError(); + err.SetErrorString(unsupported_opcode_error); return false; } case CmpInst::ICMP_EQ: @@ -940,14 +961,19 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, const lldb_private::ConstString &result_name, lldb_private::TypeFromParser result_type, Function &llvm_function, - Module &llvm_module) + Module &llvm_module, + lldb_private::Error &err) { lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); lldb_private::ClangExpressionDeclMap::TargetInfo target_info = m_decl_map.GetTargetInfo(); if (!target_info.IsValid()) + { + err.SetErrorToGenericError(); + err.SetErrorString(interpreter_initialization_error); return false; + } lldb::addr_t alloc_min; lldb::addr_t alloc_max; @@ -955,7 +981,9 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, switch (target_info.address_byte_size) { default: - return false; + err.SetErrorToGenericError(); + err.SetErrorString(interpreter_initialization_error); + return false; case 4: alloc_min = 0x00001000llu; alloc_max = 0x0000ffffllu; @@ -968,9 +996,17 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, TargetData target_data(&llvm_module); if (target_data.getPointerSize() != target_info.address_byte_size) + { + err.SetErrorToGenericError(); + err.SetErrorString(interpreter_initialization_error); return false; + } if (target_data.isLittleEndian() != (target_info.byte_order == lldb::eByteOrderLittle)) + { + err.SetErrorToGenericError(); + err.SetErrorString(interpreter_initialization_error); return false; + } Memory memory(target_data, m_decl_map, alloc_min, alloc_max); InterpreterStackFrame frame(target_data, memory, m_decl_map); @@ -1002,8 +1038,9 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, { if (log) log->Printf("getOpcode() returns %s, but instruction is not a BinaryOperator", inst->getOpcodeName()); - - return false; + err.SetErrorToGenericError(); + err.SetErrorString(interpreter_internal_error); + return false; } Value *lhs = inst->getOperand(0); @@ -1016,7 +1053,8 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, { if (log) log->Printf("Couldn't evaluate %s", PrintValue(lhs).c_str()); - + err.SetErrorToGenericError(); + err.SetErrorString(bad_value_error); return false; } @@ -1024,7 +1062,8 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, { if (log) log->Printf("Couldn't evaluate %s", PrintValue(rhs).c_str()); - + err.SetErrorToGenericError(); + err.SetErrorString(bad_value_error); return false; } @@ -1070,7 +1109,8 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, { if (log) log->Printf("getOpcode() returns Alloca, but instruction is not an AllocaInst"); - + err.SetErrorToGenericError(); + err.SetErrorString(interpreter_internal_error); return false; } @@ -1078,7 +1118,8 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, { if (log) log->Printf("AllocaInsts are not handled if isArrayAllocation() is true"); - + err.SetErrorToGenericError(); + err.SetErrorString(unsupported_opcode_error); return false; } @@ -1096,7 +1137,8 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, { if (log) log->Printf("Couldn't allocate memory for an AllocaInst"); - + err.SetErrorToGenericError(); + err.SetErrorString(memory_allocation_error); return false; } @@ -1106,7 +1148,8 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, { if (log) log->Printf("Couldn't allocate the result pointer for an AllocaInst"); - + err.SetErrorToGenericError(); + err.SetErrorString(memory_allocation_error); return false; } @@ -1115,8 +1158,9 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, if (P_encoder->PutAddress(0, R.m_base) == UINT32_MAX) { if (log) - log->Printf("Couldn't write the reseult pointer for an AllocaInst"); - + log->Printf("Couldn't write the result pointer for an AllocaInst"); + err.SetErrorToGenericError(); + err.SetErrorString(memory_write_error); return false; } @@ -1138,7 +1182,8 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, { if (log) log->Printf("getOpcode() returns BitCast, but instruction is not a BitCastInst"); - + err.SetErrorToGenericError(); + err.SetErrorString(interpreter_internal_error); return false; } @@ -1150,7 +1195,8 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, { if (log) log->Printf("Couldn't evaluate %s", PrintValue(source).c_str()); - + err.SetErrorToGenericError(); + err.SetErrorString(bad_value_error); return false; } @@ -1165,7 +1211,8 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, { if (log) log->Printf("getOpcode() returns Br, but instruction is not a BranchInst"); - + err.SetErrorToGenericError(); + err.SetErrorString(interpreter_internal_error); return false; } @@ -1179,7 +1226,8 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, { if (log) log->Printf("Couldn't evaluate %s", PrintValue(condition).c_str()); - + err.SetErrorToGenericError(); + err.SetErrorString(bad_value_error); return false; } @@ -1213,7 +1261,8 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, { if (log) log->Printf("getOpcode() returns GetElementPtr, but instruction is not a GetElementPtrInst"); - + err.SetErrorToGenericError(); + err.SetErrorString(interpreter_internal_error); return false; } @@ -1223,8 +1272,14 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, lldb_private::Scalar P; if (!frame.EvaluateValue(P, pointer_operand, llvm_module)) + { + if (log) + log->Printf("Couldn't evaluate %s", PrintValue(pointer_operand).c_str()); + err.SetErrorToGenericError(); + err.SetErrorString(bad_value_error); return false; - + } + SmallVector <Value *, 8> indices (gep_inst->idx_begin(), gep_inst->idx_end()); @@ -1250,7 +1305,8 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, { if (log) log->Printf("getOpcode() returns ICmp, but instruction is not an ICmpInst"); - + err.SetErrorToGenericError(); + err.SetErrorString(interpreter_internal_error); return false; } @@ -1266,7 +1322,8 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, { if (log) log->Printf("Couldn't evaluate %s", PrintValue(lhs).c_str()); - + err.SetErrorToGenericError(); + err.SetErrorString(bad_value_error); return false; } @@ -1274,7 +1331,8 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, { if (log) log->Printf("Couldn't evaluate %s", PrintValue(rhs).c_str()); - + err.SetErrorToGenericError(); + err.SetErrorString(bad_value_error); return false; } @@ -1335,7 +1393,8 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, { if (log) log->Printf("getOpcode() returns IntToPtr, but instruction is not an IntToPtrInst"); - + err.SetErrorToGenericError(); + err.SetErrorString(interpreter_internal_error); return false; } @@ -1344,7 +1403,13 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, lldb_private::Scalar I; if (!frame.EvaluateValue(I, src_operand, llvm_module)) + { + if (log) + log->Printf("Couldn't evaluate %s", PrintValue(src_operand).c_str()); + err.SetErrorToGenericError(); + err.SetErrorString(bad_value_error); return false; + } frame.AssignValue(inst, I, llvm_module); @@ -1364,7 +1429,8 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, { if (log) log->Printf("getOpcode() returns Load, but instruction is not a LoadInst"); - + err.SetErrorToGenericError(); + err.SetErrorString(interpreter_internal_error); return false; } @@ -1379,7 +1445,13 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, Type *pointer_ty = pointer_operand->getType(); PointerType *pointer_ptr_ty = dyn_cast<PointerType>(pointer_ty); if (!pointer_ptr_ty) + { + if (log) + log->Printf("getPointerOperand()->getType() is not a PointerType"); + err.SetErrorToGenericError(); + err.SetErrorString(interpreter_internal_error); return false; + } Type *target_ty = pointer_ptr_ty->getElementType(); Memory::Region D = frame.ResolveValue(load_inst, llvm_module); @@ -1389,7 +1461,8 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, { if (log) log->Printf("LoadInst's value doesn't resolve to anything"); - + err.SetErrorToGenericError(); + err.SetErrorString(bad_value_error); return false; } @@ -1397,7 +1470,8 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, { if (log) log->Printf("LoadInst's pointer doesn't resolve to anything"); - + err.SetErrorToGenericError(); + err.SetErrorString(bad_value_error); return false; } @@ -1415,7 +1489,8 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, { if (log) log->Printf("Couldn't read from a region on behalf of a LoadInst"); - + err.SetErrorToGenericError(); + err.SetErrorString(memory_read_error); return false; } } @@ -1425,7 +1500,8 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, { if (log) log->Printf("Couldn't read from a raw pointer on behalf of a LoadInst"); - + err.SetErrorToGenericError(); + err.SetErrorString(memory_read_error); return false; } } @@ -1458,7 +1534,8 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, { if (log) log->Printf("getOpcode() returns Store, but instruction is not a StoreInst"); - + err.SetErrorToGenericError(); + err.SetErrorString(interpreter_internal_error); return false; } @@ -1484,7 +1561,8 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, { if (log) log->Printf("StoreInst's value doesn't resolve to anything"); - + err.SetErrorToGenericError(); + err.SetErrorString(bad_value_error); return false; } @@ -1492,7 +1570,8 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, { if (log) log->Printf("StoreInst's pointer doesn't resolve to anything"); - + err.SetErrorToGenericError(); + err.SetErrorString(bad_value_error); return false; } @@ -1513,7 +1592,8 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, { if (log) log->Printf("Couldn't write to a region on behalf of a LoadInst"); - + err.SetErrorToGenericError(); + err.SetErrorString(memory_write_error); return false; } } @@ -1523,7 +1603,8 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, { if (log) log->Printf("Couldn't write to a raw pointer on behalf of a LoadInst"); - + err.SetErrorToGenericError(); + err.SetErrorString(memory_write_error); return false; } } @@ -1544,7 +1625,11 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result, } if (num_insts >= 4096) + { + err.SetErrorToGenericError(); + err.SetErrorString(infinite_loop_error); return false; - + } + return false; } |