1ac7ddfbfSEd Maste //===-- ThreadPlanCallFunction.cpp ------------------------------*- C++ -*-===// 2ac7ddfbfSEd Maste // 3ac7ddfbfSEd Maste // The LLVM Compiler Infrastructure 4ac7ddfbfSEd Maste // 5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source 6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details. 7ac7ddfbfSEd Maste // 8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===// 9ac7ddfbfSEd Maste 10ac7ddfbfSEd Maste // C Includes 11ac7ddfbfSEd Maste // C++ Includes 12ac7ddfbfSEd Maste // Other libraries and framework includes 13ac7ddfbfSEd Maste // Project includes 149f2f44ceSEd Maste #include "lldb/Target/ThreadPlanCallFunction.h" 15ac7ddfbfSEd Maste #include "lldb/Breakpoint/Breakpoint.h" 16ac7ddfbfSEd Maste #include "lldb/Breakpoint/BreakpointLocation.h" 17ac7ddfbfSEd Maste #include "lldb/Core/Address.h" 18ac7ddfbfSEd Maste #include "lldb/Core/Module.h" 19ac7ddfbfSEd Maste #include "lldb/Symbol/ObjectFile.h" 201c3bbb01SEd Maste #include "lldb/Target/ABI.h" 21ac7ddfbfSEd Maste #include "lldb/Target/LanguageRuntime.h" 22ac7ddfbfSEd Maste #include "lldb/Target/Process.h" 23ac7ddfbfSEd Maste #include "lldb/Target/RegisterContext.h" 24ac7ddfbfSEd Maste #include "lldb/Target/StopInfo.h" 25ac7ddfbfSEd Maste #include "lldb/Target/Target.h" 26ac7ddfbfSEd Maste #include "lldb/Target/Thread.h" 27ac7ddfbfSEd Maste #include "lldb/Target/ThreadPlanRunToAddress.h" 28f678e45dSDimitry Andric #include "lldb/Utility/Log.h" 29f678e45dSDimitry Andric #include "lldb/Utility/Stream.h" 30ac7ddfbfSEd Maste 31ac7ddfbfSEd Maste using namespace lldb; 32ac7ddfbfSEd Maste using namespace lldb_private; 33ac7ddfbfSEd Maste 34ac7ddfbfSEd Maste //---------------------------------------------------------------------- 35ac7ddfbfSEd Maste // ThreadPlanCallFunction: Plan to call a single function 36ac7ddfbfSEd Maste //---------------------------------------------------------------------- 37435933ddSDimitry Andric bool ThreadPlanCallFunction::ConstructorSetup( 38435933ddSDimitry Andric Thread &thread, ABI *&abi, lldb::addr_t &start_load_addr, 39435933ddSDimitry Andric lldb::addr_t &function_load_addr) { 40ac7ddfbfSEd Maste SetIsMasterPlan(true); 41ac7ddfbfSEd Maste SetOkayToDiscard(false); 42ac7ddfbfSEd Maste SetPrivate(true); 43ac7ddfbfSEd Maste 44ac7ddfbfSEd Maste ProcessSP process_sp(thread.GetProcess()); 45ac7ddfbfSEd Maste if (!process_sp) 46ac7ddfbfSEd Maste return false; 47ac7ddfbfSEd Maste 48ac7ddfbfSEd Maste abi = process_sp->GetABI().get(); 49ac7ddfbfSEd Maste 50ac7ddfbfSEd Maste if (!abi) 51ac7ddfbfSEd Maste return false; 52ac7ddfbfSEd Maste 53ac7ddfbfSEd Maste Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP)); 54ac7ddfbfSEd Maste 55ac7ddfbfSEd Maste SetBreakpoints(); 56ac7ddfbfSEd Maste 57ac7ddfbfSEd Maste m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize(); 58435933ddSDimitry Andric // If we can't read memory at the point of the process where we are planning 59435933ddSDimitry Andric // to put our function, we're 60ac7ddfbfSEd Maste // not going to get any further... 61ac7ddfbfSEd Maste Error error; 62ac7ddfbfSEd Maste process_sp->ReadUnsignedIntegerFromMemory(m_function_sp, 4, 0, error); 63435933ddSDimitry Andric if (!error.Success()) { 64435933ddSDimitry Andric m_constructor_errors.Printf( 65435933ddSDimitry Andric "Trying to put the stack in unreadable memory at: 0x%" PRIx64 ".", 66435933ddSDimitry Andric m_function_sp); 67ac7ddfbfSEd Maste if (log) 68435933ddSDimitry Andric log->Printf("ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this), 690127ef0fSEd Maste m_constructor_errors.GetData()); 70ac7ddfbfSEd Maste return false; 71ac7ddfbfSEd Maste } 72ac7ddfbfSEd Maste 73b952cd58SEd Maste Module *exe_module = GetTarget().GetExecutableModulePointer(); 74ac7ddfbfSEd Maste 75435933ddSDimitry Andric if (exe_module == nullptr) { 76435933ddSDimitry Andric m_constructor_errors.Printf( 77435933ddSDimitry Andric "Can't execute code without an executable module."); 78ac7ddfbfSEd Maste if (log) 79435933ddSDimitry Andric log->Printf("ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this), 800127ef0fSEd Maste m_constructor_errors.GetData()); 81ac7ddfbfSEd Maste return false; 82435933ddSDimitry Andric } else { 83ac7ddfbfSEd Maste ObjectFile *objectFile = exe_module->GetObjectFile(); 84435933ddSDimitry Andric if (!objectFile) { 85435933ddSDimitry Andric m_constructor_errors.Printf( 86435933ddSDimitry Andric "Could not find object file for module \"%s\".", 87ac7ddfbfSEd Maste exe_module->GetFileSpec().GetFilename().AsCString()); 88ac7ddfbfSEd Maste 89ac7ddfbfSEd Maste if (log) 900127ef0fSEd Maste log->Printf("ThreadPlanCallFunction(%p): %s.", 91435933ddSDimitry Andric static_cast<void *>(this), m_constructor_errors.GetData()); 92ac7ddfbfSEd Maste return false; 93ac7ddfbfSEd Maste } 94ac7ddfbfSEd Maste 95ac7ddfbfSEd Maste m_start_addr = objectFile->GetEntryPointAddress(); 96435933ddSDimitry Andric if (!m_start_addr.IsValid()) { 97435933ddSDimitry Andric m_constructor_errors.Printf( 98435933ddSDimitry Andric "Could not find entry point address for executable module \"%s\".", 99ac7ddfbfSEd Maste exe_module->GetFileSpec().GetFilename().AsCString()); 100ac7ddfbfSEd Maste if (log) 1010127ef0fSEd Maste log->Printf("ThreadPlanCallFunction(%p): %s.", 102435933ddSDimitry Andric static_cast<void *>(this), m_constructor_errors.GetData()); 103ac7ddfbfSEd Maste return false; 104ac7ddfbfSEd Maste } 105ac7ddfbfSEd Maste } 106ac7ddfbfSEd Maste 107b952cd58SEd Maste start_load_addr = m_start_addr.GetLoadAddress(&GetTarget()); 108ac7ddfbfSEd Maste 109ac7ddfbfSEd Maste // Checkpoint the thread state so we can restore it later. 110ac7ddfbfSEd Maste if (log && log->GetVerbose()) 111435933ddSDimitry Andric ReportRegisterState("About to checkpoint thread before function call. " 112435933ddSDimitry Andric "Original register state was:"); 113ac7ddfbfSEd Maste 114435933ddSDimitry Andric if (!thread.CheckpointThreadState(m_stored_thread_state)) { 115435933ddSDimitry Andric m_constructor_errors.Printf("Setting up ThreadPlanCallFunction, failed to " 116435933ddSDimitry Andric "checkpoint thread state."); 117ac7ddfbfSEd Maste if (log) 118435933ddSDimitry Andric log->Printf("ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this), 1190127ef0fSEd Maste m_constructor_errors.GetData()); 120ac7ddfbfSEd Maste return false; 121ac7ddfbfSEd Maste } 122b952cd58SEd Maste function_load_addr = m_function_addr.GetLoadAddress(&GetTarget()); 123ac7ddfbfSEd Maste 124ac7ddfbfSEd Maste return true; 125ac7ddfbfSEd Maste } 126ac7ddfbfSEd Maste 127435933ddSDimitry Andric ThreadPlanCallFunction::ThreadPlanCallFunction( 128435933ddSDimitry Andric Thread &thread, const Address &function, const CompilerType &return_type, 129435933ddSDimitry Andric llvm::ArrayRef<addr_t> args, const EvaluateExpressionOptions &options) 130435933ddSDimitry Andric : ThreadPlan(ThreadPlan::eKindCallFunction, "Call function plan", thread, 131435933ddSDimitry Andric eVoteNoOpinion, eVoteNoOpinion), 132435933ddSDimitry Andric m_valid(false), m_stop_other_threads(options.GetStopOthers()), 133b952cd58SEd Maste m_unwind_on_error(options.DoesUnwindOnError()), 134b952cd58SEd Maste m_ignore_breakpoints(options.DoesIgnoreBreakpoints()), 135b952cd58SEd Maste m_debug_execution(options.GetDebug()), 136435933ddSDimitry Andric m_trap_exceptions(options.GetTrapExceptions()), m_function_addr(function), 137435933ddSDimitry Andric m_function_sp(0), m_takedown_done(false), 138b952cd58SEd Maste m_should_clear_objc_exception_bp(false), 139b952cd58SEd Maste m_should_clear_cxx_exception_bp(false), 140435933ddSDimitry Andric m_stop_address(LLDB_INVALID_ADDRESS), m_return_type(return_type) { 141b91a7dfcSDimitry Andric lldb::addr_t start_load_addr = LLDB_INVALID_ADDRESS; 142b91a7dfcSDimitry Andric lldb::addr_t function_load_addr = LLDB_INVALID_ADDRESS; 143b91a7dfcSDimitry Andric ABI *abi = nullptr; 144b91a7dfcSDimitry Andric 145ac7ddfbfSEd Maste if (!ConstructorSetup(thread, abi, start_load_addr, function_load_addr)) 146ac7ddfbfSEd Maste return; 147ac7ddfbfSEd Maste 148435933ddSDimitry Andric if (!abi->PrepareTrivialCall(thread, m_function_sp, function_load_addr, 149435933ddSDimitry Andric start_load_addr, args)) 150ac7ddfbfSEd Maste return; 151ac7ddfbfSEd Maste 152ac7ddfbfSEd Maste ReportRegisterState("Function call was set up. Register state was:"); 153ac7ddfbfSEd Maste 154ac7ddfbfSEd Maste m_valid = true; 155ac7ddfbfSEd Maste } 156ac7ddfbfSEd Maste 157435933ddSDimitry Andric ThreadPlanCallFunction::ThreadPlanCallFunction( 158435933ddSDimitry Andric Thread &thread, const Address &function, 159435933ddSDimitry Andric const EvaluateExpressionOptions &options) 160435933ddSDimitry Andric : ThreadPlan(ThreadPlan::eKindCallFunction, "Call function plan", thread, 161435933ddSDimitry Andric eVoteNoOpinion, eVoteNoOpinion), 162435933ddSDimitry Andric m_valid(false), m_stop_other_threads(options.GetStopOthers()), 163b91a7dfcSDimitry Andric m_unwind_on_error(options.DoesUnwindOnError()), 164b91a7dfcSDimitry Andric m_ignore_breakpoints(options.DoesIgnoreBreakpoints()), 165b91a7dfcSDimitry Andric m_debug_execution(options.GetDebug()), 166435933ddSDimitry Andric m_trap_exceptions(options.GetTrapExceptions()), m_function_addr(function), 167435933ddSDimitry Andric m_function_sp(0), m_takedown_done(false), 168b91a7dfcSDimitry Andric m_should_clear_objc_exception_bp(false), 169b91a7dfcSDimitry Andric m_should_clear_cxx_exception_bp(false), 170435933ddSDimitry Andric m_stop_address(LLDB_INVALID_ADDRESS), m_return_type(CompilerType()) {} 171b91a7dfcSDimitry Andric 172435933ddSDimitry Andric ThreadPlanCallFunction::~ThreadPlanCallFunction() { 173ac7ddfbfSEd Maste DoTakedown(PlanSucceeded()); 174ac7ddfbfSEd Maste } 175ac7ddfbfSEd Maste 176435933ddSDimitry Andric void ThreadPlanCallFunction::ReportRegisterState(const char *message) { 177f678e45dSDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); 178f678e45dSDimitry Andric if (log && log->GetVerbose()) { 179ac7ddfbfSEd Maste StreamString strm; 180ac7ddfbfSEd Maste RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); 181ac7ddfbfSEd Maste 182ac7ddfbfSEd Maste log->PutCString(message); 183ac7ddfbfSEd Maste 184ac7ddfbfSEd Maste RegisterValue reg_value; 185ac7ddfbfSEd Maste 186ac7ddfbfSEd Maste for (uint32_t reg_idx = 0, num_registers = reg_ctx->GetRegisterCount(); 187435933ddSDimitry Andric reg_idx < num_registers; ++reg_idx) { 188ac7ddfbfSEd Maste const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_idx); 189435933ddSDimitry Andric if (reg_ctx->ReadRegister(reg_info, reg_value)) { 190ac7ddfbfSEd Maste reg_value.Dump(&strm, reg_info, true, false, eFormatDefault); 191ac7ddfbfSEd Maste strm.EOL(); 192ac7ddfbfSEd Maste } 193ac7ddfbfSEd Maste } 194435933ddSDimitry Andric log->PutString(strm.GetString()); 195ac7ddfbfSEd Maste } 196ac7ddfbfSEd Maste } 197ac7ddfbfSEd Maste 198435933ddSDimitry Andric void ThreadPlanCallFunction::DoTakedown(bool success) { 199ac7ddfbfSEd Maste Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP)); 200ac7ddfbfSEd Maste 201435933ddSDimitry Andric if (!m_valid) { 202ac7ddfbfSEd Maste // Don't call DoTakedown if we were never valid to begin with. 203ac7ddfbfSEd Maste if (log) 204435933ddSDimitry Andric log->Printf("ThreadPlanCallFunction(%p): Log called on " 205435933ddSDimitry Andric "ThreadPlanCallFunction that was never valid.", 2060127ef0fSEd Maste static_cast<void *>(this)); 207ac7ddfbfSEd Maste return; 208ac7ddfbfSEd Maste } 209ac7ddfbfSEd Maste 210435933ddSDimitry Andric if (!m_takedown_done) { 211435933ddSDimitry Andric if (success) { 212b91a7dfcSDimitry Andric SetReturnValue(); 213ac7ddfbfSEd Maste } 214ac7ddfbfSEd Maste if (log) 215435933ddSDimitry Andric log->Printf("ThreadPlanCallFunction(%p): DoTakedown called for thread " 216435933ddSDimitry Andric "0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n", 2170127ef0fSEd Maste static_cast<void *>(this), m_thread.GetID(), m_valid, 2180127ef0fSEd Maste IsPlanComplete()); 219ac7ddfbfSEd Maste m_takedown_done = true; 220435933ddSDimitry Andric m_stop_address = 221435933ddSDimitry Andric m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC(); 222ac7ddfbfSEd Maste m_real_stop_info_sp = GetPrivateStopInfo(); 223435933ddSDimitry Andric if (!m_thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state)) { 224*afda932aSEd Maste if (log) 225435933ddSDimitry Andric log->Printf("ThreadPlanCallFunction(%p): DoTakedown failed to restore " 226435933ddSDimitry Andric "register state", 2270127ef0fSEd Maste static_cast<void *>(this)); 228*afda932aSEd Maste } 229ac7ddfbfSEd Maste SetPlanComplete(success); 230ac7ddfbfSEd Maste ClearBreakpoints(); 231ac7ddfbfSEd Maste if (log && log->GetVerbose()) 232435933ddSDimitry Andric ReportRegisterState("Restoring thread state after function call. " 233435933ddSDimitry Andric "Restored register state:"); 234435933ddSDimitry Andric } else { 235ac7ddfbfSEd Maste if (log) 236435933ddSDimitry Andric log->Printf("ThreadPlanCallFunction(%p): DoTakedown called as no-op for " 237435933ddSDimitry Andric "thread 0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n", 2380127ef0fSEd Maste static_cast<void *>(this), m_thread.GetID(), m_valid, 2390127ef0fSEd Maste IsPlanComplete()); 240ac7ddfbfSEd Maste } 241ac7ddfbfSEd Maste } 242ac7ddfbfSEd Maste 243435933ddSDimitry Andric void ThreadPlanCallFunction::WillPop() { DoTakedown(PlanSucceeded()); } 244ac7ddfbfSEd Maste 245435933ddSDimitry Andric void ThreadPlanCallFunction::GetDescription(Stream *s, DescriptionLevel level) { 246435933ddSDimitry Andric if (level == eDescriptionLevelBrief) { 247ac7ddfbfSEd Maste s->Printf("Function call thread plan"); 248435933ddSDimitry Andric } else { 249ac7ddfbfSEd Maste TargetSP target_sp(m_thread.CalculateTarget()); 250435933ddSDimitry Andric s->Printf("Thread plan to call 0x%" PRIx64, 251435933ddSDimitry Andric m_function_addr.GetLoadAddress(target_sp.get())); 252ac7ddfbfSEd Maste } 253ac7ddfbfSEd Maste } 254ac7ddfbfSEd Maste 255435933ddSDimitry Andric bool ThreadPlanCallFunction::ValidatePlan(Stream *error) { 256435933ddSDimitry Andric if (!m_valid) { 257435933ddSDimitry Andric if (error) { 258ac7ddfbfSEd Maste if (m_constructor_errors.GetSize() > 0) 259435933ddSDimitry Andric error->PutCString(m_constructor_errors.GetString()); 260ac7ddfbfSEd Maste else 261ac7ddfbfSEd Maste error->PutCString("Unknown error"); 262ac7ddfbfSEd Maste } 263ac7ddfbfSEd Maste return false; 264ac7ddfbfSEd Maste } 265ac7ddfbfSEd Maste 266ac7ddfbfSEd Maste return true; 267ac7ddfbfSEd Maste } 268ac7ddfbfSEd Maste 269435933ddSDimitry Andric Vote ThreadPlanCallFunction::ShouldReportStop(Event *event_ptr) { 270ac7ddfbfSEd Maste if (m_takedown_done || IsPlanComplete()) 271ac7ddfbfSEd Maste return eVoteYes; 272ac7ddfbfSEd Maste else 273ac7ddfbfSEd Maste return ThreadPlan::ShouldReportStop(event_ptr); 274ac7ddfbfSEd Maste } 275ac7ddfbfSEd Maste 276435933ddSDimitry Andric bool ThreadPlanCallFunction::DoPlanExplainsStop(Event *event_ptr) { 277435933ddSDimitry Andric Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP | 278435933ddSDimitry Andric LIBLLDB_LOG_PROCESS)); 279ac7ddfbfSEd Maste m_real_stop_info_sp = GetPrivateStopInfo(); 280ac7ddfbfSEd Maste 281435933ddSDimitry Andric // If our subplan knows why we stopped, even if it's done (which would forward 282435933ddSDimitry Andric // the question to us) 283ac7ddfbfSEd Maste // we answer yes. 284435933ddSDimitry Andric if (m_subplan_sp && m_subplan_sp->PlanExplainsStop(event_ptr)) { 285ac7ddfbfSEd Maste SetPlanComplete(); 286ac7ddfbfSEd Maste return true; 287ac7ddfbfSEd Maste } 288ac7ddfbfSEd Maste 289ac7ddfbfSEd Maste // Check if the breakpoint is one of ours. 290ac7ddfbfSEd Maste 291ac7ddfbfSEd Maste StopReason stop_reason; 292ac7ddfbfSEd Maste if (!m_real_stop_info_sp) 293ac7ddfbfSEd Maste stop_reason = eStopReasonNone; 294ac7ddfbfSEd Maste else 295ac7ddfbfSEd Maste stop_reason = m_real_stop_info_sp->GetStopReason(); 296ac7ddfbfSEd Maste if (log) 297435933ddSDimitry Andric log->Printf( 298435933ddSDimitry Andric "ThreadPlanCallFunction::PlanExplainsStop: Got stop reason - %s.", 299435933ddSDimitry Andric Thread::StopReasonAsCString(stop_reason)); 300ac7ddfbfSEd Maste 301ac7ddfbfSEd Maste if (stop_reason == eStopReasonBreakpoint && BreakpointsExplainStop()) 302ac7ddfbfSEd Maste return true; 303ac7ddfbfSEd Maste 304435933ddSDimitry Andric // One more quirk here. If this event was from Halt interrupting the target, 305435933ddSDimitry Andric // then we should not consider 3060127ef0fSEd Maste // ourselves complete. Return true to acknowledge the stop. 307435933ddSDimitry Andric if (Process::ProcessEventData::GetInterruptedFromEvent(event_ptr)) { 3080127ef0fSEd Maste if (log) 309435933ddSDimitry Andric log->Printf("ThreadPlanCallFunction::PlanExplainsStop: The event is an " 310435933ddSDimitry Andric "Interrupt, returning true."); 3110127ef0fSEd Maste return true; 3120127ef0fSEd Maste } 313ac7ddfbfSEd Maste // We control breakpoints separately from other "stop reasons." So first, 314435933ddSDimitry Andric // check the case where we stopped for an internal breakpoint, in that case, 315435933ddSDimitry Andric // continue on. 316ac7ddfbfSEd Maste // If it is not an internal breakpoint, consult m_ignore_breakpoints. 317ac7ddfbfSEd Maste 318435933ddSDimitry Andric if (stop_reason == eStopReasonBreakpoint) { 319ac7ddfbfSEd Maste ProcessSP process_sp(m_thread.CalculateProcess()); 320ac7ddfbfSEd Maste uint64_t break_site_id = m_real_stop_info_sp->GetValue(); 321ac7ddfbfSEd Maste BreakpointSiteSP bp_site_sp; 322ac7ddfbfSEd Maste if (process_sp) 323ac7ddfbfSEd Maste bp_site_sp = process_sp->GetBreakpointSiteList().FindByID(break_site_id); 324435933ddSDimitry Andric if (bp_site_sp) { 325ac7ddfbfSEd Maste uint32_t num_owners = bp_site_sp->GetNumberOfOwners(); 326ac7ddfbfSEd Maste bool is_internal = true; 327435933ddSDimitry Andric for (uint32_t i = 0; i < num_owners; i++) { 328ac7ddfbfSEd Maste Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint(); 329ac7ddfbfSEd Maste if (log) 330435933ddSDimitry Andric log->Printf("ThreadPlanCallFunction::PlanExplainsStop: hit " 331435933ddSDimitry Andric "breakpoint %d while calling function", 332435933ddSDimitry Andric bp.GetID()); 333ac7ddfbfSEd Maste 334435933ddSDimitry Andric if (!bp.IsInternal()) { 335ac7ddfbfSEd Maste is_internal = false; 336ac7ddfbfSEd Maste break; 337ac7ddfbfSEd Maste } 338ac7ddfbfSEd Maste } 339435933ddSDimitry Andric if (is_internal) { 340ac7ddfbfSEd Maste if (log) 341435933ddSDimitry Andric log->Printf("ThreadPlanCallFunction::PlanExplainsStop hit an " 342435933ddSDimitry Andric "internal breakpoint, not stopping."); 343ac7ddfbfSEd Maste return false; 344ac7ddfbfSEd Maste } 345ac7ddfbfSEd Maste } 346ac7ddfbfSEd Maste 347435933ddSDimitry Andric if (m_ignore_breakpoints) { 348ac7ddfbfSEd Maste if (log) 349435933ddSDimitry Andric log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are ignoring " 350435933ddSDimitry Andric "breakpoints, overriding breakpoint stop info ShouldStop, " 351435933ddSDimitry Andric "returning true"); 352ac7ddfbfSEd Maste m_real_stop_info_sp->OverrideShouldStop(false); 353ac7ddfbfSEd Maste return true; 354435933ddSDimitry Andric } else { 355ac7ddfbfSEd Maste if (log) 356435933ddSDimitry Andric log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are not " 357435933ddSDimitry Andric "ignoring breakpoints, overriding breakpoint stop info " 358435933ddSDimitry Andric "ShouldStop, returning true"); 359ac7ddfbfSEd Maste m_real_stop_info_sp->OverrideShouldStop(true); 360ac7ddfbfSEd Maste return false; 361ac7ddfbfSEd Maste } 362435933ddSDimitry Andric } else if (!m_unwind_on_error) { 363435933ddSDimitry Andric // If we don't want to discard this plan, than any stop we don't understand 364435933ddSDimitry Andric // should be propagated up the stack. 365ac7ddfbfSEd Maste return false; 366435933ddSDimitry Andric } else { 367ac7ddfbfSEd Maste // If the subplan is running, any crashes are attributable to us. 368ac7ddfbfSEd Maste // If we want to discard the plan, then we say we explain the stop 369ac7ddfbfSEd Maste // but if we are going to be discarded, let whoever is above us 370ac7ddfbfSEd Maste // explain the stop. 371435933ddSDimitry Andric // But don't discard the plan if the stop would restart itself (for instance 372435933ddSDimitry Andric // if it is a 373435933ddSDimitry Andric // signal that is set not to stop. Check that here first. We just say we 374435933ddSDimitry Andric // explain the stop 375ac7ddfbfSEd Maste // but aren't done and everything will continue on from there. 376ac7ddfbfSEd Maste 377435933ddSDimitry Andric if (m_real_stop_info_sp && 378435933ddSDimitry Andric m_real_stop_info_sp->ShouldStopSynchronous(event_ptr)) { 379ac7ddfbfSEd Maste SetPlanComplete(false); 3809f2f44ceSEd Maste return m_subplan_sp ? m_unwind_on_error : false; 381435933ddSDimitry Andric } else 382ac7ddfbfSEd Maste return true; 383ac7ddfbfSEd Maste } 384ac7ddfbfSEd Maste } 385ac7ddfbfSEd Maste 386435933ddSDimitry Andric bool ThreadPlanCallFunction::ShouldStop(Event *event_ptr) { 387435933ddSDimitry Andric // We do some computation in DoPlanExplainsStop that may or may not set the 388435933ddSDimitry Andric // plan as complete. 389ac7ddfbfSEd Maste // We need to do that here to make sure our state is correct. 390ac7ddfbfSEd Maste DoPlanExplainsStop(event_ptr); 391ac7ddfbfSEd Maste 392435933ddSDimitry Andric if (IsPlanComplete()) { 393ac7ddfbfSEd Maste ReportRegisterState("Function completed. Register state was:"); 394ac7ddfbfSEd Maste return true; 395435933ddSDimitry Andric } else { 396ac7ddfbfSEd Maste return false; 397ac7ddfbfSEd Maste } 398ac7ddfbfSEd Maste } 399ac7ddfbfSEd Maste 400435933ddSDimitry Andric bool ThreadPlanCallFunction::StopOthers() { return m_stop_other_threads; } 401ac7ddfbfSEd Maste 402435933ddSDimitry Andric StateType ThreadPlanCallFunction::GetPlanRunState() { return eStateRunning; } 403ac7ddfbfSEd Maste 404435933ddSDimitry Andric void ThreadPlanCallFunction::DidPush() { 405ac7ddfbfSEd Maste //#define SINGLE_STEP_EXPRESSIONS 406ac7ddfbfSEd Maste 407435933ddSDimitry Andric // Now set the thread state to "no reason" so we don't run with whatever 408435933ddSDimitry Andric // signal was outstanding... 409435933ddSDimitry Andric // Wait till the plan is pushed so we aren't changing the stop info till we're 410435933ddSDimitry Andric // about to run. 411ac7ddfbfSEd Maste 412ac7ddfbfSEd Maste GetThread().SetStopInfoToNothing(); 413ac7ddfbfSEd Maste 414ac7ddfbfSEd Maste #ifndef SINGLE_STEP_EXPRESSIONS 415435933ddSDimitry Andric m_subplan_sp.reset( 416435933ddSDimitry Andric new ThreadPlanRunToAddress(m_thread, m_start_addr, m_stop_other_threads)); 417ac7ddfbfSEd Maste 418ac7ddfbfSEd Maste m_thread.QueueThreadPlan(m_subplan_sp, false); 419ac7ddfbfSEd Maste m_subplan_sp->SetPrivate(true); 420ac7ddfbfSEd Maste #endif 421ac7ddfbfSEd Maste } 422ac7ddfbfSEd Maste 423435933ddSDimitry Andric bool ThreadPlanCallFunction::WillStop() { return true; } 424ac7ddfbfSEd Maste 425435933ddSDimitry Andric bool ThreadPlanCallFunction::MischiefManaged() { 426ac7ddfbfSEd Maste Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); 427ac7ddfbfSEd Maste 428435933ddSDimitry Andric if (IsPlanComplete()) { 429ac7ddfbfSEd Maste if (log) 4300127ef0fSEd Maste log->Printf("ThreadPlanCallFunction(%p): Completed call function plan.", 4310127ef0fSEd Maste static_cast<void *>(this)); 432ac7ddfbfSEd Maste 433ac7ddfbfSEd Maste ThreadPlan::MischiefManaged(); 434ac7ddfbfSEd Maste return true; 435435933ddSDimitry Andric } else { 436ac7ddfbfSEd Maste return false; 437ac7ddfbfSEd Maste } 438ac7ddfbfSEd Maste } 439ac7ddfbfSEd Maste 440435933ddSDimitry Andric void ThreadPlanCallFunction::SetBreakpoints() { 441ac7ddfbfSEd Maste ProcessSP process_sp(m_thread.CalculateProcess()); 442435933ddSDimitry Andric if (m_trap_exceptions && process_sp) { 443435933ddSDimitry Andric m_cxx_language_runtime = 444435933ddSDimitry Andric process_sp->GetLanguageRuntime(eLanguageTypeC_plus_plus); 445ac7ddfbfSEd Maste m_objc_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeObjC); 446ac7ddfbfSEd Maste 447435933ddSDimitry Andric if (m_cxx_language_runtime) { 448435933ddSDimitry Andric m_should_clear_cxx_exception_bp = 449435933ddSDimitry Andric !m_cxx_language_runtime->ExceptionBreakpointsAreSet(); 450ac7ddfbfSEd Maste m_cxx_language_runtime->SetExceptionBreakpoints(); 451b952cd58SEd Maste } 452435933ddSDimitry Andric if (m_objc_language_runtime) { 453435933ddSDimitry Andric m_should_clear_objc_exception_bp = 454435933ddSDimitry Andric !m_objc_language_runtime->ExceptionBreakpointsAreSet(); 455ac7ddfbfSEd Maste m_objc_language_runtime->SetExceptionBreakpoints(); 456ac7ddfbfSEd Maste } 457ac7ddfbfSEd Maste } 458b952cd58SEd Maste } 459ac7ddfbfSEd Maste 460435933ddSDimitry Andric void ThreadPlanCallFunction::ClearBreakpoints() { 461435933ddSDimitry Andric if (m_trap_exceptions) { 462b952cd58SEd Maste if (m_cxx_language_runtime && m_should_clear_cxx_exception_bp) 463ac7ddfbfSEd Maste m_cxx_language_runtime->ClearExceptionBreakpoints(); 464b952cd58SEd Maste if (m_objc_language_runtime && m_should_clear_objc_exception_bp) 465ac7ddfbfSEd Maste m_objc_language_runtime->ClearExceptionBreakpoints(); 466ac7ddfbfSEd Maste } 467b952cd58SEd Maste } 468ac7ddfbfSEd Maste 469435933ddSDimitry Andric bool ThreadPlanCallFunction::BreakpointsExplainStop() { 470ac7ddfbfSEd Maste StopInfoSP stop_info_sp = GetPrivateStopInfo(); 471ac7ddfbfSEd Maste 472435933ddSDimitry Andric if (m_trap_exceptions) { 473ac7ddfbfSEd Maste if ((m_cxx_language_runtime && 474435933ddSDimitry Andric m_cxx_language_runtime->ExceptionBreakpointsExplainStop( 475435933ddSDimitry Andric stop_info_sp)) || 476435933ddSDimitry Andric (m_objc_language_runtime && 477435933ddSDimitry Andric m_objc_language_runtime->ExceptionBreakpointsExplainStop( 478435933ddSDimitry Andric stop_info_sp))) { 479ac7ddfbfSEd Maste Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP)); 480ac7ddfbfSEd Maste if (log) 481435933ddSDimitry Andric log->Printf("ThreadPlanCallFunction::BreakpointsExplainStop - Hit an " 482435933ddSDimitry Andric "exception breakpoint, setting plan complete."); 483ac7ddfbfSEd Maste 484ac7ddfbfSEd Maste SetPlanComplete(false); 485ac7ddfbfSEd Maste 486435933ddSDimitry Andric // If the user has set the ObjC language breakpoint, it would normally get 487435933ddSDimitry Andric // priority over our internal 488435933ddSDimitry Andric // catcher breakpoint, but in this case we can't let that happen, so force 489435933ddSDimitry Andric // the ShouldStop here. 490ac7ddfbfSEd Maste stop_info_sp->OverrideShouldStop(true); 491ac7ddfbfSEd Maste return true; 492ac7ddfbfSEd Maste } 493b952cd58SEd Maste } 494ac7ddfbfSEd Maste 495ac7ddfbfSEd Maste return false; 496ac7ddfbfSEd Maste } 497ac7ddfbfSEd Maste 498435933ddSDimitry Andric void ThreadPlanCallFunction::SetStopOthers(bool new_value) { 4990127ef0fSEd Maste m_subplan_sp->SetStopOthers(new_value); 5000127ef0fSEd Maste } 5010127ef0fSEd Maste 502435933ddSDimitry Andric bool ThreadPlanCallFunction::RestoreThreadState() { 503ac7ddfbfSEd Maste return GetThread().RestoreThreadStateFromCheckpoint(m_stored_thread_state); 504ac7ddfbfSEd Maste } 505ac7ddfbfSEd Maste 506435933ddSDimitry Andric void ThreadPlanCallFunction::SetReturnValue() { 507b91a7dfcSDimitry Andric ProcessSP process_sp(m_thread.GetProcess()); 5089f2f44ceSEd Maste const ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; 509435933ddSDimitry Andric if (abi && m_return_type.IsValid()) { 510b91a7dfcSDimitry Andric const bool persistent = false; 511435933ddSDimitry Andric m_return_valobj_sp = 512435933ddSDimitry Andric abi->GetReturnValueObject(m_thread, m_return_type, persistent); 513b91a7dfcSDimitry Andric } 514b91a7dfcSDimitry Andric } 515