1 //===-- ThreadPlanCallFunction.cpp ----------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
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/LLDBLog.h"
25 #include "lldb/Utility/Log.h"
26 #include "lldb/Utility/Stream.h"
31 using namespace lldb_private
;
33 // ThreadPlanCallFunction: Plan to call a single function
34 bool ThreadPlanCallFunction::ConstructorSetup(
35 Thread
&thread
, ABI
*&abi
, lldb::addr_t
&start_load_addr
,
36 lldb::addr_t
&function_load_addr
) {
37 SetIsControllingPlan(true);
38 SetOkayToDiscard(false);
41 ProcessSP
process_sp(thread
.GetProcess());
45 abi
= process_sp
->GetABI().get();
50 Log
*log
= GetLog(LLDBLog::Step
);
54 m_function_sp
= thread
.GetRegisterContext()->GetSP() - abi
->GetRedZoneSize();
55 // If we can't read memory at the point of the process where we are planning
56 // to put our function, we're not going to get any further...
58 process_sp
->ReadUnsignedIntegerFromMemory(m_function_sp
, 4, 0, error
);
59 if (!error
.Success()) {
60 m_constructor_errors
.Printf(
61 "Trying to put the stack in unreadable memory at: 0x%" PRIx64
".",
63 LLDB_LOGF(log
, "ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
64 m_constructor_errors
.GetData());
68 llvm::Expected
<Address
> start_address
= GetTarget().GetEntryPointAddress();
70 m_constructor_errors
.Printf(
71 "%s", llvm::toString(start_address
.takeError()).c_str());
72 LLDB_LOGF(log
, "ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
73 m_constructor_errors
.GetData());
77 m_start_addr
= *start_address
;
78 start_load_addr
= m_start_addr
.GetLoadAddress(&GetTarget());
80 // Checkpoint the thread state so we can restore it later.
81 if (log
&& log
->GetVerbose())
82 ReportRegisterState("About to checkpoint thread before function call. "
83 "Original register state was:");
85 if (!thread
.CheckpointThreadState(m_stored_thread_state
)) {
86 m_constructor_errors
.Printf("Setting up ThreadPlanCallFunction, failed to "
87 "checkpoint thread state.");
88 LLDB_LOGF(log
, "ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
89 m_constructor_errors
.GetData());
92 function_load_addr
= m_function_addr
.GetLoadAddress(&GetTarget());
97 ThreadPlanCallFunction::ThreadPlanCallFunction(
98 Thread
&thread
, const Address
&function
, const CompilerType
&return_type
,
99 llvm::ArrayRef
<addr_t
> args
, const EvaluateExpressionOptions
&options
)
100 : ThreadPlan(ThreadPlan::eKindCallFunction
, "Call function plan", thread
,
101 eVoteNoOpinion
, eVoteNoOpinion
),
102 m_valid(false), m_stop_other_threads(options
.GetStopOthers()),
103 m_unwind_on_error(options
.DoesUnwindOnError()),
104 m_ignore_breakpoints(options
.DoesIgnoreBreakpoints()),
105 m_debug_execution(options
.GetDebug()),
106 m_trap_exceptions(options
.GetTrapExceptions()), m_function_addr(function
),
107 m_start_addr(), m_function_sp(0), m_subplan_sp(),
108 m_cxx_language_runtime(nullptr), m_objc_language_runtime(nullptr),
109 m_stored_thread_state(), m_real_stop_info_sp(), m_constructor_errors(),
110 m_return_valobj_sp(), m_takedown_done(false),
111 m_should_clear_objc_exception_bp(false),
112 m_should_clear_cxx_exception_bp(false),
113 m_stop_address(LLDB_INVALID_ADDRESS
), m_return_type(return_type
) {
114 lldb::addr_t start_load_addr
= LLDB_INVALID_ADDRESS
;
115 lldb::addr_t function_load_addr
= LLDB_INVALID_ADDRESS
;
118 if (!ConstructorSetup(thread
, abi
, start_load_addr
, function_load_addr
))
121 if (!abi
->PrepareTrivialCall(thread
, m_function_sp
, function_load_addr
,
122 start_load_addr
, args
))
125 ReportRegisterState("Function call was set up. Register state was:");
130 ThreadPlanCallFunction::ThreadPlanCallFunction(
131 Thread
&thread
, const Address
&function
,
132 const EvaluateExpressionOptions
&options
)
133 : ThreadPlan(ThreadPlan::eKindCallFunction
, "Call function plan", thread
,
134 eVoteNoOpinion
, eVoteNoOpinion
),
135 m_valid(false), m_stop_other_threads(options
.GetStopOthers()),
136 m_unwind_on_error(options
.DoesUnwindOnError()),
137 m_ignore_breakpoints(options
.DoesIgnoreBreakpoints()),
138 m_debug_execution(options
.GetDebug()),
139 m_trap_exceptions(options
.GetTrapExceptions()), m_function_addr(function
),
140 m_start_addr(), m_function_sp(0), m_subplan_sp(),
141 m_cxx_language_runtime(nullptr), m_objc_language_runtime(nullptr),
142 m_stored_thread_state(), m_real_stop_info_sp(), m_constructor_errors(),
143 m_return_valobj_sp(), m_takedown_done(false),
144 m_should_clear_objc_exception_bp(false),
145 m_should_clear_cxx_exception_bp(false),
146 m_stop_address(LLDB_INVALID_ADDRESS
), m_return_type(CompilerType()) {}
148 ThreadPlanCallFunction::~ThreadPlanCallFunction() {
149 DoTakedown(PlanSucceeded());
152 void ThreadPlanCallFunction::ReportRegisterState(const char *message
) {
153 Log
*log
= GetLog(LLDBLog::Step
);
154 if (log
&& log
->GetVerbose()) {
156 RegisterContext
*reg_ctx
= GetThread().GetRegisterContext().get();
158 log
->PutCString(message
);
160 RegisterValue reg_value
;
162 for (uint32_t reg_idx
= 0, num_registers
= reg_ctx
->GetRegisterCount();
163 reg_idx
< num_registers
; ++reg_idx
) {
164 const RegisterInfo
*reg_info
= reg_ctx
->GetRegisterInfoAtIndex(reg_idx
);
165 if (reg_ctx
->ReadRegister(reg_info
, reg_value
)) {
166 DumpRegisterValue(reg_value
, strm
, *reg_info
, true, false,
171 log
->PutString(strm
.GetString());
175 void ThreadPlanCallFunction::DoTakedown(bool success
) {
176 Log
*log
= GetLog(LLDBLog::Step
);
179 // Don't call DoTakedown if we were never valid to begin with.
181 "ThreadPlanCallFunction(%p): Log called on "
182 "ThreadPlanCallFunction that was never valid.",
183 static_cast<void *>(this));
187 if (!m_takedown_done
) {
188 Thread
&thread
= GetThread();
193 "ThreadPlanCallFunction(%p): DoTakedown called for thread "
194 "0x%4.4" PRIx64
", m_valid: %d complete: %d.\n",
195 static_cast<void *>(this), m_tid
, m_valid
, IsPlanComplete());
196 m_takedown_done
= true;
198 thread
.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC();
199 m_real_stop_info_sp
= GetPrivateStopInfo();
200 if (!thread
.RestoreRegisterStateFromCheckpoint(m_stored_thread_state
)) {
202 "ThreadPlanCallFunction(%p): DoTakedown failed to restore "
204 static_cast<void *>(this));
206 SetPlanComplete(success
);
208 if (log
&& log
->GetVerbose())
209 ReportRegisterState("Restoring thread state after function call. "
210 "Restored register state:");
213 "ThreadPlanCallFunction(%p): DoTakedown called as no-op for "
214 "thread 0x%4.4" PRIx64
", m_valid: %d complete: %d.\n",
215 static_cast<void *>(this), m_tid
, m_valid
, IsPlanComplete());
219 void ThreadPlanCallFunction::DidPop() { DoTakedown(PlanSucceeded()); }
221 void ThreadPlanCallFunction::GetDescription(Stream
*s
, DescriptionLevel level
) {
222 if (level
== eDescriptionLevelBrief
) {
223 s
->Printf("Function call thread plan");
225 s
->Printf("Thread plan to call 0x%" PRIx64
,
226 m_function_addr
.GetLoadAddress(&GetTarget()));
230 bool ThreadPlanCallFunction::ValidatePlan(Stream
*error
) {
233 if (m_constructor_errors
.GetSize() > 0)
234 error
->PutCString(m_constructor_errors
.GetString());
236 error
->PutCString("Unknown error");
244 Vote
ThreadPlanCallFunction::ShouldReportStop(Event
*event_ptr
) {
245 if (m_takedown_done
|| IsPlanComplete())
248 return ThreadPlan::ShouldReportStop(event_ptr
);
251 bool ThreadPlanCallFunction::DoPlanExplainsStop(Event
*event_ptr
) {
252 Log
*log(GetLog(LLDBLog::Step
| LLDBLog::Process
));
253 m_real_stop_info_sp
= GetPrivateStopInfo();
255 // If our subplan knows why we stopped, even if it's done (which would
256 // forward the question to us) we answer yes.
257 if (m_subplan_sp
&& m_subplan_sp
->PlanExplainsStop(event_ptr
)) {
262 // Check if the breakpoint is one of ours.
264 StopReason stop_reason
;
265 if (!m_real_stop_info_sp
)
266 stop_reason
= eStopReasonNone
;
268 stop_reason
= m_real_stop_info_sp
->GetStopReason();
270 "ThreadPlanCallFunction::PlanExplainsStop: Got stop reason - {0}.",
271 Thread::StopReasonAsString(stop_reason
));
273 if (stop_reason
== eStopReasonBreakpoint
&& BreakpointsExplainStop())
276 // One more quirk here. If this event was from Halt interrupting the target,
277 // then we should not consider ourselves complete. Return true to
278 // acknowledge the stop.
279 if (Process::ProcessEventData::GetInterruptedFromEvent(event_ptr
)) {
280 LLDB_LOGF(log
, "ThreadPlanCallFunction::PlanExplainsStop: The event is an "
281 "Interrupt, returning true.");
284 // We control breakpoints separately from other "stop reasons." So first,
285 // check the case where we stopped for an internal breakpoint, in that case,
286 // continue on. If it is not an internal breakpoint, consult
287 // m_ignore_breakpoints.
289 if (stop_reason
== eStopReasonBreakpoint
) {
290 uint64_t break_site_id
= m_real_stop_info_sp
->GetValue();
291 BreakpointSiteSP bp_site_sp
;
292 bp_site_sp
= m_process
.GetBreakpointSiteList().FindByID(break_site_id
);
294 uint32_t num_owners
= bp_site_sp
->GetNumberOfConstituents();
295 bool is_internal
= true;
296 for (uint32_t i
= 0; i
< num_owners
; i
++) {
297 Breakpoint
&bp
= bp_site_sp
->GetConstituentAtIndex(i
)->GetBreakpoint();
299 "ThreadPlanCallFunction::PlanExplainsStop: hit "
300 "breakpoint %d while calling function",
303 if (!bp
.IsInternal()) {
309 LLDB_LOGF(log
, "ThreadPlanCallFunction::PlanExplainsStop hit an "
310 "internal breakpoint, not stopping.");
315 if (m_ignore_breakpoints
) {
317 "ThreadPlanCallFunction::PlanExplainsStop: we are ignoring "
318 "breakpoints, overriding breakpoint stop info ShouldStop, "
320 m_real_stop_info_sp
->OverrideShouldStop(false);
323 LLDB_LOGF(log
, "ThreadPlanCallFunction::PlanExplainsStop: we are not "
324 "ignoring breakpoints, overriding breakpoint stop info "
325 "ShouldStop, returning true");
326 m_real_stop_info_sp
->OverrideShouldStop(true);
329 } else if (!m_unwind_on_error
) {
330 // If we don't want to discard this plan, than any stop we don't understand
331 // should be propagated up the stack.
334 // If the subplan is running, any crashes are attributable to us. If we
335 // want to discard the plan, then we say we explain the stop but if we are
336 // going to be discarded, let whoever is above us explain the stop. But
337 // don't discard the plan if the stop would restart itself (for instance if
338 // it is a signal that is set not to stop. Check that here first. We just
339 // say we explain the stop but aren't done and everything will continue on
342 if (m_real_stop_info_sp
&&
343 m_real_stop_info_sp
->ShouldStopSynchronous(event_ptr
)) {
344 SetPlanComplete(false);
345 return m_subplan_sp
? m_unwind_on_error
: false;
351 bool ThreadPlanCallFunction::ShouldStop(Event
*event_ptr
) {
352 // We do some computation in DoPlanExplainsStop that may or may not set the
353 // plan as complete. We need to do that here to make sure our state is
355 DoPlanExplainsStop(event_ptr
);
357 if (IsPlanComplete()) {
358 ReportRegisterState("Function completed. Register state was:");
365 bool ThreadPlanCallFunction::StopOthers() { return m_stop_other_threads
; }
367 StateType
ThreadPlanCallFunction::GetPlanRunState() { return eStateRunning
; }
369 void ThreadPlanCallFunction::DidPush() {
370 //#define SINGLE_STEP_EXPRESSIONS
372 // Now set the thread state to "no reason" so we don't run with whatever
373 // signal was outstanding... Wait till the plan is pushed so we aren't
374 // changing the stop info till we're about to run.
376 GetThread().SetStopInfoToNothing();
378 #ifndef SINGLE_STEP_EXPRESSIONS
379 Thread
&thread
= GetThread();
380 m_subplan_sp
= std::make_shared
<ThreadPlanRunToAddress
>(thread
, m_start_addr
,
381 m_stop_other_threads
);
383 thread
.QueueThreadPlan(m_subplan_sp
, false);
384 m_subplan_sp
->SetPrivate(true);
388 bool ThreadPlanCallFunction::WillStop() { return true; }
390 bool ThreadPlanCallFunction::MischiefManaged() {
391 Log
*log
= GetLog(LLDBLog::Step
);
393 if (IsPlanComplete()) {
394 LLDB_LOGF(log
, "ThreadPlanCallFunction(%p): Completed call function plan.",
395 static_cast<void *>(this));
397 ThreadPlan::MischiefManaged();
404 void ThreadPlanCallFunction::SetBreakpoints() {
405 if (m_trap_exceptions
) {
406 m_cxx_language_runtime
=
407 m_process
.GetLanguageRuntime(eLanguageTypeC_plus_plus
);
408 m_objc_language_runtime
= m_process
.GetLanguageRuntime(eLanguageTypeObjC
);
410 if (m_cxx_language_runtime
) {
411 m_should_clear_cxx_exception_bp
=
412 !m_cxx_language_runtime
->ExceptionBreakpointsAreSet();
413 m_cxx_language_runtime
->SetExceptionBreakpoints();
415 if (m_objc_language_runtime
) {
416 m_should_clear_objc_exception_bp
=
417 !m_objc_language_runtime
->ExceptionBreakpointsAreSet();
418 m_objc_language_runtime
->SetExceptionBreakpoints();
423 void ThreadPlanCallFunction::ClearBreakpoints() {
424 if (m_trap_exceptions
) {
425 if (m_cxx_language_runtime
&& m_should_clear_cxx_exception_bp
)
426 m_cxx_language_runtime
->ClearExceptionBreakpoints();
427 if (m_objc_language_runtime
&& m_should_clear_objc_exception_bp
)
428 m_objc_language_runtime
->ClearExceptionBreakpoints();
432 bool ThreadPlanCallFunction::BreakpointsExplainStop() {
433 StopInfoSP stop_info_sp
= GetPrivateStopInfo();
435 if (m_trap_exceptions
) {
436 if ((m_cxx_language_runtime
&&
437 m_cxx_language_runtime
->ExceptionBreakpointsExplainStop(
439 (m_objc_language_runtime
&&
440 m_objc_language_runtime
->ExceptionBreakpointsExplainStop(
442 Log
*log
= GetLog(LLDBLog::Step
);
443 LLDB_LOGF(log
, "ThreadPlanCallFunction::BreakpointsExplainStop - Hit an "
444 "exception breakpoint, setting plan complete.");
446 SetPlanComplete(false);
448 // If the user has set the ObjC language breakpoint, it would normally
449 // get priority over our internal catcher breakpoint, but in this case we
450 // can't let that happen, so force the ShouldStop here.
451 stop_info_sp
->OverrideShouldStop(true);
459 void ThreadPlanCallFunction::SetStopOthers(bool new_value
) {
460 m_subplan_sp
->SetStopOthers(new_value
);
463 void ThreadPlanCallFunction::RestoreThreadState() {
464 GetThread().RestoreThreadStateFromCheckpoint(m_stored_thread_state
);
467 void ThreadPlanCallFunction::SetReturnValue() {
468 const ABI
*abi
= m_process
.GetABI().get();
469 if (abi
&& m_return_type
.IsValid()) {
470 const bool persistent
= false;
472 abi
->GetReturnValueObject(GetThread(), m_return_type
, persistent
);