ThreadPlanCallFunction.cpp revision 263367
1198892Srdivacky//===-- ThreadPlanCallFunction.cpp ------------------------------*- C++ -*-===// 2198892Srdivacky// 3198892Srdivacky// The LLVM Compiler Infrastructure 4198892Srdivacky// 5198892Srdivacky// This file is distributed under the University of Illinois Open Source 6198892Srdivacky// License. See LICENSE.TXT for details. 7198892Srdivacky// 8198892Srdivacky//===----------------------------------------------------------------------===// 9198892Srdivacky 10198892Srdivacky#include "lldb/Target/ThreadPlanCallFunction.h" 11263508Sdim 12198892Srdivacky// C Includes 13198892Srdivacky// C++ Includes 14198892Srdivacky// Other libraries and framework includes 15198892Srdivacky#include "llvm/Support/MachO.h" 16198892Srdivacky// Project includes 17198892Srdivacky#include "lldb/lldb-private-log.h" 18239462Sdim#include "lldb/Breakpoint/Breakpoint.h" 19239462Sdim#include "lldb/Breakpoint/BreakpointLocation.h" 20249423Sdim#include "lldb/Core/Address.h" 21249423Sdim#include "lldb/Core/Log.h" 22249423Sdim#include "lldb/Core/Module.h" 23239462Sdim#include "lldb/Core/Stream.h" 24239462Sdim#include "lldb/Symbol/ObjectFile.h" 25239462Sdim#include "lldb/Target/LanguageRuntime.h" 26239462Sdim#include "lldb/Target/Process.h" 27198892Srdivacky#include "lldb/Target/RegisterContext.h" 28198892Srdivacky#include "lldb/Target/StopInfo.h" 29198892Srdivacky#include "lldb/Target/Target.h" 30243830Sdim#include "lldb/Target/Thread.h" 31243830Sdim#include "lldb/Target/ThreadPlanRunToAddress.h" 32198892Srdivacky 33198892Srdivackyusing namespace lldb; 34198892Srdivackyusing namespace lldb_private; 35239462Sdim 36239462Sdim//---------------------------------------------------------------------- 37239462Sdim// ThreadPlanCallFunction: Plan to call a single function 38239462Sdim//---------------------------------------------------------------------- 39243830Sdimbool 40243830SdimThreadPlanCallFunction::ConstructorSetup (Thread &thread, 41239462Sdim ABI *& abi, 42239462Sdim lldb::addr_t &start_load_addr, 43239462Sdim lldb::addr_t &function_load_addr) 44243830Sdim{ 45243830Sdim SetIsMasterPlan (true); 46239462Sdim SetOkayToDiscard (false); 47239462Sdim SetPrivate (true); 48239462Sdim 49243830Sdim ProcessSP process_sp (thread.GetProcess()); 50243830Sdim if (!process_sp) 51239462Sdim return false; 52239462Sdim 53239462Sdim abi = process_sp->GetABI().get(); 54243830Sdim 55243830Sdim if (!abi) 56239462Sdim return false; 57239462Sdim 58239462Sdim Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP)); 59243830Sdim 60243830Sdim SetBreakpoints(); 61239462Sdim 62239462Sdim m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize(); 63239462Sdim // If we can't read memory at the point of the process where we are planning to put our function, we're 64243830Sdim // not going to get any further... 65243830Sdim Error error; 66239462Sdim process_sp->ReadUnsignedIntegerFromMemory(m_function_sp, 4, 0, error); 67263508Sdim if (!error.Success()) 68263508Sdim { 69263508Sdim m_constructor_errors.Printf ("Trying to put the stack in unreadable memory at: 0x%" PRIx64 ".", m_function_sp); 70263508Sdim if (log) 71239462Sdim log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); 72198892Srdivacky return false; 73198892Srdivacky } 74198892Srdivacky 75198892Srdivacky Module *exe_module = GetTarget().GetExecutableModulePointer(); 76198892Srdivacky 77198892Srdivacky if (exe_module == NULL) 78198892Srdivacky { 79243830Sdim m_constructor_errors.Printf ("Can't execute code without an executable module."); 80243830Sdim if (log) 81243830Sdim log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); 82243830Sdim return false; 83239462Sdim } 84198892Srdivacky else 85263508Sdim { 86198892Srdivacky ObjectFile *objectFile = exe_module->GetObjectFile(); 87198892Srdivacky if (!objectFile) 88263508Sdim { 89243830Sdim m_constructor_errors.Printf ("Could not find object file for module \"%s\".", 90198892Srdivacky exe_module->GetFileSpec().GetFilename().AsCString()); 91198892Srdivacky 92198953Srdivacky if (log) 93198953Srdivacky log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); 94198953Srdivacky return false; 95198953Srdivacky } 96243830Sdim 97198892Srdivacky m_start_addr = objectFile->GetEntryPointAddress(); 98198953Srdivacky if (!m_start_addr.IsValid()) 99198953Srdivacky { 100198953Srdivacky m_constructor_errors.Printf ("Could not find entry point address for executable module \"%s\".", 101198953Srdivacky exe_module->GetFileSpec().GetFilename().AsCString()); 102198953Srdivacky if (log) 103243830Sdim log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); 104198892Srdivacky return false; 105263508Sdim } 106198892Srdivacky } 107198892Srdivacky 108198892Srdivacky start_load_addr = m_start_addr.GetLoadAddress (&GetTarget()); 109198892Srdivacky 110263508Sdim // Checkpoint the thread state so we can restore it later. 111243830Sdim if (log && log->GetVerbose()) 112199481Srdivacky ReportRegisterState ("About to checkpoint thread before function call. Original register state was:"); 113239462Sdim 114239462Sdim if (!thread.CheckpointThreadState (m_stored_thread_state)) 115198892Srdivacky { 116239462Sdim m_constructor_errors.Printf ("Setting up ThreadPlanCallFunction, failed to checkpoint thread state."); 117239462Sdim if (log) 118239462Sdim log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); 119239462Sdim return false; 120239462Sdim } 121243830Sdim function_load_addr = m_function_addr.GetLoadAddress (&GetTarget()); 122243830Sdim 123243830Sdim return true; 124243830Sdim} 125239462Sdim 126239462SdimThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, 127239462Sdim const Address &function, 128239462Sdim const ClangASTType &return_type, 129198892Srdivacky llvm::ArrayRef<addr_t> args, 130198892Srdivacky const EvaluateExpressionOptions &options) : 131198892Srdivacky ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion), 132210299Sed m_valid (false), 133243830Sdim m_stop_other_threads (options.GetStopOthers()), 134263508Sdim m_unwind_on_error (options.DoesUnwindOnError()), 135243830Sdim m_ignore_breakpoints (options.DoesIgnoreBreakpoints()), 136243830Sdim m_debug_execution (options.GetDebug()), 137218893Sdim m_trap_exceptions (options.GetTrapExceptions()), 138198892Srdivacky m_function_addr (function), 139263508Sdim m_function_sp (0), 140239462Sdim m_return_type (return_type), 141239462Sdim m_takedown_done (false), 142239462Sdim m_should_clear_objc_exception_bp(false), 143239462Sdim m_should_clear_cxx_exception_bp (false), 144239462Sdim m_stop_address (LLDB_INVALID_ADDRESS) 145249423Sdim{ 146249423Sdim lldb::addr_t start_load_addr; 147249423Sdim ABI *abi; 148239462Sdim lldb::addr_t function_load_addr; 149239462Sdim if (!ConstructorSetup (thread, abi, start_load_addr, function_load_addr)) 150263508Sdim return; 151243830Sdim 152239462Sdim if (!abi->PrepareTrivialCall(thread, 153239462Sdim m_function_sp, 154239462Sdim function_load_addr, 155239462Sdim start_load_addr, 156239462Sdim args)) 157263508Sdim return; 158239462Sdim 159239462Sdim ReportRegisterState ("Function call was set up. Register state was:"); 160239462Sdim 161239462Sdim m_valid = true; 162263508Sdim} 163243830Sdim 164239462SdimThreadPlanCallFunction::~ThreadPlanCallFunction () 165239462Sdim{ 166239462Sdim DoTakedown(PlanSucceeded()); 167251662Sdim} 168239462Sdim 169239462Sdimvoid 170239462SdimThreadPlanCallFunction::ReportRegisterState (const char *message) 171239462Sdim{ 172239462Sdim Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP | LIBLLDB_LOG_VERBOSE)); 173239462Sdim if (log) 174239462Sdim { 175239462Sdim StreamString strm; 176263508Sdim RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); 177243830Sdim 178239462Sdim log->PutCString(message); 179239462Sdim 180239462Sdim RegisterValue reg_value; 181239462Sdim 182239462Sdim for (uint32_t reg_idx = 0, num_registers = reg_ctx->GetRegisterCount(); 183239462Sdim reg_idx < num_registers; 184239462Sdim ++reg_idx) 185239462Sdim { 186239462Sdim const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_idx); 187239462Sdim if (reg_ctx->ReadRegister(reg_info, reg_value)) 188239462Sdim { 189239462Sdim reg_value.Dump(&strm, reg_info, true, false, eFormatDefault); 190239462Sdim strm.EOL(); 191239462Sdim } 192239462Sdim } 193239462Sdim log->PutCString(strm.GetData()); 194239462Sdim } 195239462Sdim} 196239462Sdim 197239462Sdimvoid 198239462SdimThreadPlanCallFunction::DoTakedown (bool success) 199239462Sdim{ 200249423Sdim Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP)); 201239462Sdim 202239462Sdim if (!m_valid) 203239462Sdim { 204239462Sdim //Don't call DoTakedown if we were never valid to begin with. 205239462Sdim if (log) 206239462Sdim log->Printf ("ThreadPlanCallFunction(%p): Log called on ThreadPlanCallFunction that was never valid.", this); 207239462Sdim return; 208239462Sdim } 209239462Sdim 210239462Sdim if (!m_takedown_done) 211239462Sdim { 212239462Sdim if (success) 213263508Sdim { 214239462Sdim ProcessSP process_sp (m_thread.GetProcess()); 215239462Sdim const ABI *abi = process_sp ? process_sp->GetABI().get() : NULL; 216239462Sdim if (abi && m_return_type.IsValid()) 217239462Sdim { 218239462Sdim const bool persistent = false; 219239462Sdim m_return_valobj_sp = abi->GetReturnValueObject (m_thread, m_return_type, persistent); 220239462Sdim } 221239462Sdim } 222239462Sdim if (log) 223263508Sdim log->Printf ("ThreadPlanCallFunction(%p): DoTakedown called for thread 0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n", this, m_thread.GetID(), m_valid, IsPlanComplete()); 224243830Sdim m_takedown_done = true; 225239462Sdim m_stop_address = m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC(); 226239462Sdim m_real_stop_info_sp = GetPrivateStopInfo (); 227239462Sdim if (!m_thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state)) 228239462Sdim { 229239462Sdim if (log) 230239462Sdim log->Printf("ThreadPlanCallFunction(%p): DoTakedown failed to restore register state", this); 231263508Sdim } 232239462Sdim SetPlanComplete(success); 233239462Sdim ClearBreakpoints(); 234239462Sdim if (log && log->GetVerbose()) 235239462Sdim ReportRegisterState ("Restoring thread state after function call. Restored register state:"); 236239462Sdim 237239462Sdim } 238239462Sdim else 239263508Sdim { 240263508Sdim if (log) 241239462Sdim log->Printf ("ThreadPlanCallFunction(%p): DoTakedown called as no-op for thread 0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n", this, m_thread.GetID(), m_valid, IsPlanComplete()); 242239462Sdim } 243239462Sdim} 244239462Sdim 245239462Sdimvoid 246239462SdimThreadPlanCallFunction::WillPop () 247239462Sdim{ 248239462Sdim DoTakedown(PlanSucceeded()); 249239462Sdim} 250239462Sdim 251239462Sdimvoid 252239462SdimThreadPlanCallFunction::GetDescription (Stream *s, DescriptionLevel level) 253239462Sdim{ 254239462Sdim if (level == eDescriptionLevelBrief) 255239462Sdim { 256239462Sdim s->Printf("Function call thread plan"); 257239462Sdim } 258239462Sdim else 259239462Sdim { 260239462Sdim TargetSP target_sp (m_thread.CalculateTarget()); 261239462Sdim s->Printf("Thread plan to call 0x%" PRIx64, m_function_addr.GetLoadAddress(target_sp.get())); 262239462Sdim } 263239462Sdim} 264239462Sdim 265239462Sdimbool 266239462SdimThreadPlanCallFunction::ValidatePlan (Stream *error) 267239462Sdim{ 268239462Sdim if (!m_valid) 269239462Sdim { 270239462Sdim if (error) 271198892Srdivacky { 272198892Srdivacky if (m_constructor_errors.GetSize() > 0) 273198892Srdivacky error->PutCString (m_constructor_errors.GetData()); 274 else 275 error->PutCString ("Unknown error"); 276 } 277 return false; 278 } 279 280 return true; 281} 282 283 284Vote 285ThreadPlanCallFunction::ShouldReportStop(Event *event_ptr) 286{ 287 if (m_takedown_done || IsPlanComplete()) 288 return eVoteYes; 289 else 290 return ThreadPlan::ShouldReportStop(event_ptr); 291} 292 293bool 294ThreadPlanCallFunction::DoPlanExplainsStop (Event *event_ptr) 295{ 296 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP|LIBLLDB_LOG_PROCESS)); 297 m_real_stop_info_sp = GetPrivateStopInfo (); 298 299 // If our subplan knows why we stopped, even if it's done (which would forward the question to us) 300 // we answer yes. 301 if (m_subplan_sp.get() != NULL && m_subplan_sp->PlanExplainsStop(event_ptr)) 302 { 303 SetPlanComplete(); 304 return true; 305 } 306 307 // Check if the breakpoint is one of ours. 308 309 StopReason stop_reason; 310 if (!m_real_stop_info_sp) 311 stop_reason = eStopReasonNone; 312 else 313 stop_reason = m_real_stop_info_sp->GetStopReason(); 314 if (log) 315 log->Printf ("ThreadPlanCallFunction::PlanExplainsStop: Got stop reason - %s.", Thread::StopReasonAsCString(stop_reason)); 316 317 if (stop_reason == eStopReasonBreakpoint && BreakpointsExplainStop()) 318 return true; 319 320 // We control breakpoints separately from other "stop reasons." So first, 321 // check the case where we stopped for an internal breakpoint, in that case, continue on. 322 // If it is not an internal breakpoint, consult m_ignore_breakpoints. 323 324 325 if (stop_reason == eStopReasonBreakpoint) 326 { 327 ProcessSP process_sp (m_thread.CalculateProcess()); 328 uint64_t break_site_id = m_real_stop_info_sp->GetValue(); 329 BreakpointSiteSP bp_site_sp; 330 if (process_sp) 331 bp_site_sp = process_sp->GetBreakpointSiteList().FindByID(break_site_id); 332 if (bp_site_sp) 333 { 334 uint32_t num_owners = bp_site_sp->GetNumberOfOwners(); 335 bool is_internal = true; 336 for (uint32_t i = 0; i < num_owners; i++) 337 { 338 Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint(); 339 if (log) 340 log->Printf ("ThreadPlanCallFunction::PlanExplainsStop: hit breakpoint %d while calling function", bp.GetID()); 341 342 if (!bp.IsInternal()) 343 { 344 is_internal = false; 345 break; 346 } 347 } 348 if (is_internal) 349 { 350 if (log) 351 log->Printf ("ThreadPlanCallFunction::PlanExplainsStop hit an internal breakpoint, not stopping."); 352 return false; 353 } 354 } 355 356 if (m_ignore_breakpoints) 357 { 358 if (log) 359 log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are ignoring breakpoints, overriding breakpoint stop info ShouldStop, returning true"); 360 m_real_stop_info_sp->OverrideShouldStop(false); 361 return true; 362 } 363 else 364 { 365 if (log) 366 log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are not ignoring breakpoints, overriding breakpoint stop info ShouldStop, returning true"); 367 m_real_stop_info_sp->OverrideShouldStop(true); 368 return false; 369 } 370 } 371 else if (!m_unwind_on_error) 372 { 373 // If we don't want to discard this plan, than any stop we don't understand should be propagated up the stack. 374 return false; 375 } 376 else 377 { 378 // If the subplan is running, any crashes are attributable to us. 379 // If we want to discard the plan, then we say we explain the stop 380 // but if we are going to be discarded, let whoever is above us 381 // explain the stop. 382 // But don't discard the plan if the stop would restart itself (for instance if it is a 383 // signal that is set not to stop. Check that here first. We just say we explain the stop 384 // but aren't done and everything will continue on from there. 385 386 if (m_real_stop_info_sp->ShouldStopSynchronous(event_ptr)) 387 { 388 SetPlanComplete(false); 389 if (m_subplan_sp) 390 { 391 if (m_unwind_on_error) 392 return true; 393 else 394 return false; 395 } 396 else 397 return false; 398 } 399 else 400 return true; 401 } 402} 403 404bool 405ThreadPlanCallFunction::ShouldStop (Event *event_ptr) 406{ 407 // We do some computation in DoPlanExplainsStop that may or may not set the plan as complete. 408 // We need to do that here to make sure our state is correct. 409 DoPlanExplainsStop(event_ptr); 410 411 if (IsPlanComplete()) 412 { 413 ReportRegisterState ("Function completed. Register state was:"); 414 return true; 415 } 416 else 417 { 418 return false; 419 } 420} 421 422bool 423ThreadPlanCallFunction::StopOthers () 424{ 425 return m_stop_other_threads; 426} 427 428void 429ThreadPlanCallFunction::SetStopOthers (bool new_value) 430{ 431 if (m_subplan_sp) 432 { 433 ThreadPlanRunToAddress *address_plan = static_cast<ThreadPlanRunToAddress *>(m_subplan_sp.get()); 434 address_plan->SetStopOthers(new_value); 435 } 436 m_stop_other_threads = new_value; 437} 438 439StateType 440ThreadPlanCallFunction::GetPlanRunState () 441{ 442 return eStateRunning; 443} 444 445void 446ThreadPlanCallFunction::DidPush () 447{ 448//#define SINGLE_STEP_EXPRESSIONS 449 450 // Now set the thread state to "no reason" so we don't run with whatever signal was outstanding... 451 // Wait till the plan is pushed so we aren't changing the stop info till we're about to run. 452 453 GetThread().SetStopInfoToNothing(); 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 463bool 464ThreadPlanCallFunction::WillStop () 465{ 466 return true; 467} 468 469bool 470ThreadPlanCallFunction::MischiefManaged () 471{ 472 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 473 474 if (IsPlanComplete()) 475 { 476 if (log) 477 log->Printf("ThreadPlanCallFunction(%p): Completed call function plan.", this); 478 479 ThreadPlan::MischiefManaged (); 480 return true; 481 } 482 else 483 { 484 return false; 485 } 486} 487 488void 489ThreadPlanCallFunction::SetBreakpoints () 490{ 491 ProcessSP process_sp (m_thread.CalculateProcess()); 492 if (m_trap_exceptions && 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 { 499 m_should_clear_cxx_exception_bp = !m_cxx_language_runtime->ExceptionBreakpointsAreSet(); 500 m_cxx_language_runtime->SetExceptionBreakpoints(); 501 } 502 if (m_objc_language_runtime) 503 { 504 m_should_clear_objc_exception_bp = !m_objc_language_runtime->ExceptionBreakpointsAreSet(); 505 m_objc_language_runtime->SetExceptionBreakpoints(); 506 } 507 } 508} 509 510void 511ThreadPlanCallFunction::ClearBreakpoints () 512{ 513 if (m_trap_exceptions) 514 { 515 if (m_cxx_language_runtime && m_should_clear_cxx_exception_bp) 516 m_cxx_language_runtime->ClearExceptionBreakpoints(); 517 if (m_objc_language_runtime && m_should_clear_objc_exception_bp) 518 m_objc_language_runtime->ClearExceptionBreakpoints(); 519 } 520} 521 522bool 523ThreadPlanCallFunction::BreakpointsExplainStop() 524{ 525 StopInfoSP stop_info_sp = GetPrivateStopInfo (); 526 527 if (m_trap_exceptions) 528 { 529 if ((m_cxx_language_runtime && 530 m_cxx_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp)) 531 ||(m_objc_language_runtime && 532 m_objc_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))) 533 { 534 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP)); 535 if (log) 536 log->Printf ("ThreadPlanCallFunction::BreakpointsExplainStop - Hit an exception breakpoint, setting plan complete."); 537 538 SetPlanComplete(false); 539 540 // If the user has set the ObjC language breakpoint, it would normally get priority over our internal 541 // catcher breakpoint, but in this case we can't let that happen, so force the ShouldStop here. 542 stop_info_sp->OverrideShouldStop (true); 543 return true; 544 } 545 } 546 547 return false; 548} 549 550bool 551ThreadPlanCallFunction::RestoreThreadState() 552{ 553 return GetThread().RestoreThreadStateFromCheckpoint(m_stored_thread_state); 554} 555 556