blob: 57f4ef5874cd348800960c1e1a0cef318e853699 [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
Jason Molenda956761a2019-07-18 20:55:2468 m_start_addr = GetTarget().GetEntryPointAddress(error);
Kate Stoneb9c1b512016-09-06 20:57:5069
Jason Molenda956761a2019-07-18 20:55:2470 if (log && error.Fail()) {
71 m_constructor_errors.Printf("%s", error.AsCString());
72 log->Printf("ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
73 m_constructor_errors.GetData());
Kate Stoneb9c1b512016-09-06 20:57:5074 return false;
Jason Molenda956761a2019-07-18 20:55:2475 }
Kate Stoneb9c1b512016-09-06 20:57:5076
Jason Molenda956761a2019-07-18 20:55:2477 if (!m_start_addr.IsValid()) {
78 return false;
Kate Stoneb9c1b512016-09-06 20:57:5079 }
Jim Inghamea06f3b2013-03-28 00:04:0580
Kate Stoneb9c1b512016-09-06 20:57:5081 start_load_addr = m_start_addr.GetLoadAddress(&GetTarget());
Saleem Abdulrasool324a1032014-04-04 04:06:1082
Kate Stoneb9c1b512016-09-06 20:57:5083 // Checkpoint the thread state so we can restore it later.
84 if (log && log->GetVerbose())
85 ReportRegisterState("About to checkpoint thread before function call. "
86 "Original register state was:");
87
88 if (!thread.CheckpointThreadState(m_stored_thread_state)) {
89 m_constructor_errors.Printf("Setting up ThreadPlanCallFunction, failed to "
90 "checkpoint thread state.");
91 if (log)
92 log->Printf("ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
93 m_constructor_errors.GetData());
94 return false;
95 }
96 function_load_addr = m_function_addr.GetLoadAddress(&GetTarget());
97
98 return true;
99}
100
101ThreadPlanCallFunction::ThreadPlanCallFunction(
102 Thread &thread, const Address &function, const CompilerType &return_type,
103 llvm::ArrayRef<addr_t> args, const EvaluateExpressionOptions &options)
104 : ThreadPlan(ThreadPlan::eKindCallFunction, "Call function plan", thread,
105 eVoteNoOpinion, eVoteNoOpinion),
106 m_valid(false), m_stop_other_threads(options.GetStopOthers()),
107 m_unwind_on_error(options.DoesUnwindOnError()),
108 m_ignore_breakpoints(options.DoesIgnoreBreakpoints()),
109 m_debug_execution(options.GetDebug()),
110 m_trap_exceptions(options.GetTrapExceptions()), m_function_addr(function),
111 m_function_sp(0), m_takedown_done(false),
112 m_should_clear_objc_exception_bp(false),
113 m_should_clear_cxx_exception_bp(false),
114 m_stop_address(LLDB_INVALID_ADDRESS), m_return_type(return_type) {
115 lldb::addr_t start_load_addr = LLDB_INVALID_ADDRESS;
116 lldb::addr_t function_load_addr = LLDB_INVALID_ADDRESS;
117 ABI *abi = nullptr;
118
119 if (!ConstructorSetup(thread, abi, start_load_addr, function_load_addr))
120 return;
121
122 if (!abi->PrepareTrivialCall(thread, m_function_sp, function_load_addr,
123 start_load_addr, args))
124 return;
125
126 ReportRegisterState("Function call was set up. Register state was:");
127
128 m_valid = true;
129}
130
131ThreadPlanCallFunction::ThreadPlanCallFunction(
132 Thread &thread, const Address &function,
133 const EvaluateExpressionOptions &options)
134 : ThreadPlan(ThreadPlan::eKindCallFunction, "Call function plan", thread,
135 eVoteNoOpinion, eVoteNoOpinion),
136 m_valid(false), m_stop_other_threads(options.GetStopOthers()),
137 m_unwind_on_error(options.DoesUnwindOnError()),
138 m_ignore_breakpoints(options.DoesIgnoreBreakpoints()),
139 m_debug_execution(options.GetDebug()),
140 m_trap_exceptions(options.GetTrapExceptions()), m_function_addr(function),
141 m_function_sp(0), m_takedown_done(false),
142 m_should_clear_objc_exception_bp(false),
143 m_should_clear_cxx_exception_bp(false),
144 m_stop_address(LLDB_INVALID_ADDRESS), m_return_type(CompilerType()) {}
145
146ThreadPlanCallFunction::~ThreadPlanCallFunction() {
147 DoTakedown(PlanSucceeded());
148}
149
150void ThreadPlanCallFunction::ReportRegisterState(const char *message) {
Pavel Labath3b7e1982017-02-05 00:44:54151 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
152 if (log && log->GetVerbose()) {
Kate Stoneb9c1b512016-09-06 20:57:50153 StreamString strm;
154 RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
155
156 log->PutCString(message);
157
158 RegisterValue reg_value;
159
160 for (uint32_t reg_idx = 0, num_registers = reg_ctx->GetRegisterCount();
161 reg_idx < num_registers; ++reg_idx) {
162 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_idx);
163 if (reg_ctx->ReadRegister(reg_info, reg_value)) {
Pavel Labathe03334c2018-07-24 15:48:13164 DumpRegisterValue(reg_value, &strm, reg_info, true, false,
165 eFormatDefault);
Kate Stoneb9c1b512016-09-06 20:57:50166 strm.EOL();
167 }
Jim Ingham0092c8e2012-04-13 20:38:13168 }
Zachary Turnerc1564272016-11-16 21:15:24169 log->PutString(strm.GetString());
Kate Stoneb9c1b512016-09-06 20:57:50170 }
171}
Saleem Abdulrasool324a1032014-04-04 04:06:10172
Kate Stoneb9c1b512016-09-06 20:57:50173void ThreadPlanCallFunction::DoTakedown(bool success) {
174 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP));
Saleem Abdulrasool324a1032014-04-04 04:06:10175
Kate Stoneb9c1b512016-09-06 20:57:50176 if (!m_valid) {
177 // Don't call DoTakedown if we were never valid to begin with.
178 if (log)
179 log->Printf("ThreadPlanCallFunction(%p): Log called on "
180 "ThreadPlanCallFunction that was never valid.",
181 static_cast<void *>(this));
182 return;
183 }
184
185 if (!m_takedown_done) {
186 if (success) {
187 SetReturnValue();
188 }
189 if (log)
190 log->Printf("ThreadPlanCallFunction(%p): DoTakedown called for thread "
191 "0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n",
192 static_cast<void *>(this), m_thread.GetID(), m_valid,
193 IsPlanComplete());
194 m_takedown_done = true;
195 m_stop_address =
196 m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC();
197 m_real_stop_info_sp = GetPrivateStopInfo();
198 if (!m_thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state)) {
199 if (log)
200 log->Printf("ThreadPlanCallFunction(%p): DoTakedown failed to restore "
201 "register state",
202 static_cast<void *>(this));
203 }
204 SetPlanComplete(success);
205 ClearBreakpoints();
Jim Ingham0092c8e2012-04-13 20:38:13206 if (log && log->GetVerbose())
Kate Stoneb9c1b512016-09-06 20:57:50207 ReportRegisterState("Restoring thread state after function call. "
208 "Restored register state:");
209 } else {
Sean Callananece96492010-11-08 03:49:50210 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50211 log->Printf("ThreadPlanCallFunction(%p): DoTakedown called as no-op for "
212 "thread 0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n",
213 static_cast<void *>(this), m_thread.GetID(), m_valid,
214 IsPlanComplete());
215 }
Sean Callanan10af7c42010-11-04 01:51:38216}
217
Kate Stoneb9c1b512016-09-06 20:57:50218void ThreadPlanCallFunction::WillPop() { DoTakedown(PlanSucceeded()); }
Saleem Abdulrasool324a1032014-04-04 04:06:10219
Kate Stoneb9c1b512016-09-06 20:57:50220void ThreadPlanCallFunction::GetDescription(Stream *s, DescriptionLevel level) {
221 if (level == eDescriptionLevelBrief) {
222 s->Printf("Function call thread plan");
223 } else {
224 TargetSP target_sp(m_thread.CalculateTarget());
225 s->Printf("Thread plan to call 0x%" PRIx64,
226 m_function_addr.GetLoadAddress(target_sp.get()));
227 }
Chris Lattner30fdc8d2010-06-08 16:52:24228}
229
Kate Stoneb9c1b512016-09-06 20:57:50230bool ThreadPlanCallFunction::ValidatePlan(Stream *error) {
231 if (!m_valid) {
232 if (error) {
233 if (m_constructor_errors.GetSize() > 0)
Zachary Turnerc1564272016-11-16 21:15:24234 error->PutCString(m_constructor_errors.GetString());
Kate Stoneb9c1b512016-09-06 20:57:50235 else
236 error->PutCString("Unknown error");
237 }
238 return false;
239 }
240
241 return true;
Jim Inghambda4e5eb2011-01-18 01:58:06242}
243
Kate Stoneb9c1b512016-09-06 20:57:50244Vote ThreadPlanCallFunction::ShouldReportStop(Event *event_ptr) {
245 if (m_takedown_done || IsPlanComplete())
246 return eVoteYes;
247 else
248 return ThreadPlan::ShouldReportStop(event_ptr);
Chris Lattner30fdc8d2010-06-08 16:52:24249}
250
Kate Stoneb9c1b512016-09-06 20:57:50251bool ThreadPlanCallFunction::DoPlanExplainsStop(Event *event_ptr) {
252 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP |
253 LIBLLDB_LOG_PROCESS));
254 m_real_stop_info_sp = GetPrivateStopInfo();
Chris Lattner30fdc8d2010-06-08 16:52:24255
Adrian Prantl05097242018-04-30 16:49:04256 // If our subplan knows why we stopped, even if it's done (which would
257 // forward the question to us) we answer yes.
Kate Stoneb9c1b512016-09-06 20:57:50258 if (m_subplan_sp && m_subplan_sp->PlanExplainsStop(event_ptr)) {
259 SetPlanComplete();
Chris Lattner30fdc8d2010-06-08 16:52:24260 return true;
Kate Stoneb9c1b512016-09-06 20:57:50261 }
Chris Lattner30fdc8d2010-06-08 16:52:24262
Kate Stoneb9c1b512016-09-06 20:57:50263 // Check if the breakpoint is one of ours.
Jim Ingham0161b492013-02-09 01:29:05264
Kate Stoneb9c1b512016-09-06 20:57:50265 StopReason stop_reason;
266 if (!m_real_stop_info_sp)
267 stop_reason = eStopReasonNone;
268 else
269 stop_reason = m_real_stop_info_sp->GetStopReason();
270 if (log)
271 log->Printf(
272 "ThreadPlanCallFunction::PlanExplainsStop: Got stop reason - %s.",
273 Thread::StopReasonAsCString(stop_reason));
274
275 if (stop_reason == eStopReasonBreakpoint && BreakpointsExplainStop())
276 return true;
277
278 // One more quirk here. If this event was from Halt interrupting the target,
Adrian Prantl05097242018-04-30 16:49:04279 // then we should not consider ourselves complete. Return true to
280 // acknowledge the stop.
Kate Stoneb9c1b512016-09-06 20:57:50281 if (Process::ProcessEventData::GetInterruptedFromEvent(event_ptr)) {
Jim Ingham0161b492013-02-09 01:29:05282 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50283 log->Printf("ThreadPlanCallFunction::PlanExplainsStop: The event is an "
284 "Interrupt, returning true.");
285 return true;
286 }
287 // We control breakpoints separately from other "stop reasons." So first,
288 // check the case where we stopped for an internal breakpoint, in that case,
Adrian Prantl05097242018-04-30 16:49:04289 // continue on. If it is not an internal breakpoint, consult
290 // m_ignore_breakpoints.
Jim Ingham18de2fd2012-05-10 01:35:39291
Kate Stoneb9c1b512016-09-06 20:57:50292 if (stop_reason == eStopReasonBreakpoint) {
293 ProcessSP process_sp(m_thread.CalculateProcess());
294 uint64_t break_site_id = m_real_stop_info_sp->GetValue();
295 BreakpointSiteSP bp_site_sp;
296 if (process_sp)
297 bp_site_sp = process_sp->GetBreakpointSiteList().FindByID(break_site_id);
298 if (bp_site_sp) {
299 uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
300 bool is_internal = true;
301 for (uint32_t i = 0; i < num_owners; i++) {
302 Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
Jim Ingham35878c42014-04-08 21:33:21303 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50304 log->Printf("ThreadPlanCallFunction::PlanExplainsStop: hit "
305 "breakpoint %d while calling function",
306 bp.GetID());
Eugene Zelenkoe65b2cf2015-12-15 01:33:19307
Kate Stoneb9c1b512016-09-06 20:57:50308 if (!bp.IsInternal()) {
309 is_internal = false;
310 break;
Jim Ingham40d871f2010-10-26 00:27:45311 }
Kate Stoneb9c1b512016-09-06 20:57:50312 }
313 if (is_internal) {
314 if (log)
315 log->Printf("ThreadPlanCallFunction::PlanExplainsStop hit an "
316 "internal breakpoint, not stopping.");
Jim Ingham0161b492013-02-09 01:29:05317 return false;
Kate Stoneb9c1b512016-09-06 20:57:50318 }
Jim Ingham40d871f2010-10-26 00:27:45319 }
Kate Stoneb9c1b512016-09-06 20:57:50320
321 if (m_ignore_breakpoints) {
322 if (log)
323 log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are ignoring "
324 "breakpoints, overriding breakpoint stop info ShouldStop, "
325 "returning true");
326 m_real_stop_info_sp->OverrideShouldStop(false);
327 return true;
328 } else {
329 if (log)
330 log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are not "
331 "ignoring breakpoints, overriding breakpoint stop info "
332 "ShouldStop, returning true");
333 m_real_stop_info_sp->OverrideShouldStop(true);
334 return false;
Jim Ingham40d871f2010-10-26 00:27:45335 }
Kate Stoneb9c1b512016-09-06 20:57:50336 } else if (!m_unwind_on_error) {
337 // If we don't want to discard this plan, than any stop we don't understand
338 // should be propagated up the stack.
339 return false;
340 } else {
Adrian Prantl05097242018-04-30 16:49:04341 // If the subplan is running, any crashes are attributable to us. If we
342 // want to discard the plan, then we say we explain the stop but if we are
343 // going to be discarded, let whoever is above us explain the stop. But
344 // don't discard the plan if the stop would restart itself (for instance if
345 // it is a signal that is set not to stop. Check that here first. We just
346 // say we explain the stop but aren't done and everything will continue on
347 // from there.
Kate Stoneb9c1b512016-09-06 20:57:50348
349 if (m_real_stop_info_sp &&
350 m_real_stop_info_sp->ShouldStopSynchronous(event_ptr)) {
351 SetPlanComplete(false);
352 return m_subplan_sp ? m_unwind_on_error : false;
353 } else
354 return true;
355 }
Chris Lattner30fdc8d2010-06-08 16:52:24356}
357
Kate Stoneb9c1b512016-09-06 20:57:50358bool ThreadPlanCallFunction::ShouldStop(Event *event_ptr) {
359 // We do some computation in DoPlanExplainsStop that may or may not set the
Adrian Prantl05097242018-04-30 16:49:04360 // plan as complete. We need to do that here to make sure our state is
361 // correct.
Kate Stoneb9c1b512016-09-06 20:57:50362 DoPlanExplainsStop(event_ptr);
363
364 if (IsPlanComplete()) {
365 ReportRegisterState("Function completed. Register state was:");
366 return true;
367 } else {
368 return false;
369 }
Chris Lattner30fdc8d2010-06-08 16:52:24370}
371
Kate Stoneb9c1b512016-09-06 20:57:50372bool ThreadPlanCallFunction::StopOthers() { return m_stop_other_threads; }
Chris Lattner30fdc8d2010-06-08 16:52:24373
Kate Stoneb9c1b512016-09-06 20:57:50374StateType ThreadPlanCallFunction::GetPlanRunState() { return eStateRunning; }
Chris Lattner30fdc8d2010-06-08 16:52:24375
Kate Stoneb9c1b512016-09-06 20:57:50376void ThreadPlanCallFunction::DidPush() {
377 //#define SINGLE_STEP_EXPRESSIONS
378
379 // Now set the thread state to "no reason" so we don't run with whatever
Adrian Prantl05097242018-04-30 16:49:04380 // signal was outstanding... Wait till the plan is pushed so we aren't
381 // changing the stop info till we're about to run.
Kate Stoneb9c1b512016-09-06 20:57:50382
383 GetThread().SetStopInfoToNothing();
384
Sean Callananbe3a1b12010-10-26 00:31:56385#ifndef SINGLE_STEP_EXPRESSIONS
Jonas Devlieghere796ac802019-02-11 23:13:08386 m_subplan_sp = std::make_shared<ThreadPlanRunToAddress>(
387 m_thread, m_start_addr, m_stop_other_threads);
Kate Stoneb9c1b512016-09-06 20:57:50388
389 m_thread.QueueThreadPlan(m_subplan_sp, false);
390 m_subplan_sp->SetPrivate(true);
Sean Callananbe3a1b12010-10-26 00:31:56391#endif
Chris Lattner30fdc8d2010-06-08 16:52:24392}
393
Kate Stoneb9c1b512016-09-06 20:57:50394bool ThreadPlanCallFunction::WillStop() { return true; }
395
396bool ThreadPlanCallFunction::MischiefManaged() {
397 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
398
399 if (IsPlanComplete()) {
400 if (log)
401 log->Printf("ThreadPlanCallFunction(%p): Completed call function plan.",
402 static_cast<void *>(this));
403
404 ThreadPlan::MischiefManaged();
Chris Lattner30fdc8d2010-06-08 16:52:24405 return true;
Kate Stoneb9c1b512016-09-06 20:57:50406 } else {
Sean Callananc98aca62010-11-03 19:36:28407 return false;
Kate Stoneb9c1b512016-09-06 20:57:50408 }
Sean Callananc98aca62010-11-03 19:36:28409}
Jim Ingham8559a352012-11-26 23:52:18410
Kate Stoneb9c1b512016-09-06 20:57:50411void ThreadPlanCallFunction::SetBreakpoints() {
412 ProcessSP process_sp(m_thread.CalculateProcess());
413 if (m_trap_exceptions && process_sp) {
414 m_cxx_language_runtime =
415 process_sp->GetLanguageRuntime(eLanguageTypeC_plus_plus);
416 m_objc_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeObjC);
Jim Ingham0ff099f2014-03-07 11:16:37417
Kate Stoneb9c1b512016-09-06 20:57:50418 if (m_cxx_language_runtime) {
419 m_should_clear_cxx_exception_bp =
420 !m_cxx_language_runtime->ExceptionBreakpointsAreSet();
421 m_cxx_language_runtime->SetExceptionBreakpoints();
Ewan Crawford90ff7912015-07-14 10:56:58422 }
Kate Stoneb9c1b512016-09-06 20:57:50423 if (m_objc_language_runtime) {
424 m_should_clear_objc_exception_bp =
425 !m_objc_language_runtime->ExceptionBreakpointsAreSet();
426 m_objc_language_runtime->SetExceptionBreakpoints();
427 }
428 }
429}
430
431void ThreadPlanCallFunction::ClearBreakpoints() {
432 if (m_trap_exceptions) {
433 if (m_cxx_language_runtime && m_should_clear_cxx_exception_bp)
434 m_cxx_language_runtime->ClearExceptionBreakpoints();
435 if (m_objc_language_runtime && m_should_clear_objc_exception_bp)
436 m_objc_language_runtime->ClearExceptionBreakpoints();
437 }
438}
439
440bool ThreadPlanCallFunction::BreakpointsExplainStop() {
441 StopInfoSP stop_info_sp = GetPrivateStopInfo();
442
443 if (m_trap_exceptions) {
444 if ((m_cxx_language_runtime &&
445 m_cxx_language_runtime->ExceptionBreakpointsExplainStop(
446 stop_info_sp)) ||
447 (m_objc_language_runtime &&
448 m_objc_language_runtime->ExceptionBreakpointsExplainStop(
449 stop_info_sp))) {
450 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP));
451 if (log)
452 log->Printf("ThreadPlanCallFunction::BreakpointsExplainStop - Hit an "
453 "exception breakpoint, setting plan complete.");
454
455 SetPlanComplete(false);
456
Adrian Prantl05097242018-04-30 16:49:04457 // If the user has set the ObjC language breakpoint, it would normally
458 // get priority over our internal catcher breakpoint, but in this case we
459 // can't let that happen, so force the ShouldStop here.
Kate Stoneb9c1b512016-09-06 20:57:50460 stop_info_sp->OverrideShouldStop(true);
461 return true;
462 }
463 }
464
465 return false;
466}
467
468void ThreadPlanCallFunction::SetStopOthers(bool new_value) {
469 m_subplan_sp->SetStopOthers(new_value);
470}
471
472bool ThreadPlanCallFunction::RestoreThreadState() {
473 return GetThread().RestoreThreadStateFromCheckpoint(m_stored_thread_state);
474}
475
476void ThreadPlanCallFunction::SetReturnValue() {
477 ProcessSP process_sp(m_thread.GetProcess());
478 const ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr;
479 if (abi && m_return_type.IsValid()) {
480 const bool persistent = false;
481 m_return_valobj_sp =
482 abi->GetReturnValueObject(m_thread, m_return_type, persistent);
483 }
Ewan Crawford90ff7912015-07-14 10:56:58484}