1254721Semaste//===-- SBThread.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/lldb-python.h"
11254721Semaste
12254721Semaste#include "lldb/API/SBThread.h"
13254721Semaste
14254721Semaste#include "lldb/API/SBSymbolContext.h"
15254721Semaste#include "lldb/API/SBFileSpec.h"
16254721Semaste#include "lldb/API/SBStream.h"
17254721Semaste#include "lldb/Breakpoint/BreakpointLocation.h"
18254721Semaste#include "lldb/Core/Debugger.h"
19254721Semaste#include "lldb/Core/State.h"
20254721Semaste#include "lldb/Core/Stream.h"
21254721Semaste#include "lldb/Core/StreamFile.h"
22254721Semaste#include "lldb/Interpreter/CommandInterpreter.h"
23254721Semaste#include "lldb/Target/Thread.h"
24254721Semaste#include "lldb/Target/Process.h"
25254721Semaste#include "lldb/Symbol/SymbolContext.h"
26254721Semaste#include "lldb/Symbol/CompileUnit.h"
27254721Semaste#include "lldb/Target/StopInfo.h"
28254721Semaste#include "lldb/Target/Target.h"
29254721Semaste#include "lldb/Target/ThreadPlan.h"
30254721Semaste#include "lldb/Target/ThreadPlanStepInstruction.h"
31254721Semaste#include "lldb/Target/ThreadPlanStepOut.h"
32254721Semaste#include "lldb/Target/ThreadPlanStepRange.h"
33254721Semaste#include "lldb/Target/ThreadPlanStepInRange.h"
34254721Semaste
35254721Semaste
36254721Semaste#include "lldb/API/SBAddress.h"
37254721Semaste#include "lldb/API/SBDebugger.h"
38254721Semaste#include "lldb/API/SBEvent.h"
39254721Semaste#include "lldb/API/SBFrame.h"
40254721Semaste#include "lldb/API/SBProcess.h"
41254721Semaste#include "lldb/API/SBValue.h"
42254721Semaste
43254721Semasteusing namespace lldb;
44254721Semasteusing namespace lldb_private;
45254721Semaste
46254721Semasteconst char *
47254721SemasteSBThread::GetBroadcasterClassName ()
48254721Semaste{
49254721Semaste    return Thread::GetStaticBroadcasterClass().AsCString();
50254721Semaste}
51254721Semaste
52254721Semaste//----------------------------------------------------------------------
53254721Semaste// Constructors
54254721Semaste//----------------------------------------------------------------------
55254721SemasteSBThread::SBThread () :
56254721Semaste    m_opaque_sp (new ExecutionContextRef())
57254721Semaste{
58254721Semaste}
59254721Semaste
60254721SemasteSBThread::SBThread (const ThreadSP& lldb_object_sp) :
61254721Semaste    m_opaque_sp (new ExecutionContextRef(lldb_object_sp))
62254721Semaste{
63254721Semaste}
64254721Semaste
65254721SemasteSBThread::SBThread (const SBThread &rhs) :
66254721Semaste    m_opaque_sp (new ExecutionContextRef(*rhs.m_opaque_sp))
67254721Semaste{
68254721Semaste
69254721Semaste}
70254721Semaste
71254721Semaste//----------------------------------------------------------------------
72254721Semaste// Assignment operator
73254721Semaste//----------------------------------------------------------------------
74254721Semaste
75254721Semasteconst lldb::SBThread &
76254721SemasteSBThread::operator = (const SBThread &rhs)
77254721Semaste{
78254721Semaste    if (this != &rhs)
79254721Semaste        *m_opaque_sp = *rhs.m_opaque_sp;
80254721Semaste    return *this;
81254721Semaste}
82254721Semaste
83254721Semaste//----------------------------------------------------------------------
84254721Semaste// Destructor
85254721Semaste//----------------------------------------------------------------------
86254721SemasteSBThread::~SBThread()
87254721Semaste{
88254721Semaste}
89254721Semaste
90254721Semastebool
91254721SemasteSBThread::IsValid() const
92254721Semaste{
93254721Semaste    return m_opaque_sp->GetThreadSP().get() != NULL;
94254721Semaste}
95254721Semaste
96254721Semastevoid
97254721SemasteSBThread::Clear ()
98254721Semaste{
99254721Semaste    m_opaque_sp->Clear();
100254721Semaste}
101254721Semaste
102254721Semaste
103254721SemasteStopReason
104254721SemasteSBThread::GetStopReason()
105254721Semaste{
106254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
107254721Semaste
108254721Semaste    StopReason reason = eStopReasonInvalid;
109254721Semaste    Mutex::Locker api_locker;
110254721Semaste    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
111254721Semaste
112254721Semaste    if (exe_ctx.HasThreadScope())
113254721Semaste    {
114254721Semaste        Process::StopLocker stop_locker;
115254721Semaste        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
116254721Semaste        {
117254721Semaste            return exe_ctx.GetThreadPtr()->GetStopReason();
118254721Semaste        }
119254721Semaste        else
120254721Semaste        {
121254721Semaste            if (log)
122254721Semaste                log->Printf ("SBThread(%p)::GetStopReason() => error: process is running", exe_ctx.GetThreadPtr());
123254721Semaste        }
124254721Semaste    }
125254721Semaste
126254721Semaste    if (log)
127254721Semaste        log->Printf ("SBThread(%p)::GetStopReason () => %s", exe_ctx.GetThreadPtr(),
128254721Semaste                     Thread::StopReasonAsCString (reason));
129254721Semaste
130254721Semaste    return reason;
131254721Semaste}
132254721Semaste
133254721Semastesize_t
134254721SemasteSBThread::GetStopReasonDataCount ()
135254721Semaste{
136254721Semaste    Mutex::Locker api_locker;
137254721Semaste    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
138254721Semaste
139254721Semaste    if (exe_ctx.HasThreadScope())
140254721Semaste    {
141254721Semaste        Process::StopLocker stop_locker;
142254721Semaste        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
143254721Semaste        {
144254721Semaste            StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
145254721Semaste            if (stop_info_sp)
146254721Semaste            {
147254721Semaste                StopReason reason = stop_info_sp->GetStopReason();
148254721Semaste                switch (reason)
149254721Semaste                {
150254721Semaste                case eStopReasonInvalid:
151254721Semaste                case eStopReasonNone:
152254721Semaste                case eStopReasonTrace:
153254721Semaste                case eStopReasonExec:
154254721Semaste                case eStopReasonPlanComplete:
155254721Semaste                case eStopReasonThreadExiting:
156254721Semaste                    // There is no data for these stop reasons.
157254721Semaste                    return 0;
158254721Semaste
159254721Semaste                case eStopReasonBreakpoint:
160254721Semaste                    {
161254721Semaste                        break_id_t site_id = stop_info_sp->GetValue();
162254721Semaste                        lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
163254721Semaste                        if (bp_site_sp)
164254721Semaste                            return bp_site_sp->GetNumberOfOwners () * 2;
165254721Semaste                        else
166254721Semaste                            return 0; // Breakpoint must have cleared itself...
167254721Semaste                    }
168254721Semaste                    break;
169254721Semaste
170254721Semaste                case eStopReasonWatchpoint:
171254721Semaste                    return 1;
172254721Semaste
173254721Semaste                case eStopReasonSignal:
174254721Semaste                    return 1;
175254721Semaste
176254721Semaste                case eStopReasonException:
177254721Semaste                    return 1;
178254721Semaste                }
179254721Semaste            }
180254721Semaste        }
181254721Semaste        else
182254721Semaste        {
183254721Semaste            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
184254721Semaste            if (log)
185254721Semaste                log->Printf ("SBThread(%p)::GetStopReasonDataCount() => error: process is running", exe_ctx.GetThreadPtr());
186254721Semaste        }
187254721Semaste    }
188254721Semaste    return 0;
189254721Semaste}
190254721Semaste
191254721Semasteuint64_t
192254721SemasteSBThread::GetStopReasonDataAtIndex (uint32_t idx)
193254721Semaste{
194254721Semaste    Mutex::Locker api_locker;
195254721Semaste    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
196254721Semaste
197254721Semaste    if (exe_ctx.HasThreadScope())
198254721Semaste    {
199254721Semaste        Process::StopLocker stop_locker;
200254721Semaste        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
201254721Semaste        {
202254721Semaste            Thread *thread = exe_ctx.GetThreadPtr();
203254721Semaste            StopInfoSP stop_info_sp = thread->GetStopInfo ();
204254721Semaste            if (stop_info_sp)
205254721Semaste            {
206254721Semaste                StopReason reason = stop_info_sp->GetStopReason();
207254721Semaste                switch (reason)
208254721Semaste                {
209254721Semaste                case eStopReasonInvalid:
210254721Semaste                case eStopReasonNone:
211254721Semaste                case eStopReasonTrace:
212254721Semaste                case eStopReasonExec:
213254721Semaste                case eStopReasonPlanComplete:
214254721Semaste                case eStopReasonThreadExiting:
215254721Semaste                    // There is no data for these stop reasons.
216254721Semaste                    return 0;
217254721Semaste
218254721Semaste                case eStopReasonBreakpoint:
219254721Semaste                    {
220254721Semaste                        break_id_t site_id = stop_info_sp->GetValue();
221254721Semaste                        lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
222254721Semaste                        if (bp_site_sp)
223254721Semaste                        {
224254721Semaste                            uint32_t bp_index = idx / 2;
225254721Semaste                            BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index));
226254721Semaste                            if (bp_loc_sp)
227254721Semaste                            {
228254721Semaste                                if (bp_index & 1)
229254721Semaste                                {
230254721Semaste                                    // Odd idx, return the breakpoint location ID
231254721Semaste                                    return bp_loc_sp->GetID();
232254721Semaste                                }
233254721Semaste                                else
234254721Semaste                                {
235254721Semaste                                    // Even idx, return the breakpoint ID
236254721Semaste                                    return bp_loc_sp->GetBreakpoint().GetID();
237254721Semaste                                }
238254721Semaste                            }
239254721Semaste                        }
240254721Semaste                        return LLDB_INVALID_BREAK_ID;
241254721Semaste                    }
242254721Semaste                    break;
243254721Semaste
244254721Semaste                case eStopReasonWatchpoint:
245254721Semaste                    return stop_info_sp->GetValue();
246254721Semaste
247254721Semaste                case eStopReasonSignal:
248254721Semaste                    return stop_info_sp->GetValue();
249254721Semaste
250254721Semaste                case eStopReasonException:
251254721Semaste                    return stop_info_sp->GetValue();
252254721Semaste                }
253254721Semaste            }
254254721Semaste        }
255254721Semaste        else
256254721Semaste        {
257254721Semaste            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
258254721Semaste            if (log)
259254721Semaste                log->Printf ("SBThread(%p)::GetStopReasonDataAtIndex() => error: process is running", exe_ctx.GetThreadPtr());
260254721Semaste        }
261254721Semaste    }
262254721Semaste    return 0;
263254721Semaste}
264254721Semaste
265254721Semastesize_t
266254721SemasteSBThread::GetStopDescription (char *dst, size_t dst_len)
267254721Semaste{
268254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
269254721Semaste
270254721Semaste    Mutex::Locker api_locker;
271254721Semaste    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
272254721Semaste
273254721Semaste    if (exe_ctx.HasThreadScope())
274254721Semaste    {
275254721Semaste        Process::StopLocker stop_locker;
276254721Semaste        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
277254721Semaste        {
278254721Semaste
279254721Semaste            StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
280254721Semaste            if (stop_info_sp)
281254721Semaste            {
282254721Semaste                const char *stop_desc = stop_info_sp->GetDescription();
283254721Semaste                if (stop_desc)
284254721Semaste                {
285254721Semaste                    if (log)
286254721Semaste                        log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
287254721Semaste                                     exe_ctx.GetThreadPtr(), stop_desc);
288254721Semaste                    if (dst)
289254721Semaste                        return ::snprintf (dst, dst_len, "%s", stop_desc);
290254721Semaste                    else
291254721Semaste                    {
292254721Semaste                        // NULL dst passed in, return the length needed to contain the description
293254721Semaste                        return ::strlen (stop_desc) + 1; // Include the NULL byte for size
294254721Semaste                    }
295254721Semaste                }
296254721Semaste                else
297254721Semaste                {
298254721Semaste                    size_t stop_desc_len = 0;
299254721Semaste                    switch (stop_info_sp->GetStopReason())
300254721Semaste                    {
301254721Semaste                    case eStopReasonTrace:
302254721Semaste                    case eStopReasonPlanComplete:
303254721Semaste                        {
304254721Semaste                            static char trace_desc[] = "step";
305254721Semaste                            stop_desc = trace_desc;
306254721Semaste                            stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size
307254721Semaste                        }
308254721Semaste                        break;
309254721Semaste
310254721Semaste                    case eStopReasonBreakpoint:
311254721Semaste                        {
312254721Semaste                            static char bp_desc[] = "breakpoint hit";
313254721Semaste                            stop_desc = bp_desc;
314254721Semaste                            stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
315254721Semaste                        }
316254721Semaste                        break;
317254721Semaste
318254721Semaste                    case eStopReasonWatchpoint:
319254721Semaste                        {
320254721Semaste                            static char wp_desc[] = "watchpoint hit";
321254721Semaste                            stop_desc = wp_desc;
322254721Semaste                            stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
323254721Semaste                        }
324254721Semaste                        break;
325254721Semaste
326254721Semaste                    case eStopReasonSignal:
327254721Semaste                        {
328254721Semaste                            stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue());
329254721Semaste                            if (stop_desc == NULL || stop_desc[0] == '\0')
330254721Semaste                            {
331254721Semaste                                static char signal_desc[] = "signal";
332254721Semaste                                stop_desc = signal_desc;
333254721Semaste                                stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size
334254721Semaste                            }
335254721Semaste                        }
336254721Semaste                        break;
337254721Semaste
338254721Semaste                    case eStopReasonException:
339254721Semaste                        {
340254721Semaste                            char exc_desc[] = "exception";
341254721Semaste                            stop_desc = exc_desc;
342254721Semaste                            stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
343254721Semaste                        }
344254721Semaste                        break;
345254721Semaste
346254721Semaste                    case eStopReasonExec:
347254721Semaste                        {
348254721Semaste                            char exc_desc[] = "exec";
349254721Semaste                            stop_desc = exc_desc;
350254721Semaste                            stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
351254721Semaste                        }
352254721Semaste                        break;
353254721Semaste
354254721Semaste                    case eStopReasonThreadExiting:
355254721Semaste                        {
356254721Semaste                            char limbo_desc[] = "thread exiting";
357254721Semaste                            stop_desc = limbo_desc;
358254721Semaste                            stop_desc_len = sizeof(limbo_desc);
359254721Semaste                        }
360254721Semaste                        break;
361254721Semaste                    default:
362254721Semaste                        break;
363254721Semaste                    }
364254721Semaste
365254721Semaste                    if (stop_desc && stop_desc[0])
366254721Semaste                    {
367254721Semaste                        if (log)
368254721Semaste                            log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
369254721Semaste                                         exe_ctx.GetThreadPtr(), stop_desc);
370254721Semaste
371254721Semaste                        if (dst)
372254721Semaste                            return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte
373254721Semaste
374254721Semaste                        if (stop_desc_len == 0)
375254721Semaste                            stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte
376254721Semaste
377254721Semaste                        return stop_desc_len;
378254721Semaste                    }
379254721Semaste                }
380254721Semaste            }
381254721Semaste        }
382254721Semaste        else
383254721Semaste        {
384254721Semaste            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
385254721Semaste            if (log)
386254721Semaste                log->Printf ("SBThread(%p)::GetStopDescription() => error: process is running", exe_ctx.GetThreadPtr());
387254721Semaste        }
388254721Semaste    }
389254721Semaste    if (dst)
390254721Semaste        *dst = 0;
391254721Semaste    return 0;
392254721Semaste}
393254721Semaste
394254721SemasteSBValue
395254721SemasteSBThread::GetStopReturnValue ()
396254721Semaste{
397254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
398254721Semaste    ValueObjectSP return_valobj_sp;
399254721Semaste    Mutex::Locker api_locker;
400254721Semaste    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
401254721Semaste
402254721Semaste    if (exe_ctx.HasThreadScope())
403254721Semaste    {
404254721Semaste        Process::StopLocker stop_locker;
405254721Semaste        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
406254721Semaste        {
407254721Semaste            StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
408254721Semaste            if (stop_info_sp)
409254721Semaste            {
410254721Semaste                return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
411254721Semaste            }
412254721Semaste        }
413254721Semaste        else
414254721Semaste        {
415254721Semaste            if (log)
416254721Semaste                log->Printf ("SBThread(%p)::GetStopReturnValue() => error: process is running", exe_ctx.GetThreadPtr());
417254721Semaste        }
418254721Semaste    }
419254721Semaste
420254721Semaste    if (log)
421254721Semaste        log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", exe_ctx.GetThreadPtr(),
422254721Semaste                                                                  return_valobj_sp.get()
423254721Semaste                                                                      ? return_valobj_sp->GetValueAsCString()
424254721Semaste                                                                        : "<no return value>");
425254721Semaste
426254721Semaste    return SBValue (return_valobj_sp);
427254721Semaste}
428254721Semaste
429254721Semastevoid
430254721SemasteSBThread::SetThread (const ThreadSP& lldb_object_sp)
431254721Semaste{
432254721Semaste    m_opaque_sp->SetThreadSP (lldb_object_sp);
433254721Semaste}
434254721Semaste
435254721Semaste
436254721Semastelldb::tid_t
437254721SemasteSBThread::GetThreadID () const
438254721Semaste{
439254721Semaste    ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
440254721Semaste    if (thread_sp)
441254721Semaste        return thread_sp->GetID();
442254721Semaste    return LLDB_INVALID_THREAD_ID;
443254721Semaste}
444254721Semaste
445254721Semasteuint32_t
446254721SemasteSBThread::GetIndexID () const
447254721Semaste{
448254721Semaste    ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
449254721Semaste    if (thread_sp)
450254721Semaste        return thread_sp->GetIndexID();
451254721Semaste    return LLDB_INVALID_INDEX32;
452254721Semaste}
453254721Semaste
454254721Semasteconst char *
455254721SemasteSBThread::GetName () const
456254721Semaste{
457254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
458254721Semaste    const char *name = NULL;
459254721Semaste    Mutex::Locker api_locker;
460254721Semaste    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
461254721Semaste
462254721Semaste    if (exe_ctx.HasThreadScope())
463254721Semaste    {
464254721Semaste        Process::StopLocker stop_locker;
465254721Semaste        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
466254721Semaste        {
467254721Semaste            name = exe_ctx.GetThreadPtr()->GetName();
468254721Semaste        }
469254721Semaste        else
470254721Semaste        {
471254721Semaste            if (log)
472254721Semaste                log->Printf ("SBThread(%p)::GetName() => error: process is running", exe_ctx.GetThreadPtr());
473254721Semaste        }
474254721Semaste    }
475254721Semaste
476254721Semaste    if (log)
477254721Semaste        log->Printf ("SBThread(%p)::GetName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL");
478254721Semaste
479254721Semaste    return name;
480254721Semaste}
481254721Semaste
482254721Semasteconst char *
483254721SemasteSBThread::GetQueueName () const
484254721Semaste{
485254721Semaste    const char *name = NULL;
486254721Semaste    Mutex::Locker api_locker;
487254721Semaste    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
488254721Semaste
489254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
490254721Semaste    if (exe_ctx.HasThreadScope())
491254721Semaste    {
492254721Semaste        Process::StopLocker stop_locker;
493254721Semaste        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
494254721Semaste        {
495254721Semaste            name = exe_ctx.GetThreadPtr()->GetQueueName();
496254721Semaste        }
497254721Semaste        else
498254721Semaste        {
499254721Semaste            if (log)
500254721Semaste                log->Printf ("SBThread(%p)::GetQueueName() => error: process is running", exe_ctx.GetThreadPtr());
501254721Semaste        }
502254721Semaste    }
503254721Semaste
504254721Semaste    if (log)
505254721Semaste        log->Printf ("SBThread(%p)::GetQueueName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL");
506254721Semaste
507254721Semaste    return name;
508254721Semaste}
509254721Semaste
510254721SemasteSBError
511254721SemasteSBThread::ResumeNewPlan (ExecutionContext &exe_ctx, ThreadPlan *new_plan)
512254721Semaste{
513254721Semaste    SBError sb_error;
514254721Semaste
515254721Semaste    Process *process = exe_ctx.GetProcessPtr();
516254721Semaste    if (!process)
517254721Semaste    {
518254721Semaste        sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
519254721Semaste        return sb_error;
520254721Semaste    }
521254721Semaste
522254721Semaste    Thread *thread = exe_ctx.GetThreadPtr();
523254721Semaste    if (!thread)
524254721Semaste    {
525254721Semaste        sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
526254721Semaste        return sb_error;
527254721Semaste    }
528254721Semaste
529254721Semaste    // User level plans should be Master Plans so they can be interrupted, other plans executed, and
530254721Semaste    // then a "continue" will resume the plan.
531254721Semaste    if (new_plan != NULL)
532254721Semaste    {
533254721Semaste        new_plan->SetIsMasterPlan(true);
534254721Semaste        new_plan->SetOkayToDiscard(false);
535254721Semaste    }
536254721Semaste
537254721Semaste    // Why do we need to set the current thread by ID here???
538254721Semaste    process->GetThreadList().SetSelectedThreadByID (thread->GetID());
539254721Semaste    sb_error.ref() = process->Resume();
540254721Semaste
541254721Semaste    if (sb_error.Success())
542254721Semaste    {
543254721Semaste        // If we are doing synchronous mode, then wait for the
544254721Semaste        // process to stop yet again!
545254721Semaste        if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
546254721Semaste            process->WaitForProcessToStop (NULL);
547254721Semaste    }
548254721Semaste
549254721Semaste    return sb_error;
550254721Semaste}
551254721Semaste
552254721Semastevoid
553254721SemasteSBThread::StepOver (lldb::RunMode stop_other_threads)
554254721Semaste{
555254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
556254721Semaste
557254721Semaste    Mutex::Locker api_locker;
558254721Semaste    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
559254721Semaste
560254721Semaste
561254721Semaste    if (log)
562254721Semaste        log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", exe_ctx.GetThreadPtr(),
563254721Semaste                     Thread::RunModeAsCString (stop_other_threads));
564254721Semaste
565254721Semaste    if (exe_ctx.HasThreadScope())
566254721Semaste    {
567254721Semaste        Thread *thread = exe_ctx.GetThreadPtr();
568254721Semaste        bool abort_other_plans = false;
569254721Semaste        StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
570254721Semaste
571254721Semaste        ThreadPlanSP new_plan_sp;
572254721Semaste        if (frame_sp)
573254721Semaste        {
574254721Semaste            if (frame_sp->HasDebugInformation ())
575254721Semaste            {
576254721Semaste                SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
577254721Semaste                new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
578254721Semaste                                                                    sc.line_entry.range,
579254721Semaste                                                                    sc,
580254721Semaste                                                                    stop_other_threads);
581254721Semaste            }
582254721Semaste            else
583254721Semaste            {
584254721Semaste                new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
585254721Semaste                                                                            abort_other_plans,
586254721Semaste                                                                            stop_other_threads);
587254721Semaste            }
588254721Semaste        }
589254721Semaste
590254721Semaste        // This returns an error, we should use it!
591254721Semaste        ResumeNewPlan (exe_ctx, new_plan_sp.get());
592254721Semaste    }
593254721Semaste}
594254721Semaste
595254721Semastevoid
596254721SemasteSBThread::StepInto (lldb::RunMode stop_other_threads)
597254721Semaste{
598254721Semaste    StepInto (NULL, stop_other_threads);
599254721Semaste}
600254721Semaste
601254721Semastevoid
602254721SemasteSBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads)
603254721Semaste{
604254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
605254721Semaste
606254721Semaste    Mutex::Locker api_locker;
607254721Semaste    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
608254721Semaste
609254721Semaste    if (log)
610254721Semaste        log->Printf ("SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')",
611254721Semaste                     exe_ctx.GetThreadPtr(),
612254721Semaste                     target_name? target_name: "<NULL>",
613254721Semaste                     Thread::RunModeAsCString (stop_other_threads));
614254721Semaste
615254721Semaste    if (exe_ctx.HasThreadScope())
616254721Semaste    {
617254721Semaste        bool abort_other_plans = false;
618254721Semaste
619254721Semaste        Thread *thread = exe_ctx.GetThreadPtr();
620254721Semaste        StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
621254721Semaste        ThreadPlanSP new_plan_sp;
622254721Semaste
623254721Semaste        if (frame_sp && frame_sp->HasDebugInformation ())
624254721Semaste        {
625254721Semaste            bool avoid_code_without_debug_info = true;
626254721Semaste            SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
627254721Semaste            new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
628254721Semaste                                                              sc.line_entry.range,
629254721Semaste                                                              sc,
630254721Semaste                                                              target_name,
631254721Semaste                                                              stop_other_threads,
632254721Semaste                                                              avoid_code_without_debug_info);
633254721Semaste        }
634254721Semaste        else
635254721Semaste        {
636254721Semaste            new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false,
637254721Semaste                                                                        abort_other_plans,
638254721Semaste                                                                        stop_other_threads);
639254721Semaste        }
640254721Semaste
641254721Semaste        // This returns an error, we should use it!
642254721Semaste        ResumeNewPlan (exe_ctx, new_plan_sp.get());
643254721Semaste    }
644254721Semaste}
645254721Semaste
646254721Semastevoid
647254721SemasteSBThread::StepOut ()
648254721Semaste{
649254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
650254721Semaste
651254721Semaste    Mutex::Locker api_locker;
652254721Semaste    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
653254721Semaste
654254721Semaste
655254721Semaste    if (log)
656254721Semaste        log->Printf ("SBThread(%p)::StepOut ()", exe_ctx.GetThreadPtr());
657254721Semaste
658254721Semaste    if (exe_ctx.HasThreadScope())
659254721Semaste    {
660254721Semaste        bool abort_other_plans = false;
661254721Semaste        bool stop_other_threads = false;
662254721Semaste
663254721Semaste        Thread *thread = exe_ctx.GetThreadPtr();
664254721Semaste
665254721Semaste        ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans,
666254721Semaste                                                                  NULL,
667254721Semaste                                                                  false,
668254721Semaste                                                                  stop_other_threads,
669254721Semaste                                                                  eVoteYes,
670254721Semaste                                                                  eVoteNoOpinion,
671254721Semaste                                                                  0));
672254721Semaste
673254721Semaste        // This returns an error, we should use it!
674254721Semaste        ResumeNewPlan (exe_ctx, new_plan_sp.get());
675254721Semaste    }
676254721Semaste}
677254721Semaste
678254721Semastevoid
679254721SemasteSBThread::StepOutOfFrame (lldb::SBFrame &sb_frame)
680254721Semaste{
681254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
682254721Semaste
683254721Semaste    Mutex::Locker api_locker;
684254721Semaste    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
685254721Semaste
686254721Semaste    StackFrameSP frame_sp (sb_frame.GetFrameSP());
687254721Semaste    if (log)
688254721Semaste    {
689254721Semaste        SBStream frame_desc_strm;
690254721Semaste        sb_frame.GetDescription (frame_desc_strm);
691254721Semaste        log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData());
692254721Semaste    }
693254721Semaste
694254721Semaste    if (exe_ctx.HasThreadScope())
695254721Semaste    {
696254721Semaste        bool abort_other_plans = false;
697254721Semaste        bool stop_other_threads = false;
698254721Semaste        Thread *thread = exe_ctx.GetThreadPtr();
699254721Semaste
700254721Semaste        ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans,
701254721Semaste                                                                    NULL,
702254721Semaste                                                                    false,
703254721Semaste                                                                    stop_other_threads,
704254721Semaste                                                                    eVoteYes,
705254721Semaste                                                                    eVoteNoOpinion,
706254721Semaste                                                                    frame_sp->GetFrameIndex()));
707254721Semaste
708254721Semaste        // This returns an error, we should use it!
709254721Semaste        ResumeNewPlan (exe_ctx, new_plan_sp.get());
710254721Semaste    }
711254721Semaste}
712254721Semaste
713254721Semastevoid
714254721SemasteSBThread::StepInstruction (bool step_over)
715254721Semaste{
716254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
717254721Semaste
718254721Semaste    Mutex::Locker api_locker;
719254721Semaste    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
720254721Semaste
721254721Semaste
722254721Semaste
723254721Semaste    if (log)
724254721Semaste        log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", exe_ctx.GetThreadPtr(), step_over);
725254721Semaste
726254721Semaste    if (exe_ctx.HasThreadScope())
727254721Semaste    {
728254721Semaste        Thread *thread = exe_ctx.GetThreadPtr();
729254721Semaste        ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true));
730254721Semaste
731254721Semaste        // This returns an error, we should use it!
732254721Semaste        ResumeNewPlan (exe_ctx, new_plan_sp.get());
733254721Semaste    }
734254721Semaste}
735254721Semaste
736254721Semastevoid
737254721SemasteSBThread::RunToAddress (lldb::addr_t addr)
738254721Semaste{
739254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
740254721Semaste
741254721Semaste    Mutex::Locker api_locker;
742254721Semaste    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
743254721Semaste
744254721Semaste
745254721Semaste    if (log)
746254721Semaste        log->Printf ("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")", exe_ctx.GetThreadPtr(), addr);
747254721Semaste
748254721Semaste    if (exe_ctx.HasThreadScope())
749254721Semaste    {
750254721Semaste        bool abort_other_plans = false;
751254721Semaste        bool stop_other_threads = true;
752254721Semaste
753254721Semaste        Address target_addr (addr);
754254721Semaste
755254721Semaste        Thread *thread = exe_ctx.GetThreadPtr();
756254721Semaste
757254721Semaste        ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads));
758254721Semaste
759254721Semaste        // This returns an error, we should use it!
760254721Semaste        ResumeNewPlan (exe_ctx, new_plan_sp.get());
761254721Semaste    }
762254721Semaste}
763254721Semaste
764254721SemasteSBError
765254721SemasteSBThread::StepOverUntil (lldb::SBFrame &sb_frame,
766254721Semaste                         lldb::SBFileSpec &sb_file_spec,
767254721Semaste                         uint32_t line)
768254721Semaste{
769254721Semaste    SBError sb_error;
770254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
771254721Semaste    char path[PATH_MAX];
772254721Semaste
773254721Semaste    Mutex::Locker api_locker;
774254721Semaste    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
775254721Semaste
776254721Semaste    StackFrameSP frame_sp (sb_frame.GetFrameSP());
777254721Semaste
778254721Semaste    if (log)
779254721Semaste    {
780254721Semaste        SBStream frame_desc_strm;
781254721Semaste        sb_frame.GetDescription (frame_desc_strm);
782254721Semaste        sb_file_spec->GetPath (path, sizeof(path));
783254721Semaste        log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)",
784254721Semaste                     exe_ctx.GetThreadPtr(),
785254721Semaste                     frame_sp.get(),
786254721Semaste                     frame_desc_strm.GetData(),
787254721Semaste                     path, line);
788254721Semaste    }
789254721Semaste
790254721Semaste    if (exe_ctx.HasThreadScope())
791254721Semaste    {
792254721Semaste        Target *target = exe_ctx.GetTargetPtr();
793254721Semaste        Thread *thread = exe_ctx.GetThreadPtr();
794254721Semaste
795254721Semaste        if (line == 0)
796254721Semaste        {
797254721Semaste            sb_error.SetErrorString("invalid line argument");
798254721Semaste            return sb_error;
799254721Semaste        }
800254721Semaste
801254721Semaste        if (!frame_sp)
802254721Semaste        {
803254721Semaste            frame_sp = thread->GetSelectedFrame ();
804254721Semaste            if (!frame_sp)
805254721Semaste                frame_sp = thread->GetStackFrameAtIndex (0);
806254721Semaste        }
807254721Semaste
808254721Semaste        SymbolContext frame_sc;
809254721Semaste        if (!frame_sp)
810254721Semaste        {
811254721Semaste            sb_error.SetErrorString("no valid frames in thread to step");
812254721Semaste            return sb_error;
813254721Semaste        }
814254721Semaste
815254721Semaste        // If we have a frame, get its line
816254721Semaste        frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit  |
817254721Semaste                                               eSymbolContextFunction  |
818254721Semaste                                               eSymbolContextLineEntry |
819254721Semaste                                               eSymbolContextSymbol    );
820254721Semaste
821254721Semaste        if (frame_sc.comp_unit == NULL)
822254721Semaste        {
823254721Semaste            sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex());
824254721Semaste            return sb_error;
825254721Semaste        }
826254721Semaste
827254721Semaste        FileSpec step_file_spec;
828254721Semaste        if (sb_file_spec.IsValid())
829254721Semaste        {
830254721Semaste            // The file spec passed in was valid, so use it
831254721Semaste            step_file_spec = sb_file_spec.ref();
832254721Semaste        }
833254721Semaste        else
834254721Semaste        {
835254721Semaste            if (frame_sc.line_entry.IsValid())
836254721Semaste                step_file_spec = frame_sc.line_entry.file;
837254721Semaste            else
838254721Semaste            {
839254721Semaste                sb_error.SetErrorString("invalid file argument or no file for frame");
840254721Semaste                return sb_error;
841254721Semaste            }
842254721Semaste        }
843254721Semaste
844254721Semaste        // Grab the current function, then we will make sure the "until" address is
845254721Semaste        // within the function.  We discard addresses that are out of the current
846254721Semaste        // function, and then if there are no addresses remaining, give an appropriate
847254721Semaste        // error message.
848254721Semaste
849254721Semaste        bool all_in_function = true;
850254721Semaste        AddressRange fun_range = frame_sc.function->GetAddressRange();
851254721Semaste
852254721Semaste        std::vector<addr_t> step_over_until_addrs;
853254721Semaste        const bool abort_other_plans = false;
854254721Semaste        const bool stop_other_threads = false;
855254721Semaste        const bool check_inlines = true;
856254721Semaste        const bool exact = false;
857254721Semaste
858254721Semaste        SymbolContextList sc_list;
859254721Semaste        const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec,
860254721Semaste                                                                               line,
861254721Semaste                                                                               check_inlines,
862254721Semaste                                                                               exact,
863254721Semaste                                                                               eSymbolContextLineEntry,
864254721Semaste                                                                               sc_list);
865254721Semaste        if (num_matches > 0)
866254721Semaste        {
867254721Semaste            SymbolContext sc;
868254721Semaste            for (uint32_t i=0; i<num_matches; ++i)
869254721Semaste            {
870254721Semaste                if (sc_list.GetContextAtIndex(i, sc))
871254721Semaste                {
872254721Semaste                    addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
873254721Semaste                    if (step_addr != LLDB_INVALID_ADDRESS)
874254721Semaste                    {
875254721Semaste                        if (fun_range.ContainsLoadAddress(step_addr, target))
876254721Semaste                            step_over_until_addrs.push_back(step_addr);
877254721Semaste                        else
878254721Semaste                            all_in_function = false;
879254721Semaste                    }
880254721Semaste                }
881254721Semaste            }
882254721Semaste        }
883254721Semaste
884254721Semaste        if (step_over_until_addrs.empty())
885254721Semaste        {
886254721Semaste            if (all_in_function)
887254721Semaste            {
888254721Semaste                step_file_spec.GetPath (path, sizeof(path));
889254721Semaste                sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line);
890254721Semaste            }
891254721Semaste            else
892254721Semaste                sb_error.SetErrorString ("step until target not in current function");
893254721Semaste        }
894254721Semaste        else
895254721Semaste        {
896254721Semaste            ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil (abort_other_plans,
897254721Semaste                                                                        &step_over_until_addrs[0],
898254721Semaste                                                                        step_over_until_addrs.size(),
899254721Semaste                                                                        stop_other_threads,
900254721Semaste                                                                        frame_sp->GetFrameIndex()));
901254721Semaste
902254721Semaste            sb_error = ResumeNewPlan (exe_ctx, new_plan_sp.get());
903254721Semaste        }
904254721Semaste    }
905254721Semaste    else
906254721Semaste    {
907254721Semaste        sb_error.SetErrorString("this SBThread object is invalid");
908254721Semaste    }
909254721Semaste    return sb_error;
910254721Semaste}
911254721Semaste
912254721SemasteSBError
913254721SemasteSBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value)
914254721Semaste{
915254721Semaste    SBError sb_error;
916254721Semaste
917254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
918254721Semaste
919254721Semaste    Mutex::Locker api_locker;
920254721Semaste    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
921254721Semaste
922254721Semaste
923254721Semaste    if (log)
924254721Semaste        log->Printf ("SBThread(%p)::ReturnFromFrame (frame=%d)", exe_ctx.GetThreadPtr(), frame.GetFrameID());
925254721Semaste
926254721Semaste    if (exe_ctx.HasThreadScope())
927254721Semaste    {
928254721Semaste        Thread *thread = exe_ctx.GetThreadPtr();
929254721Semaste        sb_error.SetError (thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
930254721Semaste    }
931254721Semaste
932254721Semaste    return sb_error;
933254721Semaste}
934254721Semaste
935254721Semaste
936254721Semastebool
937254721SemasteSBThread::Suspend()
938254721Semaste{
939254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
940254721Semaste    ExecutionContext exe_ctx (m_opaque_sp.get());
941254721Semaste    bool result = false;
942254721Semaste    if (exe_ctx.HasThreadScope())
943254721Semaste    {
944254721Semaste        Process::StopLocker stop_locker;
945254721Semaste        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
946254721Semaste        {
947254721Semaste            exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended);
948254721Semaste            result = true;
949254721Semaste        }
950254721Semaste        else
951254721Semaste        {
952254721Semaste            if (log)
953254721Semaste                log->Printf ("SBThread(%p)::Suspend() => error: process is running", exe_ctx.GetThreadPtr());
954254721Semaste        }
955254721Semaste    }
956254721Semaste    if (log)
957254721Semaste        log->Printf ("SBThread(%p)::Suspend() => %i", exe_ctx.GetThreadPtr(), result);
958254721Semaste    return result;
959254721Semaste}
960254721Semaste
961254721Semastebool
962254721SemasteSBThread::Resume ()
963254721Semaste{
964254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
965254721Semaste    ExecutionContext exe_ctx (m_opaque_sp.get());
966254721Semaste    bool result = false;
967254721Semaste    if (exe_ctx.HasThreadScope())
968254721Semaste    {
969254721Semaste        Process::StopLocker stop_locker;
970254721Semaste        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
971254721Semaste        {
972254721Semaste            exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning);
973254721Semaste            result = true;
974254721Semaste        }
975254721Semaste        else
976254721Semaste        {
977254721Semaste            if (log)
978254721Semaste                log->Printf ("SBThread(%p)::Resume() => error: process is running", exe_ctx.GetThreadPtr());
979254721Semaste        }
980254721Semaste    }
981254721Semaste    if (log)
982254721Semaste        log->Printf ("SBThread(%p)::Resume() => %i", exe_ctx.GetThreadPtr(), result);
983254721Semaste    return result;
984254721Semaste}
985254721Semaste
986254721Semastebool
987254721SemasteSBThread::IsSuspended()
988254721Semaste{
989254721Semaste    ExecutionContext exe_ctx (m_opaque_sp.get());
990254721Semaste    if (exe_ctx.HasThreadScope())
991254721Semaste        return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended;
992254721Semaste    return false;
993254721Semaste}
994254721Semaste
995254721Semastebool
996254721SemasteSBThread::IsStopped()
997254721Semaste{
998254721Semaste    ExecutionContext exe_ctx (m_opaque_sp.get());
999254721Semaste    if (exe_ctx.HasThreadScope())
1000254721Semaste        return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1001254721Semaste    return false;
1002254721Semaste}
1003254721Semaste
1004254721SemasteSBProcess
1005254721SemasteSBThread::GetProcess ()
1006254721Semaste{
1007254721Semaste    SBProcess sb_process;
1008254721Semaste    ExecutionContext exe_ctx (m_opaque_sp.get());
1009254721Semaste    if (exe_ctx.HasThreadScope())
1010254721Semaste    {
1011254721Semaste        // Have to go up to the target so we can get a shared pointer to our process...
1012254721Semaste        sb_process.SetSP (exe_ctx.GetProcessSP());
1013254721Semaste    }
1014254721Semaste
1015254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1016254721Semaste    if (log)
1017254721Semaste    {
1018254721Semaste        SBStream frame_desc_strm;
1019254721Semaste        sb_process.GetDescription (frame_desc_strm);
1020254721Semaste        log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", exe_ctx.GetThreadPtr(),
1021254721Semaste                     sb_process.GetSP().get(), frame_desc_strm.GetData());
1022254721Semaste    }
1023254721Semaste
1024254721Semaste    return sb_process;
1025254721Semaste}
1026254721Semaste
1027254721Semasteuint32_t
1028254721SemasteSBThread::GetNumFrames ()
1029254721Semaste{
1030254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1031254721Semaste
1032254721Semaste    uint32_t num_frames = 0;
1033254721Semaste    Mutex::Locker api_locker;
1034254721Semaste    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1035254721Semaste
1036254721Semaste    if (exe_ctx.HasThreadScope())
1037254721Semaste    {
1038254721Semaste        Process::StopLocker stop_locker;
1039254721Semaste        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1040254721Semaste        {
1041254721Semaste            num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1042254721Semaste        }
1043254721Semaste        else
1044254721Semaste        {
1045254721Semaste            if (log)
1046254721Semaste                log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running", exe_ctx.GetThreadPtr());
1047254721Semaste        }
1048254721Semaste    }
1049254721Semaste
1050254721Semaste    if (log)
1051254721Semaste        log->Printf ("SBThread(%p)::GetNumFrames () => %u", exe_ctx.GetThreadPtr(), num_frames);
1052254721Semaste
1053254721Semaste    return num_frames;
1054254721Semaste}
1055254721Semaste
1056254721SemasteSBFrame
1057254721SemasteSBThread::GetFrameAtIndex (uint32_t idx)
1058254721Semaste{
1059254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1060254721Semaste
1061254721Semaste    SBFrame sb_frame;
1062254721Semaste    StackFrameSP frame_sp;
1063254721Semaste    Mutex::Locker api_locker;
1064254721Semaste    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1065254721Semaste
1066254721Semaste    if (exe_ctx.HasThreadScope())
1067254721Semaste    {
1068254721Semaste        Process::StopLocker stop_locker;
1069254721Semaste        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1070254721Semaste        {
1071254721Semaste            frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx);
1072254721Semaste            sb_frame.SetFrameSP (frame_sp);
1073254721Semaste        }
1074254721Semaste        else
1075254721Semaste        {
1076254721Semaste            if (log)
1077254721Semaste                log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running", exe_ctx.GetThreadPtr());
1078254721Semaste        }
1079254721Semaste    }
1080254721Semaste
1081254721Semaste    if (log)
1082254721Semaste    {
1083254721Semaste        SBStream frame_desc_strm;
1084254721Semaste        sb_frame.GetDescription (frame_desc_strm);
1085254721Semaste        log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
1086254721Semaste                     exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData());
1087254721Semaste    }
1088254721Semaste
1089254721Semaste    return sb_frame;
1090254721Semaste}
1091254721Semaste
1092254721Semastelldb::SBFrame
1093254721SemasteSBThread::GetSelectedFrame ()
1094254721Semaste{
1095254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1096254721Semaste
1097254721Semaste    SBFrame sb_frame;
1098254721Semaste    StackFrameSP frame_sp;
1099254721Semaste    Mutex::Locker api_locker;
1100254721Semaste    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1101254721Semaste
1102254721Semaste    if (exe_ctx.HasThreadScope())
1103254721Semaste    {
1104254721Semaste        Process::StopLocker stop_locker;
1105254721Semaste        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1106254721Semaste        {
1107254721Semaste            frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame ();
1108254721Semaste            sb_frame.SetFrameSP (frame_sp);
1109254721Semaste        }
1110254721Semaste        else
1111254721Semaste        {
1112254721Semaste            if (log)
1113254721Semaste                log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr());
1114254721Semaste        }
1115254721Semaste    }
1116254721Semaste
1117254721Semaste    if (log)
1118254721Semaste    {
1119254721Semaste        SBStream frame_desc_strm;
1120254721Semaste        sb_frame.GetDescription (frame_desc_strm);
1121254721Semaste        log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
1122254721Semaste                     exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData());
1123254721Semaste    }
1124254721Semaste
1125254721Semaste    return sb_frame;
1126254721Semaste}
1127254721Semaste
1128254721Semastelldb::SBFrame
1129254721SemasteSBThread::SetSelectedFrame (uint32_t idx)
1130254721Semaste{
1131254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1132254721Semaste
1133254721Semaste    SBFrame sb_frame;
1134254721Semaste    StackFrameSP frame_sp;
1135254721Semaste    Mutex::Locker api_locker;
1136254721Semaste    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1137254721Semaste
1138254721Semaste    if (exe_ctx.HasThreadScope())
1139254721Semaste    {
1140254721Semaste        Process::StopLocker stop_locker;
1141254721Semaste        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1142254721Semaste        {
1143254721Semaste            Thread *thread = exe_ctx.GetThreadPtr();
1144254721Semaste            frame_sp = thread->GetStackFrameAtIndex (idx);
1145254721Semaste            if (frame_sp)
1146254721Semaste            {
1147254721Semaste                thread->SetSelectedFrame (frame_sp.get());
1148254721Semaste                sb_frame.SetFrameSP (frame_sp);
1149254721Semaste            }
1150254721Semaste        }
1151254721Semaste        else
1152254721Semaste        {
1153254721Semaste            if (log)
1154254721Semaste                log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr());
1155254721Semaste        }
1156254721Semaste    }
1157254721Semaste
1158254721Semaste    if (log)
1159254721Semaste    {
1160254721Semaste        SBStream frame_desc_strm;
1161254721Semaste        sb_frame.GetDescription (frame_desc_strm);
1162254721Semaste        log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
1163254721Semaste                     exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData());
1164254721Semaste    }
1165254721Semaste    return sb_frame;
1166254721Semaste}
1167254721Semaste
1168254721Semastebool
1169254721SemasteSBThread::EventIsThreadEvent (const SBEvent &event)
1170254721Semaste{
1171254721Semaste    return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL;
1172254721Semaste}
1173254721Semaste
1174254721SemasteSBFrame
1175254721SemasteSBThread::GetStackFrameFromEvent (const SBEvent &event)
1176254721Semaste{
1177254721Semaste    return Thread::ThreadEventData::GetStackFrameFromEvent (event.get());
1178254721Semaste
1179254721Semaste}
1180254721Semaste
1181254721SemasteSBThread
1182254721SemasteSBThread::GetThreadFromEvent (const SBEvent &event)
1183254721Semaste{
1184254721Semaste    return Thread::ThreadEventData::GetThreadFromEvent (event.get());
1185254721Semaste}
1186254721Semaste
1187254721Semastebool
1188254721SemasteSBThread::operator == (const SBThread &rhs) const
1189254721Semaste{
1190254721Semaste    return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get();
1191254721Semaste}
1192254721Semaste
1193254721Semastebool
1194254721SemasteSBThread::operator != (const SBThread &rhs) const
1195254721Semaste{
1196254721Semaste    return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get();
1197254721Semaste}
1198254721Semaste
1199254721Semastebool
1200254721SemasteSBThread::GetStatus (SBStream &status) const
1201254721Semaste{
1202254721Semaste    Stream &strm = status.ref();
1203254721Semaste
1204254721Semaste    ExecutionContext exe_ctx (m_opaque_sp.get());
1205254721Semaste    if (exe_ctx.HasThreadScope())
1206254721Semaste    {
1207254721Semaste        exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1);
1208254721Semaste    }
1209254721Semaste    else
1210254721Semaste        strm.PutCString ("No status");
1211254721Semaste
1212254721Semaste    return true;
1213254721Semaste}
1214254721Semaste
1215254721Semastebool
1216254721SemasteSBThread::GetDescription (SBStream &description) const
1217254721Semaste{
1218254721Semaste    Stream &strm = description.ref();
1219254721Semaste
1220254721Semaste    ExecutionContext exe_ctx (m_opaque_sp.get());
1221254721Semaste    if (exe_ctx.HasThreadScope())
1222254721Semaste    {
1223254721Semaste        strm.Printf("SBThread: tid = 0x%4.4" PRIx64, exe_ctx.GetThreadPtr()->GetID());
1224254721Semaste    }
1225254721Semaste    else
1226254721Semaste        strm.PutCString ("No value");
1227254721Semaste
1228254721Semaste    return true;
1229254721Semaste}
1230