NSIndexPathSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd (*valobj_sp.get()), m_ptr_size(0), m_uint_star_type() { m_ptr_size = m_backend.GetTargetSP()->GetArchitecture().GetAddressByteSize(); }
lldb_private::formatters::swift::SwiftOptionalSyntheticFrontEnd::SwiftOptionalSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd(*valobj_sp.get()), m_is_none(false), m_children(false), m_some(nullptr) { }
lldb_private::formatters::swift::EnumSyntheticFrontEnd::EnumSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd(*valobj_sp.get()), m_exe_ctx_ref(), m_element_name(nullptr), m_child_index(UINT32_MAX) { if (valobj_sp) Update(); }
lldb_private::formatters::NSArrayMSyntheticFrontEnd::NSArrayMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd(*valobj_sp.get()), m_exe_ctx_ref(), m_ptr_size(8), m_data_32(NULL), m_data_64(NULL) { if (valobj_sp) m_id_type = ClangASTType(valobj_sp->GetClangAST(),valobj_sp->GetClangAST()->ObjCBuiltinIdTy.getAsOpaquePtr()); }
lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::NSDictionaryMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd(*valobj_sp.get()), m_exe_ctx_ref(), m_ptr_size(8), m_order(lldb::eByteOrderInvalid), m_data_32(NULL), m_data_64(NULL), m_pair_type() { }
lldb_private::formatters::NSSetMSyntheticFrontEnd::NSSetMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd(*valobj_sp.get()), m_exe_ctx_ref(), m_ptr_size(8), m_data_32(NULL), m_data_64(NULL) { if (valobj_sp) Update (); }
lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::LibcxxStdVectorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd(*valobj_sp.get()), m_start(NULL), m_finish(NULL), m_element_type(), m_element_size(0), m_children() { if (valobj_sp) Update(); }
lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::LibcxxStdUnorderedMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd(*valobj_sp.get()), m_tree(NULL), m_num_elements(0), m_next_element(nullptr), m_children(), m_elements_cache() { if (valobj_sp) Update(); }
lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::LibcxxInitializerListSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd(*valobj_sp.get()), m_start(NULL), m_element_type(), m_element_size(0), m_num_elements(0), m_children() { if (valobj_sp) Update(); }
lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::LibcxxStdMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd(*valobj_sp.get()), m_tree(NULL), m_root_node(NULL), m_element_type(), m_skip_size(UINT32_MAX), m_count(UINT32_MAX), m_children() { if (valobj_sp) Update(); }
std::string StringSummaryFormat::FormatObject(lldb::ValueObjectSP object) { if (!object.get()) return "NULL"; StreamString s; ExecutionContext exe_ctx; object->GetExecutionContextScope()->CalculateExecutionContext(exe_ctx); SymbolContext sc; StackFrame *frame = exe_ctx.GetFramePtr(); if (frame) sc = frame->GetSymbolContext(lldb::eSymbolContextEverything); if (m_show_members_oneliner) { ValueObjectSP synth_valobj = object->GetSyntheticValue(lldb::eUseSyntheticFilter); const uint32_t num_children = synth_valobj->GetNumChildren(); if (num_children) { s.PutChar('('); for (uint32_t idx=0; idx<num_children; ++idx) { lldb::ValueObjectSP child_sp(synth_valobj->GetChildAtIndex(idx, true)); if (child_sp.get()) { if (idx) s.PutCString(", "); s.PutCString(child_sp.get()->GetName().AsCString()); s.PutChar('='); child_sp.get()->GetPrintableRepresentation(s); } } s.PutChar(')'); return s.GetString(); } else return ""; } else { if (Debugger::FormatPrompt(m_format.c_str(), &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, NULL, object.get())) return s.GetString(); else return ""; } }
lldb_private::formatters::NSArrayMSyntheticFrontEnd::NSArrayMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd(*valobj_sp.get()), m_exe_ctx_ref(), m_ptr_size(8), m_data_32(NULL), m_data_64(NULL) { if (valobj_sp) { clang::ASTContext *ast = valobj_sp->GetClangType().GetASTContext(); if (ast) m_id_type = ClangASTType(ast, ast->ObjCBuiltinIdTy); } }
lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::LibcxxStdListSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd(*valobj_sp.get()), m_list_capping_size(0), m_loop_detected(0), m_node_address(), m_head(NULL), m_tail(NULL), m_element_type(), m_count(UINT32_MAX), m_children() { if (valobj_sp) Update(); }
lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEnd::LibstdcppMapIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd(*valobj_sp.get()), m_exe_ctx_ref(), m_pair_address(0), m_pair_type(), m_options(), m_pair_sp() { if (valobj_sp) Update(); m_options.SetCoerceToId(false); m_options.SetUnwindOnError(true); m_options.SetKeepInMemory(true); m_options.SetUseDynamic(lldb::eDynamicCanRunTarget); }
SyntheticScriptProvider::FrontEnd::FrontEnd(std::string pclass, lldb::ValueObjectSP be) : SyntheticChildrenFrontEnd(be), m_python_class(pclass) { if (be.get() == NULL) { m_interpreter = NULL; m_wrapper = NULL; return; } m_interpreter = m_backend->GetUpdatePoint().GetTargetSP()->GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); if (m_interpreter == NULL) m_wrapper = NULL; else m_wrapper = m_interpreter->CreateSyntheticScriptedProvider(m_python_class, m_backend); }
lldb::ExpressionResults ClangUserExpression::Evaluate (ExecutionContext &exe_ctx, const EvaluateExpressionOptions& options, const char *expr_cstr, const char *expr_prefix, lldb::ValueObjectSP &result_valobj_sp, Error &error) { Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP)); lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy(); const lldb::LanguageType language = options.GetLanguage(); const ResultType desired_type = options.DoesCoerceToId() ? ClangUserExpression::eResultTypeId : ClangUserExpression::eResultTypeAny; lldb::ExpressionResults execution_results = lldb::eExpressionSetupError; Process *process = exe_ctx.GetProcessPtr(); if (process == NULL || process->GetState() != lldb::eStateStopped) { if (execution_policy == eExecutionPolicyAlways) { if (log) log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant =="); error.SetErrorString ("expression needed to run but couldn't"); return execution_results; } } if (process == NULL || !process->CanJIT()) execution_policy = eExecutionPolicyNever; ClangUserExpressionSP user_expression_sp (new ClangUserExpression (expr_cstr, expr_prefix, language, desired_type)); StreamString error_stream; if (log) log->Printf("== [ClangUserExpression::Evaluate] Parsing expression %s ==", expr_cstr); const bool keep_expression_in_memory = true; const bool generate_debug_info = options.GetGenerateDebugInfo(); if (options.InvokeCancelCallback (lldb::eExpressionEvaluationParse)) { error.SetErrorString ("expression interrupted by callback before parse"); result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error); return lldb::eExpressionInterrupted; } if (!user_expression_sp->Parse (error_stream, exe_ctx, execution_policy, keep_expression_in_memory, generate_debug_info)) { if (error_stream.GetString().empty()) error.SetExpressionError (lldb::eExpressionParseError, "expression failed to parse, unknown error"); else error.SetExpressionError (lldb::eExpressionParseError, error_stream.GetString().c_str()); } else { lldb::ClangExpressionVariableSP expr_result; if (execution_policy == eExecutionPolicyNever && !user_expression_sp->CanInterpret()) { if (log) log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant =="); if (error_stream.GetString().empty()) error.SetExpressionError (lldb::eExpressionSetupError, "expression needed to run but couldn't"); } else { if (options.InvokeCancelCallback (lldb::eExpressionEvaluationExecution)) { error.SetExpressionError (lldb::eExpressionInterrupted, "expression interrupted by callback before execution"); result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error); return lldb::eExpressionInterrupted; } error_stream.GetString().clear(); if (log) log->Printf("== [ClangUserExpression::Evaluate] Executing expression =="); execution_results = user_expression_sp->Execute (error_stream, exe_ctx, options, user_expression_sp, expr_result); if (options.GetResultIsInternal()) { process->GetTarget().GetPersistentVariables().RemovePersistentVariable (expr_result); } if (execution_results != lldb::eExpressionCompleted) { if (log) log->Printf("== [ClangUserExpression::Evaluate] Execution completed abnormally =="); if (error_stream.GetString().empty()) error.SetExpressionError (execution_results, "expression failed to execute, unknown error"); else error.SetExpressionError (execution_results, error_stream.GetString().c_str()); } else { if (expr_result) { result_valobj_sp = expr_result->GetValueObject(); if (log) log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with result %s ==", result_valobj_sp->GetValueAsCString()); } else { if (log) log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with no result =="); error.SetError(ClangUserExpression::kNoResult, lldb::eErrorTypeGeneric); } } } } if (options.InvokeCancelCallback(lldb::eExpressionEvaluationComplete)) { error.SetExpressionError (lldb::eExpressionInterrupted, "expression interrupted by callback after complete"); return lldb::eExpressionInterrupted; } if (result_valobj_sp.get() == NULL) { result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error); } return execution_results; }
lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::NSOrderedSetSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd(*valobj_sp.get()), m_count(UINT32_MAX), m_children() {}
SwiftHashedContainerNativeBufferHandler::SwiftHashedContainerNativeBufferHandler (lldb::ValueObjectSP nativeStorage_sp, CompilerType key_type, CompilerType value_type) : m_nativeStorage(nativeStorage_sp.get()), m_process(nullptr), m_ptr_size(0), m_count(0), m_capacity(0), m_bitmask_ptr(LLDB_INVALID_ADDRESS), m_keys_ptr(LLDB_INVALID_ADDRESS), m_values_ptr(LLDB_INVALID_ADDRESS), m_element_type(), m_key_stride(key_type.GetByteStride()), m_value_stride(0), m_bitmask_cache() { static ConstString g_initializedEntries("initializedEntries"); static ConstString g_values("values"); static ConstString g__rawValue("_rawValue"); static ConstString g_keys("keys"); static ConstString g_buffer("buffer"); static ConstString g_key("key"); static ConstString g_value("value"); if (!m_nativeStorage) return; if (!key_type) return; if (value_type) { m_value_stride = value_type.GetByteStride(); if (SwiftASTContext *swift_ast = llvm::dyn_cast_or_null<SwiftASTContext>(key_type.GetTypeSystem())) { std::vector<SwiftASTContext::TupleElement> tuple_elements{ {g_key,key_type}, {g_value,value_type} }; m_element_type = swift_ast->CreateTupleType(tuple_elements); } } else m_element_type = key_type; if (!m_element_type) return; auto buffer_ptr = m_nativeStorage->GetChildAtNamePath( {g_buffer} )->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); if (!buffer_ptr) return; m_process = m_nativeStorage->GetProcessSP().get(); if (!m_process) return; m_ptr_size = m_process->GetAddressByteSize(); Error error; m_capacity = m_process->ReadPointerFromMemory(buffer_ptr + 2 * m_ptr_size, error); if (error.Fail()) return; m_count = m_process->ReadPointerFromMemory(buffer_ptr + 3 * m_ptr_size, error); if (error.Fail()) return; m_nativeStorage = nativeStorage_sp.get(); m_bitmask_ptr = m_nativeStorage->GetChildAtNamePath( {g_initializedEntries,g_values,g__rawValue} )->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); if (ValueObjectSP value_child_sp = m_nativeStorage->GetChildAtNamePath( {g_values,g__rawValue} )) { // it is fine not to pass a value_type, but if the value child exists, then you have to pass one if (!value_type) return; m_values_ptr = value_child_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); } m_keys_ptr = m_nativeStorage->GetChildAtNamePath( {g_keys,g__rawValue} )->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); }
lldb::ExpressionResults UserExpression::Evaluate (ExecutionContext &exe_ctx, const EvaluateExpressionOptions& options, const char *expr_cstr, const char *expr_prefix, lldb::ValueObjectSP &result_valobj_sp, Error &error, uint32_t line_offset, lldb::ModuleSP *jit_module_sp_ptr) { Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP)); lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy(); lldb::LanguageType language = options.GetLanguage(); const ResultType desired_type = options.DoesCoerceToId() ? UserExpression::eResultTypeId : UserExpression::eResultTypeAny; lldb::ExpressionResults execution_results = lldb::eExpressionSetupError; Target *target = exe_ctx.GetTargetPtr(); if (!target) { if (log) log->Printf("== [UserExpression::Evaluate] Passed a NULL target, can't run expressions."); return lldb::eExpressionSetupError; } Process *process = exe_ctx.GetProcessPtr(); if (process == NULL || process->GetState() != lldb::eStateStopped) { if (execution_policy == eExecutionPolicyAlways) { if (log) log->Printf("== [UserExpression::Evaluate] Expression may not run, but is not constant =="); error.SetErrorString ("expression needed to run but couldn't"); return execution_results; } } if (process == NULL || !process->CanJIT()) execution_policy = eExecutionPolicyNever; const char *full_prefix = NULL; const char *option_prefix = options.GetPrefix(); std::string full_prefix_storage; if (expr_prefix && option_prefix) { full_prefix_storage.assign(expr_prefix); full_prefix_storage.append(option_prefix); if (!full_prefix_storage.empty()) full_prefix = full_prefix_storage.c_str(); } else if (expr_prefix) full_prefix = expr_prefix; else full_prefix = option_prefix; // If the language was not specified in the expression command, // set it to the language in the target's properties if // specified, else default to the langage for the frame. if (language == lldb::eLanguageTypeUnknown) { if (target->GetLanguage() != lldb::eLanguageTypeUnknown) language = target->GetLanguage(); else if (StackFrame *frame = exe_ctx.GetFramePtr()) language = frame->GetLanguage(); } // If the language was not specified in the expression command, // set it to the language in the target's properties if // specified, else default to the langage for the frame. if (language == lldb::eLanguageTypeUnknown) { if (target->GetLanguage() != lldb::eLanguageTypeUnknown) language = target->GetLanguage(); else if (StackFrame *frame = exe_ctx.GetFramePtr()) language = frame->GetLanguage(); } lldb::UserExpressionSP user_expression_sp(target->GetUserExpressionForLanguage (expr_cstr, full_prefix, language, desired_type, options, error)); if (error.Fail()) { if (log) log->Printf ("== [UserExpression::Evaluate] Getting expression: %s ==", error.AsCString()); return lldb::eExpressionSetupError; } StreamString error_stream; if (log) log->Printf("== [UserExpression::Evaluate] Parsing expression %s ==", expr_cstr); const bool keep_expression_in_memory = true; const bool generate_debug_info = options.GetGenerateDebugInfo(); if (options.InvokeCancelCallback (lldb::eExpressionEvaluationParse)) { error.SetErrorString ("expression interrupted by callback before parse"); result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error); return lldb::eExpressionInterrupted; } if (!user_expression_sp->Parse (error_stream, exe_ctx, execution_policy, keep_expression_in_memory, generate_debug_info, 0)) { execution_results = lldb::eExpressionParseError; if (error_stream.GetString().empty()) error.SetExpressionError (execution_results, "expression failed to parse, unknown error"); else error.SetExpressionError (execution_results, error_stream.GetString().c_str()); } else { // If a pointer to a lldb::ModuleSP was passed in, return the JIT'ed module if one was created if (jit_module_sp_ptr) *jit_module_sp_ptr = user_expression_sp->GetJITModule(); lldb::ExpressionVariableSP expr_result; if (execution_policy == eExecutionPolicyNever && !user_expression_sp->CanInterpret()) { if (log) log->Printf("== [UserExpression::Evaluate] Expression may not run, but is not constant =="); if (error_stream.GetString().empty()) error.SetExpressionError (lldb::eExpressionSetupError, "expression needed to run but couldn't"); } else { if (options.InvokeCancelCallback (lldb::eExpressionEvaluationExecution)) { error.SetExpressionError (lldb::eExpressionInterrupted, "expression interrupted by callback before execution"); result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error); return lldb::eExpressionInterrupted; } error_stream.GetString().clear(); if (log) log->Printf("== [UserExpression::Evaluate] Executing expression =="); execution_results = user_expression_sp->Execute (error_stream, exe_ctx, options, user_expression_sp, expr_result); if (options.GetResultIsInternal() && expr_result && process) { process->GetTarget().GetPersistentExpressionStateForLanguage(language)->RemovePersistentVariable (expr_result); } if (execution_results != lldb::eExpressionCompleted) { if (log) log->Printf("== [UserExpression::Evaluate] Execution completed abnormally =="); if (error_stream.GetString().empty()) error.SetExpressionError (execution_results, "expression failed to execute, unknown error"); else error.SetExpressionError (execution_results, error_stream.GetString().c_str()); } else { if (expr_result) { result_valobj_sp = expr_result->GetValueObject(); if (log) log->Printf("== [UserExpression::Evaluate] Execution completed normally with result %s ==", result_valobj_sp->GetValueAsCString()); } else { if (log) log->Printf("== [UserExpression::Evaluate] Execution completed normally with no result =="); error.SetError(UserExpression::kNoResult, lldb::eErrorTypeGeneric); } } } } if (options.InvokeCancelCallback(lldb::eExpressionEvaluationComplete)) { error.SetExpressionError (lldb::eExpressionInterrupted, "expression interrupted by callback after complete"); return lldb::eExpressionInterrupted; } if (result_valobj_sp.get() == NULL) { result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error); } return execution_results; }
lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::NSDictionaryCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd(*valobj_sp.get()) {}
ExecutionResults ClangUserExpression::EvaluateWithError (ExecutionContext &exe_ctx, lldb_private::ExecutionPolicy execution_policy, lldb::LanguageType language, ResultType desired_type, bool unwind_on_error, bool ignore_breakpoints, const char *expr_cstr, const char *expr_prefix, lldb::ValueObjectSP &result_valobj_sp, Error &error, bool run_others, uint32_t timeout_usec) { Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP)); ExecutionResults execution_results = eExecutionSetupError; Process *process = exe_ctx.GetProcessPtr(); if (process == NULL || process->GetState() != lldb::eStateStopped) { if (execution_policy == eExecutionPolicyAlways) { if (log) log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant =="); error.SetErrorString ("expression needed to run but couldn't"); return execution_results; } } if (process == NULL || !process->CanJIT()) execution_policy = eExecutionPolicyNever; ClangUserExpressionSP user_expression_sp (new ClangUserExpression (expr_cstr, expr_prefix, language, desired_type)); StreamString error_stream; if (log) log->Printf("== [ClangUserExpression::Evaluate] Parsing expression %s ==", expr_cstr); const bool keep_expression_in_memory = true; if (!user_expression_sp->Parse (error_stream, exe_ctx, execution_policy, keep_expression_in_memory)) { if (error_stream.GetString().empty()) error.SetErrorString ("expression failed to parse, unknown error"); else error.SetErrorString (error_stream.GetString().c_str()); } else { lldb::ClangExpressionVariableSP expr_result; if (execution_policy == eExecutionPolicyNever && !user_expression_sp->CanInterpret()) { if (log) log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant =="); if (error_stream.GetString().empty()) error.SetErrorString ("expression needed to run but couldn't"); } else { error_stream.GetString().clear(); if (log) log->Printf("== [ClangUserExpression::Evaluate] Executing expression =="); execution_results = user_expression_sp->Execute (error_stream, exe_ctx, unwind_on_error, ignore_breakpoints, user_expression_sp, expr_result, run_others, timeout_usec); if (execution_results != eExecutionCompleted) { if (log) log->Printf("== [ClangUserExpression::Evaluate] Execution completed abnormally =="); if (error_stream.GetString().empty()) error.SetErrorString ("expression failed to execute, unknown error"); else error.SetErrorString (error_stream.GetString().c_str()); } else { if (expr_result) { result_valobj_sp = expr_result->GetValueObject(); if (log) log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with result %s ==", result_valobj_sp->GetValueAsCString()); } else { if (log) log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with no result =="); error.SetError(ClangUserExpression::kNoResult, lldb::eErrorTypeGeneric); } } } } if (result_valobj_sp.get() == NULL) result_valobj_sp = ValueObjectConstResult::Create (NULL, error); return execution_results; }
ObjCClassSyntheticChildrenFrontEnd (lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd(*valobj_sp.get()) { }
lldb_private::formatters::swift::HashedContainerSyntheticFrontEnd::HashedContainerSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd(*valobj_sp.get()), m_buffer() { }
lldb::ExpressionResults UserExpression::Evaluate (ExecutionContext &exe_ctx, const EvaluateExpressionOptions& options, const char *expr_cstr, const char *expr_prefix, lldb::ValueObjectSP &result_valobj_sp, Error &error, uint32_t line_offset, std::string *fixed_expression, lldb::ModuleSP *jit_module_sp_ptr) { Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP)); lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy(); lldb::LanguageType language = options.GetLanguage(); const ResultType desired_type = options.DoesCoerceToId() ? UserExpression::eResultTypeId : UserExpression::eResultTypeAny; lldb::ExpressionResults execution_results = lldb::eExpressionSetupError; Target *target = exe_ctx.GetTargetPtr(); if (!target) { if (log) log->Printf("== [UserExpression::Evaluate] Passed a NULL target, can't run expressions."); return lldb::eExpressionSetupError; } Process *process = exe_ctx.GetProcessPtr(); if (process == NULL || process->GetState() != lldb::eStateStopped) { if (execution_policy == eExecutionPolicyAlways) { if (log) log->Printf("== [UserExpression::Evaluate] Expression may not run, but is not constant =="); error.SetErrorString ("expression needed to run but couldn't"); return execution_results; } } if (process == NULL || !process->CanJIT()) execution_policy = eExecutionPolicyNever; // We need to set the expression execution thread here, turns out parse can call functions in the process of // looking up symbols, which will escape the context set by exe_ctx passed to Execute. lldb::ThreadSP thread_sp = exe_ctx.GetThreadSP(); ThreadList::ExpressionExecutionThreadPusher execution_thread_pusher(thread_sp); const char *full_prefix = NULL; const char *option_prefix = options.GetPrefix(); std::string full_prefix_storage; if (expr_prefix && option_prefix) { full_prefix_storage.assign(expr_prefix); full_prefix_storage.append(option_prefix); if (!full_prefix_storage.empty()) full_prefix = full_prefix_storage.c_str(); } else if (expr_prefix) full_prefix = expr_prefix; else full_prefix = option_prefix; // If the language was not specified in the expression command, // set it to the language in the target's properties if // specified, else default to the langage for the frame. if (language == lldb::eLanguageTypeUnknown) { if (target->GetLanguage() != lldb::eLanguageTypeUnknown) language = target->GetLanguage(); else if (StackFrame *frame = exe_ctx.GetFramePtr()) language = frame->GetLanguage(); } lldb::UserExpressionSP user_expression_sp(target->GetUserExpressionForLanguage (expr_cstr, full_prefix, language, desired_type, options, error)); if (error.Fail()) { if (log) log->Printf ("== [UserExpression::Evaluate] Getting expression: %s ==", error.AsCString()); return lldb::eExpressionSetupError; } if (log) log->Printf("== [UserExpression::Evaluate] Parsing expression %s ==", expr_cstr); const bool keep_expression_in_memory = true; const bool generate_debug_info = options.GetGenerateDebugInfo(); if (options.InvokeCancelCallback (lldb::eExpressionEvaluationParse)) { error.SetErrorString ("expression interrupted by callback before parse"); result_valobj_sp = ValueObjectConstResult::Create(exe_ctx.GetBestExecutionContextScope(), error); return lldb::eExpressionInterrupted; } DiagnosticManager diagnostic_manager; bool parse_success = user_expression_sp->Parse(diagnostic_manager, exe_ctx, execution_policy, keep_expression_in_memory, generate_debug_info); // Calculate the fixed expression always, since we need it for errors. std::string tmp_fixed_expression; if (fixed_expression == nullptr) fixed_expression = &tmp_fixed_expression; const char *fixed_text = user_expression_sp->GetFixedText(); if (fixed_text != nullptr) fixed_expression->append(fixed_text); // If there is a fixed expression, try to parse it: if (!parse_success) { execution_results = lldb::eExpressionParseError; if (fixed_expression && !fixed_expression->empty() && options.GetAutoApplyFixIts()) { lldb::UserExpressionSP fixed_expression_sp(target->GetUserExpressionForLanguage (fixed_expression->c_str(), full_prefix, language, desired_type, options, error)); DiagnosticManager fixed_diagnostic_manager; parse_success = fixed_expression_sp->Parse(fixed_diagnostic_manager, exe_ctx, execution_policy, keep_expression_in_memory, generate_debug_info); if (parse_success) { diagnostic_manager.Clear(); user_expression_sp = fixed_expression_sp; } else { // If the fixed expression failed to parse, don't tell the user about, that won't help. fixed_expression->clear(); } } if (!parse_success) { if (!fixed_expression->empty() && target->GetEnableNotifyAboutFixIts()) { error.SetExpressionErrorWithFormat(execution_results, "expression failed to parse, fixed expression suggested:\n %s", fixed_expression->c_str()); } else { if (!diagnostic_manager.Diagnostics().size()) error.SetExpressionError(execution_results, "expression failed to parse, unknown error"); else error.SetExpressionError(execution_results, diagnostic_manager.GetString().c_str()); } } } if (parse_success) { // If a pointer to a lldb::ModuleSP was passed in, return the JIT'ed module if one was created if (jit_module_sp_ptr) *jit_module_sp_ptr = user_expression_sp->GetJITModule(); lldb::ExpressionVariableSP expr_result; if (execution_policy == eExecutionPolicyNever && !user_expression_sp->CanInterpret()) { if (log) log->Printf("== [UserExpression::Evaluate] Expression may not run, but is not constant =="); if (!diagnostic_manager.Diagnostics().size()) error.SetExpressionError(lldb::eExpressionSetupError, "expression needed to run but couldn't"); } else if (execution_policy == eExecutionPolicyTopLevel) { error.SetError(UserExpression::kNoResult, lldb::eErrorTypeGeneric); return lldb::eExpressionCompleted; } else { if (options.InvokeCancelCallback (lldb::eExpressionEvaluationExecution)) { error.SetExpressionError (lldb::eExpressionInterrupted, "expression interrupted by callback before execution"); result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error); return lldb::eExpressionInterrupted; } diagnostic_manager.Clear(); if (log) log->Printf("== [UserExpression::Evaluate] Executing expression =="); execution_results = user_expression_sp->Execute(diagnostic_manager, exe_ctx, options, user_expression_sp, expr_result); if (execution_results != lldb::eExpressionCompleted) { if (log) log->Printf("== [UserExpression::Evaluate] Execution completed abnormally =="); if (!diagnostic_manager.Diagnostics().size()) error.SetExpressionError(execution_results, "expression failed to execute, unknown error"); else error.SetExpressionError(execution_results, diagnostic_manager.GetString().c_str()); } else { if (expr_result) { result_valobj_sp = expr_result->GetValueObject(); if (log) log->Printf("== [UserExpression::Evaluate] Execution completed normally with result %s ==", result_valobj_sp->GetValueAsCString()); } else { if (log) log->Printf("== [UserExpression::Evaluate] Execution completed normally with no result =="); error.SetError(UserExpression::kNoResult, lldb::eErrorTypeGeneric); } } } } if (options.InvokeCancelCallback(lldb::eExpressionEvaluationComplete)) { error.SetExpressionError (lldb::eExpressionInterrupted, "expression interrupted by callback after complete"); return lldb::eExpressionInterrupted; } if (result_valobj_sp.get() == NULL) { result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error); } return execution_results; }