ThreadPlanCallFunction.cpp revision 263367
1198892Srdivacky//===-- ThreadPlanCallFunction.cpp ------------------------------*- C++ -*-===//
2198892Srdivacky//
3198892Srdivacky//                     The LLVM Compiler Infrastructure
4198892Srdivacky//
5198892Srdivacky// This file is distributed under the University of Illinois Open Source
6198892Srdivacky// License. See LICENSE.TXT for details.
7198892Srdivacky//
8198892Srdivacky//===----------------------------------------------------------------------===//
9198892Srdivacky
10198892Srdivacky#include "lldb/Target/ThreadPlanCallFunction.h"
11263508Sdim
12198892Srdivacky// C Includes
13198892Srdivacky// C++ Includes
14198892Srdivacky// Other libraries and framework includes
15198892Srdivacky#include "llvm/Support/MachO.h"
16198892Srdivacky// Project includes
17198892Srdivacky#include "lldb/lldb-private-log.h"
18239462Sdim#include "lldb/Breakpoint/Breakpoint.h"
19239462Sdim#include "lldb/Breakpoint/BreakpointLocation.h"
20249423Sdim#include "lldb/Core/Address.h"
21249423Sdim#include "lldb/Core/Log.h"
22249423Sdim#include "lldb/Core/Module.h"
23239462Sdim#include "lldb/Core/Stream.h"
24239462Sdim#include "lldb/Symbol/ObjectFile.h"
25239462Sdim#include "lldb/Target/LanguageRuntime.h"
26239462Sdim#include "lldb/Target/Process.h"
27198892Srdivacky#include "lldb/Target/RegisterContext.h"
28198892Srdivacky#include "lldb/Target/StopInfo.h"
29198892Srdivacky#include "lldb/Target/Target.h"
30243830Sdim#include "lldb/Target/Thread.h"
31243830Sdim#include "lldb/Target/ThreadPlanRunToAddress.h"
32198892Srdivacky
33198892Srdivackyusing namespace lldb;
34198892Srdivackyusing namespace lldb_private;
35239462Sdim
36239462Sdim//----------------------------------------------------------------------
37239462Sdim// ThreadPlanCallFunction: Plan to call a single function
38239462Sdim//----------------------------------------------------------------------
39243830Sdimbool
40243830SdimThreadPlanCallFunction::ConstructorSetup (Thread &thread,
41239462Sdim                                          ABI *& abi,
42239462Sdim                                          lldb::addr_t &start_load_addr,
43239462Sdim                                          lldb::addr_t &function_load_addr)
44243830Sdim{
45243830Sdim    SetIsMasterPlan (true);
46239462Sdim    SetOkayToDiscard (false);
47239462Sdim    SetPrivate (true);
48239462Sdim
49243830Sdim    ProcessSP process_sp (thread.GetProcess());
50243830Sdim    if (!process_sp)
51239462Sdim        return false;
52239462Sdim
53239462Sdim    abi = process_sp->GetABI().get();
54243830Sdim
55243830Sdim    if (!abi)
56239462Sdim        return false;
57239462Sdim
58239462Sdim    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
59243830Sdim
60243830Sdim    SetBreakpoints();
61239462Sdim
62239462Sdim    m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize();
63239462Sdim    // If we can't read memory at the point of the process where we are planning to put our function, we're
64243830Sdim    // not going to get any further...
65243830Sdim    Error error;
66239462Sdim    process_sp->ReadUnsignedIntegerFromMemory(m_function_sp, 4, 0, error);
67263508Sdim    if (!error.Success())
68263508Sdim    {
69263508Sdim        m_constructor_errors.Printf ("Trying to put the stack in unreadable memory at: 0x%" PRIx64 ".", m_function_sp);
70263508Sdim        if (log)
71239462Sdim            log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
72198892Srdivacky        return false;
73198892Srdivacky    }
74198892Srdivacky
75198892Srdivacky    Module *exe_module = GetTarget().GetExecutableModulePointer();
76198892Srdivacky
77198892Srdivacky    if (exe_module == NULL)
78198892Srdivacky    {
79243830Sdim        m_constructor_errors.Printf ("Can't execute code without an executable module.");
80243830Sdim        if (log)
81243830Sdim            log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
82243830Sdim        return false;
83239462Sdim    }
84198892Srdivacky    else
85263508Sdim    {
86198892Srdivacky        ObjectFile *objectFile = exe_module->GetObjectFile();
87198892Srdivacky        if (!objectFile)
88263508Sdim        {
89243830Sdim            m_constructor_errors.Printf ("Could not find object file for module \"%s\".",
90198892Srdivacky                                         exe_module->GetFileSpec().GetFilename().AsCString());
91198892Srdivacky
92198953Srdivacky            if (log)
93198953Srdivacky                log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
94198953Srdivacky            return false;
95198953Srdivacky        }
96243830Sdim
97198892Srdivacky        m_start_addr = objectFile->GetEntryPointAddress();
98198953Srdivacky        if (!m_start_addr.IsValid())
99198953Srdivacky        {
100198953Srdivacky            m_constructor_errors.Printf ("Could not find entry point address for executable module \"%s\".",
101198953Srdivacky                                         exe_module->GetFileSpec().GetFilename().AsCString());
102198953Srdivacky            if (log)
103243830Sdim                log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
104198892Srdivacky            return false;
105263508Sdim        }
106198892Srdivacky    }
107198892Srdivacky
108198892Srdivacky    start_load_addr = m_start_addr.GetLoadAddress (&GetTarget());
109198892Srdivacky
110263508Sdim    // Checkpoint the thread state so we can restore it later.
111243830Sdim    if (log && log->GetVerbose())
112199481Srdivacky        ReportRegisterState ("About to checkpoint thread before function call.  Original register state was:");
113239462Sdim
114239462Sdim    if (!thread.CheckpointThreadState (m_stored_thread_state))
115198892Srdivacky    {
116239462Sdim        m_constructor_errors.Printf ("Setting up ThreadPlanCallFunction, failed to checkpoint thread state.");
117239462Sdim        if (log)
118239462Sdim            log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
119239462Sdim        return false;
120239462Sdim    }
121243830Sdim    function_load_addr = m_function_addr.GetLoadAddress (&GetTarget());
122243830Sdim
123243830Sdim    return true;
124243830Sdim}
125239462Sdim
126239462SdimThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
127239462Sdim                                                const Address &function,
128239462Sdim                                                const ClangASTType &return_type,
129198892Srdivacky                                                llvm::ArrayRef<addr_t> args,
130198892Srdivacky                                                const EvaluateExpressionOptions &options) :
131198892Srdivacky    ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion),
132210299Sed    m_valid (false),
133243830Sdim    m_stop_other_threads (options.GetStopOthers()),
134263508Sdim    m_unwind_on_error (options.DoesUnwindOnError()),
135243830Sdim    m_ignore_breakpoints (options.DoesIgnoreBreakpoints()),
136243830Sdim    m_debug_execution (options.GetDebug()),
137218893Sdim    m_trap_exceptions (options.GetTrapExceptions()),
138198892Srdivacky    m_function_addr (function),
139263508Sdim    m_function_sp (0),
140239462Sdim    m_return_type (return_type),
141239462Sdim    m_takedown_done (false),
142239462Sdim    m_should_clear_objc_exception_bp(false),
143239462Sdim    m_should_clear_cxx_exception_bp (false),
144239462Sdim    m_stop_address (LLDB_INVALID_ADDRESS)
145249423Sdim{
146249423Sdim    lldb::addr_t start_load_addr;
147249423Sdim    ABI *abi;
148239462Sdim    lldb::addr_t function_load_addr;
149239462Sdim    if (!ConstructorSetup (thread, abi, start_load_addr, function_load_addr))
150263508Sdim        return;
151243830Sdim
152239462Sdim    if (!abi->PrepareTrivialCall(thread,
153239462Sdim                                 m_function_sp,
154239462Sdim                                 function_load_addr,
155239462Sdim                                 start_load_addr,
156239462Sdim                                 args))
157263508Sdim        return;
158239462Sdim
159239462Sdim    ReportRegisterState ("Function call was set up.  Register state was:");
160239462Sdim
161239462Sdim    m_valid = true;
162263508Sdim}
163243830Sdim
164239462SdimThreadPlanCallFunction::~ThreadPlanCallFunction ()
165239462Sdim{
166239462Sdim    DoTakedown(PlanSucceeded());
167251662Sdim}
168239462Sdim
169239462Sdimvoid
170239462SdimThreadPlanCallFunction::ReportRegisterState (const char *message)
171239462Sdim{
172239462Sdim    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP | LIBLLDB_LOG_VERBOSE));
173239462Sdim    if (log)
174239462Sdim    {
175239462Sdim        StreamString strm;
176263508Sdim        RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
177243830Sdim
178239462Sdim        log->PutCString(message);
179239462Sdim
180239462Sdim        RegisterValue reg_value;
181239462Sdim
182239462Sdim        for (uint32_t reg_idx = 0, num_registers = reg_ctx->GetRegisterCount();
183239462Sdim             reg_idx < num_registers;
184239462Sdim             ++reg_idx)
185239462Sdim        {
186239462Sdim            const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_idx);
187239462Sdim            if (reg_ctx->ReadRegister(reg_info, reg_value))
188239462Sdim            {
189239462Sdim                reg_value.Dump(&strm, reg_info, true, false, eFormatDefault);
190239462Sdim                strm.EOL();
191239462Sdim            }
192239462Sdim        }
193239462Sdim        log->PutCString(strm.GetData());
194239462Sdim    }
195239462Sdim}
196239462Sdim
197239462Sdimvoid
198239462SdimThreadPlanCallFunction::DoTakedown (bool success)
199239462Sdim{
200249423Sdim    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
201239462Sdim
202239462Sdim    if (!m_valid)
203239462Sdim    {
204239462Sdim        //Don't call DoTakedown if we were never valid to begin with.
205239462Sdim        if (log)
206239462Sdim            log->Printf ("ThreadPlanCallFunction(%p): Log called on ThreadPlanCallFunction that was never valid.", this);
207239462Sdim        return;
208239462Sdim    }
209239462Sdim
210239462Sdim    if (!m_takedown_done)
211239462Sdim    {
212239462Sdim        if (success)
213263508Sdim        {
214239462Sdim            ProcessSP process_sp (m_thread.GetProcess());
215239462Sdim            const ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
216239462Sdim            if (abi && m_return_type.IsValid())
217239462Sdim            {
218239462Sdim                const bool persistent = false;
219239462Sdim                m_return_valobj_sp = abi->GetReturnValueObject (m_thread, m_return_type, persistent);
220239462Sdim            }
221239462Sdim        }
222239462Sdim        if (log)
223263508Sdim            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());
224243830Sdim        m_takedown_done = true;
225239462Sdim        m_stop_address = m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC();
226239462Sdim        m_real_stop_info_sp = GetPrivateStopInfo ();
227239462Sdim        if (!m_thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state))
228239462Sdim        {
229239462Sdim            if (log)
230239462Sdim                log->Printf("ThreadPlanCallFunction(%p): DoTakedown failed to restore register state", this);
231263508Sdim        }
232239462Sdim        SetPlanComplete(success);
233239462Sdim        ClearBreakpoints();
234239462Sdim        if (log && log->GetVerbose())
235239462Sdim            ReportRegisterState ("Restoring thread state after function call.  Restored register state:");
236239462Sdim
237239462Sdim    }
238239462Sdim    else
239263508Sdim    {
240263508Sdim        if (log)
241239462Sdim            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());
242239462Sdim    }
243239462Sdim}
244239462Sdim
245239462Sdimvoid
246239462SdimThreadPlanCallFunction::WillPop ()
247239462Sdim{
248239462Sdim    DoTakedown(PlanSucceeded());
249239462Sdim}
250239462Sdim
251239462Sdimvoid
252239462SdimThreadPlanCallFunction::GetDescription (Stream *s, DescriptionLevel level)
253239462Sdim{
254239462Sdim    if (level == eDescriptionLevelBrief)
255239462Sdim    {
256239462Sdim        s->Printf("Function call thread plan");
257239462Sdim    }
258239462Sdim    else
259239462Sdim    {
260239462Sdim        TargetSP target_sp (m_thread.CalculateTarget());
261239462Sdim        s->Printf("Thread plan to call 0x%" PRIx64, m_function_addr.GetLoadAddress(target_sp.get()));
262239462Sdim    }
263239462Sdim}
264239462Sdim
265239462Sdimbool
266239462SdimThreadPlanCallFunction::ValidatePlan (Stream *error)
267239462Sdim{
268239462Sdim    if (!m_valid)
269239462Sdim    {
270239462Sdim        if (error)
271198892Srdivacky        {
272198892Srdivacky            if (m_constructor_errors.GetSize() > 0)
273198892Srdivacky                error->PutCString (m_constructor_errors.GetData());
274            else
275                error->PutCString ("Unknown error");
276        }
277        return false;
278    }
279
280    return true;
281}
282
283
284Vote
285ThreadPlanCallFunction::ShouldReportStop(Event *event_ptr)
286{
287    if (m_takedown_done || IsPlanComplete())
288        return eVoteYes;
289    else
290        return ThreadPlan::ShouldReportStop(event_ptr);
291}
292
293bool
294ThreadPlanCallFunction::DoPlanExplainsStop (Event *event_ptr)
295{
296    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP|LIBLLDB_LOG_PROCESS));
297    m_real_stop_info_sp = GetPrivateStopInfo ();
298
299    // If our subplan knows why we stopped, even if it's done (which would forward the question to us)
300    // we answer yes.
301    if (m_subplan_sp.get() != NULL && m_subplan_sp->PlanExplainsStop(event_ptr))
302    {
303        SetPlanComplete();
304        return true;
305    }
306
307    // Check if the breakpoint is one of ours.
308
309    StopReason stop_reason;
310    if (!m_real_stop_info_sp)
311        stop_reason = eStopReasonNone;
312    else
313        stop_reason = m_real_stop_info_sp->GetStopReason();
314    if (log)
315        log->Printf ("ThreadPlanCallFunction::PlanExplainsStop: Got stop reason - %s.", Thread::StopReasonAsCString(stop_reason));
316
317    if (stop_reason == eStopReasonBreakpoint && BreakpointsExplainStop())
318        return true;
319
320    // We control breakpoints separately from other "stop reasons."  So first,
321    // check the case where we stopped for an internal breakpoint, in that case, continue on.
322    // If it is not an internal breakpoint, consult m_ignore_breakpoints.
323
324
325    if (stop_reason == eStopReasonBreakpoint)
326    {
327        ProcessSP process_sp (m_thread.CalculateProcess());
328        uint64_t break_site_id = m_real_stop_info_sp->GetValue();
329        BreakpointSiteSP bp_site_sp;
330        if (process_sp)
331            bp_site_sp = process_sp->GetBreakpointSiteList().FindByID(break_site_id);
332        if (bp_site_sp)
333        {
334            uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
335            bool is_internal = true;
336            for (uint32_t i = 0; i < num_owners; i++)
337            {
338                Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
339                if (log)
340                    log->Printf ("ThreadPlanCallFunction::PlanExplainsStop: hit breakpoint %d while calling function", bp.GetID());
341
342                if (!bp.IsInternal())
343                {
344                    is_internal = false;
345                    break;
346                }
347            }
348            if (is_internal)
349            {
350                if (log)
351                    log->Printf ("ThreadPlanCallFunction::PlanExplainsStop hit an internal breakpoint, not stopping.");
352                return false;
353            }
354        }
355
356        if (m_ignore_breakpoints)
357        {
358            if (log)
359                log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are ignoring breakpoints, overriding breakpoint stop info ShouldStop, returning true");
360            m_real_stop_info_sp->OverrideShouldStop(false);
361            return true;
362        }
363        else
364        {
365            if (log)
366                log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are not ignoring breakpoints, overriding breakpoint stop info ShouldStop, returning true");
367            m_real_stop_info_sp->OverrideShouldStop(true);
368            return false;
369        }
370    }
371    else if (!m_unwind_on_error)
372    {
373        // If we don't want to discard this plan, than any stop we don't understand should be propagated up the stack.
374        return false;
375    }
376    else
377    {
378        // If the subplan is running, any crashes are attributable to us.
379        // If we want to discard the plan, then we say we explain the stop
380        // but if we are going to be discarded, let whoever is above us
381        // explain the stop.
382        // But don't discard the plan if the stop would restart itself (for instance if it is a
383        // signal that is set not to stop.  Check that here first.  We just say we explain the stop
384        // but aren't done and everything will continue on from there.
385
386        if (m_real_stop_info_sp->ShouldStopSynchronous(event_ptr))
387        {
388            SetPlanComplete(false);
389            if (m_subplan_sp)
390            {
391                if (m_unwind_on_error)
392                    return true;
393                else
394                    return false;
395            }
396            else
397                return false;
398        }
399        else
400            return true;
401    }
402}
403
404bool
405ThreadPlanCallFunction::ShouldStop (Event *event_ptr)
406{
407    // We do some computation in DoPlanExplainsStop that may or may not set the plan as complete.
408    // We need to do that here to make sure our state is correct.
409    DoPlanExplainsStop(event_ptr);
410
411    if (IsPlanComplete())
412    {
413        ReportRegisterState ("Function completed.  Register state was:");
414        return true;
415    }
416    else
417    {
418        return false;
419    }
420}
421
422bool
423ThreadPlanCallFunction::StopOthers ()
424{
425    return m_stop_other_threads;
426}
427
428void
429ThreadPlanCallFunction::SetStopOthers (bool new_value)
430{
431    if (m_subplan_sp)
432    {
433        ThreadPlanRunToAddress *address_plan = static_cast<ThreadPlanRunToAddress *>(m_subplan_sp.get());
434        address_plan->SetStopOthers(new_value);
435    }
436    m_stop_other_threads = new_value;
437}
438
439StateType
440ThreadPlanCallFunction::GetPlanRunState ()
441{
442    return eStateRunning;
443}
444
445void
446ThreadPlanCallFunction::DidPush ()
447{
448//#define SINGLE_STEP_EXPRESSIONS
449
450    // Now set the thread state to "no reason" so we don't run with whatever signal was outstanding...
451    // Wait till the plan is pushed so we aren't changing the stop info till we're about to run.
452
453    GetThread().SetStopInfoToNothing();
454
455#ifndef SINGLE_STEP_EXPRESSIONS
456    m_subplan_sp.reset(new ThreadPlanRunToAddress(m_thread, m_start_addr, m_stop_other_threads));
457
458    m_thread.QueueThreadPlan(m_subplan_sp, false);
459    m_subplan_sp->SetPrivate (true);
460#endif
461}
462
463bool
464ThreadPlanCallFunction::WillStop ()
465{
466    return true;
467}
468
469bool
470ThreadPlanCallFunction::MischiefManaged ()
471{
472    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
473
474    if (IsPlanComplete())
475    {
476        if (log)
477            log->Printf("ThreadPlanCallFunction(%p): Completed call function plan.", this);
478
479        ThreadPlan::MischiefManaged ();
480        return true;
481    }
482    else
483    {
484        return false;
485    }
486}
487
488void
489ThreadPlanCallFunction::SetBreakpoints ()
490{
491    ProcessSP process_sp (m_thread.CalculateProcess());
492    if (m_trap_exceptions && process_sp)
493    {
494        m_cxx_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeC_plus_plus);
495        m_objc_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeObjC);
496
497        if (m_cxx_language_runtime)
498        {
499            m_should_clear_cxx_exception_bp = !m_cxx_language_runtime->ExceptionBreakpointsAreSet();
500            m_cxx_language_runtime->SetExceptionBreakpoints();
501        }
502        if (m_objc_language_runtime)
503        {
504            m_should_clear_objc_exception_bp = !m_objc_language_runtime->ExceptionBreakpointsAreSet();
505            m_objc_language_runtime->SetExceptionBreakpoints();
506        }
507    }
508}
509
510void
511ThreadPlanCallFunction::ClearBreakpoints ()
512{
513    if (m_trap_exceptions)
514    {
515        if (m_cxx_language_runtime && m_should_clear_cxx_exception_bp)
516            m_cxx_language_runtime->ClearExceptionBreakpoints();
517        if (m_objc_language_runtime && m_should_clear_objc_exception_bp)
518            m_objc_language_runtime->ClearExceptionBreakpoints();
519    }
520}
521
522bool
523ThreadPlanCallFunction::BreakpointsExplainStop()
524{
525    StopInfoSP stop_info_sp = GetPrivateStopInfo ();
526
527    if (m_trap_exceptions)
528    {
529        if ((m_cxx_language_runtime &&
530                m_cxx_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))
531           ||(m_objc_language_runtime &&
532                m_objc_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp)))
533        {
534            Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
535            if (log)
536                log->Printf ("ThreadPlanCallFunction::BreakpointsExplainStop - Hit an exception breakpoint, setting plan complete.");
537
538            SetPlanComplete(false);
539
540            // If the user has set the ObjC language breakpoint, it would normally get priority over our internal
541            // catcher breakpoint, but in this case we can't let that happen, so force the ShouldStop here.
542            stop_info_sp->OverrideShouldStop (true);
543            return true;
544        }
545    }
546
547    return false;
548}
549
550bool
551ThreadPlanCallFunction::RestoreThreadState()
552{
553    return GetThread().RestoreThreadStateFromCheckpoint(m_stored_thread_state);
554}
555
556