1254721Semaste//===-- ThreadPlanCallFunction.cpp ------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/Target/ThreadPlanCallFunction.h"
11254721Semaste
12254721Semaste// C Includes
13254721Semaste// C++ Includes
14254721Semaste// Other libraries and framework includes
15254721Semaste#include "llvm/Support/MachO.h"
16254721Semaste// Project includes
17254721Semaste#include "lldb/lldb-private-log.h"
18254721Semaste#include "lldb/Breakpoint/Breakpoint.h"
19254721Semaste#include "lldb/Breakpoint/BreakpointLocation.h"
20254721Semaste#include "lldb/Core/Address.h"
21254721Semaste#include "lldb/Core/Log.h"
22254721Semaste#include "lldb/Core/Module.h"
23254721Semaste#include "lldb/Core/Stream.h"
24254721Semaste#include "lldb/Symbol/ObjectFile.h"
25254721Semaste#include "lldb/Target/LanguageRuntime.h"
26254721Semaste#include "lldb/Target/Process.h"
27254721Semaste#include "lldb/Target/RegisterContext.h"
28254721Semaste#include "lldb/Target/StopInfo.h"
29254721Semaste#include "lldb/Target/Target.h"
30254721Semaste#include "lldb/Target/Thread.h"
31254721Semaste#include "lldb/Target/ThreadPlanRunToAddress.h"
32254721Semaste
33254721Semasteusing namespace lldb;
34254721Semasteusing namespace lldb_private;
35254721Semaste
36254721Semaste//----------------------------------------------------------------------
37254721Semaste// ThreadPlanCallFunction: Plan to call a single function
38254721Semaste//----------------------------------------------------------------------
39254721Semastebool
40254721SemasteThreadPlanCallFunction::ConstructorSetup (Thread &thread,
41254721Semaste                                          ABI *& abi,
42254721Semaste                                          lldb::addr_t &start_load_addr,
43254721Semaste                                          lldb::addr_t &function_load_addr)
44254721Semaste{
45254721Semaste    SetIsMasterPlan (true);
46254721Semaste    SetOkayToDiscard (false);
47254721Semaste    SetPrivate (true);
48254721Semaste
49254721Semaste    ProcessSP process_sp (thread.GetProcess());
50254721Semaste    if (!process_sp)
51254721Semaste        return false;
52254721Semaste
53254721Semaste    abi = process_sp->GetABI().get();
54254721Semaste
55254721Semaste    if (!abi)
56254721Semaste        return false;
57254721Semaste
58254721Semaste    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
59254721Semaste
60254721Semaste    SetBreakpoints();
61254721Semaste
62254721Semaste    m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize();
63254721Semaste    // If we can't read memory at the point of the process where we are planning to put our function, we're
64254721Semaste    // not going to get any further...
65254721Semaste    Error error;
66254721Semaste    process_sp->ReadUnsignedIntegerFromMemory(m_function_sp, 4, 0, error);
67254721Semaste    if (!error.Success())
68254721Semaste    {
69254721Semaste        m_constructor_errors.Printf ("Trying to put the stack in unreadable memory at: 0x%" PRIx64 ".", m_function_sp);
70254721Semaste        if (log)
71254721Semaste            log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
72254721Semaste        return false;
73254721Semaste    }
74254721Semaste
75263367Semaste    Module *exe_module = GetTarget().GetExecutableModulePointer();
76254721Semaste
77254721Semaste    if (exe_module == NULL)
78254721Semaste    {
79254721Semaste        m_constructor_errors.Printf ("Can't execute code without an executable module.");
80254721Semaste        if (log)
81254721Semaste            log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
82254721Semaste        return false;
83254721Semaste    }
84254721Semaste    else
85254721Semaste    {
86254721Semaste        ObjectFile *objectFile = exe_module->GetObjectFile();
87254721Semaste        if (!objectFile)
88254721Semaste        {
89254721Semaste            m_constructor_errors.Printf ("Could not find object file for module \"%s\".",
90254721Semaste                                         exe_module->GetFileSpec().GetFilename().AsCString());
91254721Semaste
92254721Semaste            if (log)
93254721Semaste                log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
94254721Semaste            return false;
95254721Semaste        }
96254721Semaste
97254721Semaste        m_start_addr = objectFile->GetEntryPointAddress();
98254721Semaste        if (!m_start_addr.IsValid())
99254721Semaste        {
100254721Semaste            m_constructor_errors.Printf ("Could not find entry point address for executable module \"%s\".",
101254721Semaste                                         exe_module->GetFileSpec().GetFilename().AsCString());
102254721Semaste            if (log)
103254721Semaste                log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
104254721Semaste            return false;
105254721Semaste        }
106254721Semaste    }
107254721Semaste
108263367Semaste    start_load_addr = m_start_addr.GetLoadAddress (&GetTarget());
109254721Semaste
110254721Semaste    // Checkpoint the thread state so we can restore it later.
111254721Semaste    if (log && log->GetVerbose())
112254721Semaste        ReportRegisterState ("About to checkpoint thread before function call.  Original register state was:");
113254721Semaste
114254721Semaste    if (!thread.CheckpointThreadState (m_stored_thread_state))
115254721Semaste    {
116254721Semaste        m_constructor_errors.Printf ("Setting up ThreadPlanCallFunction, failed to checkpoint thread state.");
117254721Semaste        if (log)
118254721Semaste            log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
119254721Semaste        return false;
120254721Semaste    }
121263367Semaste    function_load_addr = m_function_addr.GetLoadAddress (&GetTarget());
122254721Semaste
123254721Semaste    return true;
124254721Semaste}
125254721Semaste
126254721SemasteThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
127254721Semaste                                                const Address &function,
128254721Semaste                                                const ClangASTType &return_type,
129263367Semaste                                                llvm::ArrayRef<addr_t> args,
130263367Semaste                                                const EvaluateExpressionOptions &options) :
131254721Semaste    ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion),
132254721Semaste    m_valid (false),
133263367Semaste    m_stop_other_threads (options.GetStopOthers()),
134263367Semaste    m_unwind_on_error (options.DoesUnwindOnError()),
135263367Semaste    m_ignore_breakpoints (options.DoesIgnoreBreakpoints()),
136263367Semaste    m_debug_execution (options.GetDebug()),
137263367Semaste    m_trap_exceptions (options.GetTrapExceptions()),
138254721Semaste    m_function_addr (function),
139254721Semaste    m_function_sp (0),
140254721Semaste    m_return_type (return_type),
141254721Semaste    m_takedown_done (false),
142263367Semaste    m_should_clear_objc_exception_bp(false),
143263367Semaste    m_should_clear_cxx_exception_bp (false),
144263367Semaste    m_stop_address (LLDB_INVALID_ADDRESS)
145254721Semaste{
146254721Semaste    lldb::addr_t start_load_addr;
147254721Semaste    ABI *abi;
148254721Semaste    lldb::addr_t function_load_addr;
149254721Semaste    if (!ConstructorSetup (thread, abi, start_load_addr, function_load_addr))
150254721Semaste        return;
151254721Semaste
152263367Semaste    if (!abi->PrepareTrivialCall(thread,
153263367Semaste                                 m_function_sp,
154263367Semaste                                 function_load_addr,
155263367Semaste                                 start_load_addr,
156263367Semaste                                 args))
157254721Semaste        return;
158254721Semaste
159254721Semaste    ReportRegisterState ("Function call was set up.  Register state was:");
160254721Semaste
161254721Semaste    m_valid = true;
162254721Semaste}
163254721Semaste
164254721SemasteThreadPlanCallFunction::~ThreadPlanCallFunction ()
165254721Semaste{
166254721Semaste    DoTakedown(PlanSucceeded());
167254721Semaste}
168254721Semaste
169254721Semastevoid
170254721SemasteThreadPlanCallFunction::ReportRegisterState (const char *message)
171254721Semaste{
172254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP | LIBLLDB_LOG_VERBOSE));
173254721Semaste    if (log)
174254721Semaste    {
175254721Semaste        StreamString strm;
176254721Semaste        RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
177254721Semaste
178254721Semaste        log->PutCString(message);
179254721Semaste
180254721Semaste        RegisterValue reg_value;
181254721Semaste
182254721Semaste        for (uint32_t reg_idx = 0, num_registers = reg_ctx->GetRegisterCount();
183254721Semaste             reg_idx < num_registers;
184254721Semaste             ++reg_idx)
185254721Semaste        {
186254721Semaste            const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_idx);
187254721Semaste            if (reg_ctx->ReadRegister(reg_info, reg_value))
188254721Semaste            {
189254721Semaste                reg_value.Dump(&strm, reg_info, true, false, eFormatDefault);
190254721Semaste                strm.EOL();
191254721Semaste            }
192254721Semaste        }
193254721Semaste        log->PutCString(strm.GetData());
194254721Semaste    }
195254721Semaste}
196254721Semaste
197254721Semastevoid
198254721SemasteThreadPlanCallFunction::DoTakedown (bool success)
199254721Semaste{
200254721Semaste    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
201254721Semaste
202254721Semaste    if (!m_valid)
203254721Semaste    {
204254721Semaste        //Don't call DoTakedown if we were never valid to begin with.
205254721Semaste        if (log)
206254721Semaste            log->Printf ("ThreadPlanCallFunction(%p): Log called on ThreadPlanCallFunction that was never valid.", this);
207254721Semaste        return;
208254721Semaste    }
209254721Semaste
210254721Semaste    if (!m_takedown_done)
211254721Semaste    {
212254721Semaste        if (success)
213254721Semaste        {
214254721Semaste            ProcessSP process_sp (m_thread.GetProcess());
215254721Semaste            const ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
216254721Semaste            if (abi && m_return_type.IsValid())
217254721Semaste            {
218254721Semaste                const bool persistent = false;
219254721Semaste                m_return_valobj_sp = abi->GetReturnValueObject (m_thread, m_return_type, persistent);
220254721Semaste            }
221254721Semaste        }
222254721Semaste        if (log)
223254721Semaste            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());
224254721Semaste        m_takedown_done = true;
225254721Semaste        m_stop_address = m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC();
226254721Semaste        m_real_stop_info_sp = GetPrivateStopInfo ();
227263365Semaste        if (!m_thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state))
228263365Semaste        {
229263365Semaste            if (log)
230263365Semaste                log->Printf("ThreadPlanCallFunction(%p): DoTakedown failed to restore register state", this);
231263365Semaste        }
232254721Semaste        SetPlanComplete(success);
233254721Semaste        ClearBreakpoints();
234254721Semaste        if (log && log->GetVerbose())
235254721Semaste            ReportRegisterState ("Restoring thread state after function call.  Restored register state:");
236254721Semaste
237254721Semaste    }
238254721Semaste    else
239254721Semaste    {
240254721Semaste        if (log)
241254721Semaste            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());
242254721Semaste    }
243254721Semaste}
244254721Semaste
245254721Semastevoid
246254721SemasteThreadPlanCallFunction::WillPop ()
247254721Semaste{
248254721Semaste    DoTakedown(PlanSucceeded());
249254721Semaste}
250254721Semaste
251254721Semastevoid
252254721SemasteThreadPlanCallFunction::GetDescription (Stream *s, DescriptionLevel level)
253254721Semaste{
254254721Semaste    if (level == eDescriptionLevelBrief)
255254721Semaste    {
256254721Semaste        s->Printf("Function call thread plan");
257254721Semaste    }
258254721Semaste    else
259254721Semaste    {
260254721Semaste        TargetSP target_sp (m_thread.CalculateTarget());
261254721Semaste        s->Printf("Thread plan to call 0x%" PRIx64, m_function_addr.GetLoadAddress(target_sp.get()));
262254721Semaste    }
263254721Semaste}
264254721Semaste
265254721Semastebool
266254721SemasteThreadPlanCallFunction::ValidatePlan (Stream *error)
267254721Semaste{
268254721Semaste    if (!m_valid)
269254721Semaste    {
270254721Semaste        if (error)
271254721Semaste        {
272254721Semaste            if (m_constructor_errors.GetSize() > 0)
273254721Semaste                error->PutCString (m_constructor_errors.GetData());
274254721Semaste            else
275254721Semaste                error->PutCString ("Unknown error");
276254721Semaste        }
277254721Semaste        return false;
278254721Semaste    }
279254721Semaste
280254721Semaste    return true;
281254721Semaste}
282254721Semaste
283254721Semaste
284254721SemasteVote
285254721SemasteThreadPlanCallFunction::ShouldReportStop(Event *event_ptr)
286254721Semaste{
287254721Semaste    if (m_takedown_done || IsPlanComplete())
288254721Semaste        return eVoteYes;
289254721Semaste    else
290254721Semaste        return ThreadPlan::ShouldReportStop(event_ptr);
291254721Semaste}
292254721Semaste
293254721Semastebool
294254721SemasteThreadPlanCallFunction::DoPlanExplainsStop (Event *event_ptr)
295254721Semaste{
296254721Semaste    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP|LIBLLDB_LOG_PROCESS));
297254721Semaste    m_real_stop_info_sp = GetPrivateStopInfo ();
298254721Semaste
299254721Semaste    // If our subplan knows why we stopped, even if it's done (which would forward the question to us)
300254721Semaste    // we answer yes.
301254721Semaste    if (m_subplan_sp.get() != NULL && m_subplan_sp->PlanExplainsStop(event_ptr))
302254721Semaste    {
303254721Semaste        SetPlanComplete();
304254721Semaste        return true;
305254721Semaste    }
306254721Semaste
307254721Semaste    // Check if the breakpoint is one of ours.
308254721Semaste
309254721Semaste    StopReason stop_reason;
310254721Semaste    if (!m_real_stop_info_sp)
311254721Semaste        stop_reason = eStopReasonNone;
312254721Semaste    else
313254721Semaste        stop_reason = m_real_stop_info_sp->GetStopReason();
314254721Semaste    if (log)
315254721Semaste        log->Printf ("ThreadPlanCallFunction::PlanExplainsStop: Got stop reason - %s.", Thread::StopReasonAsCString(stop_reason));
316254721Semaste
317254721Semaste    if (stop_reason == eStopReasonBreakpoint && BreakpointsExplainStop())
318254721Semaste        return true;
319254721Semaste
320254721Semaste    // We control breakpoints separately from other "stop reasons."  So first,
321254721Semaste    // check the case where we stopped for an internal breakpoint, in that case, continue on.
322254721Semaste    // If it is not an internal breakpoint, consult m_ignore_breakpoints.
323254721Semaste
324254721Semaste
325254721Semaste    if (stop_reason == eStopReasonBreakpoint)
326254721Semaste    {
327254721Semaste        ProcessSP process_sp (m_thread.CalculateProcess());
328254721Semaste        uint64_t break_site_id = m_real_stop_info_sp->GetValue();
329254721Semaste        BreakpointSiteSP bp_site_sp;
330254721Semaste        if (process_sp)
331254721Semaste            bp_site_sp = process_sp->GetBreakpointSiteList().FindByID(break_site_id);
332254721Semaste        if (bp_site_sp)
333254721Semaste        {
334254721Semaste            uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
335254721Semaste            bool is_internal = true;
336254721Semaste            for (uint32_t i = 0; i < num_owners; i++)
337254721Semaste            {
338254721Semaste                Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
339254721Semaste                if (log)
340254721Semaste                    log->Printf ("ThreadPlanCallFunction::PlanExplainsStop: hit breakpoint %d while calling function", bp.GetID());
341254721Semaste
342254721Semaste                if (!bp.IsInternal())
343254721Semaste                {
344254721Semaste                    is_internal = false;
345254721Semaste                    break;
346254721Semaste                }
347254721Semaste            }
348254721Semaste            if (is_internal)
349254721Semaste            {
350254721Semaste                if (log)
351254721Semaste                    log->Printf ("ThreadPlanCallFunction::PlanExplainsStop hit an internal breakpoint, not stopping.");
352254721Semaste                return false;
353254721Semaste            }
354254721Semaste        }
355254721Semaste
356254721Semaste        if (m_ignore_breakpoints)
357254721Semaste        {
358254721Semaste            if (log)
359254721Semaste                log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are ignoring breakpoints, overriding breakpoint stop info ShouldStop, returning true");
360254721Semaste            m_real_stop_info_sp->OverrideShouldStop(false);
361254721Semaste            return true;
362254721Semaste        }
363254721Semaste        else
364254721Semaste        {
365254721Semaste            if (log)
366254721Semaste                log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are not ignoring breakpoints, overriding breakpoint stop info ShouldStop, returning true");
367254721Semaste            m_real_stop_info_sp->OverrideShouldStop(true);
368254721Semaste            return false;
369254721Semaste        }
370254721Semaste    }
371254721Semaste    else if (!m_unwind_on_error)
372254721Semaste    {
373254721Semaste        // If we don't want to discard this plan, than any stop we don't understand should be propagated up the stack.
374254721Semaste        return false;
375254721Semaste    }
376254721Semaste    else
377254721Semaste    {
378254721Semaste        // If the subplan is running, any crashes are attributable to us.
379254721Semaste        // If we want to discard the plan, then we say we explain the stop
380254721Semaste        // but if we are going to be discarded, let whoever is above us
381254721Semaste        // explain the stop.
382254721Semaste        // But don't discard the plan if the stop would restart itself (for instance if it is a
383254721Semaste        // signal that is set not to stop.  Check that here first.  We just say we explain the stop
384254721Semaste        // but aren't done and everything will continue on from there.
385254721Semaste
386254721Semaste        if (m_real_stop_info_sp->ShouldStopSynchronous(event_ptr))
387254721Semaste        {
388254721Semaste            SetPlanComplete(false);
389254721Semaste            if (m_subplan_sp)
390254721Semaste            {
391254721Semaste                if (m_unwind_on_error)
392254721Semaste                    return true;
393254721Semaste                else
394254721Semaste                    return false;
395254721Semaste            }
396254721Semaste            else
397254721Semaste                return false;
398254721Semaste        }
399254721Semaste        else
400254721Semaste            return true;
401254721Semaste    }
402254721Semaste}
403254721Semaste
404254721Semastebool
405254721SemasteThreadPlanCallFunction::ShouldStop (Event *event_ptr)
406254721Semaste{
407254721Semaste    // We do some computation in DoPlanExplainsStop that may or may not set the plan as complete.
408254721Semaste    // We need to do that here to make sure our state is correct.
409254721Semaste    DoPlanExplainsStop(event_ptr);
410254721Semaste
411254721Semaste    if (IsPlanComplete())
412254721Semaste    {
413254721Semaste        ReportRegisterState ("Function completed.  Register state was:");
414254721Semaste        return true;
415254721Semaste    }
416254721Semaste    else
417254721Semaste    {
418254721Semaste        return false;
419254721Semaste    }
420254721Semaste}
421254721Semaste
422254721Semastebool
423254721SemasteThreadPlanCallFunction::StopOthers ()
424254721Semaste{
425254721Semaste    return m_stop_other_threads;
426254721Semaste}
427254721Semaste
428254721Semastevoid
429254721SemasteThreadPlanCallFunction::SetStopOthers (bool new_value)
430254721Semaste{
431254721Semaste    if (m_subplan_sp)
432254721Semaste    {
433254721Semaste        ThreadPlanRunToAddress *address_plan = static_cast<ThreadPlanRunToAddress *>(m_subplan_sp.get());
434254721Semaste        address_plan->SetStopOthers(new_value);
435254721Semaste    }
436254721Semaste    m_stop_other_threads = new_value;
437254721Semaste}
438254721Semaste
439254721SemasteStateType
440254721SemasteThreadPlanCallFunction::GetPlanRunState ()
441254721Semaste{
442254721Semaste    return eStateRunning;
443254721Semaste}
444254721Semaste
445254721Semastevoid
446254721SemasteThreadPlanCallFunction::DidPush ()
447254721Semaste{
448254721Semaste//#define SINGLE_STEP_EXPRESSIONS
449254721Semaste
450254721Semaste    // Now set the thread state to "no reason" so we don't run with whatever signal was outstanding...
451254721Semaste    // Wait till the plan is pushed so we aren't changing the stop info till we're about to run.
452254721Semaste
453254721Semaste    GetThread().SetStopInfoToNothing();
454254721Semaste
455254721Semaste#ifndef SINGLE_STEP_EXPRESSIONS
456254721Semaste    m_subplan_sp.reset(new ThreadPlanRunToAddress(m_thread, m_start_addr, m_stop_other_threads));
457254721Semaste
458254721Semaste    m_thread.QueueThreadPlan(m_subplan_sp, false);
459254721Semaste    m_subplan_sp->SetPrivate (true);
460254721Semaste#endif
461254721Semaste}
462254721Semaste
463254721Semastebool
464254721SemasteThreadPlanCallFunction::WillStop ()
465254721Semaste{
466254721Semaste    return true;
467254721Semaste}
468254721Semaste
469254721Semastebool
470254721SemasteThreadPlanCallFunction::MischiefManaged ()
471254721Semaste{
472254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
473254721Semaste
474254721Semaste    if (IsPlanComplete())
475254721Semaste    {
476254721Semaste        if (log)
477254721Semaste            log->Printf("ThreadPlanCallFunction(%p): Completed call function plan.", this);
478254721Semaste
479254721Semaste        ThreadPlan::MischiefManaged ();
480254721Semaste        return true;
481254721Semaste    }
482254721Semaste    else
483254721Semaste    {
484254721Semaste        return false;
485254721Semaste    }
486254721Semaste}
487254721Semaste
488254721Semastevoid
489254721SemasteThreadPlanCallFunction::SetBreakpoints ()
490254721Semaste{
491254721Semaste    ProcessSP process_sp (m_thread.CalculateProcess());
492263367Semaste    if (m_trap_exceptions && process_sp)
493254721Semaste    {
494254721Semaste        m_cxx_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeC_plus_plus);
495254721Semaste        m_objc_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeObjC);
496254721Semaste
497254721Semaste        if (m_cxx_language_runtime)
498263367Semaste        {
499263367Semaste            m_should_clear_cxx_exception_bp = !m_cxx_language_runtime->ExceptionBreakpointsAreSet();
500254721Semaste            m_cxx_language_runtime->SetExceptionBreakpoints();
501263367Semaste        }
502254721Semaste        if (m_objc_language_runtime)
503263367Semaste        {
504263367Semaste            m_should_clear_objc_exception_bp = !m_objc_language_runtime->ExceptionBreakpointsAreSet();
505254721Semaste            m_objc_language_runtime->SetExceptionBreakpoints();
506263367Semaste        }
507254721Semaste    }
508254721Semaste}
509254721Semaste
510254721Semastevoid
511254721SemasteThreadPlanCallFunction::ClearBreakpoints ()
512254721Semaste{
513263367Semaste    if (m_trap_exceptions)
514263367Semaste    {
515263367Semaste        if (m_cxx_language_runtime && m_should_clear_cxx_exception_bp)
516263367Semaste            m_cxx_language_runtime->ClearExceptionBreakpoints();
517263367Semaste        if (m_objc_language_runtime && m_should_clear_objc_exception_bp)
518263367Semaste            m_objc_language_runtime->ClearExceptionBreakpoints();
519263367Semaste    }
520254721Semaste}
521254721Semaste
522254721Semastebool
523254721SemasteThreadPlanCallFunction::BreakpointsExplainStop()
524254721Semaste{
525254721Semaste    StopInfoSP stop_info_sp = GetPrivateStopInfo ();
526254721Semaste
527263367Semaste    if (m_trap_exceptions)
528254721Semaste    {
529263367Semaste        if ((m_cxx_language_runtime &&
530263367Semaste                m_cxx_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))
531263367Semaste           ||(m_objc_language_runtime &&
532263367Semaste                m_objc_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp)))
533263367Semaste        {
534263367Semaste            Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
535263367Semaste            if (log)
536263367Semaste                log->Printf ("ThreadPlanCallFunction::BreakpointsExplainStop - Hit an exception breakpoint, setting plan complete.");
537263367Semaste
538263367Semaste            SetPlanComplete(false);
539263367Semaste
540263367Semaste            // If the user has set the ObjC language breakpoint, it would normally get priority over our internal
541263367Semaste            // catcher breakpoint, but in this case we can't let that happen, so force the ShouldStop here.
542263367Semaste            stop_info_sp->OverrideShouldStop (true);
543263367Semaste            return true;
544263367Semaste        }
545254721Semaste    }
546254721Semaste
547254721Semaste    return false;
548254721Semaste}
549254721Semaste
550254721Semastebool
551254721SemasteThreadPlanCallFunction::RestoreThreadState()
552254721Semaste{
553254721Semaste    return GetThread().RestoreThreadStateFromCheckpoint(m_stored_thread_state);
554254721Semaste}
555254721Semaste
556