130fdc8d8SChris Lattner //===-- ThreadPlanCallFunction.cpp ------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 1030fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanCallFunction.h" 1130fdc8d8SChris Lattner 1230fdc8d8SChris Lattner // C Includes 1330fdc8d8SChris Lattner // C++ Includes 1430fdc8d8SChris Lattner // Other libraries and framework includes 156db73ca5SSean Callanan #include "llvm/Support/MachO.h" 1630fdc8d8SChris Lattner // Project includes 1730fdc8d8SChris Lattner #include "lldb/lldb-private-log.h" 1840d871faSJim Ingham #include "lldb/Breakpoint/Breakpoint.h" 1940d871faSJim Ingham #include "lldb/Breakpoint/BreakpointLocation.h" 2030fdc8d8SChris Lattner #include "lldb/Core/Address.h" 2130fdc8d8SChris Lattner #include "lldb/Core/Log.h" 221f746071SGreg Clayton #include "lldb/Core/Module.h" 2330fdc8d8SChris Lattner #include "lldb/Core/Stream.h" 241f746071SGreg Clayton #include "lldb/Symbol/ObjectFile.h" 25f211510fSSean Callanan #include "lldb/Target/LanguageRuntime.h" 2630fdc8d8SChris Lattner #include "lldb/Target/Process.h" 2730fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h" 2840d871faSJim Ingham #include "lldb/Target/StopInfo.h" 2930fdc8d8SChris Lattner #include "lldb/Target/Target.h" 3030fdc8d8SChris Lattner #include "lldb/Target/Thread.h" 3130fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanRunToAddress.h" 3230fdc8d8SChris Lattner 3330fdc8d8SChris Lattner using namespace lldb; 3430fdc8d8SChris Lattner using namespace lldb_private; 3530fdc8d8SChris Lattner 3630fdc8d8SChris Lattner //---------------------------------------------------------------------- 3730fdc8d8SChris Lattner // ThreadPlanCallFunction: Plan to call a single function 3830fdc8d8SChris Lattner //---------------------------------------------------------------------- 390092c8ebSJim Ingham bool 400092c8ebSJim Ingham ThreadPlanCallFunction::ConstructorSetup (Thread &thread, 410092c8ebSJim Ingham ABI *& abi, 420092c8ebSJim Ingham lldb::addr_t &start_load_addr, 430092c8ebSJim Ingham lldb::addr_t &function_load_addr) 440092c8ebSJim Ingham { 450092c8ebSJim Ingham SetIsMasterPlan (true); 46923886ceSJim Ingham SetOkayToDiscard (false); 47327c267aSAndrew Kaylor SetPrivate (true); 480092c8ebSJim Ingham 490092c8ebSJim Ingham ProcessSP process_sp (thread.GetProcess()); 500092c8ebSJim Ingham if (!process_sp) 510092c8ebSJim Ingham return false; 520092c8ebSJim Ingham 530092c8ebSJim Ingham abi = process_sp->GetABI().get(); 540092c8ebSJim Ingham 550092c8ebSJim Ingham if (!abi) 560092c8ebSJim Ingham return false; 570092c8ebSJim Ingham 585160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP)); 590092c8ebSJim Ingham 600092c8ebSJim Ingham SetBreakpoints(); 610092c8ebSJim Ingham 620092c8ebSJim Ingham m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize(); 630092c8ebSJim Ingham // If we can't read memory at the point of the process where we are planning to put our function, we're 640092c8ebSJim Ingham // not going to get any further... 650092c8ebSJim Ingham Error error; 660092c8ebSJim Ingham process_sp->ReadUnsignedIntegerFromMemory(m_function_sp, 4, 0, error); 670092c8ebSJim Ingham if (!error.Success()) 680092c8ebSJim Ingham { 69ea06f3bfSJim Ingham m_constructor_errors.Printf ("Trying to put the stack in unreadable memory at: 0x%" PRIx64 ".", m_function_sp); 700092c8ebSJim Ingham if (log) 71ea06f3bfSJim Ingham log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); 720092c8ebSJim Ingham return false; 730092c8ebSJim Ingham } 740092c8ebSJim Ingham 756fbc48bcSJim Ingham Module *exe_module = GetTarget().GetExecutableModulePointer(); 760092c8ebSJim Ingham 770092c8ebSJim Ingham if (exe_module == NULL) 780092c8ebSJim Ingham { 79ea06f3bfSJim Ingham m_constructor_errors.Printf ("Can't execute code without an executable module."); 800092c8ebSJim Ingham if (log) 81ea06f3bfSJim Ingham log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); 820092c8ebSJim Ingham return false; 830092c8ebSJim Ingham } 840092c8ebSJim Ingham else 850092c8ebSJim Ingham { 860092c8ebSJim Ingham ObjectFile *objectFile = exe_module->GetObjectFile(); 870092c8ebSJim Ingham if (!objectFile) 880092c8ebSJim Ingham { 89ea06f3bfSJim Ingham m_constructor_errors.Printf ("Could not find object file for module \"%s\".", 90ea06f3bfSJim Ingham exe_module->GetFileSpec().GetFilename().AsCString()); 91ea06f3bfSJim Ingham 920092c8ebSJim Ingham if (log) 93ea06f3bfSJim Ingham log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); 940092c8ebSJim Ingham return false; 950092c8ebSJim Ingham } 96ea06f3bfSJim Ingham 970092c8ebSJim Ingham m_start_addr = objectFile->GetEntryPointAddress(); 980092c8ebSJim Ingham if (!m_start_addr.IsValid()) 990092c8ebSJim Ingham { 100ea06f3bfSJim Ingham m_constructor_errors.Printf ("Could not find entry point address for executable module \"%s\".", 101ea06f3bfSJim Ingham exe_module->GetFileSpec().GetFilename().AsCString()); 1020092c8ebSJim Ingham if (log) 103ea06f3bfSJim Ingham log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); 1040092c8ebSJim Ingham return false; 1050092c8ebSJim Ingham } 1060092c8ebSJim Ingham } 1070092c8ebSJim Ingham 1086fbc48bcSJim Ingham start_load_addr = m_start_addr.GetLoadAddress (&GetTarget()); 1090092c8ebSJim Ingham 1100092c8ebSJim Ingham // Checkpoint the thread state so we can restore it later. 1110092c8ebSJim Ingham if (log && log->GetVerbose()) 1120092c8ebSJim Ingham ReportRegisterState ("About to checkpoint thread before function call. Original register state was:"); 1130092c8ebSJim Ingham 1140092c8ebSJim Ingham if (!thread.CheckpointThreadState (m_stored_thread_state)) 1150092c8ebSJim Ingham { 116ea06f3bfSJim Ingham m_constructor_errors.Printf ("Setting up ThreadPlanCallFunction, failed to checkpoint thread state."); 1170092c8ebSJim Ingham if (log) 118ea06f3bfSJim Ingham log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); 1190092c8ebSJim Ingham return false; 1200092c8ebSJim Ingham } 1216fbc48bcSJim Ingham function_load_addr = m_function_addr.GetLoadAddress (&GetTarget()); 1220092c8ebSJim Ingham 1230092c8ebSJim Ingham return true; 1240092c8ebSJim Ingham } 12530fdc8d8SChris Lattner 12630fdc8d8SChris Lattner ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, 12700049b8bSMatt Kopec const Address &function, 128ef651600SJim Ingham const ClangASTType &return_type, 129*a464f3d4SSean Callanan llvm::ArrayRef<addr_t> args, 130*a464f3d4SSean Callanan const EvaluateExpressionOptions &options) : 131b01e742aSJim Ingham ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion), 13230fdc8d8SChris Lattner m_valid (false), 1336fbc48bcSJim Ingham m_stop_other_threads (options.GetStopOthers()), 1346fbc48bcSJim Ingham m_unwind_on_error (options.DoesUnwindOnError()), 1356fbc48bcSJim Ingham m_ignore_breakpoints (options.DoesIgnoreBreakpoints()), 1366fbc48bcSJim Ingham m_debug_execution (options.GetDebug()), 1376fbc48bcSJim Ingham m_trap_exceptions (options.GetTrapExceptions()), 13816e0c686SJim Ingham m_function_addr (function), 139b4cb0be3SFilipe Cabecinhas m_function_sp (0), 140ef651600SJim Ingham m_return_type (return_type), 141ce553d88SJim Ingham m_takedown_done (false), 1426fbc48bcSJim Ingham m_should_clear_objc_exception_bp(false), 1436fbc48bcSJim Ingham m_should_clear_cxx_exception_bp (false), 1446fbc48bcSJim Ingham m_stop_address (LLDB_INVALID_ADDRESS) 14530fdc8d8SChris Lattner { 1460092c8ebSJim Ingham lldb::addr_t start_load_addr; 1470092c8ebSJim Ingham ABI *abi; 1480092c8ebSJim Ingham lldb::addr_t function_load_addr; 149923886ceSJim Ingham if (!ConstructorSetup (thread, abi, start_load_addr, function_load_addr)) 1501ac04c30SGreg Clayton return; 1511ac04c30SGreg Clayton 15230fdc8d8SChris Lattner if (!abi->PrepareTrivialCall(thread, 153e359d9b7SSean Callanan m_function_sp, 1540092c8ebSJim Ingham function_load_addr, 1552a48f525SGreg Clayton start_load_addr, 156*a464f3d4SSean Callanan args)) 15730fdc8d8SChris Lattner return; 15830fdc8d8SChris Lattner 1599da3683cSJim Ingham ReportRegisterState ("Function call was set up. Register state was:"); 1609da3683cSJim Ingham 1619da3683cSJim Ingham m_valid = true; 1629da3683cSJim Ingham } 1639da3683cSJim Ingham 1649da3683cSJim Ingham ThreadPlanCallFunction::~ThreadPlanCallFunction () 1659da3683cSJim Ingham { 1660161b49cSJim Ingham DoTakedown(PlanSucceeded()); 1679da3683cSJim Ingham } 1689da3683cSJim Ingham 1699da3683cSJim Ingham void 1709da3683cSJim Ingham ThreadPlanCallFunction::ReportRegisterState (const char *message) 1719da3683cSJim Ingham { 1725160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP | LIBLLDB_LOG_VERBOSE)); 173ece96492SSean Callanan if (log) 174ece96492SSean Callanan { 175af247d7bSGreg Clayton StreamString strm; 1765ccbd294SGreg Clayton RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); 177ece96492SSean Callanan 1789da3683cSJim Ingham log->PutCString(message); 179ece96492SSean Callanan 180af247d7bSGreg Clayton RegisterValue reg_value; 181ece96492SSean Callanan 182af247d7bSGreg Clayton for (uint32_t reg_idx = 0, num_registers = reg_ctx->GetRegisterCount(); 183af247d7bSGreg Clayton reg_idx < num_registers; 184af247d7bSGreg Clayton ++reg_idx) 185af247d7bSGreg Clayton { 186af247d7bSGreg Clayton const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_idx); 187af247d7bSGreg Clayton if (reg_ctx->ReadRegister(reg_info, reg_value)) 188af247d7bSGreg Clayton { 189af247d7bSGreg Clayton reg_value.Dump(&strm, reg_info, true, false, eFormatDefault); 190af247d7bSGreg Clayton strm.EOL(); 191ece96492SSean Callanan } 192ece96492SSean Callanan } 193af247d7bSGreg Clayton log->PutCString(strm.GetData()); 194af247d7bSGreg Clayton } 19510af7c43SSean Callanan } 19610af7c43SSean Callanan 19710af7c43SSean Callanan void 19818de2fdcSJim Ingham ThreadPlanCallFunction::DoTakedown (bool success) 19910af7c43SSean Callanan { 2005160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP)); 20187d0e618SJim Ingham 20287d0e618SJim Ingham if (!m_valid) 20387d0e618SJim Ingham { 20487d0e618SJim Ingham //Don't call DoTakedown if we were never valid to begin with. 20587d0e618SJim Ingham if (log) 20687d0e618SJim Ingham log->Printf ("ThreadPlanCallFunction(%p): Log called on ThreadPlanCallFunction that was never valid.", this); 20787d0e618SJim Ingham return; 20887d0e618SJim Ingham } 20987d0e618SJim Ingham 2109da3683cSJim Ingham if (!m_takedown_done) 21177787033SJim Ingham { 21218de2fdcSJim Ingham if (success) 21318de2fdcSJim Ingham { 2141ac04c30SGreg Clayton ProcessSP process_sp (m_thread.GetProcess()); 2151ac04c30SGreg Clayton const ABI *abi = process_sp ? process_sp->GetABI().get() : NULL; 216ef651600SJim Ingham if (abi && m_return_type.IsValid()) 217ef651600SJim Ingham { 2186153c518SSean Callanan const bool persistent = false; 2196153c518SSean Callanan m_return_valobj_sp = abi->GetReturnValueObject (m_thread, m_return_type, persistent); 22070b57657SGreg Clayton } 22118de2fdcSJim Ingham } 2229da3683cSJim Ingham if (log) 223d01b2953SDaniel Malea 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()); 2249da3683cSJim Ingham m_takedown_done = true; 225ce553d88SJim Ingham m_stop_address = m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC(); 22660c4118cSJim Ingham m_real_stop_info_sp = GetPrivateStopInfo (); 2278559a355SJim Ingham m_thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state); 22818de2fdcSJim Ingham SetPlanComplete(success); 22910af7c43SSean Callanan ClearBreakpoints(); 2309da3683cSJim Ingham if (log && log->GetVerbose()) 2319da3683cSJim Ingham ReportRegisterState ("Restoring thread state after function call. Restored register state:"); 2322c36439cSJim Ingham 2339da3683cSJim Ingham } 2349da3683cSJim Ingham else 2359da3683cSJim Ingham { 2369da3683cSJim Ingham if (log) 237d01b2953SDaniel Malea 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()); 23830fdc8d8SChris Lattner } 23977787033SJim Ingham } 24030fdc8d8SChris Lattner 24130fdc8d8SChris Lattner void 242bda4e5ebSJim Ingham ThreadPlanCallFunction::WillPop () 243bda4e5ebSJim Ingham { 2440161b49cSJim Ingham DoTakedown(PlanSucceeded()); 245bda4e5ebSJim Ingham } 246bda4e5ebSJim Ingham 247bda4e5ebSJim Ingham void 2482a48f525SGreg Clayton ThreadPlanCallFunction::GetDescription (Stream *s, DescriptionLevel level) 24930fdc8d8SChris Lattner { 2502a48f525SGreg Clayton if (level == eDescriptionLevelBrief) 25130fdc8d8SChris Lattner { 25230fdc8d8SChris Lattner s->Printf("Function call thread plan"); 25330fdc8d8SChris Lattner } 25430fdc8d8SChris Lattner else 25530fdc8d8SChris Lattner { 2561ac04c30SGreg Clayton TargetSP target_sp (m_thread.CalculateTarget()); 257d01b2953SDaniel Malea s->Printf("Thread plan to call 0x%" PRIx64, m_function_addr.GetLoadAddress(target_sp.get())); 25830fdc8d8SChris Lattner } 25930fdc8d8SChris Lattner } 26030fdc8d8SChris Lattner 26130fdc8d8SChris Lattner bool 26230fdc8d8SChris Lattner ThreadPlanCallFunction::ValidatePlan (Stream *error) 26330fdc8d8SChris Lattner { 26430fdc8d8SChris Lattner if (!m_valid) 265ea06f3bfSJim Ingham { 266ea06f3bfSJim Ingham if (error) 267ea06f3bfSJim Ingham { 268ea06f3bfSJim Ingham if (m_constructor_errors.GetSize() > 0) 269ea06f3bfSJim Ingham error->PutCString (m_constructor_errors.GetData()); 270ea06f3bfSJim Ingham else 271ea06f3bfSJim Ingham error->PutCString ("Unknown error"); 272ea06f3bfSJim Ingham } 27330fdc8d8SChris Lattner return false; 274ea06f3bfSJim Ingham } 27530fdc8d8SChris Lattner 27630fdc8d8SChris Lattner return true; 27730fdc8d8SChris Lattner } 27830fdc8d8SChris Lattner 2790161b49cSJim Ingham 2800161b49cSJim Ingham Vote 2810161b49cSJim Ingham ThreadPlanCallFunction::ShouldReportStop(Event *event_ptr) 28230fdc8d8SChris Lattner { 2830161b49cSJim Ingham if (m_takedown_done || IsPlanComplete()) 2840161b49cSJim Ingham return eVoteYes; 2850161b49cSJim Ingham else 2860161b49cSJim Ingham return ThreadPlan::ShouldReportStop(event_ptr); 2870161b49cSJim Ingham } 2880161b49cSJim Ingham 2890161b49cSJim Ingham bool 290221d51cfSJim Ingham ThreadPlanCallFunction::DoPlanExplainsStop (Event *event_ptr) 2910161b49cSJim Ingham { 2925160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP|LIBLLDB_LOG_PROCESS)); 29360c4118cSJim Ingham m_real_stop_info_sp = GetPrivateStopInfo (); 294160f78c5SJim Ingham 29540d871faSJim Ingham // If our subplan knows why we stopped, even if it's done (which would forward the question to us) 29640d871faSJim Ingham // we answer yes. 2970161b49cSJim Ingham if (m_subplan_sp.get() != NULL && m_subplan_sp->PlanExplainsStop(event_ptr)) 298184e9811SJim Ingham { 299184e9811SJim Ingham SetPlanComplete(); 30040d871faSJim Ingham return true; 301184e9811SJim Ingham } 3023e6fedcaSSean Callanan 303c98aca60SSean Callanan // Check if the breakpoint is one of ours. 304c98aca60SSean Callanan 30518de2fdcSJim Ingham StopReason stop_reason; 30618de2fdcSJim Ingham if (!m_real_stop_info_sp) 30718de2fdcSJim Ingham stop_reason = eStopReasonNone; 30818de2fdcSJim Ingham else 30918de2fdcSJim Ingham stop_reason = m_real_stop_info_sp->GetStopReason(); 3100161b49cSJim Ingham if (log) 3110161b49cSJim Ingham log->Printf ("ThreadPlanCallFunction::PlanExplainsStop: Got stop reason - %s.", Thread::StopReasonAsCString(stop_reason)); 31218de2fdcSJim Ingham 31318de2fdcSJim Ingham if (stop_reason == eStopReasonBreakpoint && BreakpointsExplainStop()) 314c98aca60SSean Callanan return true; 315c98aca60SSean Callanan 3160161b49cSJim Ingham // We control breakpoints separately from other "stop reasons." So first, 3170161b49cSJim Ingham // check the case where we stopped for an internal breakpoint, in that case, continue on. 3180161b49cSJim Ingham // If it is not an internal breakpoint, consult m_ignore_breakpoints. 3196db73ca5SSean Callanan 32018de2fdcSJim Ingham 32118de2fdcSJim Ingham if (stop_reason == eStopReasonBreakpoint) 32240d871faSJim Ingham { 3231ac04c30SGreg Clayton ProcessSP process_sp (m_thread.CalculateProcess()); 324160f78c5SJim Ingham uint64_t break_site_id = m_real_stop_info_sp->GetValue(); 3251ac04c30SGreg Clayton BreakpointSiteSP bp_site_sp; 3261ac04c30SGreg Clayton if (process_sp) 3271ac04c30SGreg Clayton bp_site_sp = process_sp->GetBreakpointSiteList().FindByID(break_site_id); 32840d871faSJim Ingham if (bp_site_sp) 32940d871faSJim Ingham { 33040d871faSJim Ingham uint32_t num_owners = bp_site_sp->GetNumberOfOwners(); 33140d871faSJim Ingham bool is_internal = true; 33240d871faSJim Ingham for (uint32_t i = 0; i < num_owners; i++) 33340d871faSJim Ingham { 3346db73ca5SSean Callanan Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint(); 3350161b49cSJim Ingham if (log) 3360161b49cSJim Ingham log->Printf ("ThreadPlanCallFunction::PlanExplainsStop: hit breakpoint %d while calling function", bp.GetID()); 3376db73ca5SSean Callanan 3386db73ca5SSean Callanan if (!bp.IsInternal()) 33940d871faSJim Ingham { 34040d871faSJim Ingham is_internal = false; 34140d871faSJim Ingham break; 34240d871faSJim Ingham } 34340d871faSJim Ingham } 34440d871faSJim Ingham if (is_internal) 3450161b49cSJim Ingham { 3460161b49cSJim Ingham if (log) 3470161b49cSJim Ingham log->Printf ("ThreadPlanCallFunction::PlanExplainsStop hit an internal breakpoint, not stopping."); 34840d871faSJim Ingham return false; 34940d871faSJim Ingham } 3500161b49cSJim Ingham } 35140d871faSJim Ingham 352184e9811SJim Ingham if (m_ignore_breakpoints) 353923886ceSJim Ingham { 3540161b49cSJim Ingham if (log) 3550161b49cSJim Ingham log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are ignoring breakpoints, overriding breakpoint stop info ShouldStop, returning true"); 3560161b49cSJim Ingham m_real_stop_info_sp->OverrideShouldStop(false); 357923886ceSJim Ingham return true; 358923886ceSJim Ingham } 359923886ceSJim Ingham else 3600161b49cSJim Ingham { 3610161b49cSJim Ingham if (log) 3620161b49cSJim Ingham log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are not ignoring breakpoints, overriding breakpoint stop info ShouldStop, returning true"); 3630161b49cSJim Ingham m_real_stop_info_sp->OverrideShouldStop(true); 3640161b49cSJim Ingham return false; 3650161b49cSJim Ingham } 3660161b49cSJim Ingham } 3670161b49cSJim Ingham else if (!m_unwind_on_error) 3680161b49cSJim Ingham { 3690161b49cSJim Ingham // If we don't want to discard this plan, than any stop we don't understand should be propagated up the stack. 370923886ceSJim Ingham return false; 37140d871faSJim Ingham } 37240d871faSJim Ingham else 37340d871faSJim Ingham { 37440d871faSJim Ingham // If the subplan is running, any crashes are attributable to us. 3752c36439cSJim Ingham // If we want to discard the plan, then we say we explain the stop 3762c36439cSJim Ingham // but if we are going to be discarded, let whoever is above us 3772c36439cSJim Ingham // explain the stop. 3780161b49cSJim Ingham // But don't discard the plan if the stop would restart itself (for instance if it is a 3790161b49cSJim Ingham // signal that is set not to stop. Check that here first. We just say we explain the stop 3800161b49cSJim Ingham // but aren't done and everything will continue on from there. 3810161b49cSJim Ingham 3820161b49cSJim Ingham if (m_real_stop_info_sp->ShouldStopSynchronous(event_ptr)) 3830161b49cSJim Ingham { 384184e9811SJim Ingham SetPlanComplete(false); 3859a028519SSean Callanan if (m_subplan_sp) 38618de2fdcSJim Ingham { 387184e9811SJim Ingham if (m_unwind_on_error) 38818de2fdcSJim Ingham return true; 38918de2fdcSJim Ingham else 39018de2fdcSJim Ingham return false; 39118de2fdcSJim Ingham } 39218de2fdcSJim Ingham else 39318de2fdcSJim Ingham return false; 39430fdc8d8SChris Lattner } 3950161b49cSJim Ingham else 3960161b49cSJim Ingham return true; 3970161b49cSJim Ingham } 39840d871faSJim Ingham } 39930fdc8d8SChris Lattner 40030fdc8d8SChris Lattner bool 40130fdc8d8SChris Lattner ThreadPlanCallFunction::ShouldStop (Event *event_ptr) 40230fdc8d8SChris Lattner { 403221d51cfSJim Ingham // We do some computation in DoPlanExplainsStop that may or may not set the plan as complete. 404184e9811SJim Ingham // We need to do that here to make sure our state is correct. 405221d51cfSJim Ingham DoPlanExplainsStop(event_ptr); 406184e9811SJim Ingham 407184e9811SJim Ingham if (IsPlanComplete()) 40830fdc8d8SChris Lattner { 4099da3683cSJim Ingham ReportRegisterState ("Function completed. Register state was:"); 41030fdc8d8SChris Lattner return true; 41130fdc8d8SChris Lattner } 41230fdc8d8SChris Lattner else 41330fdc8d8SChris Lattner { 41430fdc8d8SChris Lattner return false; 41530fdc8d8SChris Lattner } 41630fdc8d8SChris Lattner } 41730fdc8d8SChris Lattner 41830fdc8d8SChris Lattner bool 41930fdc8d8SChris Lattner ThreadPlanCallFunction::StopOthers () 42030fdc8d8SChris Lattner { 42130fdc8d8SChris Lattner return m_stop_other_threads; 42230fdc8d8SChris Lattner } 42330fdc8d8SChris Lattner 42430fdc8d8SChris Lattner void 42530fdc8d8SChris Lattner ThreadPlanCallFunction::SetStopOthers (bool new_value) 42630fdc8d8SChris Lattner { 42730fdc8d8SChris Lattner if (m_subplan_sp) 42830fdc8d8SChris Lattner { 42930fdc8d8SChris Lattner ThreadPlanRunToAddress *address_plan = static_cast<ThreadPlanRunToAddress *>(m_subplan_sp.get()); 43030fdc8d8SChris Lattner address_plan->SetStopOthers(new_value); 43130fdc8d8SChris Lattner } 43230fdc8d8SChris Lattner m_stop_other_threads = new_value; 43330fdc8d8SChris Lattner } 43430fdc8d8SChris Lattner 43530fdc8d8SChris Lattner StateType 43606e827ccSJim Ingham ThreadPlanCallFunction::GetPlanRunState () 43730fdc8d8SChris Lattner { 43830fdc8d8SChris Lattner return eStateRunning; 43930fdc8d8SChris Lattner } 44030fdc8d8SChris Lattner 44130fdc8d8SChris Lattner void 44230fdc8d8SChris Lattner ThreadPlanCallFunction::DidPush () 44330fdc8d8SChris Lattner { 444be3a1b14SSean Callanan //#define SINGLE_STEP_EXPRESSIONS 445be3a1b14SSean Callanan 4468559a355SJim Ingham // Now set the thread state to "no reason" so we don't run with whatever signal was outstanding... 4478559a355SJim Ingham // Wait till the plan is pushed so we aren't changing the stop info till we're about to run. 4488559a355SJim Ingham 4498559a355SJim Ingham GetThread().SetStopInfoToNothing(); 4508559a355SJim Ingham 451be3a1b14SSean Callanan #ifndef SINGLE_STEP_EXPRESSIONS 45230fdc8d8SChris Lattner m_subplan_sp.reset(new ThreadPlanRunToAddress(m_thread, m_start_addr, m_stop_other_threads)); 45330fdc8d8SChris Lattner 45430fdc8d8SChris Lattner m_thread.QueueThreadPlan(m_subplan_sp, false); 45577787033SJim Ingham m_subplan_sp->SetPrivate (true); 456be3a1b14SSean Callanan #endif 45730fdc8d8SChris Lattner } 45830fdc8d8SChris Lattner 45930fdc8d8SChris Lattner bool 46030fdc8d8SChris Lattner ThreadPlanCallFunction::WillStop () 46130fdc8d8SChris Lattner { 46230fdc8d8SChris Lattner return true; 46330fdc8d8SChris Lattner } 46430fdc8d8SChris Lattner 46530fdc8d8SChris Lattner bool 46630fdc8d8SChris Lattner ThreadPlanCallFunction::MischiefManaged () 46730fdc8d8SChris Lattner { 4685160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 46930fdc8d8SChris Lattner 470184e9811SJim Ingham if (IsPlanComplete()) 471184e9811SJim Ingham { 47230fdc8d8SChris Lattner if (log) 47387d0e618SJim Ingham log->Printf("ThreadPlanCallFunction(%p): Completed call function plan.", this); 47430fdc8d8SChris Lattner 47530fdc8d8SChris Lattner ThreadPlan::MischiefManaged (); 47630fdc8d8SChris Lattner return true; 47730fdc8d8SChris Lattner } 47830fdc8d8SChris Lattner else 47930fdc8d8SChris Lattner { 48030fdc8d8SChris Lattner return false; 48130fdc8d8SChris Lattner } 48230fdc8d8SChris Lattner } 4836db73ca5SSean Callanan 4846db73ca5SSean Callanan void 4856db73ca5SSean Callanan ThreadPlanCallFunction::SetBreakpoints () 4866db73ca5SSean Callanan { 4871ac04c30SGreg Clayton ProcessSP process_sp (m_thread.CalculateProcess()); 4886fbc48bcSJim Ingham if (m_trap_exceptions && process_sp) 4891ac04c30SGreg Clayton { 4901ac04c30SGreg Clayton m_cxx_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeC_plus_plus); 4911ac04c30SGreg Clayton m_objc_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeObjC); 4926db73ca5SSean Callanan 493f211510fSSean Callanan if (m_cxx_language_runtime) 4946fbc48bcSJim Ingham { 4956fbc48bcSJim Ingham m_should_clear_cxx_exception_bp = !m_cxx_language_runtime->ExceptionBreakpointsAreSet(); 496f211510fSSean Callanan m_cxx_language_runtime->SetExceptionBreakpoints(); 4976fbc48bcSJim Ingham } 498f211510fSSean Callanan if (m_objc_language_runtime) 4996fbc48bcSJim Ingham { 5006fbc48bcSJim Ingham m_should_clear_objc_exception_bp = !m_objc_language_runtime->ExceptionBreakpointsAreSet(); 501f211510fSSean Callanan m_objc_language_runtime->SetExceptionBreakpoints(); 5026db73ca5SSean Callanan } 5031ac04c30SGreg Clayton } 5046fbc48bcSJim Ingham } 5056db73ca5SSean Callanan 5066db73ca5SSean Callanan void 5076db73ca5SSean Callanan ThreadPlanCallFunction::ClearBreakpoints () 5086db73ca5SSean Callanan { 5096fbc48bcSJim Ingham if (m_trap_exceptions) 5106fbc48bcSJim Ingham { 5116fbc48bcSJim Ingham if (m_cxx_language_runtime && m_should_clear_cxx_exception_bp) 512f211510fSSean Callanan m_cxx_language_runtime->ClearExceptionBreakpoints(); 5136fbc48bcSJim Ingham if (m_objc_language_runtime && m_should_clear_objc_exception_bp) 514f211510fSSean Callanan m_objc_language_runtime->ClearExceptionBreakpoints(); 5156db73ca5SSean Callanan } 5166fbc48bcSJim Ingham } 517c98aca60SSean Callanan 518c98aca60SSean Callanan bool 519c98aca60SSean Callanan ThreadPlanCallFunction::BreakpointsExplainStop() 520c98aca60SSean Callanan { 52160c4118cSJim Ingham StopInfoSP stop_info_sp = GetPrivateStopInfo (); 522c98aca60SSean Callanan 5236fbc48bcSJim Ingham if (m_trap_exceptions) 5246fbc48bcSJim Ingham { 525184e9811SJim Ingham if ((m_cxx_language_runtime && 526f211510fSSean Callanan m_cxx_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp)) 527184e9811SJim Ingham ||(m_objc_language_runtime && 528184e9811SJim Ingham m_objc_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))) 529184e9811SJim Ingham { 530641a67ceSJim Ingham Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP)); 531641a67ceSJim Ingham if (log) 532641a67ceSJim Ingham log->Printf ("ThreadPlanCallFunction::BreakpointsExplainStop - Hit an exception breakpoint, setting plan complete."); 533641a67ceSJim Ingham 534184e9811SJim Ingham SetPlanComplete(false); 535641a67ceSJim Ingham 536641a67ceSJim Ingham // If the user has set the ObjC language breakpoint, it would normally get priority over our internal 537641a67ceSJim Ingham // catcher breakpoint, but in this case we can't let that happen, so force the ShouldStop here. 538641a67ceSJim Ingham stop_info_sp->OverrideShouldStop (true); 539c98aca60SSean Callanan return true; 540184e9811SJim Ingham } 5416fbc48bcSJim Ingham } 542f211510fSSean Callanan 543c98aca60SSean Callanan return false; 544c98aca60SSean Callanan } 5458559a355SJim Ingham 5468559a355SJim Ingham bool 5478559a355SJim Ingham ThreadPlanCallFunction::RestoreThreadState() 5488559a355SJim Ingham { 5498559a355SJim Ingham return GetThread().RestoreThreadStateFromCheckpoint(m_stored_thread_state); 5508559a355SJim Ingham } 5518559a355SJim Ingham 552