• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- ThreadPlanCallFunction.cpp ------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/Target/ThreadPlanCallFunction.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 #include "llvm/Support/MachO.h"
16 // Project includes
17 #include "lldb/lldb-private-log.h"
18 #include "lldb/Breakpoint/Breakpoint.h"
19 #include "lldb/Breakpoint/BreakpointLocation.h"
20 #include "lldb/Core/Address.h"
21 #include "lldb/Core/Log.h"
22 #include "lldb/Core/Module.h"
23 #include "lldb/Core/Stream.h"
24 #include "lldb/Symbol/ObjectFile.h"
25 #include "lldb/Target/LanguageRuntime.h"
26 #include "lldb/Target/Process.h"
27 #include "lldb/Target/RegisterContext.h"
28 #include "lldb/Target/StopInfo.h"
29 #include "lldb/Target/Target.h"
30 #include "lldb/Target/Thread.h"
31 #include "lldb/Target/ThreadPlanRunToAddress.h"
32 
33 using namespace lldb;
34 using namespace lldb_private;
35 
36 //----------------------------------------------------------------------
37 // ThreadPlanCallFunction: Plan to call a single function
38 //----------------------------------------------------------------------
39 bool
ConstructorSetup(Thread & thread,ABI * & abi,lldb::addr_t & start_load_addr,lldb::addr_t & function_load_addr)40 ThreadPlanCallFunction::ConstructorSetup (Thread &thread,
41                                           ABI *& abi,
42                                           lldb::addr_t &start_load_addr,
43                                           lldb::addr_t &function_load_addr)
44 {
45     SetIsMasterPlan (true);
46     SetOkayToDiscard (false);
47     SetPrivate (true);
48 
49     ProcessSP process_sp (thread.GetProcess());
50     if (!process_sp)
51         return false;
52 
53     abi = process_sp->GetABI().get();
54 
55     if (!abi)
56         return false;
57 
58     TargetSP target_sp (thread.CalculateTarget());
59 
60     Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
61 
62     SetBreakpoints();
63 
64     m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize();
65     // If we can't read memory at the point of the process where we are planning to put our function, we're
66     // not going to get any further...
67     Error error;
68     process_sp->ReadUnsignedIntegerFromMemory(m_function_sp, 4, 0, error);
69     if (!error.Success())
70     {
71         m_constructor_errors.Printf ("Trying to put the stack in unreadable memory at: 0x%" PRIx64 ".", m_function_sp);
72         if (log)
73             log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
74         return false;
75     }
76 
77     Module *exe_module = target_sp->GetExecutableModulePointer();
78 
79     if (exe_module == NULL)
80     {
81         m_constructor_errors.Printf ("Can't execute code without an executable module.");
82         if (log)
83             log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
84         return false;
85     }
86     else
87     {
88         ObjectFile *objectFile = exe_module->GetObjectFile();
89         if (!objectFile)
90         {
91             m_constructor_errors.Printf ("Could not find object file for module \"%s\".",
92                                          exe_module->GetFileSpec().GetFilename().AsCString());
93 
94             if (log)
95                 log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
96             return false;
97         }
98 
99         m_start_addr = objectFile->GetEntryPointAddress();
100         if (!m_start_addr.IsValid())
101         {
102             m_constructor_errors.Printf ("Could not find entry point address for executable module \"%s\".",
103                                          exe_module->GetFileSpec().GetFilename().AsCString());
104             if (log)
105                 log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
106             return false;
107         }
108     }
109 
110     start_load_addr = m_start_addr.GetLoadAddress (target_sp.get());
111 
112     // Checkpoint the thread state so we can restore it later.
113     if (log && log->GetVerbose())
114         ReportRegisterState ("About to checkpoint thread before function call.  Original register state was:");
115 
116     if (!thread.CheckpointThreadState (m_stored_thread_state))
117     {
118         m_constructor_errors.Printf ("Setting up ThreadPlanCallFunction, failed to checkpoint thread state.");
119         if (log)
120             log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
121         return false;
122     }
123     function_load_addr = m_function_addr.GetLoadAddress (target_sp.get());
124 
125     return true;
126 }
127 
ThreadPlanCallFunction(Thread & thread,const Address & function,const ClangASTType & return_type,addr_t arg,bool stop_other_threads,bool unwind_on_error,bool ignore_breakpoints,addr_t * this_arg,addr_t * cmd_arg)128 ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
129                                                 const Address &function,
130                                                 const ClangASTType &return_type,
131                                                 addr_t arg,
132                                                 bool stop_other_threads,
133                                                 bool unwind_on_error,
134                                                 bool ignore_breakpoints,
135                                                 addr_t *this_arg,
136                                                 addr_t *cmd_arg) :
137     ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion),
138     m_valid (false),
139     m_stop_other_threads (stop_other_threads),
140     m_function_addr (function),
141     m_function_sp (0),
142     m_return_type (return_type),
143     m_takedown_done (false),
144     m_stop_address (LLDB_INVALID_ADDRESS),
145     m_unwind_on_error (unwind_on_error),
146     m_ignore_breakpoints (ignore_breakpoints)
147 {
148     lldb::addr_t start_load_addr;
149     ABI *abi;
150     lldb::addr_t function_load_addr;
151     if (!ConstructorSetup (thread, abi, start_load_addr, function_load_addr))
152         return;
153 
154     if (this_arg && cmd_arg)
155     {
156         if (!abi->PrepareTrivialCall (thread,
157                                       m_function_sp,
158                                       function_load_addr,
159                                       start_load_addr,
160                                       this_arg,
161                                       cmd_arg,
162                                       &arg))
163             return;
164     }
165     else if (this_arg)
166     {
167         if (!abi->PrepareTrivialCall (thread,
168                                       m_function_sp,
169                                       function_load_addr,
170                                       start_load_addr,
171                                       this_arg,
172                                       &arg))
173             return;
174     }
175     else
176     {
177         if (!abi->PrepareTrivialCall (thread,
178                                       m_function_sp,
179                                       function_load_addr,
180                                       start_load_addr,
181                                       &arg))
182             return;
183     }
184 
185     ReportRegisterState ("Function call was set up.  Register state was:");
186 
187     m_valid = true;
188 }
189 
190 
ThreadPlanCallFunction(Thread & thread,const Address & function,const ClangASTType & return_type,bool stop_other_threads,bool unwind_on_error,bool ignore_breakpoints,addr_t * arg1_ptr,addr_t * arg2_ptr,addr_t * arg3_ptr,addr_t * arg4_ptr,addr_t * arg5_ptr,addr_t * arg6_ptr)191 ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
192                                                 const Address &function,
193                                                 const ClangASTType &return_type,
194                                                 bool stop_other_threads,
195                                                 bool unwind_on_error,
196                                                 bool ignore_breakpoints,
197                                                 addr_t *arg1_ptr,
198                                                 addr_t *arg2_ptr,
199                                                 addr_t *arg3_ptr,
200                                                 addr_t *arg4_ptr,
201                                                 addr_t *arg5_ptr,
202                                                 addr_t *arg6_ptr) :
203     ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion),
204     m_valid (false),
205     m_stop_other_threads (stop_other_threads),
206     m_function_addr (function),
207     m_function_sp (0),
208     m_return_type (return_type),
209     m_takedown_done (false),
210     m_stop_address (LLDB_INVALID_ADDRESS),
211     m_unwind_on_error (unwind_on_error),
212     m_ignore_breakpoints (ignore_breakpoints)
213 {
214     lldb::addr_t start_load_addr;
215     ABI *abi;
216     lldb::addr_t function_load_addr;
217     if (!ConstructorSetup (thread, abi, start_load_addr, function_load_addr))
218         return;
219 
220     if (!abi->PrepareTrivialCall (thread,
221                                   m_function_sp,
222                                   function_load_addr,
223                                   start_load_addr,
224                                   arg1_ptr,
225                                   arg2_ptr,
226                                   arg3_ptr,
227                                   arg4_ptr,
228                                   arg5_ptr,
229                                   arg6_ptr))
230     {
231             return;
232     }
233 
234     ReportRegisterState ("Function call was set up.  Register state was:");
235 
236     m_valid = true;
237 }
238 
~ThreadPlanCallFunction()239 ThreadPlanCallFunction::~ThreadPlanCallFunction ()
240 {
241     DoTakedown(PlanSucceeded());
242 }
243 
244 void
ReportRegisterState(const char * message)245 ThreadPlanCallFunction::ReportRegisterState (const char *message)
246 {
247     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP | LIBLLDB_LOG_VERBOSE));
248     if (log)
249     {
250         StreamString strm;
251         RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
252 
253         log->PutCString(message);
254 
255         RegisterValue reg_value;
256 
257         for (uint32_t reg_idx = 0, num_registers = reg_ctx->GetRegisterCount();
258              reg_idx < num_registers;
259              ++reg_idx)
260         {
261             const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_idx);
262             if (reg_ctx->ReadRegister(reg_info, reg_value))
263             {
264                 reg_value.Dump(&strm, reg_info, true, false, eFormatDefault);
265                 strm.EOL();
266             }
267         }
268         log->PutCString(strm.GetData());
269     }
270 }
271 
272 void
DoTakedown(bool success)273 ThreadPlanCallFunction::DoTakedown (bool success)
274 {
275     Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
276 
277     if (!m_valid)
278     {
279         //Don't call DoTakedown if we were never valid to begin with.
280         if (log)
281             log->Printf ("ThreadPlanCallFunction(%p): Log called on ThreadPlanCallFunction that was never valid.", this);
282         return;
283     }
284 
285     if (!m_takedown_done)
286     {
287         if (success)
288         {
289             ProcessSP process_sp (m_thread.GetProcess());
290             const ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
291             if (abi && m_return_type.IsValid())
292             {
293                 const bool persistent = false;
294                 m_return_valobj_sp = abi->GetReturnValueObject (m_thread, m_return_type, persistent);
295             }
296         }
297         if (log)
298             log->Printf ("ThreadPlanCallFunction(%p): DoTakedown called for thread 0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n", this, m_thread.GetID(), m_valid, IsPlanComplete());
299         m_takedown_done = true;
300         m_stop_address = m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC();
301         m_real_stop_info_sp = GetPrivateStopInfo ();
302         m_thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state);
303         SetPlanComplete(success);
304         ClearBreakpoints();
305         if (log && log->GetVerbose())
306             ReportRegisterState ("Restoring thread state after function call.  Restored register state:");
307 
308     }
309     else
310     {
311         if (log)
312             log->Printf ("ThreadPlanCallFunction(%p): DoTakedown called as no-op for thread 0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n", this, m_thread.GetID(), m_valid, IsPlanComplete());
313     }
314 }
315 
316 void
WillPop()317 ThreadPlanCallFunction::WillPop ()
318 {
319     DoTakedown(PlanSucceeded());
320 }
321 
322 void
GetDescription(Stream * s,DescriptionLevel level)323 ThreadPlanCallFunction::GetDescription (Stream *s, DescriptionLevel level)
324 {
325     if (level == eDescriptionLevelBrief)
326     {
327         s->Printf("Function call thread plan");
328     }
329     else
330     {
331         TargetSP target_sp (m_thread.CalculateTarget());
332         s->Printf("Thread plan to call 0x%" PRIx64, m_function_addr.GetLoadAddress(target_sp.get()));
333     }
334 }
335 
336 bool
ValidatePlan(Stream * error)337 ThreadPlanCallFunction::ValidatePlan (Stream *error)
338 {
339     if (!m_valid)
340     {
341         if (error)
342         {
343             if (m_constructor_errors.GetSize() > 0)
344                 error->PutCString (m_constructor_errors.GetData());
345             else
346                 error->PutCString ("Unknown error");
347         }
348         return false;
349     }
350 
351     return true;
352 }
353 
354 
355 Vote
ShouldReportStop(Event * event_ptr)356 ThreadPlanCallFunction::ShouldReportStop(Event *event_ptr)
357 {
358     if (m_takedown_done || IsPlanComplete())
359         return eVoteYes;
360     else
361         return ThreadPlan::ShouldReportStop(event_ptr);
362 }
363 
364 bool
DoPlanExplainsStop(Event * event_ptr)365 ThreadPlanCallFunction::DoPlanExplainsStop (Event *event_ptr)
366 {
367     Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP|LIBLLDB_LOG_PROCESS));
368     m_real_stop_info_sp = GetPrivateStopInfo ();
369 
370     // If our subplan knows why we stopped, even if it's done (which would forward the question to us)
371     // we answer yes.
372     if (m_subplan_sp.get() != NULL && m_subplan_sp->PlanExplainsStop(event_ptr))
373     {
374         SetPlanComplete();
375         return true;
376     }
377 
378     // Check if the breakpoint is one of ours.
379 
380     StopReason stop_reason;
381     if (!m_real_stop_info_sp)
382         stop_reason = eStopReasonNone;
383     else
384         stop_reason = m_real_stop_info_sp->GetStopReason();
385     if (log)
386         log->Printf ("ThreadPlanCallFunction::PlanExplainsStop: Got stop reason - %s.", Thread::StopReasonAsCString(stop_reason));
387 
388     if (stop_reason == eStopReasonBreakpoint && BreakpointsExplainStop())
389         return true;
390 
391     // We control breakpoints separately from other "stop reasons."  So first,
392     // check the case where we stopped for an internal breakpoint, in that case, continue on.
393     // If it is not an internal breakpoint, consult m_ignore_breakpoints.
394 
395 
396     if (stop_reason == eStopReasonBreakpoint)
397     {
398         ProcessSP process_sp (m_thread.CalculateProcess());
399         uint64_t break_site_id = m_real_stop_info_sp->GetValue();
400         BreakpointSiteSP bp_site_sp;
401         if (process_sp)
402             bp_site_sp = process_sp->GetBreakpointSiteList().FindByID(break_site_id);
403         if (bp_site_sp)
404         {
405             uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
406             bool is_internal = true;
407             for (uint32_t i = 0; i < num_owners; i++)
408             {
409                 Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
410                 if (log)
411                     log->Printf ("ThreadPlanCallFunction::PlanExplainsStop: hit breakpoint %d while calling function", bp.GetID());
412 
413                 if (!bp.IsInternal())
414                 {
415                     is_internal = false;
416                     break;
417                 }
418             }
419             if (is_internal)
420             {
421                 if (log)
422                     log->Printf ("ThreadPlanCallFunction::PlanExplainsStop hit an internal breakpoint, not stopping.");
423                 return false;
424             }
425         }
426 
427         if (m_ignore_breakpoints)
428         {
429             if (log)
430                 log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are ignoring breakpoints, overriding breakpoint stop info ShouldStop, returning true");
431             m_real_stop_info_sp->OverrideShouldStop(false);
432             return true;
433         }
434         else
435         {
436             if (log)
437                 log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are not ignoring breakpoints, overriding breakpoint stop info ShouldStop, returning true");
438             m_real_stop_info_sp->OverrideShouldStop(true);
439             return false;
440         }
441     }
442     else if (!m_unwind_on_error)
443     {
444         // If we don't want to discard this plan, than any stop we don't understand should be propagated up the stack.
445         return false;
446     }
447     else
448     {
449         // If the subplan is running, any crashes are attributable to us.
450         // If we want to discard the plan, then we say we explain the stop
451         // but if we are going to be discarded, let whoever is above us
452         // explain the stop.
453         // But don't discard the plan if the stop would restart itself (for instance if it is a
454         // signal that is set not to stop.  Check that here first.  We just say we explain the stop
455         // but aren't done and everything will continue on from there.
456 
457         if (m_real_stop_info_sp->ShouldStopSynchronous(event_ptr))
458         {
459             SetPlanComplete(false);
460             if (m_subplan_sp)
461             {
462                 if (m_unwind_on_error)
463                     return true;
464                 else
465                     return false;
466             }
467             else
468                 return false;
469         }
470         else
471             return true;
472     }
473 }
474 
475 bool
ShouldStop(Event * event_ptr)476 ThreadPlanCallFunction::ShouldStop (Event *event_ptr)
477 {
478     // We do some computation in DoPlanExplainsStop that may or may not set the plan as complete.
479     // We need to do that here to make sure our state is correct.
480     DoPlanExplainsStop(event_ptr);
481 
482     if (IsPlanComplete())
483     {
484         ReportRegisterState ("Function completed.  Register state was:");
485         return true;
486     }
487     else
488     {
489         return false;
490     }
491 }
492 
493 bool
StopOthers()494 ThreadPlanCallFunction::StopOthers ()
495 {
496     return m_stop_other_threads;
497 }
498 
499 void
SetStopOthers(bool new_value)500 ThreadPlanCallFunction::SetStopOthers (bool new_value)
501 {
502     if (m_subplan_sp)
503     {
504         ThreadPlanRunToAddress *address_plan = static_cast<ThreadPlanRunToAddress *>(m_subplan_sp.get());
505         address_plan->SetStopOthers(new_value);
506     }
507     m_stop_other_threads = new_value;
508 }
509 
510 StateType
GetPlanRunState()511 ThreadPlanCallFunction::GetPlanRunState ()
512 {
513     return eStateRunning;
514 }
515 
516 void
DidPush()517 ThreadPlanCallFunction::DidPush ()
518 {
519 //#define SINGLE_STEP_EXPRESSIONS
520 
521     // Now set the thread state to "no reason" so we don't run with whatever signal was outstanding...
522     // Wait till the plan is pushed so we aren't changing the stop info till we're about to run.
523 
524     GetThread().SetStopInfoToNothing();
525 
526 #ifndef SINGLE_STEP_EXPRESSIONS
527     m_subplan_sp.reset(new ThreadPlanRunToAddress(m_thread, m_start_addr, m_stop_other_threads));
528 
529     m_thread.QueueThreadPlan(m_subplan_sp, false);
530     m_subplan_sp->SetPrivate (true);
531 #endif
532 }
533 
534 bool
WillStop()535 ThreadPlanCallFunction::WillStop ()
536 {
537     return true;
538 }
539 
540 bool
MischiefManaged()541 ThreadPlanCallFunction::MischiefManaged ()
542 {
543     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
544 
545     if (IsPlanComplete())
546     {
547         if (log)
548             log->Printf("ThreadPlanCallFunction(%p): Completed call function plan.", this);
549 
550         ThreadPlan::MischiefManaged ();
551         return true;
552     }
553     else
554     {
555         return false;
556     }
557 }
558 
559 void
SetBreakpoints()560 ThreadPlanCallFunction::SetBreakpoints ()
561 {
562     ProcessSP process_sp (m_thread.CalculateProcess());
563     if (process_sp)
564     {
565         m_cxx_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeC_plus_plus);
566         m_objc_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeObjC);
567 
568         if (m_cxx_language_runtime)
569             m_cxx_language_runtime->SetExceptionBreakpoints();
570         if (m_objc_language_runtime)
571             m_objc_language_runtime->SetExceptionBreakpoints();
572     }
573 }
574 
575 void
ClearBreakpoints()576 ThreadPlanCallFunction::ClearBreakpoints ()
577 {
578     if (m_cxx_language_runtime)
579         m_cxx_language_runtime->ClearExceptionBreakpoints();
580     if (m_objc_language_runtime)
581         m_objc_language_runtime->ClearExceptionBreakpoints();
582 }
583 
584 bool
BreakpointsExplainStop()585 ThreadPlanCallFunction::BreakpointsExplainStop()
586 {
587     StopInfoSP stop_info_sp = GetPrivateStopInfo ();
588 
589     if ((m_cxx_language_runtime &&
590             m_cxx_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))
591        ||(m_objc_language_runtime &&
592             m_objc_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp)))
593     {
594         Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
595         if (log)
596             log->Printf ("ThreadPlanCallFunction::BreakpointsExplainStop - Hit an exception breakpoint, setting plan complete.");
597 
598         SetPlanComplete(false);
599 
600         // If the user has set the ObjC language breakpoint, it would normally get priority over our internal
601         // catcher breakpoint, but in this case we can't let that happen, so force the ShouldStop here.
602         stop_info_sp->OverrideShouldStop (true);
603         return true;
604     }
605 
606     return false;
607 }
608 
609 bool
RestoreThreadState()610 ThreadPlanCallFunction::RestoreThreadState()
611 {
612     return GetThread().RestoreThreadStateFromCheckpoint(m_stored_thread_state);
613 }
614 
615