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