1 //===-- ThreadPlanCallFunction.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 "lldb/Target/ThreadPlanCallFunction.h" 11 12 // C Includes 13 // C++ Includes 14 // Other libraries and framework includes 15 #include "llvm/Support/MachO.h" 16 // Project includes 17 #include "lldb/lldb-private-log.h" 18 #include "lldb/Breakpoint/Breakpoint.h" 19 #include "lldb/Breakpoint/BreakpointLocation.h" 20 #include "lldb/Core/Address.h" 21 #include "lldb/Core/Log.h" 22 #include "lldb/Core/Stream.h" 23 #include "lldb/Target/LanguageRuntime.h" 24 #include "lldb/Target/Process.h" 25 #include "lldb/Target/RegisterContext.h" 26 #include "lldb/Target/StopInfo.h" 27 #include "lldb/Target/Target.h" 28 #include "lldb/Target/Thread.h" 29 #include "lldb/Target/ThreadPlanRunToAddress.h" 30 31 using namespace lldb; 32 using namespace lldb_private; 33 34 //---------------------------------------------------------------------- 35 // ThreadPlanCallFunction: Plan to call a single function 36 //---------------------------------------------------------------------- 37 38 ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, 39 Address &function, 40 const ClangASTType &return_type, 41 addr_t arg, 42 bool stop_other_threads, 43 bool discard_on_error, 44 addr_t *this_arg, 45 addr_t *cmd_arg) : 46 ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion), 47 m_valid (false), 48 m_stop_other_threads (stop_other_threads), 49 m_function_addr (function), 50 m_function_sp (NULL), 51 m_return_type (return_type), 52 m_takedown_done (false), 53 m_stop_address (LLDB_INVALID_ADDRESS) 54 { 55 SetOkayToDiscard (discard_on_error); 56 57 ProcessSP process_sp (thread.GetProcess()); 58 if (!process_sp) 59 return; 60 61 const ABI *abi = process_sp->GetABI().get(); 62 63 if (!abi) 64 return; 65 66 TargetSP target_sp (thread.CalculateTarget()); 67 68 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 69 70 SetBreakpoints(); 71 72 m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize(); 73 74 Module *exe_module = target_sp->GetExecutableModulePointer(); 75 76 if (exe_module == NULL) 77 { 78 if (log) 79 log->Printf ("Can't execute code without an executable module."); 80 return; 81 } 82 else 83 { 84 ObjectFile *objectFile = exe_module->GetObjectFile(); 85 if (!objectFile) 86 { 87 if (log) 88 log->Printf ("Could not find object file for module \"%s\".", 89 exe_module->GetFileSpec().GetFilename().AsCString()); 90 return; 91 } 92 m_start_addr = objectFile->GetEntryPointAddress(); 93 if (!m_start_addr.IsValid()) 94 { 95 if (log) 96 log->Printf ("Could not find entry point address for executable module \"%s\".", 97 exe_module->GetFileSpec().GetFilename().AsCString()); 98 return; 99 } 100 } 101 102 addr_t start_load_addr = m_start_addr.GetLoadAddress (target_sp.get()); 103 104 // Checkpoint the thread state so we can restore it later. 105 if (log && log->GetVerbose()) 106 ReportRegisterState ("About to checkpoint thread before function call. Original register state was:"); 107 108 if (!thread.CheckpointThreadState (m_stored_thread_state)) 109 { 110 if (log) 111 log->Printf ("Setting up ThreadPlanCallFunction, failed to checkpoint thread state."); 112 return; 113 } 114 // Now set the thread state to "no reason" so we don't run with whatever signal was outstanding... 115 thread.SetStopInfoToNothing(); 116 117 addr_t FunctionLoadAddr = m_function_addr.GetLoadAddress (target_sp.get()); 118 119 if (this_arg && cmd_arg) 120 { 121 if (!abi->PrepareTrivialCall (thread, 122 m_function_sp, 123 FunctionLoadAddr, 124 start_load_addr, 125 this_arg, 126 cmd_arg, 127 &arg)) 128 return; 129 } 130 else if (this_arg) 131 { 132 if (!abi->PrepareTrivialCall (thread, 133 m_function_sp, 134 FunctionLoadAddr, 135 start_load_addr, 136 this_arg, 137 &arg)) 138 return; 139 } 140 else 141 { 142 if (!abi->PrepareTrivialCall (thread, 143 m_function_sp, 144 FunctionLoadAddr, 145 start_load_addr, 146 &arg)) 147 return; 148 } 149 150 ReportRegisterState ("Function call was set up. Register state was:"); 151 152 m_valid = true; 153 } 154 155 156 ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, 157 Address &function, 158 const ClangASTType &return_type, 159 bool stop_other_threads, 160 bool discard_on_error, 161 addr_t *arg1_ptr, 162 addr_t *arg2_ptr, 163 addr_t *arg3_ptr, 164 addr_t *arg4_ptr, 165 addr_t *arg5_ptr, 166 addr_t *arg6_ptr) : 167 ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion), 168 m_valid (false), 169 m_stop_other_threads (stop_other_threads), 170 m_function_addr (function), 171 m_function_sp(NULL), 172 m_return_type (return_type), 173 m_takedown_done (false) 174 { 175 SetOkayToDiscard (discard_on_error); 176 177 ProcessSP process_sp (thread.GetProcess()); 178 if (!process_sp) 179 return; 180 181 const ABI *abi = process_sp->GetABI().get(); 182 183 if (!abi) 184 return; 185 186 TargetSP target_sp (thread.CalculateTarget()); 187 188 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 189 190 SetBreakpoints(); 191 192 m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize(); 193 194 Module *exe_module = target_sp->GetExecutableModulePointer(); 195 196 if (exe_module == NULL) 197 { 198 if (log) 199 log->Printf ("Can't execute code without an executable module."); 200 return; 201 } 202 else 203 { 204 ObjectFile *objectFile = exe_module->GetObjectFile(); 205 if (!objectFile) 206 { 207 if (log) 208 log->Printf ("Could not find object file for module \"%s\".", 209 exe_module->GetFileSpec().GetFilename().AsCString()); 210 return; 211 } 212 m_start_addr = objectFile->GetEntryPointAddress(); 213 if (!m_start_addr.IsValid()) 214 { 215 if (log) 216 log->Printf ("Could not find entry point address for executable module \"%s\".", 217 exe_module->GetFileSpec().GetFilename().AsCString()); 218 return; 219 } 220 } 221 222 addr_t start_load_addr = m_start_addr.GetLoadAddress(target_sp.get()); 223 224 // Checkpoint the thread state so we can restore it later. 225 if (log && log->GetVerbose()) 226 ReportRegisterState ("About to checkpoint thread before function call. Original register state was:"); 227 228 if (!thread.CheckpointThreadState (m_stored_thread_state)) 229 { 230 if (log) 231 log->Printf ("Setting up ThreadPlanCallFunction, failed to checkpoint thread state."); 232 return; 233 } 234 // Now set the thread state to "no reason" so we don't run with whatever signal was outstanding... 235 thread.SetStopInfoToNothing(); 236 237 addr_t FunctionLoadAddr = m_function_addr.GetLoadAddress(target_sp.get()); 238 239 if (!abi->PrepareTrivialCall (thread, 240 m_function_sp, 241 FunctionLoadAddr, 242 start_load_addr, 243 arg1_ptr, 244 arg2_ptr, 245 arg3_ptr, 246 arg4_ptr, 247 arg5_ptr, 248 arg6_ptr)) 249 { 250 return; 251 } 252 253 ReportRegisterState ("Function call was set up. Register state was:"); 254 255 m_valid = true; 256 } 257 258 ThreadPlanCallFunction::~ThreadPlanCallFunction () 259 { 260 } 261 262 void 263 ThreadPlanCallFunction::ReportRegisterState (const char *message) 264 { 265 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP | LIBLLDB_LOG_VERBOSE)); 266 if (log) 267 { 268 StreamString strm; 269 RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); 270 271 log->PutCString(message); 272 273 RegisterValue reg_value; 274 275 for (uint32_t reg_idx = 0, num_registers = reg_ctx->GetRegisterCount(); 276 reg_idx < num_registers; 277 ++reg_idx) 278 { 279 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_idx); 280 if (reg_ctx->ReadRegister(reg_info, reg_value)) 281 { 282 reg_value.Dump(&strm, reg_info, true, false, eFormatDefault); 283 strm.EOL(); 284 } 285 } 286 log->PutCString(strm.GetData()); 287 } 288 } 289 290 void 291 ThreadPlanCallFunction::DoTakedown () 292 { 293 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 294 if (!m_takedown_done) 295 { 296 ProcessSP process_sp (m_thread.GetProcess()); 297 const ABI *abi = process_sp ? process_sp->GetABI().get() : NULL; 298 if (abi && m_return_type.IsValid()) 299 { 300 m_return_valobj_sp = abi->GetReturnValueObject (m_thread, m_return_type); 301 } 302 303 if (log) 304 log->Printf ("DoTakedown called for thread 0x%4.4llx, m_valid: %d complete: %d.\n", m_thread.GetID(), m_valid, IsPlanComplete()); 305 m_takedown_done = true; 306 m_stop_address = m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC(); 307 m_real_stop_info_sp = GetPrivateStopReason(); 308 m_thread.RestoreThreadStateFromCheckpoint(m_stored_thread_state); 309 SetPlanComplete(); 310 ClearBreakpoints(); 311 if (log && log->GetVerbose()) 312 ReportRegisterState ("Restoring thread state after function call. Restored register state:"); 313 314 } 315 else 316 { 317 if (log) 318 log->Printf ("DoTakedown called as no-op for thread 0x%4.4llx, m_valid: %d complete: %d.\n", m_thread.GetID(), m_valid, IsPlanComplete()); 319 } 320 } 321 322 void 323 ThreadPlanCallFunction::WillPop () 324 { 325 DoTakedown(); 326 } 327 328 void 329 ThreadPlanCallFunction::GetDescription (Stream *s, DescriptionLevel level) 330 { 331 if (level == eDescriptionLevelBrief) 332 { 333 s->Printf("Function call thread plan"); 334 } 335 else 336 { 337 TargetSP target_sp (m_thread.CalculateTarget()); 338 s->Printf("Thread plan to call 0x%llx", m_function_addr.GetLoadAddress(target_sp.get())); 339 } 340 } 341 342 bool 343 ThreadPlanCallFunction::ValidatePlan (Stream *error) 344 { 345 if (!m_valid) 346 return false; 347 348 return true; 349 } 350 351 bool 352 ThreadPlanCallFunction::PlanExplainsStop () 353 { 354 m_real_stop_info_sp = GetPrivateStopReason(); 355 356 // If our subplan knows why we stopped, even if it's done (which would forward the question to us) 357 // we answer yes. 358 if (m_subplan_sp.get() != NULL && m_subplan_sp->PlanExplainsStop()) 359 return true; 360 361 // Check if the breakpoint is one of ours. 362 363 if (BreakpointsExplainStop()) 364 return true; 365 366 // If we don't want to discard this plan, than any stop we don't understand should be propagated up the stack. 367 if (!OkayToDiscard()) 368 return false; 369 370 // Otherwise, check the case where we stopped for an internal breakpoint, in that case, continue on. 371 // If it is not an internal breakpoint, consult OkayToDiscard. 372 373 if (m_real_stop_info_sp && m_real_stop_info_sp->GetStopReason() == eStopReasonBreakpoint) 374 { 375 ProcessSP process_sp (m_thread.CalculateProcess()); 376 uint64_t break_site_id = m_real_stop_info_sp->GetValue(); 377 BreakpointSiteSP bp_site_sp; 378 if (process_sp) 379 bp_site_sp = process_sp->GetBreakpointSiteList().FindByID(break_site_id); 380 if (bp_site_sp) 381 { 382 uint32_t num_owners = bp_site_sp->GetNumberOfOwners(); 383 bool is_internal = true; 384 for (uint32_t i = 0; i < num_owners; i++) 385 { 386 Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint(); 387 388 if (!bp.IsInternal()) 389 { 390 is_internal = false; 391 break; 392 } 393 } 394 if (is_internal) 395 return false; 396 } 397 398 return OkayToDiscard(); 399 } 400 else 401 { 402 // If the subplan is running, any crashes are attributable to us. 403 // If we want to discard the plan, then we say we explain the stop 404 // but if we are going to be discarded, let whoever is above us 405 // explain the stop. 406 return ((m_subplan_sp.get() != NULL) && !OkayToDiscard()); 407 } 408 } 409 410 bool 411 ThreadPlanCallFunction::ShouldStop (Event *event_ptr) 412 { 413 if (PlanExplainsStop()) 414 { 415 ReportRegisterState ("Function completed. Register state was:"); 416 417 DoTakedown(); 418 419 return true; 420 } 421 else 422 { 423 return false; 424 } 425 } 426 427 bool 428 ThreadPlanCallFunction::StopOthers () 429 { 430 return m_stop_other_threads; 431 } 432 433 void 434 ThreadPlanCallFunction::SetStopOthers (bool new_value) 435 { 436 if (m_subplan_sp) 437 { 438 ThreadPlanRunToAddress *address_plan = static_cast<ThreadPlanRunToAddress *>(m_subplan_sp.get()); 439 address_plan->SetStopOthers(new_value); 440 } 441 m_stop_other_threads = new_value; 442 } 443 444 StateType 445 ThreadPlanCallFunction::GetPlanRunState () 446 { 447 return eStateRunning; 448 } 449 450 void 451 ThreadPlanCallFunction::DidPush () 452 { 453 //#define SINGLE_STEP_EXPRESSIONS 454 455 #ifndef SINGLE_STEP_EXPRESSIONS 456 m_subplan_sp.reset(new ThreadPlanRunToAddress(m_thread, m_start_addr, m_stop_other_threads)); 457 458 m_thread.QueueThreadPlan(m_subplan_sp, false); 459 m_subplan_sp->SetPrivate (true); 460 #endif 461 } 462 463 bool 464 ThreadPlanCallFunction::WillStop () 465 { 466 return true; 467 } 468 469 bool 470 ThreadPlanCallFunction::MischiefManaged () 471 { 472 if (IsPlanComplete()) 473 { 474 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 475 476 if (log) 477 log->Printf("Completed call function plan."); 478 479 ThreadPlan::MischiefManaged (); 480 return true; 481 } 482 else 483 { 484 return false; 485 } 486 } 487 488 void 489 ThreadPlanCallFunction::SetBreakpoints () 490 { 491 ProcessSP process_sp (m_thread.CalculateProcess()); 492 if (process_sp) 493 { 494 m_cxx_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeC_plus_plus); 495 m_objc_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeObjC); 496 497 if (m_cxx_language_runtime) 498 m_cxx_language_runtime->SetExceptionBreakpoints(); 499 if (m_objc_language_runtime) 500 m_objc_language_runtime->SetExceptionBreakpoints(); 501 } 502 } 503 504 void 505 ThreadPlanCallFunction::ClearBreakpoints () 506 { 507 if (m_cxx_language_runtime) 508 m_cxx_language_runtime->ClearExceptionBreakpoints(); 509 if (m_objc_language_runtime) 510 m_objc_language_runtime->ClearExceptionBreakpoints(); 511 } 512 513 bool 514 ThreadPlanCallFunction::BreakpointsExplainStop() 515 { 516 StopInfoSP stop_info_sp = GetPrivateStopReason(); 517 518 if (m_cxx_language_runtime && 519 m_cxx_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp)) 520 return true; 521 522 if (m_objc_language_runtime && 523 m_objc_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp)) 524 return true; 525 526 return false; 527 } 528