blob: 4f0b5d328d6e096763b7934316b5b7ee44633a02 [file] [log] [blame]
Raphael Isemann80814282020-01-24 08:23:27 +01001//===-- ThreadPlanCallFunction.cpp ----------------------------------------===//
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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:24 +00006//
7//===----------------------------------------------------------------------===//
8
Eugene Zelenkoe65b2cf2015-12-15 01:33:19 +00009#include "lldb/Target/ThreadPlanCallFunction.h"
Jim Ingham40d871f2010-10-26 00:27:45 +000010#include "lldb/Breakpoint/Breakpoint.h"
11#include "lldb/Breakpoint/BreakpointLocation.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012#include "lldb/Core/Address.h"
Pavel Labathe03334c2018-07-24 15:48:13 +000013#include "lldb/Core/DumpRegisterValue.h"
Greg Clayton1f746072012-08-29 21:13:06 +000014#include "lldb/Core/Module.h"
Greg Clayton1f746072012-08-29 21:13:06 +000015#include "lldb/Symbol/ObjectFile.h"
Zachary Turner32abc6e2015-03-03 19:23:09 +000016#include "lldb/Target/ABI.h"
Sean Callananf2115102010-11-03 22:19:38 +000017#include "lldb/Target/LanguageRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000018#include "lldb/Target/Process.h"
19#include "lldb/Target/RegisterContext.h"
Jim Ingham40d871f2010-10-26 00:27:45 +000020#include "lldb/Target/StopInfo.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000021#include "lldb/Target/Target.h"
22#include "lldb/Target/Thread.h"
23#include "lldb/Target/ThreadPlanRunToAddress.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000024#include "lldb/Utility/Log.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000025#include "lldb/Utility/Stream.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026
Jonas Devlieghere796ac802019-02-11 23:13:08 +000027#include <memory>
28
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029using namespace lldb;
30using namespace lldb_private;
31
Chris Lattner30fdc8d2010-06-08 16:52:24 +000032// ThreadPlanCallFunction: Plan to call a single function
Kate Stoneb9c1b512016-09-06 20:57:50 +000033bool 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:13 +000039
Kate Stoneb9c1b512016-09-06 20:57:50 +000040 ProcessSP process_sp(thread.GetProcess());
41 if (!process_sp)
42 return false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000043
Kate Stoneb9c1b512016-09-06 20:57:50 +000044 abi = process_sp->GetABI().get();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000045
Kate Stoneb9c1b512016-09-06 20:57:50 +000046 if (!abi)
47 return false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000048
Kate Stoneb9c1b512016-09-06 20:57:50 +000049 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000050
Kate Stoneb9c1b512016-09-06 20:57:50 +000051 SetBreakpoints();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000052
Kate Stoneb9c1b512016-09-06 20:57:50 +000053 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:04 +000055 // to put our function, we're not going to get any further...
Zachary Turner97206d52017-05-12 04:51:55 +000056 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +000057 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);
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +000062 LLDB_LOGF(log, "ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
63 m_constructor_errors.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +000064 return false;
65 }
66
Jonas Devlieghere0288c262019-07-19 00:52:08 +000067 llvm::Expected<Address> start_address = GetTarget().GetEntryPointAddress();
68 if (!start_address) {
69 m_constructor_errors.Printf(
70 "%s", llvm::toString(start_address.takeError()).c_str());
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +000071 LLDB_LOGF(log, "ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
72 m_constructor_errors.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +000073 return false;
Jason Molenda956761a2019-07-18 20:55:24 +000074 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000075
Jonas Devlieghere0288c262019-07-19 00:52:08 +000076 m_start_addr = *start_address;
Kate Stoneb9c1b512016-09-06 20:57:50 +000077 start_load_addr = m_start_addr.GetLoadAddress(&GetTarget());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000078
Kate Stoneb9c1b512016-09-06 20:57:50 +000079 // Checkpoint the thread state so we can restore it later.
80 if (log && log->GetVerbose())
81 ReportRegisterState("About to checkpoint thread before function call. "
82 "Original register state was:");
83
84 if (!thread.CheckpointThreadState(m_stored_thread_state)) {
85 m_constructor_errors.Printf("Setting up ThreadPlanCallFunction, failed to "
86 "checkpoint thread state.");
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +000087 LLDB_LOGF(log, "ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
88 m_constructor_errors.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +000089 return false;
90 }
91 function_load_addr = m_function_addr.GetLoadAddress(&GetTarget());
92
93 return true;
94}
95
96ThreadPlanCallFunction::ThreadPlanCallFunction(
97 Thread &thread, const Address &function, const CompilerType &return_type,
98 llvm::ArrayRef<addr_t> args, const EvaluateExpressionOptions &options)
99 : ThreadPlan(ThreadPlan::eKindCallFunction, "Call function plan", thread,
100 eVoteNoOpinion, eVoteNoOpinion),
101 m_valid(false), m_stop_other_threads(options.GetStopOthers()),
102 m_unwind_on_error(options.DoesUnwindOnError()),
103 m_ignore_breakpoints(options.DoesIgnoreBreakpoints()),
104 m_debug_execution(options.GetDebug()),
105 m_trap_exceptions(options.GetTrapExceptions()), m_function_addr(function),
106 m_function_sp(0), m_takedown_done(false),
107 m_should_clear_objc_exception_bp(false),
108 m_should_clear_cxx_exception_bp(false),
109 m_stop_address(LLDB_INVALID_ADDRESS), m_return_type(return_type) {
110 lldb::addr_t start_load_addr = LLDB_INVALID_ADDRESS;
111 lldb::addr_t function_load_addr = LLDB_INVALID_ADDRESS;
112 ABI *abi = nullptr;
113
114 if (!ConstructorSetup(thread, abi, start_load_addr, function_load_addr))
115 return;
116
117 if (!abi->PrepareTrivialCall(thread, m_function_sp, function_load_addr,
118 start_load_addr, args))
119 return;
120
121 ReportRegisterState("Function call was set up. Register state was:");
122
123 m_valid = true;
124}
125
126ThreadPlanCallFunction::ThreadPlanCallFunction(
127 Thread &thread, const Address &function,
128 const EvaluateExpressionOptions &options)
129 : ThreadPlan(ThreadPlan::eKindCallFunction, "Call function plan", thread,
130 eVoteNoOpinion, eVoteNoOpinion),
131 m_valid(false), m_stop_other_threads(options.GetStopOthers()),
132 m_unwind_on_error(options.DoesUnwindOnError()),
133 m_ignore_breakpoints(options.DoesIgnoreBreakpoints()),
134 m_debug_execution(options.GetDebug()),
135 m_trap_exceptions(options.GetTrapExceptions()), m_function_addr(function),
136 m_function_sp(0), m_takedown_done(false),
137 m_should_clear_objc_exception_bp(false),
138 m_should_clear_cxx_exception_bp(false),
139 m_stop_address(LLDB_INVALID_ADDRESS), m_return_type(CompilerType()) {}
140
141ThreadPlanCallFunction::~ThreadPlanCallFunction() {
142 DoTakedown(PlanSucceeded());
143}
144
145void ThreadPlanCallFunction::ReportRegisterState(const char *message) {
Pavel Labath3b7e1982017-02-05 00:44:54 +0000146 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
147 if (log && log->GetVerbose()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000148 StreamString strm;
149 RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
150
151 log->PutCString(message);
152
153 RegisterValue reg_value;
154
155 for (uint32_t reg_idx = 0, num_registers = reg_ctx->GetRegisterCount();
156 reg_idx < num_registers; ++reg_idx) {
157 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_idx);
158 if (reg_ctx->ReadRegister(reg_info, reg_value)) {
Pavel Labathe03334c2018-07-24 15:48:13 +0000159 DumpRegisterValue(reg_value, &strm, reg_info, true, false,
160 eFormatDefault);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000161 strm.EOL();
162 }
Jim Ingham0092c8e2012-04-13 20:38:13 +0000163 }
Zachary Turnerc1564272016-11-16 21:15:24 +0000164 log->PutString(strm.GetString());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000165 }
166}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000167
Kate Stoneb9c1b512016-09-06 20:57:50 +0000168void ThreadPlanCallFunction::DoTakedown(bool success) {
169 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000170
Kate Stoneb9c1b512016-09-06 20:57:50 +0000171 if (!m_valid) {
172 // Don't call DoTakedown if we were never valid to begin with.
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000173 LLDB_LOGF(log,
174 "ThreadPlanCallFunction(%p): Log called on "
175 "ThreadPlanCallFunction that was never valid.",
176 static_cast<void *>(this));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000177 return;
178 }
179
180 if (!m_takedown_done) {
181 if (success) {
182 SetReturnValue();
183 }
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000184 LLDB_LOGF(log,
185 "ThreadPlanCallFunction(%p): DoTakedown called for thread "
186 "0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n",
187 static_cast<void *>(this), m_thread.GetID(), m_valid,
188 IsPlanComplete());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000189 m_takedown_done = true;
190 m_stop_address =
191 m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC();
192 m_real_stop_info_sp = GetPrivateStopInfo();
193 if (!m_thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state)) {
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000194 LLDB_LOGF(log,
195 "ThreadPlanCallFunction(%p): DoTakedown failed to restore "
196 "register state",
197 static_cast<void *>(this));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000198 }
199 SetPlanComplete(success);
200 ClearBreakpoints();
Jim Ingham0092c8e2012-04-13 20:38:13 +0000201 if (log && log->GetVerbose())
Kate Stoneb9c1b512016-09-06 20:57:50 +0000202 ReportRegisterState("Restoring thread state after function call. "
203 "Restored register state:");
204 } else {
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000205 LLDB_LOGF(log,
206 "ThreadPlanCallFunction(%p): DoTakedown called as no-op for "
207 "thread 0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n",
208 static_cast<void *>(this), m_thread.GetID(), m_valid,
209 IsPlanComplete());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000210 }
Sean Callanan10af7c42010-11-04 01:51:38 +0000211}
212
Kate Stoneb9c1b512016-09-06 20:57:50 +0000213void ThreadPlanCallFunction::WillPop() { DoTakedown(PlanSucceeded()); }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000214
Kate Stoneb9c1b512016-09-06 20:57:50 +0000215void ThreadPlanCallFunction::GetDescription(Stream *s, DescriptionLevel level) {
216 if (level == eDescriptionLevelBrief) {
217 s->Printf("Function call thread plan");
218 } else {
219 TargetSP target_sp(m_thread.CalculateTarget());
220 s->Printf("Thread plan to call 0x%" PRIx64,
221 m_function_addr.GetLoadAddress(target_sp.get()));
222 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000223}
224
Kate Stoneb9c1b512016-09-06 20:57:50 +0000225bool ThreadPlanCallFunction::ValidatePlan(Stream *error) {
226 if (!m_valid) {
227 if (error) {
228 if (m_constructor_errors.GetSize() > 0)
Zachary Turnerc1564272016-11-16 21:15:24 +0000229 error->PutCString(m_constructor_errors.GetString());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000230 else
231 error->PutCString("Unknown error");
232 }
233 return false;
234 }
235
236 return true;
Jim Inghambda4e5eb2011-01-18 01:58:06 +0000237}
238
Kate Stoneb9c1b512016-09-06 20:57:50 +0000239Vote ThreadPlanCallFunction::ShouldReportStop(Event *event_ptr) {
240 if (m_takedown_done || IsPlanComplete())
241 return eVoteYes;
242 else
243 return ThreadPlan::ShouldReportStop(event_ptr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000244}
245
Kate Stoneb9c1b512016-09-06 20:57:50 +0000246bool ThreadPlanCallFunction::DoPlanExplainsStop(Event *event_ptr) {
247 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP |
248 LIBLLDB_LOG_PROCESS));
249 m_real_stop_info_sp = GetPrivateStopInfo();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000250
Adrian Prantl05097242018-04-30 16:49:04 +0000251 // If our subplan knows why we stopped, even if it's done (which would
252 // forward the question to us) we answer yes.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000253 if (m_subplan_sp && m_subplan_sp->PlanExplainsStop(event_ptr)) {
254 SetPlanComplete();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000255 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000256 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000257
Kate Stoneb9c1b512016-09-06 20:57:50 +0000258 // Check if the breakpoint is one of ours.
Jim Ingham0161b492013-02-09 01:29:05 +0000259
Kate Stoneb9c1b512016-09-06 20:57:50 +0000260 StopReason stop_reason;
261 if (!m_real_stop_info_sp)
262 stop_reason = eStopReasonNone;
263 else
264 stop_reason = m_real_stop_info_sp->GetStopReason();
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000265 LLDB_LOGF(log,
266 "ThreadPlanCallFunction::PlanExplainsStop: Got stop reason - %s.",
267 Thread::StopReasonAsCString(stop_reason));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000268
269 if (stop_reason == eStopReasonBreakpoint && BreakpointsExplainStop())
270 return true;
271
272 // One more quirk here. If this event was from Halt interrupting the target,
Adrian Prantl05097242018-04-30 16:49:04 +0000273 // then we should not consider ourselves complete. Return true to
274 // acknowledge the stop.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000275 if (Process::ProcessEventData::GetInterruptedFromEvent(event_ptr)) {
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000276 LLDB_LOGF(log, "ThreadPlanCallFunction::PlanExplainsStop: The event is an "
277 "Interrupt, returning true.");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000278 return true;
279 }
280 // We control breakpoints separately from other "stop reasons." So first,
281 // check the case where we stopped for an internal breakpoint, in that case,
Adrian Prantl05097242018-04-30 16:49:04 +0000282 // continue on. If it is not an internal breakpoint, consult
283 // m_ignore_breakpoints.
Jim Ingham18de2fd2012-05-10 01:35:39 +0000284
Kate Stoneb9c1b512016-09-06 20:57:50 +0000285 if (stop_reason == eStopReasonBreakpoint) {
286 ProcessSP process_sp(m_thread.CalculateProcess());
287 uint64_t break_site_id = m_real_stop_info_sp->GetValue();
288 BreakpointSiteSP bp_site_sp;
289 if (process_sp)
290 bp_site_sp = process_sp->GetBreakpointSiteList().FindByID(break_site_id);
291 if (bp_site_sp) {
292 uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
293 bool is_internal = true;
294 for (uint32_t i = 0; i < num_owners; i++) {
295 Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000296 LLDB_LOGF(log,
297 "ThreadPlanCallFunction::PlanExplainsStop: hit "
298 "breakpoint %d while calling function",
299 bp.GetID());
Eugene Zelenkoe65b2cf2015-12-15 01:33:19 +0000300
Kate Stoneb9c1b512016-09-06 20:57:50 +0000301 if (!bp.IsInternal()) {
302 is_internal = false;
303 break;
Jim Ingham40d871f2010-10-26 00:27:45 +0000304 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000305 }
306 if (is_internal) {
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000307 LLDB_LOGF(log, "ThreadPlanCallFunction::PlanExplainsStop hit an "
308 "internal breakpoint, not stopping.");
Jim Ingham0161b492013-02-09 01:29:05 +0000309 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000310 }
Jim Ingham40d871f2010-10-26 00:27:45 +0000311 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000312
313 if (m_ignore_breakpoints) {
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000314 LLDB_LOGF(log,
315 "ThreadPlanCallFunction::PlanExplainsStop: we are ignoring "
316 "breakpoints, overriding breakpoint stop info ShouldStop, "
317 "returning true");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000318 m_real_stop_info_sp->OverrideShouldStop(false);
319 return true;
320 } else {
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000321 LLDB_LOGF(log, "ThreadPlanCallFunction::PlanExplainsStop: we are not "
322 "ignoring breakpoints, overriding breakpoint stop info "
323 "ShouldStop, returning true");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000324 m_real_stop_info_sp->OverrideShouldStop(true);
325 return false;
Jim Ingham40d871f2010-10-26 00:27:45 +0000326 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000327 } else if (!m_unwind_on_error) {
328 // If we don't want to discard this plan, than any stop we don't understand
329 // should be propagated up the stack.
330 return false;
331 } else {
Adrian Prantl05097242018-04-30 16:49:04 +0000332 // If the subplan is running, any crashes are attributable to us. If we
333 // want to discard the plan, then we say we explain the stop but if we are
334 // going to be discarded, let whoever is above us explain the stop. But
335 // don't discard the plan if the stop would restart itself (for instance if
336 // it is a signal that is set not to stop. Check that here first. We just
337 // say we explain the stop but aren't done and everything will continue on
338 // from there.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000339
340 if (m_real_stop_info_sp &&
341 m_real_stop_info_sp->ShouldStopSynchronous(event_ptr)) {
342 SetPlanComplete(false);
343 return m_subplan_sp ? m_unwind_on_error : false;
344 } else
345 return true;
346 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000347}
348
Kate Stoneb9c1b512016-09-06 20:57:50 +0000349bool ThreadPlanCallFunction::ShouldStop(Event *event_ptr) {
350 // We do some computation in DoPlanExplainsStop that may or may not set the
Adrian Prantl05097242018-04-30 16:49:04 +0000351 // plan as complete. We need to do that here to make sure our state is
352 // correct.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000353 DoPlanExplainsStop(event_ptr);
354
355 if (IsPlanComplete()) {
356 ReportRegisterState("Function completed. Register state was:");
357 return true;
358 } else {
359 return false;
360 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000361}
362
Kate Stoneb9c1b512016-09-06 20:57:50 +0000363bool ThreadPlanCallFunction::StopOthers() { return m_stop_other_threads; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000364
Kate Stoneb9c1b512016-09-06 20:57:50 +0000365StateType ThreadPlanCallFunction::GetPlanRunState() { return eStateRunning; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000366
Kate Stoneb9c1b512016-09-06 20:57:50 +0000367void ThreadPlanCallFunction::DidPush() {
368 //#define SINGLE_STEP_EXPRESSIONS
369
370 // Now set the thread state to "no reason" so we don't run with whatever
Adrian Prantl05097242018-04-30 16:49:04 +0000371 // signal was outstanding... Wait till the plan is pushed so we aren't
372 // changing the stop info till we're about to run.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000373
374 GetThread().SetStopInfoToNothing();
375
Sean Callananbe3a1b12010-10-26 00:31:56 +0000376#ifndef SINGLE_STEP_EXPRESSIONS
Jonas Devlieghere796ac802019-02-11 23:13:08 +0000377 m_subplan_sp = std::make_shared<ThreadPlanRunToAddress>(
378 m_thread, m_start_addr, m_stop_other_threads);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000379
380 m_thread.QueueThreadPlan(m_subplan_sp, false);
381 m_subplan_sp->SetPrivate(true);
Sean Callananbe3a1b12010-10-26 00:31:56 +0000382#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000383}
384
Kate Stoneb9c1b512016-09-06 20:57:50 +0000385bool ThreadPlanCallFunction::WillStop() { return true; }
386
387bool ThreadPlanCallFunction::MischiefManaged() {
388 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
389
390 if (IsPlanComplete()) {
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000391 LLDB_LOGF(log, "ThreadPlanCallFunction(%p): Completed call function plan.",
392 static_cast<void *>(this));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000393
394 ThreadPlan::MischiefManaged();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000395 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000396 } else {
Sean Callananc98aca62010-11-03 19:36:28 +0000397 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000398 }
Sean Callananc98aca62010-11-03 19:36:28 +0000399}
Jim Ingham8559a352012-11-26 23:52:18 +0000400
Kate Stoneb9c1b512016-09-06 20:57:50 +0000401void ThreadPlanCallFunction::SetBreakpoints() {
402 ProcessSP process_sp(m_thread.CalculateProcess());
403 if (m_trap_exceptions && process_sp) {
404 m_cxx_language_runtime =
405 process_sp->GetLanguageRuntime(eLanguageTypeC_plus_plus);
406 m_objc_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeObjC);
Jim Ingham0ff099f2014-03-07 11:16:37 +0000407
Kate Stoneb9c1b512016-09-06 20:57:50 +0000408 if (m_cxx_language_runtime) {
409 m_should_clear_cxx_exception_bp =
410 !m_cxx_language_runtime->ExceptionBreakpointsAreSet();
411 m_cxx_language_runtime->SetExceptionBreakpoints();
Ewan Crawford90ff7912015-07-14 10:56:58 +0000412 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000413 if (m_objc_language_runtime) {
414 m_should_clear_objc_exception_bp =
415 !m_objc_language_runtime->ExceptionBreakpointsAreSet();
416 m_objc_language_runtime->SetExceptionBreakpoints();
417 }
418 }
419}
420
421void ThreadPlanCallFunction::ClearBreakpoints() {
422 if (m_trap_exceptions) {
423 if (m_cxx_language_runtime && m_should_clear_cxx_exception_bp)
424 m_cxx_language_runtime->ClearExceptionBreakpoints();
425 if (m_objc_language_runtime && m_should_clear_objc_exception_bp)
426 m_objc_language_runtime->ClearExceptionBreakpoints();
427 }
428}
429
430bool ThreadPlanCallFunction::BreakpointsExplainStop() {
431 StopInfoSP stop_info_sp = GetPrivateStopInfo();
432
433 if (m_trap_exceptions) {
434 if ((m_cxx_language_runtime &&
435 m_cxx_language_runtime->ExceptionBreakpointsExplainStop(
436 stop_info_sp)) ||
437 (m_objc_language_runtime &&
438 m_objc_language_runtime->ExceptionBreakpointsExplainStop(
439 stop_info_sp))) {
440 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP));
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000441 LLDB_LOGF(log, "ThreadPlanCallFunction::BreakpointsExplainStop - Hit an "
442 "exception breakpoint, setting plan complete.");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000443
444 SetPlanComplete(false);
445
Adrian Prantl05097242018-04-30 16:49:04 +0000446 // If the user has set the ObjC language breakpoint, it would normally
447 // get priority over our internal catcher breakpoint, but in this case we
448 // can't let that happen, so force the ShouldStop here.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000449 stop_info_sp->OverrideShouldStop(true);
450 return true;
451 }
452 }
453
454 return false;
455}
456
457void ThreadPlanCallFunction::SetStopOthers(bool new_value) {
458 m_subplan_sp->SetStopOthers(new_value);
459}
460
461bool ThreadPlanCallFunction::RestoreThreadState() {
462 return GetThread().RestoreThreadStateFromCheckpoint(m_stored_thread_state);
463}
464
465void ThreadPlanCallFunction::SetReturnValue() {
466 ProcessSP process_sp(m_thread.GetProcess());
467 const ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr;
468 if (abi && m_return_type.IsValid()) {
469 const bool persistent = false;
470 m_return_valobj_sp =
471 abi->GetReturnValueObject(m_thread, m_return_type, persistent);
472 }
Ewan Crawford90ff7912015-07-14 10:56:58 +0000473}