xref: /freebsd-src/contrib/llvm-project/lldb/source/Target/ThreadPlanCallFunction.cpp (revision fcaf7f8644a9988098ac6be2165bce3ea4786e91)
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/LLDBLog.h"
25 #include "lldb/Utility/Log.h"
26 #include "lldb/Utility/Stream.h"
27 
28 #include <memory>
29 
30 using namespace lldb;
31 using namespace lldb_private;
32 
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);
39   SetPrivate(true);
40 
41   ProcessSP process_sp(thread.GetProcess());
42   if (!process_sp)
43     return false;
44 
45   abi = process_sp->GetABI().get();
46 
47   if (!abi)
48     return false;
49 
50   Log *log = GetLog(LLDBLog::Step);
51 
52   SetBreakpoints();
53 
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...
57   Status error;
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 ".",
62         m_function_sp);
63     LLDB_LOGF(log, "ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
64               m_constructor_errors.GetData());
65     return false;
66   }
67 
68   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     LLDB_LOGF(log, "ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
73               m_constructor_errors.GetData());
74     return false;
75   }
76 
77   m_start_addr = *start_address;
78   start_load_addr = m_start_addr.GetLoadAddress(&GetTarget());
79 
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:");
84 
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());
90     return false;
91   }
92   function_load_addr = m_function_addr.GetLoadAddress(&GetTarget());
93 
94   return true;
95 }
96 
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_function_sp(0), m_takedown_done(false),
108       m_should_clear_objc_exception_bp(false),
109       m_should_clear_cxx_exception_bp(false),
110       m_stop_address(LLDB_INVALID_ADDRESS), m_return_type(return_type) {
111   lldb::addr_t start_load_addr = LLDB_INVALID_ADDRESS;
112   lldb::addr_t function_load_addr = LLDB_INVALID_ADDRESS;
113   ABI *abi = nullptr;
114 
115   if (!ConstructorSetup(thread, abi, start_load_addr, function_load_addr))
116     return;
117 
118   if (!abi->PrepareTrivialCall(thread, m_function_sp, function_load_addr,
119                                start_load_addr, args))
120     return;
121 
122   ReportRegisterState("Function call was set up.  Register state was:");
123 
124   m_valid = true;
125 }
126 
127 ThreadPlanCallFunction::ThreadPlanCallFunction(
128     Thread &thread, const Address &function,
129     const EvaluateExpressionOptions &options)
130     : ThreadPlan(ThreadPlan::eKindCallFunction, "Call function plan", thread,
131                  eVoteNoOpinion, eVoteNoOpinion),
132       m_valid(false), m_stop_other_threads(options.GetStopOthers()),
133       m_unwind_on_error(options.DoesUnwindOnError()),
134       m_ignore_breakpoints(options.DoesIgnoreBreakpoints()),
135       m_debug_execution(options.GetDebug()),
136       m_trap_exceptions(options.GetTrapExceptions()), m_function_addr(function),
137       m_function_sp(0), m_takedown_done(false),
138       m_should_clear_objc_exception_bp(false),
139       m_should_clear_cxx_exception_bp(false),
140       m_stop_address(LLDB_INVALID_ADDRESS), m_return_type(CompilerType()) {}
141 
142 ThreadPlanCallFunction::~ThreadPlanCallFunction() {
143   DoTakedown(PlanSucceeded());
144 }
145 
146 void ThreadPlanCallFunction::ReportRegisterState(const char *message) {
147   Log *log = GetLog(LLDBLog::Step);
148   if (log && log->GetVerbose()) {
149     StreamString strm;
150     RegisterContext *reg_ctx = GetThread().GetRegisterContext().get();
151 
152     log->PutCString(message);
153 
154     RegisterValue reg_value;
155 
156     for (uint32_t reg_idx = 0, num_registers = reg_ctx->GetRegisterCount();
157          reg_idx < num_registers; ++reg_idx) {
158       const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_idx);
159       if (reg_ctx->ReadRegister(reg_info, reg_value)) {
160         DumpRegisterValue(reg_value, &strm, reg_info, true, false,
161                           eFormatDefault);
162         strm.EOL();
163       }
164     }
165     log->PutString(strm.GetString());
166   }
167 }
168 
169 void ThreadPlanCallFunction::DoTakedown(bool success) {
170   Log *log = GetLog(LLDBLog::Step);
171 
172   if (!m_valid) {
173     // Don't call DoTakedown if we were never valid to begin with.
174     LLDB_LOGF(log,
175               "ThreadPlanCallFunction(%p): Log called on "
176               "ThreadPlanCallFunction that was never valid.",
177               static_cast<void *>(this));
178     return;
179   }
180 
181   if (!m_takedown_done) {
182     Thread &thread = GetThread();
183     if (success) {
184       SetReturnValue();
185     }
186     LLDB_LOGF(log,
187               "ThreadPlanCallFunction(%p): DoTakedown called for thread "
188               "0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n",
189               static_cast<void *>(this), m_tid, m_valid, IsPlanComplete());
190     m_takedown_done = true;
191     m_stop_address =
192         thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC();
193     m_real_stop_info_sp = GetPrivateStopInfo();
194     if (!thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state)) {
195       LLDB_LOGF(log,
196                 "ThreadPlanCallFunction(%p): DoTakedown failed to restore "
197                 "register state",
198                 static_cast<void *>(this));
199     }
200     SetPlanComplete(success);
201     ClearBreakpoints();
202     if (log && log->GetVerbose())
203       ReportRegisterState("Restoring thread state after function call.  "
204                           "Restored register state:");
205   } else {
206     LLDB_LOGF(log,
207               "ThreadPlanCallFunction(%p): DoTakedown called as no-op for "
208               "thread 0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n",
209               static_cast<void *>(this), m_tid, m_valid, IsPlanComplete());
210   }
211 }
212 
213 void ThreadPlanCallFunction::DidPop() { DoTakedown(PlanSucceeded()); }
214 
215 void ThreadPlanCallFunction::GetDescription(Stream *s, DescriptionLevel level) {
216   if (level == eDescriptionLevelBrief) {
217     s->Printf("Function call thread plan");
218   } else {
219     s->Printf("Thread plan to call 0x%" PRIx64,
220               m_function_addr.GetLoadAddress(&GetTarget()));
221   }
222 }
223 
224 bool ThreadPlanCallFunction::ValidatePlan(Stream *error) {
225   if (!m_valid) {
226     if (error) {
227       if (m_constructor_errors.GetSize() > 0)
228         error->PutCString(m_constructor_errors.GetString());
229       else
230         error->PutCString("Unknown error");
231     }
232     return false;
233   }
234 
235   return true;
236 }
237 
238 Vote ThreadPlanCallFunction::ShouldReportStop(Event *event_ptr) {
239   if (m_takedown_done || IsPlanComplete())
240     return eVoteYes;
241   else
242     return ThreadPlan::ShouldReportStop(event_ptr);
243 }
244 
245 bool ThreadPlanCallFunction::DoPlanExplainsStop(Event *event_ptr) {
246   Log *log(GetLog(LLDBLog::Step | LLDBLog::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 
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 
359 bool ThreadPlanCallFunction::StopOthers() { return m_stop_other_threads; }
360 
361 StateType ThreadPlanCallFunction::GetPlanRunState() { return eStateRunning; }
362 
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 
382 bool ThreadPlanCallFunction::WillStop() { return true; }
383 
384 bool ThreadPlanCallFunction::MischiefManaged() {
385   Log *log = GetLog(LLDBLog::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 
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 
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 
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 = GetLog(LLDBLog::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 
453 void ThreadPlanCallFunction::SetStopOthers(bool new_value) {
454   m_subplan_sp->SetStopOthers(new_value);
455 }
456 
457 void ThreadPlanCallFunction::RestoreThreadState() {
458   GetThread().RestoreThreadStateFromCheckpoint(m_stored_thread_state);
459 }
460 
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