blob: c4cf133a27fd18b3279e8cd07db1e135d1ea190d [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:241//===-- ThreadPlanCallFunction.cpp ------------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:563// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Chris Lattner30fdc8d2010-06-08 16:52:246//
7//===----------------------------------------------------------------------===//
8
Eugene Zelenkoe65b2cf2015-12-15 01:33:199#include "lldb/Target/ThreadPlanCallFunction.h"
Jim Ingham40d871f2010-10-26 00:27:4510#include "lldb/Breakpoint/Breakpoint.h"
11#include "lldb/Breakpoint/BreakpointLocation.h"
Chris Lattner30fdc8d2010-06-08 16:52:2412#include "lldb/Core/Address.h"
Pavel Labathe03334c2018-07-24 15:48:1313#include "lldb/Core/DumpRegisterValue.h"
Greg Clayton1f746072012-08-29 21:13:0614#include "lldb/Core/Module.h"
Greg Clayton1f746072012-08-29 21:13:0615#include "lldb/Symbol/ObjectFile.h"
Zachary Turner32abc6e2015-03-03 19:23:0916#include "lldb/Target/ABI.h"
Sean Callananf2115102010-11-03 22:19:3817#include "lldb/Target/LanguageRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:2418#include "lldb/Target/Process.h"
19#include "lldb/Target/RegisterContext.h"
Jim Ingham40d871f2010-10-26 00:27:4520#include "lldb/Target/StopInfo.h"
Chris Lattner30fdc8d2010-06-08 16:52:2421#include "lldb/Target/Target.h"
22#include "lldb/Target/Thread.h"
23#include "lldb/Target/ThreadPlanRunToAddress.h"
Zachary Turner6f9e6902017-03-03 20:56:2824#include "lldb/Utility/Log.h"
Zachary Turnerbf9a7732017-02-02 21:39:5025#include "lldb/Utility/Stream.h"
Chris Lattner30fdc8d2010-06-08 16:52:2426
Jonas Devlieghere796ac802019-02-11 23:13:0827#include <memory>
28
Chris Lattner30fdc8d2010-06-08 16:52:2429using namespace lldb;
30using namespace lldb_private;
31
Chris Lattner30fdc8d2010-06-08 16:52:2432// ThreadPlanCallFunction: Plan to call a single function
Kate Stoneb9c1b512016-09-06 20:57:5033bool ThreadPlanCallFunction::ConstructorSetup(
34 Thread &thread, ABI *&abi, lldb::addr_t &start_load_addr,
35 lldb::addr_t &function_load_addr) {
36 SetIsMasterPlan(true);
37 SetOkayToDiscard(false);
38 SetPrivate(true);
Jim Ingham0092c8e2012-04-13 20:38:1339
Kate Stoneb9c1b512016-09-06 20:57:5040 ProcessSP process_sp(thread.GetProcess());
41 if (!process_sp)
42 return false;
Saleem Abdulrasool324a1032014-04-04 04:06:1043
Kate Stoneb9c1b512016-09-06 20:57:5044 abi = process_sp->GetABI().get();
Saleem Abdulrasool324a1032014-04-04 04:06:1045
Kate Stoneb9c1b512016-09-06 20:57:5046 if (!abi)
47 return false;
Saleem Abdulrasool324a1032014-04-04 04:06:1048
Kate Stoneb9c1b512016-09-06 20:57:5049 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP));
Saleem Abdulrasool324a1032014-04-04 04:06:1050
Kate Stoneb9c1b512016-09-06 20:57:5051 SetBreakpoints();
Saleem Abdulrasool324a1032014-04-04 04:06:1052
Kate Stoneb9c1b512016-09-06 20:57:5053 m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize();
54 // If we can't read memory at the point of the process where we are planning
Adrian Prantl05097242018-04-30 16:49:0455 // to put our function, we're not going to get any further...
Zachary Turner97206d52017-05-12 04:51:5556 Status error;
Kate Stoneb9c1b512016-09-06 20:57:5057 process_sp->ReadUnsignedIntegerFromMemory(m_function_sp, 4, 0, error);
58 if (!error.Success()) {
59 m_constructor_errors.Printf(
60 "Trying to put the stack in unreadable memory at: 0x%" PRIx64 ".",
61 m_function_sp);
62 if (log)
63 log->Printf("ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
64 m_constructor_errors.GetData());
65 return false;
66 }
67
Jonas Devlieghere0288c262019-07-19 00:52:0868 llvm::Expected<Address> start_address = GetTarget().GetEntryPointAddress();
69 if (!start_address) {
70 m_constructor_errors.Printf(
71 "%s", llvm::toString(start_address.takeError()).c_str());
72 if (log)
73 log->Printf("ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
74 m_constructor_errors.GetData());
Kate Stoneb9c1b512016-09-06 20:57:5075 return false;
Jason Molenda956761a2019-07-18 20:55:2476 }
Kate Stoneb9c1b512016-09-06 20:57:5077
Jonas Devlieghere0288c262019-07-19 00:52:0878 m_start_addr = *start_address;
Kate Stoneb9c1b512016-09-06 20:57:5079 start_load_addr = m_start_addr.GetLoadAddress(&GetTarget());
Saleem Abdulrasool324a1032014-04-04 04:06:1080
Kate Stoneb9c1b512016-09-06 20:57:5081 // Checkpoint the thread state so we can restore it later.
82 if (log && log->GetVerbose())
83 ReportRegisterState("About to checkpoint thread before function call. "
84 "Original register state was:");
85
86 if (!thread.CheckpointThreadState(m_stored_thread_state)) {
87 m_constructor_errors.Printf("Setting up ThreadPlanCallFunction, failed to "
88 "checkpoint thread state.");
89 if (log)
90 log->Printf("ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
91 m_constructor_errors.GetData());
92 return false;
93 }
94 function_load_addr = m_function_addr.GetLoadAddress(&GetTarget());
95
96 return true;
97}
98
99ThreadPlanCallFunction::ThreadPlanCallFunction(
100 Thread &thread, const Address &function, const CompilerType &return_type,
101 llvm::ArrayRef<addr_t> args, const EvaluateExpressionOptions &options)
102 : ThreadPlan(ThreadPlan::eKindCallFunction, "Call function plan", thread,
103 eVoteNoOpinion, eVoteNoOpinion),
104 m_valid(false), m_stop_other_threads(options.GetStopOthers()),
105 m_unwind_on_error(options.DoesUnwindOnError()),
106 m_ignore_breakpoints(options.DoesIgnoreBreakpoints()),
107 m_debug_execution(options.GetDebug()),
108 m_trap_exceptions(options.GetTrapExceptions()), m_function_addr(function),
109 m_function_sp(0), m_takedown_done(false),
110 m_should_clear_objc_exception_bp(false),
111 m_should_clear_cxx_exception_bp(false),
112 m_stop_address(LLDB_INVALID_ADDRESS), m_return_type(return_type) {
113 lldb::addr_t start_load_addr = LLDB_INVALID_ADDRESS;
114 lldb::addr_t function_load_addr = LLDB_INVALID_ADDRESS;
115 ABI *abi = nullptr;
116
117 if (!ConstructorSetup(thread, abi, start_load_addr, function_load_addr))
118 return;
119
120 if (!abi->PrepareTrivialCall(thread, m_function_sp, function_load_addr,
121 start_load_addr, args))
122 return;
123
124 ReportRegisterState("Function call was set up. Register state was:");
125
126 m_valid = true;
127}
128
129ThreadPlanCallFunction::ThreadPlanCallFunction(
130 Thread &thread, const Address &function,
131 const EvaluateExpressionOptions &options)
132 : ThreadPlan(ThreadPlan::eKindCallFunction, "Call function plan", thread,
133 eVoteNoOpinion, eVoteNoOpinion),
134 m_valid(false), m_stop_other_threads(options.GetStopOthers()),
135 m_unwind_on_error(options.DoesUnwindOnError()),
136 m_ignore_breakpoints(options.DoesIgnoreBreakpoints()),
137 m_debug_execution(options.GetDebug()),
138 m_trap_exceptions(options.GetTrapExceptions()), m_function_addr(function),
139 m_function_sp(0), m_takedown_done(false),
140 m_should_clear_objc_exception_bp(false),
141 m_should_clear_cxx_exception_bp(false),
142 m_stop_address(LLDB_INVALID_ADDRESS), m_return_type(CompilerType()) {}
143
144ThreadPlanCallFunction::~ThreadPlanCallFunction() {
145 DoTakedown(PlanSucceeded());
146}
147
148void ThreadPlanCallFunction::ReportRegisterState(const char *message) {
Pavel Labath3b7e1982017-02-05 00:44:54149 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
150 if (log && log->GetVerbose()) {
Kate Stoneb9c1b512016-09-06 20:57:50151 StreamString strm;
152 RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
153
154 log->PutCString(message);
155
156 RegisterValue reg_value;
157
158 for (uint32_t reg_idx = 0, num_registers = reg_ctx->GetRegisterCount();
159 reg_idx < num_registers; ++reg_idx) {
160 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_idx);
161 if (reg_ctx->ReadRegister(reg_info, reg_value)) {
Pavel Labathe03334c2018-07-24 15:48:13162 DumpRegisterValue(reg_value, &strm, reg_info, true, false,
163 eFormatDefault);
Kate Stoneb9c1b512016-09-06 20:57:50164 strm.EOL();
165 }
Jim Ingham0092c8e2012-04-13 20:38:13166 }
Zachary Turnerc1564272016-11-16 21:15:24167 log->PutString(strm.GetString());
Kate Stoneb9c1b512016-09-06 20:57:50168 }
169}
Saleem Abdulrasool324a1032014-04-04 04:06:10170
Kate Stoneb9c1b512016-09-06 20:57:50171void ThreadPlanCallFunction::DoTakedown(bool success) {
172 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP));
Saleem Abdulrasool324a1032014-04-04 04:06:10173
Kate Stoneb9c1b512016-09-06 20:57:50174 if (!m_valid) {
175 // Don't call DoTakedown if we were never valid to begin with.
176 if (log)
177 log->Printf("ThreadPlanCallFunction(%p): Log called on "
178 "ThreadPlanCallFunction that was never valid.",
179 static_cast<void *>(this));
180 return;
181 }
182
183 if (!m_takedown_done) {
184 if (success) {
185 SetReturnValue();
186 }
187 if (log)
188 log->Printf("ThreadPlanCallFunction(%p): DoTakedown called for thread "
189 "0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n",
190 static_cast<void *>(this), m_thread.GetID(), m_valid,
191 IsPlanComplete());
192 m_takedown_done = true;
193 m_stop_address =
194 m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC();
195 m_real_stop_info_sp = GetPrivateStopInfo();
196 if (!m_thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state)) {
197 if (log)
198 log->Printf("ThreadPlanCallFunction(%p): DoTakedown failed to restore "
199 "register state",
200 static_cast<void *>(this));
201 }
202 SetPlanComplete(success);
203 ClearBreakpoints();
Jim Ingham0092c8e2012-04-13 20:38:13204 if (log && log->GetVerbose())
Kate Stoneb9c1b512016-09-06 20:57:50205 ReportRegisterState("Restoring thread state after function call. "
206 "Restored register state:");
207 } else {
Sean Callananece96492010-11-08 03:49:50208 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50209 log->Printf("ThreadPlanCallFunction(%p): DoTakedown called as no-op for "
210 "thread 0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n",
211 static_cast<void *>(this), m_thread.GetID(), m_valid,
212 IsPlanComplete());
213 }
Sean Callanan10af7c42010-11-04 01:51:38214}
215
Kate Stoneb9c1b512016-09-06 20:57:50216void ThreadPlanCallFunction::WillPop() { DoTakedown(PlanSucceeded()); }
Saleem Abdulrasool324a1032014-04-04 04:06:10217
Kate Stoneb9c1b512016-09-06 20:57:50218void ThreadPlanCallFunction::GetDescription(Stream *s, DescriptionLevel level) {
219 if (level == eDescriptionLevelBrief) {
220 s->Printf("Function call thread plan");
221 } else {
222 TargetSP target_sp(m_thread.CalculateTarget());
223 s->Printf("Thread plan to call 0x%" PRIx64,
224 m_function_addr.GetLoadAddress(target_sp.get()));
225 }
Chris Lattner30fdc8d2010-06-08 16:52:24226}
227
Kate Stoneb9c1b512016-09-06 20:57:50228bool ThreadPlanCallFunction::ValidatePlan(Stream *error) {
229 if (!m_valid) {
230 if (error) {
231 if (m_constructor_errors.GetSize() > 0)
Zachary Turnerc1564272016-11-16 21:15:24232 error->PutCString(m_constructor_errors.GetString());
Kate Stoneb9c1b512016-09-06 20:57:50233 else
234 error->PutCString("Unknown error");
235 }
236 return false;
237 }
238
239 return true;
Jim Inghambda4e5eb2011-01-18 01:58:06240}
241
Kate Stoneb9c1b512016-09-06 20:57:50242Vote ThreadPlanCallFunction::ShouldReportStop(Event *event_ptr) {
243 if (m_takedown_done || IsPlanComplete())
244 return eVoteYes;
245 else
246 return ThreadPlan::ShouldReportStop(event_ptr);
Chris Lattner30fdc8d2010-06-08 16:52:24247}
248
Kate Stoneb9c1b512016-09-06 20:57:50249bool ThreadPlanCallFunction::DoPlanExplainsStop(Event *event_ptr) {
250 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP |
251 LIBLLDB_LOG_PROCESS));
252 m_real_stop_info_sp = GetPrivateStopInfo();
Chris Lattner30fdc8d2010-06-08 16:52:24253
Adrian Prantl05097242018-04-30 16:49:04254 // If our subplan knows why we stopped, even if it's done (which would
255 // forward the question to us) we answer yes.
Kate Stoneb9c1b512016-09-06 20:57:50256 if (m_subplan_sp && m_subplan_sp->PlanExplainsStop(event_ptr)) {
257 SetPlanComplete();
Chris Lattner30fdc8d2010-06-08 16:52:24258 return true;
Kate Stoneb9c1b512016-09-06 20:57:50259 }
Chris Lattner30fdc8d2010-06-08 16:52:24260
Kate Stoneb9c1b512016-09-06 20:57:50261 // Check if the breakpoint is one of ours.
Jim Ingham0161b492013-02-09 01:29:05262
Kate Stoneb9c1b512016-09-06 20:57:50263 StopReason stop_reason;
264 if (!m_real_stop_info_sp)
265 stop_reason = eStopReasonNone;
266 else
267 stop_reason = m_real_stop_info_sp->GetStopReason();
268 if (log)
269 log->Printf(
270 "ThreadPlanCallFunction::PlanExplainsStop: Got stop reason - %s.",
271 Thread::StopReasonAsCString(stop_reason));
272
273 if (stop_reason == eStopReasonBreakpoint && BreakpointsExplainStop())
274 return true;
275
276 // One more quirk here. If this event was from Halt interrupting the target,
Adrian Prantl05097242018-04-30 16:49:04277 // then we should not consider ourselves complete. Return true to
278 // acknowledge the stop.
Kate Stoneb9c1b512016-09-06 20:57:50279 if (Process::ProcessEventData::GetInterruptedFromEvent(event_ptr)) {
Jim Ingham0161b492013-02-09 01:29:05280 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50281 log->Printf("ThreadPlanCallFunction::PlanExplainsStop: The event is an "
282 "Interrupt, returning true.");
283 return true;
284 }
285 // We control breakpoints separately from other "stop reasons." So first,
286 // check the case where we stopped for an internal breakpoint, in that case,
Adrian Prantl05097242018-04-30 16:49:04287 // continue on. If it is not an internal breakpoint, consult
288 // m_ignore_breakpoints.
Jim Ingham18de2fd2012-05-10 01:35:39289
Kate Stoneb9c1b512016-09-06 20:57:50290 if (stop_reason == eStopReasonBreakpoint) {
291 ProcessSP process_sp(m_thread.CalculateProcess());
292 uint64_t break_site_id = m_real_stop_info_sp->GetValue();
293 BreakpointSiteSP bp_site_sp;
294 if (process_sp)
295 bp_site_sp = process_sp->GetBreakpointSiteList().FindByID(break_site_id);
296 if (bp_site_sp) {
297 uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
298 bool is_internal = true;
299 for (uint32_t i = 0; i < num_owners; i++) {
300 Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
Jim Ingham35878c42014-04-08 21:33:21301 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50302 log->Printf("ThreadPlanCallFunction::PlanExplainsStop: hit "
303 "breakpoint %d while calling function",
304 bp.GetID());
Eugene Zelenkoe65b2cf2015-12-15 01:33:19305
Kate Stoneb9c1b512016-09-06 20:57:50306 if (!bp.IsInternal()) {
307 is_internal = false;
308 break;
Jim Ingham40d871f2010-10-26 00:27:45309 }
Kate Stoneb9c1b512016-09-06 20:57:50310 }
311 if (is_internal) {
312 if (log)
313 log->Printf("ThreadPlanCallFunction::PlanExplainsStop hit an "
314 "internal breakpoint, not stopping.");
Jim Ingham0161b492013-02-09 01:29:05315 return false;
Kate Stoneb9c1b512016-09-06 20:57:50316 }
Jim Ingham40d871f2010-10-26 00:27:45317 }
Kate Stoneb9c1b512016-09-06 20:57:50318
319 if (m_ignore_breakpoints) {
320 if (log)
321 log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are ignoring "
322 "breakpoints, overriding breakpoint stop info ShouldStop, "
323 "returning true");
324 m_real_stop_info_sp->OverrideShouldStop(false);
325 return true;
326 } else {
327 if (log)
328 log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are not "
329 "ignoring breakpoints, overriding breakpoint stop info "
330 "ShouldStop, returning true");
331 m_real_stop_info_sp->OverrideShouldStop(true);
332 return false;
Jim Ingham40d871f2010-10-26 00:27:45333 }
Kate Stoneb9c1b512016-09-06 20:57:50334 } else if (!m_unwind_on_error) {
335 // If we don't want to discard this plan, than any stop we don't understand
336 // should be propagated up the stack.
337 return false;
338 } else {
Adrian Prantl05097242018-04-30 16:49:04339 // If the subplan is running, any crashes are attributable to us. If we
340 // want to discard the plan, then we say we explain the stop but if we are
341 // going to be discarded, let whoever is above us explain the stop. But
342 // don't discard the plan if the stop would restart itself (for instance if
343 // it is a signal that is set not to stop. Check that here first. We just
344 // say we explain the stop but aren't done and everything will continue on
345 // from there.
Kate Stoneb9c1b512016-09-06 20:57:50346
347 if (m_real_stop_info_sp &&
348 m_real_stop_info_sp->ShouldStopSynchronous(event_ptr)) {
349 SetPlanComplete(false);
350 return m_subplan_sp ? m_unwind_on_error : false;
351 } else
352 return true;
353 }
Chris Lattner30fdc8d2010-06-08 16:52:24354}
355
Kate Stoneb9c1b512016-09-06 20:57:50356bool ThreadPlanCallFunction::ShouldStop(Event *event_ptr) {
357 // We do some computation in DoPlanExplainsStop that may or may not set the
Adrian Prantl05097242018-04-30 16:49:04358 // plan as complete. We need to do that here to make sure our state is
359 // correct.
Kate Stoneb9c1b512016-09-06 20:57:50360 DoPlanExplainsStop(event_ptr);
361
362 if (IsPlanComplete()) {
363 ReportRegisterState("Function completed. Register state was:");
364 return true;
365 } else {
366 return false;
367 }
Chris Lattner30fdc8d2010-06-08 16:52:24368}
369
Kate Stoneb9c1b512016-09-06 20:57:50370bool ThreadPlanCallFunction::StopOthers() { return m_stop_other_threads; }
Chris Lattner30fdc8d2010-06-08 16:52:24371
Kate Stoneb9c1b512016-09-06 20:57:50372StateType ThreadPlanCallFunction::GetPlanRunState() { return eStateRunning; }
Chris Lattner30fdc8d2010-06-08 16:52:24373
Kate Stoneb9c1b512016-09-06 20:57:50374void ThreadPlanCallFunction::DidPush() {
375 //#define SINGLE_STEP_EXPRESSIONS
376
377 // Now set the thread state to "no reason" so we don't run with whatever
Adrian Prantl05097242018-04-30 16:49:04378 // signal was outstanding... Wait till the plan is pushed so we aren't
379 // changing the stop info till we're about to run.
Kate Stoneb9c1b512016-09-06 20:57:50380
381 GetThread().SetStopInfoToNothing();
382
Sean Callananbe3a1b12010-10-26 00:31:56383#ifndef SINGLE_STEP_EXPRESSIONS
Jonas Devlieghere796ac802019-02-11 23:13:08384 m_subplan_sp = std::make_shared<ThreadPlanRunToAddress>(
385 m_thread, m_start_addr, m_stop_other_threads);
Kate Stoneb9c1b512016-09-06 20:57:50386
387 m_thread.QueueThreadPlan(m_subplan_sp, false);
388 m_subplan_sp->SetPrivate(true);
Sean Callananbe3a1b12010-10-26 00:31:56389#endif
Chris Lattner30fdc8d2010-06-08 16:52:24390}
391
Kate Stoneb9c1b512016-09-06 20:57:50392bool ThreadPlanCallFunction::WillStop() { return true; }
393
394bool ThreadPlanCallFunction::MischiefManaged() {
395 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
396
397 if (IsPlanComplete()) {
398 if (log)
399 log->Printf("ThreadPlanCallFunction(%p): Completed call function plan.",
400 static_cast<void *>(this));
401
402 ThreadPlan::MischiefManaged();
Chris Lattner30fdc8d2010-06-08 16:52:24403 return true;
Kate Stoneb9c1b512016-09-06 20:57:50404 } else {
Sean Callananc98aca62010-11-03 19:36:28405 return false;
Kate Stoneb9c1b512016-09-06 20:57:50406 }
Sean Callananc98aca62010-11-03 19:36:28407}
Jim Ingham8559a352012-11-26 23:52:18408
Kate Stoneb9c1b512016-09-06 20:57:50409void ThreadPlanCallFunction::SetBreakpoints() {
410 ProcessSP process_sp(m_thread.CalculateProcess());
411 if (m_trap_exceptions && process_sp) {
412 m_cxx_language_runtime =
413 process_sp->GetLanguageRuntime(eLanguageTypeC_plus_plus);
414 m_objc_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeObjC);
Jim Ingham0ff099f2014-03-07 11:16:37415
Kate Stoneb9c1b512016-09-06 20:57:50416 if (m_cxx_language_runtime) {
417 m_should_clear_cxx_exception_bp =
418 !m_cxx_language_runtime->ExceptionBreakpointsAreSet();
419 m_cxx_language_runtime->SetExceptionBreakpoints();
Ewan Crawford90ff7912015-07-14 10:56:58420 }
Kate Stoneb9c1b512016-09-06 20:57:50421 if (m_objc_language_runtime) {
422 m_should_clear_objc_exception_bp =
423 !m_objc_language_runtime->ExceptionBreakpointsAreSet();
424 m_objc_language_runtime->SetExceptionBreakpoints();
425 }
426 }
427}
428
429void ThreadPlanCallFunction::ClearBreakpoints() {
430 if (m_trap_exceptions) {
431 if (m_cxx_language_runtime && m_should_clear_cxx_exception_bp)
432 m_cxx_language_runtime->ClearExceptionBreakpoints();
433 if (m_objc_language_runtime && m_should_clear_objc_exception_bp)
434 m_objc_language_runtime->ClearExceptionBreakpoints();
435 }
436}
437
438bool ThreadPlanCallFunction::BreakpointsExplainStop() {
439 StopInfoSP stop_info_sp = GetPrivateStopInfo();
440
441 if (m_trap_exceptions) {
442 if ((m_cxx_language_runtime &&
443 m_cxx_language_runtime->ExceptionBreakpointsExplainStop(
444 stop_info_sp)) ||
445 (m_objc_language_runtime &&
446 m_objc_language_runtime->ExceptionBreakpointsExplainStop(
447 stop_info_sp))) {
448 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP));
449 if (log)
450 log->Printf("ThreadPlanCallFunction::BreakpointsExplainStop - Hit an "
451 "exception breakpoint, setting plan complete.");
452
453 SetPlanComplete(false);
454
Adrian Prantl05097242018-04-30 16:49:04455 // If the user has set the ObjC language breakpoint, it would normally
456 // get priority over our internal catcher breakpoint, but in this case we
457 // can't let that happen, so force the ShouldStop here.
Kate Stoneb9c1b512016-09-06 20:57:50458 stop_info_sp->OverrideShouldStop(true);
459 return true;
460 }
461 }
462
463 return false;
464}
465
466void ThreadPlanCallFunction::SetStopOthers(bool new_value) {
467 m_subplan_sp->SetStopOthers(new_value);
468}
469
470bool ThreadPlanCallFunction::RestoreThreadState() {
471 return GetThread().RestoreThreadStateFromCheckpoint(m_stored_thread_state);
472}
473
474void ThreadPlanCallFunction::SetReturnValue() {
475 ProcessSP process_sp(m_thread.GetProcess());
476 const ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr;
477 if (abi && m_return_type.IsValid()) {
478 const bool persistent = false;
479 m_return_valobj_sp =
480 abi->GetReturnValueObject(m_thread, m_return_type, persistent);
481 }
Ewan Crawford90ff7912015-07-14 10:56:58482}