xref: /llvm-project/lldb/source/Target/ThreadPlanCallFunction.cpp (revision 796ac80b863ed92c3d8bcc296f678ff416afc8a8)
1 //===-- ThreadPlanCallFunction.cpp ------------------------------*- C++ -*-===//
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 //----------------------------------------------------------------------
33 // ThreadPlanCallFunction: Plan to call a single function
34 //----------------------------------------------------------------------
35 bool ThreadPlanCallFunction::ConstructorSetup(
36     Thread &thread, ABI *&abi, lldb::addr_t &start_load_addr,
37     lldb::addr_t &function_load_addr) {
38   SetIsMasterPlan(true);
39   SetOkayToDiscard(false);
40   SetPrivate(true);
41 
42   ProcessSP process_sp(thread.GetProcess());
43   if (!process_sp)
44     return false;
45 
46   abi = process_sp->GetABI().get();
47 
48   if (!abi)
49     return false;
50 
51   Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP));
52 
53   SetBreakpoints();
54 
55   m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize();
56   // If we can't read memory at the point of the process where we are planning
57   // to put our function, we're not going to get any further...
58   Status error;
59   process_sp->ReadUnsignedIntegerFromMemory(m_function_sp, 4, 0, error);
60   if (!error.Success()) {
61     m_constructor_errors.Printf(
62         "Trying to put the stack in unreadable memory at: 0x%" PRIx64 ".",
63         m_function_sp);
64     if (log)
65       log->Printf("ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
66                   m_constructor_errors.GetData());
67     return false;
68   }
69 
70   Module *exe_module = GetTarget().GetExecutableModulePointer();
71 
72   if (exe_module == nullptr) {
73     m_constructor_errors.Printf(
74         "Can't execute code without an executable module.");
75     if (log)
76       log->Printf("ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
77                   m_constructor_errors.GetData());
78     return false;
79   } else {
80     ObjectFile *objectFile = exe_module->GetObjectFile();
81     if (!objectFile) {
82       m_constructor_errors.Printf(
83           "Could not find object file for module \"%s\".",
84           exe_module->GetFileSpec().GetFilename().AsCString());
85 
86       if (log)
87         log->Printf("ThreadPlanCallFunction(%p): %s.",
88                     static_cast<void *>(this), m_constructor_errors.GetData());
89       return false;
90     }
91 
92     m_start_addr = objectFile->GetEntryPointAddress();
93     if (!m_start_addr.IsValid()) {
94       m_constructor_errors.Printf(
95           "Could not find entry point address for executable module \"%s\".",
96           exe_module->GetFileSpec().GetFilename().AsCString());
97       if (log)
98         log->Printf("ThreadPlanCallFunction(%p): %s.",
99                     static_cast<void *>(this), m_constructor_errors.GetData());
100       return false;
101     }
102   }
103 
104   start_load_addr = m_start_addr.GetLoadAddress(&GetTarget());
105 
106   // Checkpoint the thread state so we can restore it later.
107   if (log && log->GetVerbose())
108     ReportRegisterState("About to checkpoint thread before function call.  "
109                         "Original register state was:");
110 
111   if (!thread.CheckpointThreadState(m_stored_thread_state)) {
112     m_constructor_errors.Printf("Setting up ThreadPlanCallFunction, failed to "
113                                 "checkpoint thread state.");
114     if (log)
115       log->Printf("ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
116                   m_constructor_errors.GetData());
117     return false;
118   }
119   function_load_addr = m_function_addr.GetLoadAddress(&GetTarget());
120 
121   return true;
122 }
123 
124 ThreadPlanCallFunction::ThreadPlanCallFunction(
125     Thread &thread, const Address &function, const CompilerType &return_type,
126     llvm::ArrayRef<addr_t> args, const EvaluateExpressionOptions &options)
127     : ThreadPlan(ThreadPlan::eKindCallFunction, "Call function plan", thread,
128                  eVoteNoOpinion, eVoteNoOpinion),
129       m_valid(false), m_stop_other_threads(options.GetStopOthers()),
130       m_unwind_on_error(options.DoesUnwindOnError()),
131       m_ignore_breakpoints(options.DoesIgnoreBreakpoints()),
132       m_debug_execution(options.GetDebug()),
133       m_trap_exceptions(options.GetTrapExceptions()), m_function_addr(function),
134       m_function_sp(0), m_takedown_done(false),
135       m_should_clear_objc_exception_bp(false),
136       m_should_clear_cxx_exception_bp(false),
137       m_stop_address(LLDB_INVALID_ADDRESS), m_return_type(return_type) {
138   lldb::addr_t start_load_addr = LLDB_INVALID_ADDRESS;
139   lldb::addr_t function_load_addr = LLDB_INVALID_ADDRESS;
140   ABI *abi = nullptr;
141 
142   if (!ConstructorSetup(thread, abi, start_load_addr, function_load_addr))
143     return;
144 
145   if (!abi->PrepareTrivialCall(thread, m_function_sp, function_load_addr,
146                                start_load_addr, args))
147     return;
148 
149   ReportRegisterState("Function call was set up.  Register state was:");
150 
151   m_valid = true;
152 }
153 
154 ThreadPlanCallFunction::ThreadPlanCallFunction(
155     Thread &thread, const Address &function,
156     const EvaluateExpressionOptions &options)
157     : ThreadPlan(ThreadPlan::eKindCallFunction, "Call function plan", thread,
158                  eVoteNoOpinion, eVoteNoOpinion),
159       m_valid(false), m_stop_other_threads(options.GetStopOthers()),
160       m_unwind_on_error(options.DoesUnwindOnError()),
161       m_ignore_breakpoints(options.DoesIgnoreBreakpoints()),
162       m_debug_execution(options.GetDebug()),
163       m_trap_exceptions(options.GetTrapExceptions()), m_function_addr(function),
164       m_function_sp(0), m_takedown_done(false),
165       m_should_clear_objc_exception_bp(false),
166       m_should_clear_cxx_exception_bp(false),
167       m_stop_address(LLDB_INVALID_ADDRESS), m_return_type(CompilerType()) {}
168 
169 ThreadPlanCallFunction::~ThreadPlanCallFunction() {
170   DoTakedown(PlanSucceeded());
171 }
172 
173 void ThreadPlanCallFunction::ReportRegisterState(const char *message) {
174   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
175   if (log && log->GetVerbose()) {
176     StreamString strm;
177     RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
178 
179     log->PutCString(message);
180 
181     RegisterValue reg_value;
182 
183     for (uint32_t reg_idx = 0, num_registers = reg_ctx->GetRegisterCount();
184          reg_idx < num_registers; ++reg_idx) {
185       const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_idx);
186       if (reg_ctx->ReadRegister(reg_info, reg_value)) {
187         DumpRegisterValue(reg_value, &strm, reg_info, true, false,
188                           eFormatDefault);
189         strm.EOL();
190       }
191     }
192     log->PutString(strm.GetString());
193   }
194 }
195 
196 void ThreadPlanCallFunction::DoTakedown(bool success) {
197   Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP));
198 
199   if (!m_valid) {
200     // Don't call DoTakedown if we were never valid to begin with.
201     if (log)
202       log->Printf("ThreadPlanCallFunction(%p): Log called on "
203                   "ThreadPlanCallFunction that was never valid.",
204                   static_cast<void *>(this));
205     return;
206   }
207 
208   if (!m_takedown_done) {
209     if (success) {
210       SetReturnValue();
211     }
212     if (log)
213       log->Printf("ThreadPlanCallFunction(%p): DoTakedown called for thread "
214                   "0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n",
215                   static_cast<void *>(this), m_thread.GetID(), m_valid,
216                   IsPlanComplete());
217     m_takedown_done = true;
218     m_stop_address =
219         m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC();
220     m_real_stop_info_sp = GetPrivateStopInfo();
221     if (!m_thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state)) {
222       if (log)
223         log->Printf("ThreadPlanCallFunction(%p): DoTakedown failed to restore "
224                     "register state",
225                     static_cast<void *>(this));
226     }
227     SetPlanComplete(success);
228     ClearBreakpoints();
229     if (log && log->GetVerbose())
230       ReportRegisterState("Restoring thread state after function call.  "
231                           "Restored register state:");
232   } else {
233     if (log)
234       log->Printf("ThreadPlanCallFunction(%p): DoTakedown called as no-op for "
235                   "thread 0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n",
236                   static_cast<void *>(this), m_thread.GetID(), m_valid,
237                   IsPlanComplete());
238   }
239 }
240 
241 void ThreadPlanCallFunction::WillPop() { DoTakedown(PlanSucceeded()); }
242 
243 void ThreadPlanCallFunction::GetDescription(Stream *s, DescriptionLevel level) {
244   if (level == eDescriptionLevelBrief) {
245     s->Printf("Function call thread plan");
246   } else {
247     TargetSP target_sp(m_thread.CalculateTarget());
248     s->Printf("Thread plan to call 0x%" PRIx64,
249               m_function_addr.GetLoadAddress(target_sp.get()));
250   }
251 }
252 
253 bool ThreadPlanCallFunction::ValidatePlan(Stream *error) {
254   if (!m_valid) {
255     if (error) {
256       if (m_constructor_errors.GetSize() > 0)
257         error->PutCString(m_constructor_errors.GetString());
258       else
259         error->PutCString("Unknown error");
260     }
261     return false;
262   }
263 
264   return true;
265 }
266 
267 Vote ThreadPlanCallFunction::ShouldReportStop(Event *event_ptr) {
268   if (m_takedown_done || IsPlanComplete())
269     return eVoteYes;
270   else
271     return ThreadPlan::ShouldReportStop(event_ptr);
272 }
273 
274 bool ThreadPlanCallFunction::DoPlanExplainsStop(Event *event_ptr) {
275   Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP |
276                                                   LIBLLDB_LOG_PROCESS));
277   m_real_stop_info_sp = GetPrivateStopInfo();
278 
279   // If our subplan knows why we stopped, even if it's done (which would
280   // forward the question to us) we answer yes.
281   if (m_subplan_sp && m_subplan_sp->PlanExplainsStop(event_ptr)) {
282     SetPlanComplete();
283     return true;
284   }
285 
286   // Check if the breakpoint is one of ours.
287 
288   StopReason stop_reason;
289   if (!m_real_stop_info_sp)
290     stop_reason = eStopReasonNone;
291   else
292     stop_reason = m_real_stop_info_sp->GetStopReason();
293   if (log)
294     log->Printf(
295         "ThreadPlanCallFunction::PlanExplainsStop: Got stop reason - %s.",
296         Thread::StopReasonAsCString(stop_reason));
297 
298   if (stop_reason == eStopReasonBreakpoint && BreakpointsExplainStop())
299     return true;
300 
301   // One more quirk here.  If this event was from Halt interrupting the target,
302   // then we should not consider ourselves complete.  Return true to
303   // acknowledge the stop.
304   if (Process::ProcessEventData::GetInterruptedFromEvent(event_ptr)) {
305     if (log)
306       log->Printf("ThreadPlanCallFunction::PlanExplainsStop: The event is an "
307                   "Interrupt, returning true.");
308     return true;
309   }
310   // We control breakpoints separately from other "stop reasons."  So first,
311   // check the case where we stopped for an internal breakpoint, in that case,
312   // continue on. If it is not an internal breakpoint, consult
313   // m_ignore_breakpoints.
314 
315   if (stop_reason == eStopReasonBreakpoint) {
316     ProcessSP process_sp(m_thread.CalculateProcess());
317     uint64_t break_site_id = m_real_stop_info_sp->GetValue();
318     BreakpointSiteSP bp_site_sp;
319     if (process_sp)
320       bp_site_sp = process_sp->GetBreakpointSiteList().FindByID(break_site_id);
321     if (bp_site_sp) {
322       uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
323       bool is_internal = true;
324       for (uint32_t i = 0; i < num_owners; i++) {
325         Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
326         if (log)
327           log->Printf("ThreadPlanCallFunction::PlanExplainsStop: hit "
328                       "breakpoint %d while calling function",
329                       bp.GetID());
330 
331         if (!bp.IsInternal()) {
332           is_internal = false;
333           break;
334         }
335       }
336       if (is_internal) {
337         if (log)
338           log->Printf("ThreadPlanCallFunction::PlanExplainsStop hit an "
339                       "internal breakpoint, not stopping.");
340         return false;
341       }
342     }
343 
344     if (m_ignore_breakpoints) {
345       if (log)
346         log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are ignoring "
347                     "breakpoints, overriding breakpoint stop info ShouldStop, "
348                     "returning true");
349       m_real_stop_info_sp->OverrideShouldStop(false);
350       return true;
351     } else {
352       if (log)
353         log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are not "
354                     "ignoring breakpoints, overriding breakpoint stop info "
355                     "ShouldStop, returning true");
356       m_real_stop_info_sp->OverrideShouldStop(true);
357       return false;
358     }
359   } else if (!m_unwind_on_error) {
360     // If we don't want to discard this plan, than any stop we don't understand
361     // should be propagated up the stack.
362     return false;
363   } else {
364     // If the subplan is running, any crashes are attributable to us. If we
365     // want to discard the plan, then we say we explain the stop but if we are
366     // going to be discarded, let whoever is above us explain the stop. But
367     // don't discard the plan if the stop would restart itself (for instance if
368     // it is a signal that is set not to stop.  Check that here first.  We just
369     // say we explain the stop but aren't done and everything will continue on
370     // from there.
371 
372     if (m_real_stop_info_sp &&
373         m_real_stop_info_sp->ShouldStopSynchronous(event_ptr)) {
374       SetPlanComplete(false);
375       return m_subplan_sp ? m_unwind_on_error : false;
376     } else
377       return true;
378   }
379 }
380 
381 bool ThreadPlanCallFunction::ShouldStop(Event *event_ptr) {
382   // We do some computation in DoPlanExplainsStop that may or may not set the
383   // plan as complete. We need to do that here to make sure our state is
384   // correct.
385   DoPlanExplainsStop(event_ptr);
386 
387   if (IsPlanComplete()) {
388     ReportRegisterState("Function completed.  Register state was:");
389     return true;
390   } else {
391     return false;
392   }
393 }
394 
395 bool ThreadPlanCallFunction::StopOthers() { return m_stop_other_threads; }
396 
397 StateType ThreadPlanCallFunction::GetPlanRunState() { return eStateRunning; }
398 
399 void ThreadPlanCallFunction::DidPush() {
400   //#define SINGLE_STEP_EXPRESSIONS
401 
402   // Now set the thread state to "no reason" so we don't run with whatever
403   // signal was outstanding... Wait till the plan is pushed so we aren't
404   // changing the stop info till we're about to run.
405 
406   GetThread().SetStopInfoToNothing();
407 
408 #ifndef SINGLE_STEP_EXPRESSIONS
409   m_subplan_sp = std::make_shared<ThreadPlanRunToAddress>(
410       m_thread, m_start_addr, m_stop_other_threads);
411 
412   m_thread.QueueThreadPlan(m_subplan_sp, false);
413   m_subplan_sp->SetPrivate(true);
414 #endif
415 }
416 
417 bool ThreadPlanCallFunction::WillStop() { return true; }
418 
419 bool ThreadPlanCallFunction::MischiefManaged() {
420   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
421 
422   if (IsPlanComplete()) {
423     if (log)
424       log->Printf("ThreadPlanCallFunction(%p): Completed call function plan.",
425                   static_cast<void *>(this));
426 
427     ThreadPlan::MischiefManaged();
428     return true;
429   } else {
430     return false;
431   }
432 }
433 
434 void ThreadPlanCallFunction::SetBreakpoints() {
435   ProcessSP process_sp(m_thread.CalculateProcess());
436   if (m_trap_exceptions && process_sp) {
437     m_cxx_language_runtime =
438         process_sp->GetLanguageRuntime(eLanguageTypeC_plus_plus);
439     m_objc_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeObjC);
440 
441     if (m_cxx_language_runtime) {
442       m_should_clear_cxx_exception_bp =
443           !m_cxx_language_runtime->ExceptionBreakpointsAreSet();
444       m_cxx_language_runtime->SetExceptionBreakpoints();
445     }
446     if (m_objc_language_runtime) {
447       m_should_clear_objc_exception_bp =
448           !m_objc_language_runtime->ExceptionBreakpointsAreSet();
449       m_objc_language_runtime->SetExceptionBreakpoints();
450     }
451   }
452 }
453 
454 void ThreadPlanCallFunction::ClearBreakpoints() {
455   if (m_trap_exceptions) {
456     if (m_cxx_language_runtime && m_should_clear_cxx_exception_bp)
457       m_cxx_language_runtime->ClearExceptionBreakpoints();
458     if (m_objc_language_runtime && m_should_clear_objc_exception_bp)
459       m_objc_language_runtime->ClearExceptionBreakpoints();
460   }
461 }
462 
463 bool ThreadPlanCallFunction::BreakpointsExplainStop() {
464   StopInfoSP stop_info_sp = GetPrivateStopInfo();
465 
466   if (m_trap_exceptions) {
467     if ((m_cxx_language_runtime &&
468          m_cxx_language_runtime->ExceptionBreakpointsExplainStop(
469              stop_info_sp)) ||
470         (m_objc_language_runtime &&
471          m_objc_language_runtime->ExceptionBreakpointsExplainStop(
472              stop_info_sp))) {
473       Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP));
474       if (log)
475         log->Printf("ThreadPlanCallFunction::BreakpointsExplainStop - Hit an "
476                     "exception breakpoint, setting plan complete.");
477 
478       SetPlanComplete(false);
479 
480       // If the user has set the ObjC language breakpoint, it would normally
481       // get priority over our internal catcher breakpoint, but in this case we
482       // can't let that happen, so force the ShouldStop here.
483       stop_info_sp->OverrideShouldStop(true);
484       return true;
485     }
486   }
487 
488   return false;
489 }
490 
491 void ThreadPlanCallFunction::SetStopOthers(bool new_value) {
492   m_subplan_sp->SetStopOthers(new_value);
493 }
494 
495 bool ThreadPlanCallFunction::RestoreThreadState() {
496   return GetThread().RestoreThreadStateFromCheckpoint(m_stored_thread_state);
497 }
498 
499 void ThreadPlanCallFunction::SetReturnValue() {
500   ProcessSP process_sp(m_thread.GetProcess());
501   const ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr;
502   if (abi && m_return_type.IsValid()) {
503     const bool persistent = false;
504     m_return_valobj_sp =
505         abi->GetReturnValueObject(m_thread, m_return_type, persistent);
506   }
507 }
508