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