1 //===-- ThreadPlanCallFunction.cpp ----------------------------------------===//
2 //
3 // 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
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "lldb/Target/ThreadPlanCallFunction.h"
10 #include "lldb/Breakpoint/Breakpoint.h"
11 #include "lldb/Breakpoint/BreakpointLocation.h"
12 #include "lldb/Core/Address.h"
13 #include "lldb/Core/DumpRegisterValue.h"
14 #include "lldb/Core/Module.h"
15 #include "lldb/Symbol/ObjectFile.h"
16 #include "lldb/Target/ABI.h"
17 #include "lldb/Target/LanguageRuntime.h"
18 #include "lldb/Target/Process.h"
19 #include "lldb/Target/RegisterContext.h"
20 #include "lldb/Target/StopInfo.h"
21 #include "lldb/Target/Target.h"
22 #include "lldb/Target/Thread.h"
23 #include "lldb/Target/ThreadPlanRunToAddress.h"
24 #include "lldb/Utility/Log.h"
25 #include "lldb/Utility/Stream.h"
26
27 #include <memory>
28
29 using namespace lldb;
30 using namespace lldb_private;
31
32 // ThreadPlanCallFunction: Plan to call a single function
ConstructorSetup(Thread & thread,ABI * & abi,lldb::addr_t & start_load_addr,lldb::addr_t & function_load_addr)33 bool 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);
39
40 ProcessSP process_sp(thread.GetProcess());
41 if (!process_sp)
42 return false;
43
44 abi = process_sp->GetABI().get();
45
46 if (!abi)
47 return false;
48
49 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP));
50
51 SetBreakpoints();
52
53 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
55 // to put our function, we're not going to get any further...
56 Status error;
57 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 LLDB_LOGF(log, "ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
63 m_constructor_errors.GetData());
64 return false;
65 }
66
67 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());
71 LLDB_LOGF(log, "ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
72 m_constructor_errors.GetData());
73 return false;
74 }
75
76 m_start_addr = *start_address;
77 start_load_addr = m_start_addr.GetLoadAddress(&GetTarget());
78
79 // 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.");
87 LLDB_LOGF(log, "ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
88 m_constructor_errors.GetData());
89 return false;
90 }
91 function_load_addr = m_function_addr.GetLoadAddress(&GetTarget());
92
93 return true;
94 }
95
ThreadPlanCallFunction(Thread & thread,const Address & function,const CompilerType & return_type,llvm::ArrayRef<addr_t> args,const EvaluateExpressionOptions & options)96 ThreadPlanCallFunction::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
ThreadPlanCallFunction(Thread & thread,const Address & function,const EvaluateExpressionOptions & options)126 ThreadPlanCallFunction::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
~ThreadPlanCallFunction()141 ThreadPlanCallFunction::~ThreadPlanCallFunction() {
142 DoTakedown(PlanSucceeded());
143 }
144
ReportRegisterState(const char * message)145 void ThreadPlanCallFunction::ReportRegisterState(const char *message) {
146 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
147 if (log && log->GetVerbose()) {
148 StreamString strm;
149 RegisterContext *reg_ctx = GetThread().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)) {
159 DumpRegisterValue(reg_value, &strm, reg_info, true, false,
160 eFormatDefault);
161 strm.EOL();
162 }
163 }
164 log->PutString(strm.GetString());
165 }
166 }
167
DoTakedown(bool success)168 void ThreadPlanCallFunction::DoTakedown(bool success) {
169 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP));
170
171 if (!m_valid) {
172 // Don't call DoTakedown if we were never valid to begin with.
173 LLDB_LOGF(log,
174 "ThreadPlanCallFunction(%p): Log called on "
175 "ThreadPlanCallFunction that was never valid.",
176 static_cast<void *>(this));
177 return;
178 }
179
180 if (!m_takedown_done) {
181 Thread &thread = GetThread();
182 if (success) {
183 SetReturnValue();
184 }
185 LLDB_LOGF(log,
186 "ThreadPlanCallFunction(%p): DoTakedown called for thread "
187 "0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n",
188 static_cast<void *>(this), m_tid, m_valid, IsPlanComplete());
189 m_takedown_done = true;
190 m_stop_address =
191 thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC();
192 m_real_stop_info_sp = GetPrivateStopInfo();
193 if (!thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state)) {
194 LLDB_LOGF(log,
195 "ThreadPlanCallFunction(%p): DoTakedown failed to restore "
196 "register state",
197 static_cast<void *>(this));
198 }
199 SetPlanComplete(success);
200 ClearBreakpoints();
201 if (log && log->GetVerbose())
202 ReportRegisterState("Restoring thread state after function call. "
203 "Restored register state:");
204 } else {
205 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_tid, m_valid, IsPlanComplete());
209 }
210 }
211
WillPop()212 void ThreadPlanCallFunction::WillPop() { DoTakedown(PlanSucceeded()); }
213
GetDescription(Stream * s,DescriptionLevel level)214 void ThreadPlanCallFunction::GetDescription(Stream *s, DescriptionLevel level) {
215 if (level == eDescriptionLevelBrief) {
216 s->Printf("Function call thread plan");
217 } else {
218 s->Printf("Thread plan to call 0x%" PRIx64,
219 m_function_addr.GetLoadAddress(&GetTarget()));
220 }
221 }
222
ValidatePlan(Stream * error)223 bool ThreadPlanCallFunction::ValidatePlan(Stream *error) {
224 if (!m_valid) {
225 if (error) {
226 if (m_constructor_errors.GetSize() > 0)
227 error->PutCString(m_constructor_errors.GetString());
228 else
229 error->PutCString("Unknown error");
230 }
231 return false;
232 }
233
234 return true;
235 }
236
ShouldReportStop(Event * event_ptr)237 Vote ThreadPlanCallFunction::ShouldReportStop(Event *event_ptr) {
238 if (m_takedown_done || IsPlanComplete())
239 return eVoteYes;
240 else
241 return ThreadPlan::ShouldReportStop(event_ptr);
242 }
243
DoPlanExplainsStop(Event * event_ptr)244 bool ThreadPlanCallFunction::DoPlanExplainsStop(Event *event_ptr) {
245 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP |
246 LIBLLDB_LOG_PROCESS));
247 m_real_stop_info_sp = GetPrivateStopInfo();
248
249 // If our subplan knows why we stopped, even if it's done (which would
250 // forward the question to us) we answer yes.
251 if (m_subplan_sp && m_subplan_sp->PlanExplainsStop(event_ptr)) {
252 SetPlanComplete();
253 return true;
254 }
255
256 // Check if the breakpoint is one of ours.
257
258 StopReason stop_reason;
259 if (!m_real_stop_info_sp)
260 stop_reason = eStopReasonNone;
261 else
262 stop_reason = m_real_stop_info_sp->GetStopReason();
263 LLDB_LOG(log,
264 "ThreadPlanCallFunction::PlanExplainsStop: Got stop reason - {0}.",
265 Thread::StopReasonAsString(stop_reason));
266
267 if (stop_reason == eStopReasonBreakpoint && BreakpointsExplainStop())
268 return true;
269
270 // One more quirk here. If this event was from Halt interrupting the target,
271 // then we should not consider ourselves complete. Return true to
272 // acknowledge the stop.
273 if (Process::ProcessEventData::GetInterruptedFromEvent(event_ptr)) {
274 LLDB_LOGF(log, "ThreadPlanCallFunction::PlanExplainsStop: The event is an "
275 "Interrupt, returning true.");
276 return true;
277 }
278 // We control breakpoints separately from other "stop reasons." So first,
279 // check the case where we stopped for an internal breakpoint, in that case,
280 // continue on. If it is not an internal breakpoint, consult
281 // m_ignore_breakpoints.
282
283 if (stop_reason == eStopReasonBreakpoint) {
284 uint64_t break_site_id = m_real_stop_info_sp->GetValue();
285 BreakpointSiteSP bp_site_sp;
286 bp_site_sp = m_process.GetBreakpointSiteList().FindByID(break_site_id);
287 if (bp_site_sp) {
288 uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
289 bool is_internal = true;
290 for (uint32_t i = 0; i < num_owners; i++) {
291 Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
292 LLDB_LOGF(log,
293 "ThreadPlanCallFunction::PlanExplainsStop: hit "
294 "breakpoint %d while calling function",
295 bp.GetID());
296
297 if (!bp.IsInternal()) {
298 is_internal = false;
299 break;
300 }
301 }
302 if (is_internal) {
303 LLDB_LOGF(log, "ThreadPlanCallFunction::PlanExplainsStop hit an "
304 "internal breakpoint, not stopping.");
305 return false;
306 }
307 }
308
309 if (m_ignore_breakpoints) {
310 LLDB_LOGF(log,
311 "ThreadPlanCallFunction::PlanExplainsStop: we are ignoring "
312 "breakpoints, overriding breakpoint stop info ShouldStop, "
313 "returning true");
314 m_real_stop_info_sp->OverrideShouldStop(false);
315 return true;
316 } else {
317 LLDB_LOGF(log, "ThreadPlanCallFunction::PlanExplainsStop: we are not "
318 "ignoring breakpoints, overriding breakpoint stop info "
319 "ShouldStop, returning true");
320 m_real_stop_info_sp->OverrideShouldStop(true);
321 return false;
322 }
323 } else if (!m_unwind_on_error) {
324 // If we don't want to discard this plan, than any stop we don't understand
325 // should be propagated up the stack.
326 return false;
327 } else {
328 // If the subplan is running, any crashes are attributable to us. If we
329 // want to discard the plan, then we say we explain the stop but if we are
330 // going to be discarded, let whoever is above us explain the stop. But
331 // don't discard the plan if the stop would restart itself (for instance if
332 // it is a signal that is set not to stop. Check that here first. We just
333 // say we explain the stop but aren't done and everything will continue on
334 // from there.
335
336 if (m_real_stop_info_sp &&
337 m_real_stop_info_sp->ShouldStopSynchronous(event_ptr)) {
338 SetPlanComplete(false);
339 return m_subplan_sp ? m_unwind_on_error : false;
340 } else
341 return true;
342 }
343 }
344
ShouldStop(Event * event_ptr)345 bool ThreadPlanCallFunction::ShouldStop(Event *event_ptr) {
346 // We do some computation in DoPlanExplainsStop that may or may not set the
347 // plan as complete. We need to do that here to make sure our state is
348 // correct.
349 DoPlanExplainsStop(event_ptr);
350
351 if (IsPlanComplete()) {
352 ReportRegisterState("Function completed. Register state was:");
353 return true;
354 } else {
355 return false;
356 }
357 }
358
StopOthers()359 bool ThreadPlanCallFunction::StopOthers() { return m_stop_other_threads; }
360
GetPlanRunState()361 StateType ThreadPlanCallFunction::GetPlanRunState() { return eStateRunning; }
362
DidPush()363 void ThreadPlanCallFunction::DidPush() {
364 //#define SINGLE_STEP_EXPRESSIONS
365
366 // Now set the thread state to "no reason" so we don't run with whatever
367 // signal was outstanding... Wait till the plan is pushed so we aren't
368 // changing the stop info till we're about to run.
369
370 GetThread().SetStopInfoToNothing();
371
372 #ifndef SINGLE_STEP_EXPRESSIONS
373 Thread &thread = GetThread();
374 m_subplan_sp = std::make_shared<ThreadPlanRunToAddress>(thread, m_start_addr,
375 m_stop_other_threads);
376
377 thread.QueueThreadPlan(m_subplan_sp, false);
378 m_subplan_sp->SetPrivate(true);
379 #endif
380 }
381
WillStop()382 bool ThreadPlanCallFunction::WillStop() { return true; }
383
MischiefManaged()384 bool ThreadPlanCallFunction::MischiefManaged() {
385 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
386
387 if (IsPlanComplete()) {
388 LLDB_LOGF(log, "ThreadPlanCallFunction(%p): Completed call function plan.",
389 static_cast<void *>(this));
390
391 ThreadPlan::MischiefManaged();
392 return true;
393 } else {
394 return false;
395 }
396 }
397
SetBreakpoints()398 void ThreadPlanCallFunction::SetBreakpoints() {
399 if (m_trap_exceptions) {
400 m_cxx_language_runtime =
401 m_process.GetLanguageRuntime(eLanguageTypeC_plus_plus);
402 m_objc_language_runtime = m_process.GetLanguageRuntime(eLanguageTypeObjC);
403
404 if (m_cxx_language_runtime) {
405 m_should_clear_cxx_exception_bp =
406 !m_cxx_language_runtime->ExceptionBreakpointsAreSet();
407 m_cxx_language_runtime->SetExceptionBreakpoints();
408 }
409 if (m_objc_language_runtime) {
410 m_should_clear_objc_exception_bp =
411 !m_objc_language_runtime->ExceptionBreakpointsAreSet();
412 m_objc_language_runtime->SetExceptionBreakpoints();
413 }
414 }
415 }
416
ClearBreakpoints()417 void ThreadPlanCallFunction::ClearBreakpoints() {
418 if (m_trap_exceptions) {
419 if (m_cxx_language_runtime && m_should_clear_cxx_exception_bp)
420 m_cxx_language_runtime->ClearExceptionBreakpoints();
421 if (m_objc_language_runtime && m_should_clear_objc_exception_bp)
422 m_objc_language_runtime->ClearExceptionBreakpoints();
423 }
424 }
425
BreakpointsExplainStop()426 bool ThreadPlanCallFunction::BreakpointsExplainStop() {
427 StopInfoSP stop_info_sp = GetPrivateStopInfo();
428
429 if (m_trap_exceptions) {
430 if ((m_cxx_language_runtime &&
431 m_cxx_language_runtime->ExceptionBreakpointsExplainStop(
432 stop_info_sp)) ||
433 (m_objc_language_runtime &&
434 m_objc_language_runtime->ExceptionBreakpointsExplainStop(
435 stop_info_sp))) {
436 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP));
437 LLDB_LOGF(log, "ThreadPlanCallFunction::BreakpointsExplainStop - Hit an "
438 "exception breakpoint, setting plan complete.");
439
440 SetPlanComplete(false);
441
442 // If the user has set the ObjC language breakpoint, it would normally
443 // get priority over our internal catcher breakpoint, but in this case we
444 // can't let that happen, so force the ShouldStop here.
445 stop_info_sp->OverrideShouldStop(true);
446 return true;
447 }
448 }
449
450 return false;
451 }
452
SetStopOthers(bool new_value)453 void ThreadPlanCallFunction::SetStopOthers(bool new_value) {
454 m_subplan_sp->SetStopOthers(new_value);
455 }
456
RestoreThreadState()457 bool ThreadPlanCallFunction::RestoreThreadState() {
458 return GetThread().RestoreThreadStateFromCheckpoint(m_stored_thread_state);
459 }
460
SetReturnValue()461 void ThreadPlanCallFunction::SetReturnValue() {
462 const ABI *abi = m_process.GetABI().get();
463 if (abi && m_return_type.IsValid()) {
464 const bool persistent = false;
465 m_return_valobj_sp =
466 abi->GetReturnValueObject(GetThread(), m_return_type, persistent);
467 }
468 }
469