SBThread.cpp revision 263367
1//===-- SBThread.cpp --------------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/lldb-python.h"
11
12#include "lldb/API/SBThread.h"
13
14#include "lldb/API/SBSymbolContext.h"
15#include "lldb/API/SBFileSpec.h"
16#include "lldb/API/SBStream.h"
17#include "lldb/Breakpoint/BreakpointLocation.h"
18#include "lldb/Core/Debugger.h"
19#include "lldb/Core/State.h"
20#include "lldb/Core/Stream.h"
21#include "lldb/Core/StreamFile.h"
22#include "lldb/Interpreter/CommandInterpreter.h"
23#include "lldb/Target/SystemRuntime.h"
24#include "lldb/Target/Thread.h"
25#include "lldb/Target/Process.h"
26#include "lldb/Symbol/SymbolContext.h"
27#include "lldb/Symbol/CompileUnit.h"
28#include "lldb/Target/StopInfo.h"
29#include "lldb/Target/Target.h"
30#include "lldb/Target/ThreadPlan.h"
31#include "lldb/Target/ThreadPlanStepInstruction.h"
32#include "lldb/Target/ThreadPlanStepOut.h"
33#include "lldb/Target/ThreadPlanStepRange.h"
34#include "lldb/Target/ThreadPlanStepInRange.h"
35
36
37#include "lldb/API/SBAddress.h"
38#include "lldb/API/SBDebugger.h"
39#include "lldb/API/SBEvent.h"
40#include "lldb/API/SBFrame.h"
41#include "lldb/API/SBProcess.h"
42#include "lldb/API/SBValue.h"
43
44using namespace lldb;
45using namespace lldb_private;
46
47const char *
48SBThread::GetBroadcasterClassName ()
49{
50    return Thread::GetStaticBroadcasterClass().AsCString();
51}
52
53//----------------------------------------------------------------------
54// Constructors
55//----------------------------------------------------------------------
56SBThread::SBThread () :
57    m_opaque_sp (new ExecutionContextRef())
58{
59}
60
61SBThread::SBThread (const ThreadSP& lldb_object_sp) :
62    m_opaque_sp (new ExecutionContextRef(lldb_object_sp))
63{
64}
65
66SBThread::SBThread (const SBThread &rhs) :
67    m_opaque_sp (new ExecutionContextRef(*rhs.m_opaque_sp))
68{
69
70}
71
72//----------------------------------------------------------------------
73// Assignment operator
74//----------------------------------------------------------------------
75
76const lldb::SBThread &
77SBThread::operator = (const SBThread &rhs)
78{
79    if (this != &rhs)
80        *m_opaque_sp = *rhs.m_opaque_sp;
81    return *this;
82}
83
84//----------------------------------------------------------------------
85// Destructor
86//----------------------------------------------------------------------
87SBThread::~SBThread()
88{
89}
90
91bool
92SBThread::IsValid() const
93{
94    return m_opaque_sp->GetThreadSP().get() != NULL;
95}
96
97void
98SBThread::Clear ()
99{
100    m_opaque_sp->Clear();
101}
102
103
104StopReason
105SBThread::GetStopReason()
106{
107    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
108
109    StopReason reason = eStopReasonInvalid;
110    Mutex::Locker api_locker;
111    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
112
113    if (exe_ctx.HasThreadScope())
114    {
115        Process::StopLocker stop_locker;
116        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
117        {
118            return exe_ctx.GetThreadPtr()->GetStopReason();
119        }
120        else
121        {
122            if (log)
123                log->Printf ("SBThread(%p)::GetStopReason() => error: process is running", exe_ctx.GetThreadPtr());
124        }
125    }
126
127    if (log)
128        log->Printf ("SBThread(%p)::GetStopReason () => %s", exe_ctx.GetThreadPtr(),
129                     Thread::StopReasonAsCString (reason));
130
131    return reason;
132}
133
134size_t
135SBThread::GetStopReasonDataCount ()
136{
137    Mutex::Locker api_locker;
138    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
139
140    if (exe_ctx.HasThreadScope())
141    {
142        Process::StopLocker stop_locker;
143        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
144        {
145            StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
146            if (stop_info_sp)
147            {
148                StopReason reason = stop_info_sp->GetStopReason();
149                switch (reason)
150                {
151                case eStopReasonInvalid:
152                case eStopReasonNone:
153                case eStopReasonTrace:
154                case eStopReasonExec:
155                case eStopReasonPlanComplete:
156                case eStopReasonThreadExiting:
157                    // There is no data for these stop reasons.
158                    return 0;
159
160                case eStopReasonBreakpoint:
161                    {
162                        break_id_t site_id = stop_info_sp->GetValue();
163                        lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
164                        if (bp_site_sp)
165                            return bp_site_sp->GetNumberOfOwners () * 2;
166                        else
167                            return 0; // Breakpoint must have cleared itself...
168                    }
169                    break;
170
171                case eStopReasonWatchpoint:
172                    return 1;
173
174                case eStopReasonSignal:
175                    return 1;
176
177                case eStopReasonException:
178                    return 1;
179                }
180            }
181        }
182        else
183        {
184            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
185            if (log)
186                log->Printf ("SBThread(%p)::GetStopReasonDataCount() => error: process is running", exe_ctx.GetThreadPtr());
187        }
188    }
189    return 0;
190}
191
192uint64_t
193SBThread::GetStopReasonDataAtIndex (uint32_t idx)
194{
195    Mutex::Locker api_locker;
196    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
197
198    if (exe_ctx.HasThreadScope())
199    {
200        Process::StopLocker stop_locker;
201        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
202        {
203            Thread *thread = exe_ctx.GetThreadPtr();
204            StopInfoSP stop_info_sp = thread->GetStopInfo ();
205            if (stop_info_sp)
206            {
207                StopReason reason = stop_info_sp->GetStopReason();
208                switch (reason)
209                {
210                case eStopReasonInvalid:
211                case eStopReasonNone:
212                case eStopReasonTrace:
213                case eStopReasonExec:
214                case eStopReasonPlanComplete:
215                case eStopReasonThreadExiting:
216                    // There is no data for these stop reasons.
217                    return 0;
218
219                case eStopReasonBreakpoint:
220                    {
221                        break_id_t site_id = stop_info_sp->GetValue();
222                        lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
223                        if (bp_site_sp)
224                        {
225                            uint32_t bp_index = idx / 2;
226                            BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index));
227                            if (bp_loc_sp)
228                            {
229                                if (bp_index & 1)
230                                {
231                                    // Odd idx, return the breakpoint location ID
232                                    return bp_loc_sp->GetID();
233                                }
234                                else
235                                {
236                                    // Even idx, return the breakpoint ID
237                                    return bp_loc_sp->GetBreakpoint().GetID();
238                                }
239                            }
240                        }
241                        return LLDB_INVALID_BREAK_ID;
242                    }
243                    break;
244
245                case eStopReasonWatchpoint:
246                    return stop_info_sp->GetValue();
247
248                case eStopReasonSignal:
249                    return stop_info_sp->GetValue();
250
251                case eStopReasonException:
252                    return stop_info_sp->GetValue();
253                }
254            }
255        }
256        else
257        {
258            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
259            if (log)
260                log->Printf ("SBThread(%p)::GetStopReasonDataAtIndex() => error: process is running", exe_ctx.GetThreadPtr());
261        }
262    }
263    return 0;
264}
265
266size_t
267SBThread::GetStopDescription (char *dst, size_t dst_len)
268{
269    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
270
271    Mutex::Locker api_locker;
272    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
273
274    if (exe_ctx.HasThreadScope())
275    {
276        Process::StopLocker stop_locker;
277        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
278        {
279
280            StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
281            if (stop_info_sp)
282            {
283                const char *stop_desc = stop_info_sp->GetDescription();
284                if (stop_desc)
285                {
286                    if (log)
287                        log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
288                                     exe_ctx.GetThreadPtr(), stop_desc);
289                    if (dst)
290                        return ::snprintf (dst, dst_len, "%s", stop_desc);
291                    else
292                    {
293                        // NULL dst passed in, return the length needed to contain the description
294                        return ::strlen (stop_desc) + 1; // Include the NULL byte for size
295                    }
296                }
297                else
298                {
299                    size_t stop_desc_len = 0;
300                    switch (stop_info_sp->GetStopReason())
301                    {
302                    case eStopReasonTrace:
303                    case eStopReasonPlanComplete:
304                        {
305                            static char trace_desc[] = "step";
306                            stop_desc = trace_desc;
307                            stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size
308                        }
309                        break;
310
311                    case eStopReasonBreakpoint:
312                        {
313                            static char bp_desc[] = "breakpoint hit";
314                            stop_desc = bp_desc;
315                            stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
316                        }
317                        break;
318
319                    case eStopReasonWatchpoint:
320                        {
321                            static char wp_desc[] = "watchpoint hit";
322                            stop_desc = wp_desc;
323                            stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
324                        }
325                        break;
326
327                    case eStopReasonSignal:
328                        {
329                            stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue());
330                            if (stop_desc == NULL || stop_desc[0] == '\0')
331                            {
332                                static char signal_desc[] = "signal";
333                                stop_desc = signal_desc;
334                                stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size
335                            }
336                        }
337                        break;
338
339                    case eStopReasonException:
340                        {
341                            char exc_desc[] = "exception";
342                            stop_desc = exc_desc;
343                            stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
344                        }
345                        break;
346
347                    case eStopReasonExec:
348                        {
349                            char exc_desc[] = "exec";
350                            stop_desc = exc_desc;
351                            stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
352                        }
353                        break;
354
355                    case eStopReasonThreadExiting:
356                        {
357                            char limbo_desc[] = "thread exiting";
358                            stop_desc = limbo_desc;
359                            stop_desc_len = sizeof(limbo_desc);
360                        }
361                        break;
362                    default:
363                        break;
364                    }
365
366                    if (stop_desc && stop_desc[0])
367                    {
368                        if (log)
369                            log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
370                                         exe_ctx.GetThreadPtr(), stop_desc);
371
372                        if (dst)
373                            return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte
374
375                        if (stop_desc_len == 0)
376                            stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte
377
378                        return stop_desc_len;
379                    }
380                }
381            }
382        }
383        else
384        {
385            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
386            if (log)
387                log->Printf ("SBThread(%p)::GetStopDescription() => error: process is running", exe_ctx.GetThreadPtr());
388        }
389    }
390    if (dst)
391        *dst = 0;
392    return 0;
393}
394
395SBValue
396SBThread::GetStopReturnValue ()
397{
398    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
399    ValueObjectSP return_valobj_sp;
400    Mutex::Locker api_locker;
401    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
402
403    if (exe_ctx.HasThreadScope())
404    {
405        Process::StopLocker stop_locker;
406        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
407        {
408            StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
409            if (stop_info_sp)
410            {
411                return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
412            }
413        }
414        else
415        {
416            if (log)
417                log->Printf ("SBThread(%p)::GetStopReturnValue() => error: process is running", exe_ctx.GetThreadPtr());
418        }
419    }
420
421    if (log)
422        log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", exe_ctx.GetThreadPtr(),
423                                                                  return_valobj_sp.get()
424                                                                      ? return_valobj_sp->GetValueAsCString()
425                                                                        : "<no return value>");
426
427    return SBValue (return_valobj_sp);
428}
429
430void
431SBThread::SetThread (const ThreadSP& lldb_object_sp)
432{
433    m_opaque_sp->SetThreadSP (lldb_object_sp);
434}
435
436lldb::tid_t
437SBThread::GetThreadID () const
438{
439    ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
440    if (thread_sp)
441        return thread_sp->GetID();
442    return LLDB_INVALID_THREAD_ID;
443}
444
445uint32_t
446SBThread::GetIndexID () const
447{
448    ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
449    if (thread_sp)
450        return thread_sp->GetIndexID();
451    return LLDB_INVALID_INDEX32;
452}
453
454const char *
455SBThread::GetName () const
456{
457    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
458    const char *name = NULL;
459    Mutex::Locker api_locker;
460    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
461
462    if (exe_ctx.HasThreadScope())
463    {
464        Process::StopLocker stop_locker;
465        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
466        {
467            name = exe_ctx.GetThreadPtr()->GetName();
468        }
469        else
470        {
471            if (log)
472                log->Printf ("SBThread(%p)::GetName() => error: process is running", exe_ctx.GetThreadPtr());
473        }
474    }
475
476    if (log)
477        log->Printf ("SBThread(%p)::GetName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL");
478
479    return name;
480}
481
482const char *
483SBThread::GetQueueName () const
484{
485    const char *name = NULL;
486    Mutex::Locker api_locker;
487    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
488
489    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
490    if (exe_ctx.HasThreadScope())
491    {
492        Process::StopLocker stop_locker;
493        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
494        {
495            name = exe_ctx.GetThreadPtr()->GetQueueName();
496        }
497        else
498        {
499            if (log)
500                log->Printf ("SBThread(%p)::GetQueueName() => error: process is running", exe_ctx.GetThreadPtr());
501        }
502    }
503
504    if (log)
505        log->Printf ("SBThread(%p)::GetQueueName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL");
506
507    return name;
508}
509
510lldb::queue_id_t
511SBThread::GetQueueID () const
512{
513    queue_id_t id = LLDB_INVALID_QUEUE_ID;
514    Mutex::Locker api_locker;
515    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
516
517    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
518    if (exe_ctx.HasThreadScope())
519    {
520        Process::StopLocker stop_locker;
521        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
522        {
523            id = exe_ctx.GetThreadPtr()->GetQueueID();
524        }
525        else
526        {
527            if (log)
528                log->Printf ("SBThread(%p)::GetQueueID() => error: process is running", exe_ctx.GetThreadPtr());
529        }
530    }
531
532    if (log)
533        log->Printf ("SBThread(%p)::GetQueueID () => 0x%" PRIx64, exe_ctx.GetThreadPtr(), id);
534
535    return id;
536}
537
538SBError
539SBThread::ResumeNewPlan (ExecutionContext &exe_ctx, ThreadPlan *new_plan)
540{
541    SBError sb_error;
542
543    Process *process = exe_ctx.GetProcessPtr();
544    if (!process)
545    {
546        sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
547        return sb_error;
548    }
549
550    Thread *thread = exe_ctx.GetThreadPtr();
551    if (!thread)
552    {
553        sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
554        return sb_error;
555    }
556
557    // User level plans should be Master Plans so they can be interrupted, other plans executed, and
558    // then a "continue" will resume the plan.
559    if (new_plan != NULL)
560    {
561        new_plan->SetIsMasterPlan(true);
562        new_plan->SetOkayToDiscard(false);
563    }
564
565    // Why do we need to set the current thread by ID here???
566    process->GetThreadList().SetSelectedThreadByID (thread->GetID());
567    sb_error.ref() = process->Resume();
568
569    if (sb_error.Success())
570    {
571        // If we are doing synchronous mode, then wait for the
572        // process to stop yet again!
573        if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
574            process->WaitForProcessToStop (NULL);
575    }
576
577    return sb_error;
578}
579
580void
581SBThread::StepOver (lldb::RunMode stop_other_threads)
582{
583    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
584
585    Mutex::Locker api_locker;
586    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
587
588
589    if (log)
590        log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", exe_ctx.GetThreadPtr(),
591                     Thread::RunModeAsCString (stop_other_threads));
592
593    if (exe_ctx.HasThreadScope())
594    {
595        Thread *thread = exe_ctx.GetThreadPtr();
596        bool abort_other_plans = false;
597        StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
598
599        ThreadPlanSP new_plan_sp;
600        if (frame_sp)
601        {
602            if (frame_sp->HasDebugInformation ())
603            {
604                SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
605                new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
606                                                                    sc.line_entry.range,
607                                                                    sc,
608                                                                    stop_other_threads);
609            }
610            else
611            {
612                new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
613                                                                            abort_other_plans,
614                                                                            stop_other_threads);
615            }
616        }
617
618        // This returns an error, we should use it!
619        ResumeNewPlan (exe_ctx, new_plan_sp.get());
620    }
621}
622
623void
624SBThread::StepInto (lldb::RunMode stop_other_threads)
625{
626    StepInto (NULL, stop_other_threads);
627}
628
629void
630SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads)
631{
632    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
633
634    Mutex::Locker api_locker;
635    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
636
637    if (log)
638        log->Printf ("SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')",
639                     exe_ctx.GetThreadPtr(),
640                     target_name? target_name: "<NULL>",
641                     Thread::RunModeAsCString (stop_other_threads));
642
643    if (exe_ctx.HasThreadScope())
644    {
645        bool abort_other_plans = false;
646
647        Thread *thread = exe_ctx.GetThreadPtr();
648        StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
649        ThreadPlanSP new_plan_sp;
650
651        if (frame_sp && frame_sp->HasDebugInformation ())
652        {
653            bool avoid_code_without_debug_info = true;
654            SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
655            new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
656                                                              sc.line_entry.range,
657                                                              sc,
658                                                              target_name,
659                                                              stop_other_threads,
660                                                              avoid_code_without_debug_info);
661        }
662        else
663        {
664            new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false,
665                                                                        abort_other_plans,
666                                                                        stop_other_threads);
667        }
668
669        // This returns an error, we should use it!
670        ResumeNewPlan (exe_ctx, new_plan_sp.get());
671    }
672}
673
674void
675SBThread::StepOut ()
676{
677    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
678
679    Mutex::Locker api_locker;
680    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
681
682
683    if (log)
684        log->Printf ("SBThread(%p)::StepOut ()", exe_ctx.GetThreadPtr());
685
686    if (exe_ctx.HasThreadScope())
687    {
688        bool abort_other_plans = false;
689        bool stop_other_threads = false;
690
691        Thread *thread = exe_ctx.GetThreadPtr();
692
693        ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans,
694                                                                  NULL,
695                                                                  false,
696                                                                  stop_other_threads,
697                                                                  eVoteYes,
698                                                                  eVoteNoOpinion,
699                                                                  0));
700
701        // This returns an error, we should use it!
702        ResumeNewPlan (exe_ctx, new_plan_sp.get());
703    }
704}
705
706void
707SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame)
708{
709    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
710
711    Mutex::Locker api_locker;
712    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
713
714    StackFrameSP frame_sp (sb_frame.GetFrameSP());
715    if (log)
716    {
717        SBStream frame_desc_strm;
718        sb_frame.GetDescription (frame_desc_strm);
719        log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData());
720    }
721
722    if (exe_ctx.HasThreadScope())
723    {
724        bool abort_other_plans = false;
725        bool stop_other_threads = false;
726        Thread *thread = exe_ctx.GetThreadPtr();
727
728        ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans,
729                                                                    NULL,
730                                                                    false,
731                                                                    stop_other_threads,
732                                                                    eVoteYes,
733                                                                    eVoteNoOpinion,
734                                                                    frame_sp->GetFrameIndex()));
735
736        // This returns an error, we should use it!
737        ResumeNewPlan (exe_ctx, new_plan_sp.get());
738    }
739}
740
741void
742SBThread::StepInstruction (bool step_over)
743{
744    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
745
746    Mutex::Locker api_locker;
747    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
748
749
750
751    if (log)
752        log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", exe_ctx.GetThreadPtr(), step_over);
753
754    if (exe_ctx.HasThreadScope())
755    {
756        Thread *thread = exe_ctx.GetThreadPtr();
757        ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true));
758
759        // This returns an error, we should use it!
760        ResumeNewPlan (exe_ctx, new_plan_sp.get());
761    }
762}
763
764void
765SBThread::RunToAddress (lldb::addr_t addr)
766{
767    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
768
769    Mutex::Locker api_locker;
770    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
771
772
773    if (log)
774        log->Printf ("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")", exe_ctx.GetThreadPtr(), addr);
775
776    if (exe_ctx.HasThreadScope())
777    {
778        bool abort_other_plans = false;
779        bool stop_other_threads = true;
780
781        Address target_addr (addr);
782
783        Thread *thread = exe_ctx.GetThreadPtr();
784
785        ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads));
786
787        // This returns an error, we should use it!
788        ResumeNewPlan (exe_ctx, new_plan_sp.get());
789    }
790}
791
792SBError
793SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
794                         lldb::SBFileSpec &sb_file_spec,
795                         uint32_t line)
796{
797    SBError sb_error;
798    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
799    char path[PATH_MAX];
800
801    Mutex::Locker api_locker;
802    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
803
804    StackFrameSP frame_sp (sb_frame.GetFrameSP());
805
806    if (log)
807    {
808        SBStream frame_desc_strm;
809        sb_frame.GetDescription (frame_desc_strm);
810        sb_file_spec->GetPath (path, sizeof(path));
811        log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)",
812                     exe_ctx.GetThreadPtr(),
813                     frame_sp.get(),
814                     frame_desc_strm.GetData(),
815                     path, line);
816    }
817
818    if (exe_ctx.HasThreadScope())
819    {
820        Target *target = exe_ctx.GetTargetPtr();
821        Thread *thread = exe_ctx.GetThreadPtr();
822
823        if (line == 0)
824        {
825            sb_error.SetErrorString("invalid line argument");
826            return sb_error;
827        }
828
829        if (!frame_sp)
830        {
831            frame_sp = thread->GetSelectedFrame ();
832            if (!frame_sp)
833                frame_sp = thread->GetStackFrameAtIndex (0);
834        }
835
836        SymbolContext frame_sc;
837        if (!frame_sp)
838        {
839            sb_error.SetErrorString("no valid frames in thread to step");
840            return sb_error;
841        }
842
843        // If we have a frame, get its line
844        frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit  |
845                                               eSymbolContextFunction  |
846                                               eSymbolContextLineEntry |
847                                               eSymbolContextSymbol    );
848
849        if (frame_sc.comp_unit == NULL)
850        {
851            sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex());
852            return sb_error;
853        }
854
855        FileSpec step_file_spec;
856        if (sb_file_spec.IsValid())
857        {
858            // The file spec passed in was valid, so use it
859            step_file_spec = sb_file_spec.ref();
860        }
861        else
862        {
863            if (frame_sc.line_entry.IsValid())
864                step_file_spec = frame_sc.line_entry.file;
865            else
866            {
867                sb_error.SetErrorString("invalid file argument or no file for frame");
868                return sb_error;
869            }
870        }
871
872        // Grab the current function, then we will make sure the "until" address is
873        // within the function.  We discard addresses that are out of the current
874        // function, and then if there are no addresses remaining, give an appropriate
875        // error message.
876
877        bool all_in_function = true;
878        AddressRange fun_range = frame_sc.function->GetAddressRange();
879
880        std::vector<addr_t> step_over_until_addrs;
881        const bool abort_other_plans = false;
882        const bool stop_other_threads = false;
883        const bool check_inlines = true;
884        const bool exact = false;
885
886        SymbolContextList sc_list;
887        const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec,
888                                                                               line,
889                                                                               check_inlines,
890                                                                               exact,
891                                                                               eSymbolContextLineEntry,
892                                                                               sc_list);
893        if (num_matches > 0)
894        {
895            SymbolContext sc;
896            for (uint32_t i=0; i<num_matches; ++i)
897            {
898                if (sc_list.GetContextAtIndex(i, sc))
899                {
900                    addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
901                    if (step_addr != LLDB_INVALID_ADDRESS)
902                    {
903                        if (fun_range.ContainsLoadAddress(step_addr, target))
904                            step_over_until_addrs.push_back(step_addr);
905                        else
906                            all_in_function = false;
907                    }
908                }
909            }
910        }
911
912        if (step_over_until_addrs.empty())
913        {
914            if (all_in_function)
915            {
916                step_file_spec.GetPath (path, sizeof(path));
917                sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line);
918            }
919            else
920                sb_error.SetErrorString ("step until target not in current function");
921        }
922        else
923        {
924            ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil (abort_other_plans,
925                                                                        &step_over_until_addrs[0],
926                                                                        step_over_until_addrs.size(),
927                                                                        stop_other_threads,
928                                                                        frame_sp->GetFrameIndex()));
929
930            sb_error = ResumeNewPlan (exe_ctx, new_plan_sp.get());
931        }
932    }
933    else
934    {
935        sb_error.SetErrorString("this SBThread object is invalid");
936    }
937    return sb_error;
938}
939
940SBError
941SBThread::JumpToLine (lldb::SBFileSpec &file_spec, uint32_t line)
942{
943    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
944    SBError sb_error;
945
946    Mutex::Locker api_locker;
947    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
948
949    if (log)
950        log->Printf ("SBThread(%p)::JumpToLine (file+line = %s:%u)", exe_ctx.GetThreadPtr(), file_spec->GetPath().c_str(), line);
951
952    if (!exe_ctx.HasThreadScope())
953    {
954        sb_error.SetErrorString("this SBThread object is invalid");
955        return sb_error;
956    }
957
958    Thread *thread = exe_ctx.GetThreadPtr();
959
960    Error err = thread->JumpToLine (file_spec.get(), line, true);
961    sb_error.SetError (err);
962    return sb_error;
963}
964
965SBError
966SBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value)
967{
968    SBError sb_error;
969
970    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
971
972    Mutex::Locker api_locker;
973    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
974
975
976    if (log)
977        log->Printf ("SBThread(%p)::ReturnFromFrame (frame=%d)", exe_ctx.GetThreadPtr(), frame.GetFrameID());
978
979    if (exe_ctx.HasThreadScope())
980    {
981        Thread *thread = exe_ctx.GetThreadPtr();
982        sb_error.SetError (thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
983    }
984
985    return sb_error;
986}
987
988
989bool
990SBThread::Suspend()
991{
992    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
993    ExecutionContext exe_ctx (m_opaque_sp.get());
994    bool result = false;
995    if (exe_ctx.HasThreadScope())
996    {
997        Process::StopLocker stop_locker;
998        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
999        {
1000            exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended);
1001            result = true;
1002        }
1003        else
1004        {
1005            if (log)
1006                log->Printf ("SBThread(%p)::Suspend() => error: process is running", exe_ctx.GetThreadPtr());
1007        }
1008    }
1009    if (log)
1010        log->Printf ("SBThread(%p)::Suspend() => %i", exe_ctx.GetThreadPtr(), result);
1011    return result;
1012}
1013
1014bool
1015SBThread::Resume ()
1016{
1017    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1018    ExecutionContext exe_ctx (m_opaque_sp.get());
1019    bool result = false;
1020    if (exe_ctx.HasThreadScope())
1021    {
1022        Process::StopLocker stop_locker;
1023        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1024        {
1025            exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning);
1026            result = true;
1027        }
1028        else
1029        {
1030            if (log)
1031                log->Printf ("SBThread(%p)::Resume() => error: process is running", exe_ctx.GetThreadPtr());
1032        }
1033    }
1034    if (log)
1035        log->Printf ("SBThread(%p)::Resume() => %i", exe_ctx.GetThreadPtr(), result);
1036    return result;
1037}
1038
1039bool
1040SBThread::IsSuspended()
1041{
1042    ExecutionContext exe_ctx (m_opaque_sp.get());
1043    if (exe_ctx.HasThreadScope())
1044        return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended;
1045    return false;
1046}
1047
1048bool
1049SBThread::IsStopped()
1050{
1051    ExecutionContext exe_ctx (m_opaque_sp.get());
1052    if (exe_ctx.HasThreadScope())
1053        return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1054    return false;
1055}
1056
1057SBProcess
1058SBThread::GetProcess ()
1059{
1060    SBProcess sb_process;
1061    ExecutionContext exe_ctx (m_opaque_sp.get());
1062    if (exe_ctx.HasThreadScope())
1063    {
1064        // Have to go up to the target so we can get a shared pointer to our process...
1065        sb_process.SetSP (exe_ctx.GetProcessSP());
1066    }
1067
1068    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1069    if (log)
1070    {
1071        SBStream frame_desc_strm;
1072        sb_process.GetDescription (frame_desc_strm);
1073        log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", exe_ctx.GetThreadPtr(),
1074                     sb_process.GetSP().get(), frame_desc_strm.GetData());
1075    }
1076
1077    return sb_process;
1078}
1079
1080uint32_t
1081SBThread::GetNumFrames ()
1082{
1083    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1084
1085    uint32_t num_frames = 0;
1086    Mutex::Locker api_locker;
1087    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1088
1089    if (exe_ctx.HasThreadScope())
1090    {
1091        Process::StopLocker stop_locker;
1092        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1093        {
1094            num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1095        }
1096        else
1097        {
1098            if (log)
1099                log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running", exe_ctx.GetThreadPtr());
1100        }
1101    }
1102
1103    if (log)
1104        log->Printf ("SBThread(%p)::GetNumFrames () => %u", exe_ctx.GetThreadPtr(), num_frames);
1105
1106    return num_frames;
1107}
1108
1109SBFrame
1110SBThread::GetFrameAtIndex (uint32_t idx)
1111{
1112    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1113
1114    SBFrame sb_frame;
1115    StackFrameSP frame_sp;
1116    Mutex::Locker api_locker;
1117    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1118
1119    if (exe_ctx.HasThreadScope())
1120    {
1121        Process::StopLocker stop_locker;
1122        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1123        {
1124            frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx);
1125            sb_frame.SetFrameSP (frame_sp);
1126        }
1127        else
1128        {
1129            if (log)
1130                log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running", exe_ctx.GetThreadPtr());
1131        }
1132    }
1133
1134    if (log)
1135    {
1136        SBStream frame_desc_strm;
1137        sb_frame.GetDescription (frame_desc_strm);
1138        log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
1139                     exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData());
1140    }
1141
1142    return sb_frame;
1143}
1144
1145lldb::SBFrame
1146SBThread::GetSelectedFrame ()
1147{
1148    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1149
1150    SBFrame sb_frame;
1151    StackFrameSP frame_sp;
1152    Mutex::Locker api_locker;
1153    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1154
1155    if (exe_ctx.HasThreadScope())
1156    {
1157        Process::StopLocker stop_locker;
1158        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1159        {
1160            frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame ();
1161            sb_frame.SetFrameSP (frame_sp);
1162        }
1163        else
1164        {
1165            if (log)
1166                log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr());
1167        }
1168    }
1169
1170    if (log)
1171    {
1172        SBStream frame_desc_strm;
1173        sb_frame.GetDescription (frame_desc_strm);
1174        log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
1175                     exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData());
1176    }
1177
1178    return sb_frame;
1179}
1180
1181lldb::SBFrame
1182SBThread::SetSelectedFrame (uint32_t idx)
1183{
1184    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1185
1186    SBFrame sb_frame;
1187    StackFrameSP frame_sp;
1188    Mutex::Locker api_locker;
1189    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1190
1191    if (exe_ctx.HasThreadScope())
1192    {
1193        Process::StopLocker stop_locker;
1194        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1195        {
1196            Thread *thread = exe_ctx.GetThreadPtr();
1197            frame_sp = thread->GetStackFrameAtIndex (idx);
1198            if (frame_sp)
1199            {
1200                thread->SetSelectedFrame (frame_sp.get());
1201                sb_frame.SetFrameSP (frame_sp);
1202            }
1203        }
1204        else
1205        {
1206            if (log)
1207                log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr());
1208        }
1209    }
1210
1211    if (log)
1212    {
1213        SBStream frame_desc_strm;
1214        sb_frame.GetDescription (frame_desc_strm);
1215        log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
1216                     exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData());
1217    }
1218    return sb_frame;
1219}
1220
1221bool
1222SBThread::EventIsThreadEvent (const SBEvent &event)
1223{
1224    return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL;
1225}
1226
1227SBFrame
1228SBThread::GetStackFrameFromEvent (const SBEvent &event)
1229{
1230    return Thread::ThreadEventData::GetStackFrameFromEvent (event.get());
1231
1232}
1233
1234SBThread
1235SBThread::GetThreadFromEvent (const SBEvent &event)
1236{
1237    return Thread::ThreadEventData::GetThreadFromEvent (event.get());
1238}
1239
1240bool
1241SBThread::operator == (const SBThread &rhs) const
1242{
1243    return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get();
1244}
1245
1246bool
1247SBThread::operator != (const SBThread &rhs) const
1248{
1249    return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get();
1250}
1251
1252bool
1253SBThread::GetStatus (SBStream &status) const
1254{
1255    Stream &strm = status.ref();
1256
1257    ExecutionContext exe_ctx (m_opaque_sp.get());
1258    if (exe_ctx.HasThreadScope())
1259    {
1260        exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1);
1261    }
1262    else
1263        strm.PutCString ("No status");
1264
1265    return true;
1266}
1267
1268bool
1269SBThread::GetDescription (SBStream &description) const
1270{
1271    Stream &strm = description.ref();
1272
1273    ExecutionContext exe_ctx (m_opaque_sp.get());
1274    if (exe_ctx.HasThreadScope())
1275    {
1276        strm.Printf("SBThread: tid = 0x%4.4" PRIx64, exe_ctx.GetThreadPtr()->GetID());
1277    }
1278    else
1279        strm.PutCString ("No value");
1280
1281    return true;
1282}
1283
1284SBThread
1285SBThread::GetExtendedBacktraceThread (const char *type)
1286{
1287    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1288    Mutex::Locker api_locker;
1289    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1290    SBThread sb_origin_thread;
1291
1292    if (exe_ctx.HasThreadScope())
1293    {
1294        Process::StopLocker stop_locker;
1295        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1296        {
1297            ThreadSP real_thread(exe_ctx.GetThreadSP());
1298            if (real_thread)
1299            {
1300                ConstString type_const (type);
1301                Process *process = exe_ctx.GetProcessPtr();
1302                if (process)
1303                {
1304                    SystemRuntime *runtime = process->GetSystemRuntime();
1305                    if (runtime)
1306                    {
1307                        ThreadSP new_thread_sp (runtime->GetExtendedBacktraceThread (real_thread, type_const));
1308                        if (new_thread_sp)
1309                        {
1310                            // Save this in the Process' ExtendedThreadList so a strong pointer retains the
1311                            // object.
1312                            process->GetExtendedThreadList().AddThread (new_thread_sp);
1313                            sb_origin_thread.SetThread (new_thread_sp);
1314                            if (log)
1315                            {
1316                                const char *queue_name = new_thread_sp->GetQueueName();
1317                                if (queue_name == NULL)
1318                                    queue_name = "";
1319                                log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => new extended Thread created (%p) with queue_id 0x%" PRIx64 " queue name '%s'", exe_ctx.GetThreadPtr(), new_thread_sp.get(), new_thread_sp->GetQueueID(), queue_name);
1320                            }
1321                        }
1322                    }
1323                }
1324            }
1325        }
1326        else
1327        {
1328            if (log)
1329                log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => error: process is running", exe_ctx.GetThreadPtr());
1330        }
1331    }
1332
1333    return sb_origin_thread;
1334}
1335
1336uint32_t
1337SBThread::GetExtendedBacktraceOriginatingIndexID ()
1338{
1339    ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1340    if (thread_sp)
1341        return thread_sp->GetExtendedBacktraceOriginatingIndexID();
1342    return LLDB_INVALID_INDEX32;
1343}
1344