1 //===-- 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 <map> 17 #include <string> 18 19 #include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h" 20 #include "lldb/Core/ConstString.h" 21 #include "lldb/Core/Log.h" 22 #include "lldb/Core/Module.h" 23 #include "lldb/Core/StreamFile.h" 24 #include "lldb/Core/StreamString.h" 25 #include "lldb/Core/ValueObjectConstResult.h" 26 #include "lldb/Expression/DiagnosticManager.h" 27 #include "lldb/Expression/ExpressionSourceCode.h" 28 #include "lldb/Expression/IRExecutionUnit.h" 29 #include "lldb/Expression/IRInterpreter.h" 30 #include "lldb/Expression/Materializer.h" 31 #include "lldb/Expression/UserExpression.h" 32 #include "lldb/Host/HostInfo.h" 33 #include "lldb/Symbol/Block.h" 34 #include "lldb/Symbol/Function.h" 35 #include "lldb/Symbol/ObjectFile.h" 36 #include "lldb/Symbol/SymbolVendor.h" 37 #include "lldb/Symbol/Type.h" 38 #include "lldb/Symbol/TypeSystem.h" 39 #include "lldb/Symbol/VariableList.h" 40 #include "lldb/Target/ExecutionContext.h" 41 #include "lldb/Target/Process.h" 42 #include "lldb/Target/StackFrame.h" 43 #include "lldb/Target/Target.h" 44 #include "lldb/Target/ThreadPlan.h" 45 #include "lldb/Target/ThreadPlanCallUserExpression.h" 46 47 using namespace lldb_private; 48 49 UserExpression::UserExpression(ExecutionContextScope &exe_scope, 50 const char *expr, const char *expr_prefix, 51 lldb::LanguageType language, 52 ResultType desired_type, 53 const EvaluateExpressionOptions &options) 54 : Expression(exe_scope), m_expr_text(expr), 55 m_expr_prefix(expr_prefix ? expr_prefix : ""), m_language(language), 56 m_desired_type(desired_type), m_options(options) {} 57 58 UserExpression::~UserExpression() {} 59 60 void UserExpression::InstallContext(ExecutionContext &exe_ctx) { 61 m_jit_process_wp = exe_ctx.GetProcessSP(); 62 63 lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP(); 64 65 if (frame_sp) 66 m_address = frame_sp->GetFrameCodeAddress(); 67 } 68 69 bool UserExpression::LockAndCheckContext(ExecutionContext &exe_ctx, 70 lldb::TargetSP &target_sp, 71 lldb::ProcessSP &process_sp, 72 lldb::StackFrameSP &frame_sp) { 73 lldb::ProcessSP expected_process_sp = m_jit_process_wp.lock(); 74 process_sp = exe_ctx.GetProcessSP(); 75 76 if (process_sp != expected_process_sp) 77 return false; 78 79 process_sp = exe_ctx.GetProcessSP(); 80 target_sp = exe_ctx.GetTargetSP(); 81 frame_sp = exe_ctx.GetFrameSP(); 82 83 if (m_address.IsValid()) { 84 if (!frame_sp) 85 return false; 86 else 87 return (0 == Address::CompareLoadAddress(m_address, 88 frame_sp->GetFrameCodeAddress(), 89 target_sp.get())); 90 } 91 92 return true; 93 } 94 95 bool UserExpression::MatchesContext(ExecutionContext &exe_ctx) { 96 lldb::TargetSP target_sp; 97 lldb::ProcessSP process_sp; 98 lldb::StackFrameSP frame_sp; 99 100 return LockAndCheckContext(exe_ctx, target_sp, process_sp, frame_sp); 101 } 102 103 lldb::addr_t UserExpression::GetObjectPointer(lldb::StackFrameSP frame_sp, 104 ConstString &object_name, 105 Error &err) { 106 err.Clear(); 107 108 if (!frame_sp) { 109 err.SetErrorStringWithFormat( 110 "Couldn't load '%s' because the context is incomplete", 111 object_name.AsCString()); 112 return LLDB_INVALID_ADDRESS; 113 } 114 115 lldb::VariableSP var_sp; 116 lldb::ValueObjectSP valobj_sp; 117 118 valobj_sp = frame_sp->GetValueForVariableExpressionPath( 119 object_name.AsCString(), lldb::eNoDynamicValues, 120 StackFrame::eExpressionPathOptionCheckPtrVsMember | 121 StackFrame::eExpressionPathOptionsNoFragileObjcIvar | 122 StackFrame::eExpressionPathOptionsNoSyntheticChildren | 123 StackFrame::eExpressionPathOptionsNoSyntheticArrayRange, 124 var_sp, err); 125 126 if (!err.Success() || !valobj_sp.get()) 127 return LLDB_INVALID_ADDRESS; 128 129 lldb::addr_t ret = valobj_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); 130 131 if (ret == LLDB_INVALID_ADDRESS) { 132 err.SetErrorStringWithFormat( 133 "Couldn't load '%s' because its value couldn't be evaluated", 134 object_name.AsCString()); 135 return LLDB_INVALID_ADDRESS; 136 } 137 138 return ret; 139 } 140 141 lldb::ExpressionResults UserExpression::Evaluate( 142 ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options, 143 const char *expr_cstr, const char *expr_prefix, 144 lldb::ValueObjectSP &result_valobj_sp, Error &error, uint32_t line_offset, 145 std::string *fixed_expression, lldb::ModuleSP *jit_module_sp_ptr) { 146 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS | 147 LIBLLDB_LOG_STEP)); 148 149 lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy(); 150 lldb::LanguageType language = options.GetLanguage(); 151 const ResultType desired_type = options.DoesCoerceToId() 152 ? UserExpression::eResultTypeId 153 : UserExpression::eResultTypeAny; 154 lldb::ExpressionResults execution_results = lldb::eExpressionSetupError; 155 156 Target *target = exe_ctx.GetTargetPtr(); 157 if (!target) { 158 if (log) 159 log->Printf("== [UserExpression::Evaluate] Passed a NULL target, can't " 160 "run expressions."); 161 return lldb::eExpressionSetupError; 162 } 163 164 Process *process = exe_ctx.GetProcessPtr(); 165 166 if (process == NULL || process->GetState() != lldb::eStateStopped) { 167 if (execution_policy == eExecutionPolicyAlways) { 168 if (log) 169 log->Printf("== [UserExpression::Evaluate] Expression may not run, but " 170 "is not constant =="); 171 172 error.SetErrorString("expression needed to run but couldn't"); 173 174 return execution_results; 175 } 176 } 177 178 if (process == NULL || !process->CanJIT()) 179 execution_policy = eExecutionPolicyNever; 180 181 // We need to set the expression execution thread here, turns out parse can 182 // call functions in the process of 183 // looking up symbols, which will escape the context set by exe_ctx passed to 184 // Execute. 185 lldb::ThreadSP thread_sp = exe_ctx.GetThreadSP(); 186 ThreadList::ExpressionExecutionThreadPusher execution_thread_pusher( 187 thread_sp); 188 189 const char *full_prefix = NULL; 190 const char *option_prefix = options.GetPrefix(); 191 std::string full_prefix_storage; 192 if (expr_prefix && option_prefix) { 193 full_prefix_storage.assign(expr_prefix); 194 full_prefix_storage.append(option_prefix); 195 if (!full_prefix_storage.empty()) 196 full_prefix = full_prefix_storage.c_str(); 197 } else if (expr_prefix) 198 full_prefix = expr_prefix; 199 else 200 full_prefix = option_prefix; 201 202 // If the language was not specified in the expression command, 203 // set it to the language in the target's properties if 204 // specified, else default to the langage for the frame. 205 if (language == lldb::eLanguageTypeUnknown) { 206 if (target->GetLanguage() != lldb::eLanguageTypeUnknown) 207 language = target->GetLanguage(); 208 else if (StackFrame *frame = exe_ctx.GetFramePtr()) 209 language = frame->GetLanguage(); 210 } 211 212 lldb::UserExpressionSP user_expression_sp( 213 target->GetUserExpressionForLanguage(expr_cstr, full_prefix, language, 214 desired_type, options, error)); 215 if (error.Fail()) { 216 if (log) 217 log->Printf("== [UserExpression::Evaluate] Getting expression: %s ==", 218 error.AsCString()); 219 return lldb::eExpressionSetupError; 220 } 221 222 if (log) 223 log->Printf("== [UserExpression::Evaluate] Parsing expression %s ==", 224 expr_cstr); 225 226 const bool keep_expression_in_memory = true; 227 const bool generate_debug_info = options.GetGenerateDebugInfo(); 228 229 if (options.InvokeCancelCallback(lldb::eExpressionEvaluationParse)) { 230 error.SetErrorString("expression interrupted by callback before parse"); 231 result_valobj_sp = ValueObjectConstResult::Create( 232 exe_ctx.GetBestExecutionContextScope(), error); 233 return lldb::eExpressionInterrupted; 234 } 235 236 DiagnosticManager diagnostic_manager; 237 238 bool parse_success = 239 user_expression_sp->Parse(diagnostic_manager, exe_ctx, execution_policy, 240 keep_expression_in_memory, generate_debug_info); 241 242 // Calculate the fixed expression always, since we need it for errors. 243 std::string tmp_fixed_expression; 244 if (fixed_expression == nullptr) 245 fixed_expression = &tmp_fixed_expression; 246 247 const char *fixed_text = user_expression_sp->GetFixedText(); 248 if (fixed_text != nullptr) 249 fixed_expression->append(fixed_text); 250 251 // If there is a fixed expression, try to parse it: 252 if (!parse_success) { 253 execution_results = lldb::eExpressionParseError; 254 if (fixed_expression && !fixed_expression->empty() && 255 options.GetAutoApplyFixIts()) { 256 lldb::UserExpressionSP fixed_expression_sp( 257 target->GetUserExpressionForLanguage(fixed_expression->c_str(), 258 full_prefix, language, 259 desired_type, options, error)); 260 DiagnosticManager fixed_diagnostic_manager; 261 parse_success = fixed_expression_sp->Parse( 262 fixed_diagnostic_manager, exe_ctx, execution_policy, 263 keep_expression_in_memory, generate_debug_info); 264 if (parse_success) { 265 diagnostic_manager.Clear(); 266 user_expression_sp = fixed_expression_sp; 267 } else { 268 // If the fixed expression failed to parse, don't tell the user about, 269 // that won't help. 270 fixed_expression->clear(); 271 } 272 } 273 274 if (!parse_success) { 275 if (!fixed_expression->empty() && target->GetEnableNotifyAboutFixIts()) { 276 error.SetExpressionErrorWithFormat( 277 execution_results, 278 "expression failed to parse, fixed expression suggested:\n %s", 279 fixed_expression->c_str()); 280 } else { 281 if (!diagnostic_manager.Diagnostics().size()) 282 error.SetExpressionError(execution_results, 283 "expression failed to parse, unknown error"); 284 else 285 error.SetExpressionError(execution_results, 286 diagnostic_manager.GetString().c_str()); 287 } 288 } 289 } 290 291 if (parse_success) { 292 // If a pointer to a lldb::ModuleSP was passed in, return the JIT'ed module 293 // if one was created 294 if (jit_module_sp_ptr) 295 *jit_module_sp_ptr = user_expression_sp->GetJITModule(); 296 297 lldb::ExpressionVariableSP expr_result; 298 299 if (execution_policy == eExecutionPolicyNever && 300 !user_expression_sp->CanInterpret()) { 301 if (log) 302 log->Printf("== [UserExpression::Evaluate] Expression may not run, but " 303 "is not constant =="); 304 305 if (!diagnostic_manager.Diagnostics().size()) 306 error.SetExpressionError(lldb::eExpressionSetupError, 307 "expression needed to run but couldn't"); 308 } else if (execution_policy == eExecutionPolicyTopLevel) { 309 error.SetError(UserExpression::kNoResult, lldb::eErrorTypeGeneric); 310 return lldb::eExpressionCompleted; 311 } else { 312 if (options.InvokeCancelCallback(lldb::eExpressionEvaluationExecution)) { 313 error.SetExpressionError( 314 lldb::eExpressionInterrupted, 315 "expression interrupted by callback before execution"); 316 result_valobj_sp = ValueObjectConstResult::Create( 317 exe_ctx.GetBestExecutionContextScope(), error); 318 return lldb::eExpressionInterrupted; 319 } 320 321 diagnostic_manager.Clear(); 322 323 if (log) 324 log->Printf("== [UserExpression::Evaluate] Executing expression =="); 325 326 execution_results = 327 user_expression_sp->Execute(diagnostic_manager, exe_ctx, options, 328 user_expression_sp, expr_result); 329 330 if (execution_results != lldb::eExpressionCompleted) { 331 if (log) 332 log->Printf("== [UserExpression::Evaluate] Execution completed " 333 "abnormally =="); 334 335 if (!diagnostic_manager.Diagnostics().size()) 336 error.SetExpressionError( 337 execution_results, "expression failed to execute, unknown error"); 338 else 339 error.SetExpressionError(execution_results, 340 diagnostic_manager.GetString().c_str()); 341 } else { 342 if (expr_result) { 343 result_valobj_sp = expr_result->GetValueObject(); 344 345 if (log) 346 log->Printf("== [UserExpression::Evaluate] Execution completed " 347 "normally with result %s ==", 348 result_valobj_sp->GetValueAsCString()); 349 } else { 350 if (log) 351 log->Printf("== [UserExpression::Evaluate] Execution completed " 352 "normally with no result =="); 353 354 error.SetError(UserExpression::kNoResult, lldb::eErrorTypeGeneric); 355 } 356 } 357 } 358 } 359 360 if (options.InvokeCancelCallback(lldb::eExpressionEvaluationComplete)) { 361 error.SetExpressionError( 362 lldb::eExpressionInterrupted, 363 "expression interrupted by callback after complete"); 364 return lldb::eExpressionInterrupted; 365 } 366 367 if (result_valobj_sp.get() == NULL) { 368 result_valobj_sp = ValueObjectConstResult::Create( 369 exe_ctx.GetBestExecutionContextScope(), error); 370 } 371 372 return execution_results; 373 } 374 375 lldb::ExpressionResults 376 UserExpression::Execute(DiagnosticManager &diagnostic_manager, 377 ExecutionContext &exe_ctx, 378 const EvaluateExpressionOptions &options, 379 lldb::UserExpressionSP &shared_ptr_to_me, 380 lldb::ExpressionVariableSP &result_var) { 381 lldb::ExpressionResults expr_result = DoExecute( 382 diagnostic_manager, exe_ctx, options, shared_ptr_to_me, result_var); 383 Target *target = exe_ctx.GetTargetPtr(); 384 if (options.GetResultIsInternal() && result_var && target) { 385 target->GetPersistentExpressionStateForLanguage(m_language) 386 ->RemovePersistentVariable(result_var); 387 } 388 return expr_result; 389 } 390