1254721Semaste//===-- ThreadPlanCallFunction.cpp ------------------------------*- C++ -*-===// 2254721Semaste// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6254721Semaste// 7254721Semaste//===----------------------------------------------------------------------===// 8254721Semaste 9296417Sdim#include "lldb/Target/ThreadPlanCallFunction.h" 10254721Semaste#include "lldb/Breakpoint/Breakpoint.h" 11254721Semaste#include "lldb/Breakpoint/BreakpointLocation.h" 12254721Semaste#include "lldb/Core/Address.h" 13341825Sdim#include "lldb/Core/DumpRegisterValue.h" 14254721Semaste#include "lldb/Core/Module.h" 15254721Semaste#include "lldb/Symbol/ObjectFile.h" 16288943Sdim#include "lldb/Target/ABI.h" 17254721Semaste#include "lldb/Target/LanguageRuntime.h" 18254721Semaste#include "lldb/Target/Process.h" 19254721Semaste#include "lldb/Target/RegisterContext.h" 20254721Semaste#include "lldb/Target/StopInfo.h" 21254721Semaste#include "lldb/Target/Target.h" 22254721Semaste#include "lldb/Target/Thread.h" 23254721Semaste#include "lldb/Target/ThreadPlanRunToAddress.h" 24321369Sdim#include "lldb/Utility/Log.h" 25321369Sdim#include "lldb/Utility/Stream.h" 26254721Semaste 27353358Sdim#include <memory> 28353358Sdim 29254721Semasteusing namespace lldb; 30254721Semasteusing namespace lldb_private; 31254721Semaste 32254721Semaste// ThreadPlanCallFunction: Plan to call a single function 33314564Sdimbool ThreadPlanCallFunction::ConstructorSetup( 34314564Sdim Thread &thread, ABI *&abi, lldb::addr_t &start_load_addr, 35314564Sdim lldb::addr_t &function_load_addr) { 36314564Sdim SetIsMasterPlan(true); 37314564Sdim SetOkayToDiscard(false); 38314564Sdim SetPrivate(true); 39254721Semaste 40314564Sdim ProcessSP process_sp(thread.GetProcess()); 41314564Sdim if (!process_sp) 42314564Sdim return false; 43276479Sdim 44314564Sdim abi = process_sp->GetABI().get(); 45276479Sdim 46314564Sdim if (!abi) 47314564Sdim return false; 48276479Sdim 49314564Sdim Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP)); 50276479Sdim 51314564Sdim SetBreakpoints(); 52276479Sdim 53314564Sdim m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize(); 54314564Sdim // If we can't read memory at the point of the process where we are planning 55341825Sdim // to put our function, we're not going to get any further... 56321369Sdim Status error; 57314564Sdim process_sp->ReadUnsignedIntegerFromMemory(m_function_sp, 4, 0, error); 58314564Sdim if (!error.Success()) { 59314564Sdim m_constructor_errors.Printf( 60314564Sdim "Trying to put the stack in unreadable memory at: 0x%" PRIx64 ".", 61314564Sdim m_function_sp); 62360784Sdim LLDB_LOGF(log, "ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this), 63360784Sdim m_constructor_errors.GetData()); 64314564Sdim return false; 65314564Sdim } 66276479Sdim 67360784Sdim llvm::Expected<Address> start_address = GetTarget().GetEntryPointAddress(); 68360784Sdim if (!start_address) { 69314564Sdim m_constructor_errors.Printf( 70360784Sdim "%s", llvm::toString(start_address.takeError()).c_str()); 71360784Sdim LLDB_LOGF(log, "ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this), 72360784Sdim m_constructor_errors.GetData()); 73314564Sdim return false; 74314564Sdim } 75276479Sdim 76360784Sdim m_start_addr = *start_address; 77314564Sdim start_load_addr = m_start_addr.GetLoadAddress(&GetTarget()); 78276479Sdim 79314564Sdim // Checkpoint the thread state so we can restore it later. 80314564Sdim if (log && log->GetVerbose()) 81314564Sdim ReportRegisterState("About to checkpoint thread before function call. " 82314564Sdim "Original register state was:"); 83254721Semaste 84314564Sdim if (!thread.CheckpointThreadState(m_stored_thread_state)) { 85314564Sdim m_constructor_errors.Printf("Setting up ThreadPlanCallFunction, failed to " 86314564Sdim "checkpoint thread state."); 87360784Sdim LLDB_LOGF(log, "ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this), 88360784Sdim m_constructor_errors.GetData()); 89314564Sdim return false; 90314564Sdim } 91314564Sdim function_load_addr = m_function_addr.GetLoadAddress(&GetTarget()); 92276479Sdim 93314564Sdim return true; 94254721Semaste} 95254721Semaste 96314564SdimThreadPlanCallFunction::ThreadPlanCallFunction( 97314564Sdim Thread &thread, const Address &function, const CompilerType &return_type, 98314564Sdim llvm::ArrayRef<addr_t> args, const EvaluateExpressionOptions &options) 99314564Sdim : ThreadPlan(ThreadPlan::eKindCallFunction, "Call function plan", thread, 100314564Sdim eVoteNoOpinion, eVoteNoOpinion), 101314564Sdim m_valid(false), m_stop_other_threads(options.GetStopOthers()), 102314564Sdim m_unwind_on_error(options.DoesUnwindOnError()), 103314564Sdim m_ignore_breakpoints(options.DoesIgnoreBreakpoints()), 104314564Sdim m_debug_execution(options.GetDebug()), 105314564Sdim m_trap_exceptions(options.GetTrapExceptions()), m_function_addr(function), 106314564Sdim m_function_sp(0), m_takedown_done(false), 107314564Sdim m_should_clear_objc_exception_bp(false), 108314564Sdim m_should_clear_cxx_exception_bp(false), 109314564Sdim m_stop_address(LLDB_INVALID_ADDRESS), m_return_type(return_type) { 110314564Sdim lldb::addr_t start_load_addr = LLDB_INVALID_ADDRESS; 111314564Sdim lldb::addr_t function_load_addr = LLDB_INVALID_ADDRESS; 112314564Sdim ABI *abi = nullptr; 113288943Sdim 114314564Sdim if (!ConstructorSetup(thread, abi, start_load_addr, function_load_addr)) 115314564Sdim return; 116276479Sdim 117314564Sdim if (!abi->PrepareTrivialCall(thread, m_function_sp, function_load_addr, 118314564Sdim start_load_addr, args)) 119314564Sdim return; 120276479Sdim 121314564Sdim ReportRegisterState("Function call was set up. Register state was:"); 122276479Sdim 123314564Sdim m_valid = true; 124254721Semaste} 125254721Semaste 126314564SdimThreadPlanCallFunction::ThreadPlanCallFunction( 127314564Sdim Thread &thread, const Address &function, 128314564Sdim const EvaluateExpressionOptions &options) 129314564Sdim : ThreadPlan(ThreadPlan::eKindCallFunction, "Call function plan", thread, 130314564Sdim eVoteNoOpinion, eVoteNoOpinion), 131314564Sdim m_valid(false), m_stop_other_threads(options.GetStopOthers()), 132314564Sdim m_unwind_on_error(options.DoesUnwindOnError()), 133314564Sdim m_ignore_breakpoints(options.DoesIgnoreBreakpoints()), 134314564Sdim m_debug_execution(options.GetDebug()), 135314564Sdim m_trap_exceptions(options.GetTrapExceptions()), m_function_addr(function), 136314564Sdim m_function_sp(0), m_takedown_done(false), 137314564Sdim m_should_clear_objc_exception_bp(false), 138314564Sdim m_should_clear_cxx_exception_bp(false), 139314564Sdim m_stop_address(LLDB_INVALID_ADDRESS), m_return_type(CompilerType()) {} 140288943Sdim 141314564SdimThreadPlanCallFunction::~ThreadPlanCallFunction() { 142314564Sdim DoTakedown(PlanSucceeded()); 143254721Semaste} 144254721Semaste 145314564Sdimvoid ThreadPlanCallFunction::ReportRegisterState(const char *message) { 146321369Sdim Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); 147321369Sdim if (log && log->GetVerbose()) { 148314564Sdim StreamString strm; 149314564Sdim RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); 150254721Semaste 151314564Sdim log->PutCString(message); 152254721Semaste 153314564Sdim RegisterValue reg_value; 154254721Semaste 155314564Sdim for (uint32_t reg_idx = 0, num_registers = reg_ctx->GetRegisterCount(); 156314564Sdim reg_idx < num_registers; ++reg_idx) { 157314564Sdim const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_idx); 158314564Sdim if (reg_ctx->ReadRegister(reg_info, reg_value)) { 159341825Sdim DumpRegisterValue(reg_value, &strm, reg_info, true, false, 160341825Sdim eFormatDefault); 161314564Sdim strm.EOL(); 162314564Sdim } 163254721Semaste } 164314564Sdim log->PutString(strm.GetString()); 165314564Sdim } 166254721Semaste} 167254721Semaste 168314564Sdimvoid ThreadPlanCallFunction::DoTakedown(bool success) { 169314564Sdim Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP)); 170276479Sdim 171314564Sdim if (!m_valid) { 172314564Sdim // Don't call DoTakedown if we were never valid to begin with. 173360784Sdim LLDB_LOGF(log, 174360784Sdim "ThreadPlanCallFunction(%p): Log called on " 175360784Sdim "ThreadPlanCallFunction that was never valid.", 176360784Sdim static_cast<void *>(this)); 177314564Sdim return; 178314564Sdim } 179276479Sdim 180314564Sdim if (!m_takedown_done) { 181314564Sdim if (success) { 182314564Sdim SetReturnValue(); 183254721Semaste } 184360784Sdim LLDB_LOGF(log, 185360784Sdim "ThreadPlanCallFunction(%p): DoTakedown called for thread " 186360784Sdim "0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n", 187360784Sdim static_cast<void *>(this), m_thread.GetID(), m_valid, 188360784Sdim IsPlanComplete()); 189314564Sdim m_takedown_done = true; 190314564Sdim m_stop_address = 191314564Sdim m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC(); 192314564Sdim m_real_stop_info_sp = GetPrivateStopInfo(); 193314564Sdim if (!m_thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state)) { 194360784Sdim LLDB_LOGF(log, 195360784Sdim "ThreadPlanCallFunction(%p): DoTakedown failed to restore " 196360784Sdim "register state", 197360784Sdim static_cast<void *>(this)); 198254721Semaste } 199314564Sdim SetPlanComplete(success); 200314564Sdim ClearBreakpoints(); 201314564Sdim if (log && log->GetVerbose()) 202314564Sdim ReportRegisterState("Restoring thread state after function call. " 203314564Sdim "Restored register state:"); 204314564Sdim } else { 205360784Sdim LLDB_LOGF(log, 206360784Sdim "ThreadPlanCallFunction(%p): DoTakedown called as no-op for " 207360784Sdim "thread 0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n", 208360784Sdim static_cast<void *>(this), m_thread.GetID(), m_valid, 209360784Sdim IsPlanComplete()); 210314564Sdim } 211254721Semaste} 212254721Semaste 213314564Sdimvoid ThreadPlanCallFunction::WillPop() { DoTakedown(PlanSucceeded()); } 214254721Semaste 215314564Sdimvoid ThreadPlanCallFunction::GetDescription(Stream *s, DescriptionLevel level) { 216314564Sdim if (level == eDescriptionLevelBrief) { 217314564Sdim s->Printf("Function call thread plan"); 218314564Sdim } else { 219314564Sdim TargetSP target_sp(m_thread.CalculateTarget()); 220314564Sdim s->Printf("Thread plan to call 0x%" PRIx64, 221314564Sdim m_function_addr.GetLoadAddress(target_sp.get())); 222314564Sdim } 223254721Semaste} 224254721Semaste 225314564Sdimbool ThreadPlanCallFunction::ValidatePlan(Stream *error) { 226314564Sdim if (!m_valid) { 227314564Sdim if (error) { 228314564Sdim if (m_constructor_errors.GetSize() > 0) 229314564Sdim error->PutCString(m_constructor_errors.GetString()); 230314564Sdim else 231314564Sdim error->PutCString("Unknown error"); 232254721Semaste } 233314564Sdim return false; 234314564Sdim } 235254721Semaste 236314564Sdim return true; 237254721Semaste} 238254721Semaste 239314564SdimVote ThreadPlanCallFunction::ShouldReportStop(Event *event_ptr) { 240314564Sdim if (m_takedown_done || IsPlanComplete()) 241314564Sdim return eVoteYes; 242314564Sdim else 243314564Sdim return ThreadPlan::ShouldReportStop(event_ptr); 244254721Semaste} 245254721Semaste 246314564Sdimbool ThreadPlanCallFunction::DoPlanExplainsStop(Event *event_ptr) { 247314564Sdim Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP | 248314564Sdim LIBLLDB_LOG_PROCESS)); 249314564Sdim m_real_stop_info_sp = GetPrivateStopInfo(); 250314564Sdim 251341825Sdim // If our subplan knows why we stopped, even if it's done (which would 252341825Sdim // forward the question to us) we answer yes. 253314564Sdim if (m_subplan_sp && m_subplan_sp->PlanExplainsStop(event_ptr)) { 254314564Sdim SetPlanComplete(); 255314564Sdim return true; 256314564Sdim } 257314564Sdim 258314564Sdim // Check if the breakpoint is one of ours. 259314564Sdim 260314564Sdim StopReason stop_reason; 261314564Sdim if (!m_real_stop_info_sp) 262314564Sdim stop_reason = eStopReasonNone; 263314564Sdim else 264314564Sdim stop_reason = m_real_stop_info_sp->GetStopReason(); 265360784Sdim LLDB_LOGF(log, 266360784Sdim "ThreadPlanCallFunction::PlanExplainsStop: Got stop reason - %s.", 267360784Sdim Thread::StopReasonAsCString(stop_reason)); 268314564Sdim 269314564Sdim if (stop_reason == eStopReasonBreakpoint && BreakpointsExplainStop()) 270314564Sdim return true; 271314564Sdim 272314564Sdim // One more quirk here. If this event was from Halt interrupting the target, 273341825Sdim // then we should not consider ourselves complete. Return true to 274341825Sdim // acknowledge the stop. 275314564Sdim if (Process::ProcessEventData::GetInterruptedFromEvent(event_ptr)) { 276360784Sdim LLDB_LOGF(log, "ThreadPlanCallFunction::PlanExplainsStop: The event is an " 277360784Sdim "Interrupt, returning true."); 278314564Sdim return true; 279314564Sdim } 280314564Sdim // We control breakpoints separately from other "stop reasons." So first, 281314564Sdim // check the case where we stopped for an internal breakpoint, in that case, 282341825Sdim // continue on. If it is not an internal breakpoint, consult 283341825Sdim // m_ignore_breakpoints. 284254721Semaste 285314564Sdim if (stop_reason == eStopReasonBreakpoint) { 286314564Sdim ProcessSP process_sp(m_thread.CalculateProcess()); 287314564Sdim uint64_t break_site_id = m_real_stop_info_sp->GetValue(); 288314564Sdim BreakpointSiteSP bp_site_sp; 289314564Sdim if (process_sp) 290314564Sdim bp_site_sp = process_sp->GetBreakpointSiteList().FindByID(break_site_id); 291314564Sdim if (bp_site_sp) { 292314564Sdim uint32_t num_owners = bp_site_sp->GetNumberOfOwners(); 293314564Sdim bool is_internal = true; 294314564Sdim for (uint32_t i = 0; i < num_owners; i++) { 295314564Sdim Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint(); 296360784Sdim LLDB_LOGF(log, 297360784Sdim "ThreadPlanCallFunction::PlanExplainsStop: hit " 298360784Sdim "breakpoint %d while calling function", 299360784Sdim bp.GetID()); 300296417Sdim 301314564Sdim if (!bp.IsInternal()) { 302314564Sdim is_internal = false; 303314564Sdim break; 304254721Semaste } 305314564Sdim } 306314564Sdim if (is_internal) { 307360784Sdim LLDB_LOGF(log, "ThreadPlanCallFunction::PlanExplainsStop hit an " 308360784Sdim "internal breakpoint, not stopping."); 309254721Semaste return false; 310314564Sdim } 311254721Semaste } 312254721Semaste 313314564Sdim if (m_ignore_breakpoints) { 314360784Sdim LLDB_LOGF(log, 315360784Sdim "ThreadPlanCallFunction::PlanExplainsStop: we are ignoring " 316360784Sdim "breakpoints, overriding breakpoint stop info ShouldStop, " 317360784Sdim "returning true"); 318314564Sdim m_real_stop_info_sp->OverrideShouldStop(false); 319314564Sdim return true; 320314564Sdim } else { 321360784Sdim LLDB_LOGF(log, "ThreadPlanCallFunction::PlanExplainsStop: we are not " 322360784Sdim "ignoring breakpoints, overriding breakpoint stop info " 323360784Sdim "ShouldStop, returning true"); 324314564Sdim m_real_stop_info_sp->OverrideShouldStop(true); 325314564Sdim return false; 326254721Semaste } 327314564Sdim } else if (!m_unwind_on_error) { 328314564Sdim // If we don't want to discard this plan, than any stop we don't understand 329314564Sdim // should be propagated up the stack. 330314564Sdim return false; 331314564Sdim } else { 332341825Sdim // If the subplan is running, any crashes are attributable to us. If we 333341825Sdim // want to discard the plan, then we say we explain the stop but if we are 334341825Sdim // going to be discarded, let whoever is above us explain the stop. But 335341825Sdim // don't discard the plan if the stop would restart itself (for instance if 336341825Sdim // it is a signal that is set not to stop. Check that here first. We just 337341825Sdim // say we explain the stop but aren't done and everything will continue on 338341825Sdim // from there. 339254721Semaste 340314564Sdim if (m_real_stop_info_sp && 341314564Sdim m_real_stop_info_sp->ShouldStopSynchronous(event_ptr)) { 342314564Sdim SetPlanComplete(false); 343314564Sdim return m_subplan_sp ? m_unwind_on_error : false; 344314564Sdim } else 345314564Sdim return true; 346314564Sdim } 347254721Semaste} 348254721Semaste 349314564Sdimbool ThreadPlanCallFunction::ShouldStop(Event *event_ptr) { 350314564Sdim // We do some computation in DoPlanExplainsStop that may or may not set the 351341825Sdim // plan as complete. We need to do that here to make sure our state is 352341825Sdim // correct. 353314564Sdim DoPlanExplainsStop(event_ptr); 354314564Sdim 355314564Sdim if (IsPlanComplete()) { 356314564Sdim ReportRegisterState("Function completed. Register state was:"); 357314564Sdim return true; 358314564Sdim } else { 359314564Sdim return false; 360314564Sdim } 361254721Semaste} 362254721Semaste 363314564Sdimbool ThreadPlanCallFunction::StopOthers() { return m_stop_other_threads; } 364314564Sdim 365314564SdimStateType ThreadPlanCallFunction::GetPlanRunState() { return eStateRunning; } 366314564Sdim 367314564Sdimvoid ThreadPlanCallFunction::DidPush() { 368314564Sdim //#define SINGLE_STEP_EXPRESSIONS 369314564Sdim 370314564Sdim // Now set the thread state to "no reason" so we don't run with whatever 371341825Sdim // signal was outstanding... Wait till the plan is pushed so we aren't 372341825Sdim // changing the stop info till we're about to run. 373314564Sdim 374314564Sdim GetThread().SetStopInfoToNothing(); 375314564Sdim 376254721Semaste#ifndef SINGLE_STEP_EXPRESSIONS 377353358Sdim m_subplan_sp = std::make_shared<ThreadPlanRunToAddress>( 378353358Sdim m_thread, m_start_addr, m_stop_other_threads); 379314564Sdim 380314564Sdim m_thread.QueueThreadPlan(m_subplan_sp, false); 381314564Sdim m_subplan_sp->SetPrivate(true); 382254721Semaste#endif 383254721Semaste} 384254721Semaste 385314564Sdimbool ThreadPlanCallFunction::WillStop() { return true; } 386314564Sdim 387314564Sdimbool ThreadPlanCallFunction::MischiefManaged() { 388314564Sdim Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); 389314564Sdim 390314564Sdim if (IsPlanComplete()) { 391360784Sdim LLDB_LOGF(log, "ThreadPlanCallFunction(%p): Completed call function plan.", 392360784Sdim static_cast<void *>(this)); 393314564Sdim 394314564Sdim ThreadPlan::MischiefManaged(); 395254721Semaste return true; 396314564Sdim } else { 397314564Sdim return false; 398314564Sdim } 399254721Semaste} 400254721Semaste 401314564Sdimvoid ThreadPlanCallFunction::SetBreakpoints() { 402314564Sdim ProcessSP process_sp(m_thread.CalculateProcess()); 403314564Sdim if (m_trap_exceptions && process_sp) { 404314564Sdim m_cxx_language_runtime = 405314564Sdim process_sp->GetLanguageRuntime(eLanguageTypeC_plus_plus); 406314564Sdim m_objc_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeObjC); 407276479Sdim 408314564Sdim if (m_cxx_language_runtime) { 409314564Sdim m_should_clear_cxx_exception_bp = 410314564Sdim !m_cxx_language_runtime->ExceptionBreakpointsAreSet(); 411314564Sdim m_cxx_language_runtime->SetExceptionBreakpoints(); 412254721Semaste } 413314564Sdim if (m_objc_language_runtime) { 414314564Sdim m_should_clear_objc_exception_bp = 415314564Sdim !m_objc_language_runtime->ExceptionBreakpointsAreSet(); 416314564Sdim m_objc_language_runtime->SetExceptionBreakpoints(); 417254721Semaste } 418314564Sdim } 419254721Semaste} 420254721Semaste 421314564Sdimvoid ThreadPlanCallFunction::ClearBreakpoints() { 422314564Sdim if (m_trap_exceptions) { 423314564Sdim if (m_cxx_language_runtime && m_should_clear_cxx_exception_bp) 424314564Sdim m_cxx_language_runtime->ClearExceptionBreakpoints(); 425314564Sdim if (m_objc_language_runtime && m_should_clear_objc_exception_bp) 426314564Sdim m_objc_language_runtime->ClearExceptionBreakpoints(); 427314564Sdim } 428254721Semaste} 429254721Semaste 430314564Sdimbool ThreadPlanCallFunction::BreakpointsExplainStop() { 431314564Sdim StopInfoSP stop_info_sp = GetPrivateStopInfo(); 432314564Sdim 433314564Sdim if (m_trap_exceptions) { 434314564Sdim if ((m_cxx_language_runtime && 435314564Sdim m_cxx_language_runtime->ExceptionBreakpointsExplainStop( 436314564Sdim stop_info_sp)) || 437314564Sdim (m_objc_language_runtime && 438314564Sdim m_objc_language_runtime->ExceptionBreakpointsExplainStop( 439314564Sdim stop_info_sp))) { 440314564Sdim Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP)); 441360784Sdim LLDB_LOGF(log, "ThreadPlanCallFunction::BreakpointsExplainStop - Hit an " 442360784Sdim "exception breakpoint, setting plan complete."); 443314564Sdim 444314564Sdim SetPlanComplete(false); 445314564Sdim 446341825Sdim // If the user has set the ObjC language breakpoint, it would normally 447341825Sdim // get priority over our internal catcher breakpoint, but in this case we 448341825Sdim // can't let that happen, so force the ShouldStop here. 449314564Sdim stop_info_sp->OverrideShouldStop(true); 450314564Sdim return true; 451258884Semaste } 452314564Sdim } 453254721Semaste 454314564Sdim return false; 455254721Semaste} 456254721Semaste 457314564Sdimvoid ThreadPlanCallFunction::SetStopOthers(bool new_value) { 458314564Sdim m_subplan_sp->SetStopOthers(new_value); 459276479Sdim} 460276479Sdim 461314564Sdimbool ThreadPlanCallFunction::RestoreThreadState() { 462314564Sdim return GetThread().RestoreThreadStateFromCheckpoint(m_stored_thread_state); 463254721Semaste} 464254721Semaste 465314564Sdimvoid ThreadPlanCallFunction::SetReturnValue() { 466314564Sdim ProcessSP process_sp(m_thread.GetProcess()); 467314564Sdim const ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; 468314564Sdim if (abi && m_return_type.IsValid()) { 469314564Sdim const bool persistent = false; 470314564Sdim m_return_valobj_sp = 471314564Sdim abi->GetReturnValueObject(m_thread, m_return_type, persistent); 472314564Sdim } 473288943Sdim} 474