SBThread.cpp revision 263363
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
436
437lldb::tid_t
438SBThread::GetThreadID () const
439{
440    ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
441    if (thread_sp)
442        return thread_sp->GetID();
443    return LLDB_INVALID_THREAD_ID;
444}
445
446uint32_t
447SBThread::GetIndexID () const
448{
449    ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
450    if (thread_sp)
451        return thread_sp->GetIndexID();
452    return LLDB_INVALID_INDEX32;
453}
454
455const char *
456SBThread::GetName () const
457{
458    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
459    const char *name = NULL;
460    Mutex::Locker api_locker;
461    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
462
463    if (exe_ctx.HasThreadScope())
464    {
465        Process::StopLocker stop_locker;
466        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
467        {
468            name = exe_ctx.GetThreadPtr()->GetName();
469        }
470        else
471        {
472            if (log)
473                log->Printf ("SBThread(%p)::GetName() => error: process is running", exe_ctx.GetThreadPtr());
474        }
475    }
476
477    if (log)
478        log->Printf ("SBThread(%p)::GetName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL");
479
480    return name;
481}
482
483const char *
484SBThread::GetQueueName () const
485{
486    const char *name = NULL;
487    Mutex::Locker api_locker;
488    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
489
490    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
491    if (exe_ctx.HasThreadScope())
492    {
493        Process::StopLocker stop_locker;
494        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
495        {
496            name = exe_ctx.GetThreadPtr()->GetQueueName();
497        }
498        else
499        {
500            if (log)
501                log->Printf ("SBThread(%p)::GetQueueName() => error: process is running", exe_ctx.GetThreadPtr());
502        }
503    }
504
505    if (log)
506        log->Printf ("SBThread(%p)::GetQueueName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL");
507
508    return name;
509}
510
511lldb::queue_id_t
512SBThread::GetQueueID () const
513{
514    queue_id_t id = LLDB_INVALID_QUEUE_ID;
515    Mutex::Locker api_locker;
516    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
517
518    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
519    if (exe_ctx.HasThreadScope())
520    {
521        Process::StopLocker stop_locker;
522        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
523        {
524            id = exe_ctx.GetThreadPtr()->GetQueueID();
525        }
526        else
527        {
528            if (log)
529                log->Printf ("SBThread(%p)::GetQueueID() => error: process is running", exe_ctx.GetThreadPtr());
530        }
531    }
532
533    if (log)
534        log->Printf ("SBThread(%p)::GetQueueID () => 0x%" PRIx64, exe_ctx.GetThreadPtr(), id);
535
536    return id;
537}
538
539SBError
540SBThread::ResumeNewPlan (ExecutionContext &exe_ctx, ThreadPlan *new_plan)
541{
542    SBError sb_error;
543
544    Process *process = exe_ctx.GetProcessPtr();
545    if (!process)
546    {
547        sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
548        return sb_error;
549    }
550
551    Thread *thread = exe_ctx.GetThreadPtr();
552    if (!thread)
553    {
554        sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
555        return sb_error;
556    }
557
558    // User level plans should be Master Plans so they can be interrupted, other plans executed, and
559    // then a "continue" will resume the plan.
560    if (new_plan != NULL)
561    {
562        new_plan->SetIsMasterPlan(true);
563        new_plan->SetOkayToDiscard(false);
564    }
565
566    // Why do we need to set the current thread by ID here???
567    process->GetThreadList().SetSelectedThreadByID (thread->GetID());
568    sb_error.ref() = process->Resume();
569
570    if (sb_error.Success())
571    {
572        // If we are doing synchronous mode, then wait for the
573        // process to stop yet again!
574        if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
575            process->WaitForProcessToStop (NULL);
576    }
577
578    return sb_error;
579}
580
581void
582SBThread::StepOver (lldb::RunMode stop_other_threads)
583{
584    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
585
586    Mutex::Locker api_locker;
587    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
588
589
590    if (log)
591        log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", exe_ctx.GetThreadPtr(),
592                     Thread::RunModeAsCString (stop_other_threads));
593
594    if (exe_ctx.HasThreadScope())
595    {
596        Thread *thread = exe_ctx.GetThreadPtr();
597        bool abort_other_plans = false;
598        StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
599
600        ThreadPlanSP new_plan_sp;
601        if (frame_sp)
602        {
603            if (frame_sp->HasDebugInformation ())
604            {
605                SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
606                new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
607                                                                    sc.line_entry.range,
608                                                                    sc,
609                                                                    stop_other_threads);
610            }
611            else
612            {
613                new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
614                                                                            abort_other_plans,
615                                                                            stop_other_threads);
616            }
617        }
618
619        // This returns an error, we should use it!
620        ResumeNewPlan (exe_ctx, new_plan_sp.get());
621    }
622}
623
624void
625SBThread::StepInto (lldb::RunMode stop_other_threads)
626{
627    StepInto (NULL, stop_other_threads);
628}
629
630void
631SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads)
632{
633    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
634
635    Mutex::Locker api_locker;
636    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
637
638    if (log)
639        log->Printf ("SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')",
640                     exe_ctx.GetThreadPtr(),
641                     target_name? target_name: "<NULL>",
642                     Thread::RunModeAsCString (stop_other_threads));
643
644    if (exe_ctx.HasThreadScope())
645    {
646        bool abort_other_plans = false;
647
648        Thread *thread = exe_ctx.GetThreadPtr();
649        StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
650        ThreadPlanSP new_plan_sp;
651
652        if (frame_sp && frame_sp->HasDebugInformation ())
653        {
654            bool avoid_code_without_debug_info = true;
655            SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
656            new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
657                                                              sc.line_entry.range,
658                                                              sc,
659                                                              target_name,
660                                                              stop_other_threads,
661                                                              avoid_code_without_debug_info);
662        }
663        else
664        {
665            new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false,
666                                                                        abort_other_plans,
667                                                                        stop_other_threads);
668        }
669
670        // This returns an error, we should use it!
671        ResumeNewPlan (exe_ctx, new_plan_sp.get());
672    }
673}
674
675void
676SBThread::StepOut ()
677{
678    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
679
680    Mutex::Locker api_locker;
681    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
682
683
684    if (log)
685        log->Printf ("SBThread(%p)::StepOut ()", exe_ctx.GetThreadPtr());
686
687    if (exe_ctx.HasThreadScope())
688    {
689        bool abort_other_plans = false;
690        bool stop_other_threads = false;
691
692        Thread *thread = exe_ctx.GetThreadPtr();
693
694        ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans,
695                                                                  NULL,
696                                                                  false,
697                                                                  stop_other_threads,
698                                                                  eVoteYes,
699                                                                  eVoteNoOpinion,
700                                                                  0));
701
702        // This returns an error, we should use it!
703        ResumeNewPlan (exe_ctx, new_plan_sp.get());
704    }
705}
706
707void
708SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame)
709{
710    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
711
712    Mutex::Locker api_locker;
713    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
714
715    StackFrameSP frame_sp (sb_frame.GetFrameSP());
716    if (log)
717    {
718        SBStream frame_desc_strm;
719        sb_frame.GetDescription (frame_desc_strm);
720        log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData());
721    }
722
723    if (exe_ctx.HasThreadScope())
724    {
725        bool abort_other_plans = false;
726        bool stop_other_threads = false;
727        Thread *thread = exe_ctx.GetThreadPtr();
728
729        ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans,
730                                                                    NULL,
731                                                                    false,
732                                                                    stop_other_threads,
733                                                                    eVoteYes,
734                                                                    eVoteNoOpinion,
735                                                                    frame_sp->GetFrameIndex()));
736
737        // This returns an error, we should use it!
738        ResumeNewPlan (exe_ctx, new_plan_sp.get());
739    }
740}
741
742void
743SBThread::StepInstruction (bool step_over)
744{
745    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
746
747    Mutex::Locker api_locker;
748    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
749
750
751
752    if (log)
753        log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", exe_ctx.GetThreadPtr(), step_over);
754
755    if (exe_ctx.HasThreadScope())
756    {
757        Thread *thread = exe_ctx.GetThreadPtr();
758        ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true));
759
760        // This returns an error, we should use it!
761        ResumeNewPlan (exe_ctx, new_plan_sp.get());
762    }
763}
764
765void
766SBThread::RunToAddress (lldb::addr_t addr)
767{
768    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
769
770    Mutex::Locker api_locker;
771    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
772
773
774    if (log)
775        log->Printf ("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")", exe_ctx.GetThreadPtr(), addr);
776
777    if (exe_ctx.HasThreadScope())
778    {
779        bool abort_other_plans = false;
780        bool stop_other_threads = true;
781
782        Address target_addr (addr);
783
784        Thread *thread = exe_ctx.GetThreadPtr();
785
786        ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads));
787
788        // This returns an error, we should use it!
789        ResumeNewPlan (exe_ctx, new_plan_sp.get());
790    }
791}
792
793SBError
794SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
795                         lldb::SBFileSpec &sb_file_spec,
796                         uint32_t line)
797{
798    SBError sb_error;
799    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
800    char path[PATH_MAX];
801
802    Mutex::Locker api_locker;
803    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
804
805    StackFrameSP frame_sp (sb_frame.GetFrameSP());
806
807    if (log)
808    {
809        SBStream frame_desc_strm;
810        sb_frame.GetDescription (frame_desc_strm);
811        sb_file_spec->GetPath (path, sizeof(path));
812        log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)",
813                     exe_ctx.GetThreadPtr(),
814                     frame_sp.get(),
815                     frame_desc_strm.GetData(),
816                     path, line);
817    }
818
819    if (exe_ctx.HasThreadScope())
820    {
821        Target *target = exe_ctx.GetTargetPtr();
822        Thread *thread = exe_ctx.GetThreadPtr();
823
824        if (line == 0)
825        {
826            sb_error.SetErrorString("invalid line argument");
827            return sb_error;
828        }
829
830        if (!frame_sp)
831        {
832            frame_sp = thread->GetSelectedFrame ();
833            if (!frame_sp)
834                frame_sp = thread->GetStackFrameAtIndex (0);
835        }
836
837        SymbolContext frame_sc;
838        if (!frame_sp)
839        {
840            sb_error.SetErrorString("no valid frames in thread to step");
841            return sb_error;
842        }
843
844        // If we have a frame, get its line
845        frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit  |
846                                               eSymbolContextFunction  |
847                                               eSymbolContextLineEntry |
848                                               eSymbolContextSymbol    );
849
850        if (frame_sc.comp_unit == NULL)
851        {
852            sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex());
853            return sb_error;
854        }
855
856        FileSpec step_file_spec;
857        if (sb_file_spec.IsValid())
858        {
859            // The file spec passed in was valid, so use it
860            step_file_spec = sb_file_spec.ref();
861        }
862        else
863        {
864            if (frame_sc.line_entry.IsValid())
865                step_file_spec = frame_sc.line_entry.file;
866            else
867            {
868                sb_error.SetErrorString("invalid file argument or no file for frame");
869                return sb_error;
870            }
871        }
872
873        // Grab the current function, then we will make sure the "until" address is
874        // within the function.  We discard addresses that are out of the current
875        // function, and then if there are no addresses remaining, give an appropriate
876        // error message.
877
878        bool all_in_function = true;
879        AddressRange fun_range = frame_sc.function->GetAddressRange();
880
881        std::vector<addr_t> step_over_until_addrs;
882        const bool abort_other_plans = false;
883        const bool stop_other_threads = false;
884        const bool check_inlines = true;
885        const bool exact = false;
886
887        SymbolContextList sc_list;
888        const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec,
889                                                                               line,
890                                                                               check_inlines,
891                                                                               exact,
892                                                                               eSymbolContextLineEntry,
893                                                                               sc_list);
894        if (num_matches > 0)
895        {
896            SymbolContext sc;
897            for (uint32_t i=0; i<num_matches; ++i)
898            {
899                if (sc_list.GetContextAtIndex(i, sc))
900                {
901                    addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
902                    if (step_addr != LLDB_INVALID_ADDRESS)
903                    {
904                        if (fun_range.ContainsLoadAddress(step_addr, target))
905                            step_over_until_addrs.push_back(step_addr);
906                        else
907                            all_in_function = false;
908                    }
909                }
910            }
911        }
912
913        if (step_over_until_addrs.empty())
914        {
915            if (all_in_function)
916            {
917                step_file_spec.GetPath (path, sizeof(path));
918                sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line);
919            }
920            else
921                sb_error.SetErrorString ("step until target not in current function");
922        }
923        else
924        {
925            ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil (abort_other_plans,
926                                                                        &step_over_until_addrs[0],
927                                                                        step_over_until_addrs.size(),
928                                                                        stop_other_threads,
929                                                                        frame_sp->GetFrameIndex()));
930
931            sb_error = ResumeNewPlan (exe_ctx, new_plan_sp.get());
932        }
933    }
934    else
935    {
936        sb_error.SetErrorString("this SBThread object is invalid");
937    }
938    return sb_error;
939}
940
941SBError
942SBThread::JumpToLine (lldb::SBFileSpec &file_spec, uint32_t line)
943{
944    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
945    SBError sb_error;
946
947    Mutex::Locker api_locker;
948    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
949
950    if (log)
951        log->Printf ("SBThread(%p)::JumpToLine (file+line = %s:%u)", exe_ctx.GetThreadPtr(), file_spec->GetPath().c_str(), line);
952
953    if (!exe_ctx.HasThreadScope())
954    {
955        sb_error.SetErrorString("this SBThread object is invalid");
956        return sb_error;
957    }
958
959    Thread *thread = exe_ctx.GetThreadPtr();
960
961    Error err = thread->JumpToLine (file_spec.get(), line, true);
962    sb_error.SetError (err);
963    return sb_error;
964}
965
966SBError
967SBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value)
968{
969    SBError sb_error;
970
971    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
972
973    Mutex::Locker api_locker;
974    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
975
976
977    if (log)
978        log->Printf ("SBThread(%p)::ReturnFromFrame (frame=%d)", exe_ctx.GetThreadPtr(), frame.GetFrameID());
979
980    if (exe_ctx.HasThreadScope())
981    {
982        Thread *thread = exe_ctx.GetThreadPtr();
983        sb_error.SetError (thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
984    }
985
986    return sb_error;
987}
988
989
990bool
991SBThread::Suspend()
992{
993    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
994    ExecutionContext exe_ctx (m_opaque_sp.get());
995    bool result = false;
996    if (exe_ctx.HasThreadScope())
997    {
998        Process::StopLocker stop_locker;
999        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1000        {
1001            exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended);
1002            result = true;
1003        }
1004        else
1005        {
1006            if (log)
1007                log->Printf ("SBThread(%p)::Suspend() => error: process is running", exe_ctx.GetThreadPtr());
1008        }
1009    }
1010    if (log)
1011        log->Printf ("SBThread(%p)::Suspend() => %i", exe_ctx.GetThreadPtr(), result);
1012    return result;
1013}
1014
1015bool
1016SBThread::Resume ()
1017{
1018    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1019    ExecutionContext exe_ctx (m_opaque_sp.get());
1020    bool result = false;
1021    if (exe_ctx.HasThreadScope())
1022    {
1023        Process::StopLocker stop_locker;
1024        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1025        {
1026            exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning);
1027            result = true;
1028        }
1029        else
1030        {
1031            if (log)
1032                log->Printf ("SBThread(%p)::Resume() => error: process is running", exe_ctx.GetThreadPtr());
1033        }
1034    }
1035    if (log)
1036        log->Printf ("SBThread(%p)::Resume() => %i", exe_ctx.GetThreadPtr(), result);
1037    return result;
1038}
1039
1040bool
1041SBThread::IsSuspended()
1042{
1043    ExecutionContext exe_ctx (m_opaque_sp.get());
1044    if (exe_ctx.HasThreadScope())
1045        return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended;
1046    return false;
1047}
1048
1049bool
1050SBThread::IsStopped()
1051{
1052    ExecutionContext exe_ctx (m_opaque_sp.get());
1053    if (exe_ctx.HasThreadScope())
1054        return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1055    return false;
1056}
1057
1058SBProcess
1059SBThread::GetProcess ()
1060{
1061    SBProcess sb_process;
1062    ExecutionContext exe_ctx (m_opaque_sp.get());
1063    if (exe_ctx.HasThreadScope())
1064    {
1065        // Have to go up to the target so we can get a shared pointer to our process...
1066        sb_process.SetSP (exe_ctx.GetProcessSP());
1067    }
1068
1069    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1070    if (log)
1071    {
1072        SBStream frame_desc_strm;
1073        sb_process.GetDescription (frame_desc_strm);
1074        log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", exe_ctx.GetThreadPtr(),
1075                     sb_process.GetSP().get(), frame_desc_strm.GetData());
1076    }
1077
1078    return sb_process;
1079}
1080
1081uint32_t
1082SBThread::GetNumFrames ()
1083{
1084    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1085
1086    uint32_t num_frames = 0;
1087    Mutex::Locker api_locker;
1088    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1089
1090    if (exe_ctx.HasThreadScope())
1091    {
1092        Process::StopLocker stop_locker;
1093        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1094        {
1095            num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1096        }
1097        else
1098        {
1099            if (log)
1100                log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running", exe_ctx.GetThreadPtr());
1101        }
1102    }
1103
1104    if (log)
1105        log->Printf ("SBThread(%p)::GetNumFrames () => %u", exe_ctx.GetThreadPtr(), num_frames);
1106
1107    return num_frames;
1108}
1109
1110SBFrame
1111SBThread::GetFrameAtIndex (uint32_t idx)
1112{
1113    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1114
1115    SBFrame sb_frame;
1116    StackFrameSP frame_sp;
1117    Mutex::Locker api_locker;
1118    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1119
1120    if (exe_ctx.HasThreadScope())
1121    {
1122        Process::StopLocker stop_locker;
1123        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1124        {
1125            frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx);
1126            sb_frame.SetFrameSP (frame_sp);
1127        }
1128        else
1129        {
1130            if (log)
1131                log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running", exe_ctx.GetThreadPtr());
1132        }
1133    }
1134
1135    if (log)
1136    {
1137        SBStream frame_desc_strm;
1138        sb_frame.GetDescription (frame_desc_strm);
1139        log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
1140                     exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData());
1141    }
1142
1143    return sb_frame;
1144}
1145
1146lldb::SBFrame
1147SBThread::GetSelectedFrame ()
1148{
1149    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1150
1151    SBFrame sb_frame;
1152    StackFrameSP frame_sp;
1153    Mutex::Locker api_locker;
1154    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1155
1156    if (exe_ctx.HasThreadScope())
1157    {
1158        Process::StopLocker stop_locker;
1159        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1160        {
1161            frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame ();
1162            sb_frame.SetFrameSP (frame_sp);
1163        }
1164        else
1165        {
1166            if (log)
1167                log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr());
1168        }
1169    }
1170
1171    if (log)
1172    {
1173        SBStream frame_desc_strm;
1174        sb_frame.GetDescription (frame_desc_strm);
1175        log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
1176                     exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData());
1177    }
1178
1179    return sb_frame;
1180}
1181
1182lldb::SBFrame
1183SBThread::SetSelectedFrame (uint32_t idx)
1184{
1185    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1186
1187    SBFrame sb_frame;
1188    StackFrameSP frame_sp;
1189    Mutex::Locker api_locker;
1190    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1191
1192    if (exe_ctx.HasThreadScope())
1193    {
1194        Process::StopLocker stop_locker;
1195        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1196        {
1197            Thread *thread = exe_ctx.GetThreadPtr();
1198            frame_sp = thread->GetStackFrameAtIndex (idx);
1199            if (frame_sp)
1200            {
1201                thread->SetSelectedFrame (frame_sp.get());
1202                sb_frame.SetFrameSP (frame_sp);
1203            }
1204        }
1205        else
1206        {
1207            if (log)
1208                log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr());
1209        }
1210    }
1211
1212    if (log)
1213    {
1214        SBStream frame_desc_strm;
1215        sb_frame.GetDescription (frame_desc_strm);
1216        log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
1217                     exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData());
1218    }
1219    return sb_frame;
1220}
1221
1222bool
1223SBThread::EventIsThreadEvent (const SBEvent &event)
1224{
1225    return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL;
1226}
1227
1228SBFrame
1229SBThread::GetStackFrameFromEvent (const SBEvent &event)
1230{
1231    return Thread::ThreadEventData::GetStackFrameFromEvent (event.get());
1232
1233}
1234
1235SBThread
1236SBThread::GetThreadFromEvent (const SBEvent &event)
1237{
1238    return Thread::ThreadEventData::GetThreadFromEvent (event.get());
1239}
1240
1241bool
1242SBThread::operator == (const SBThread &rhs) const
1243{
1244    return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get();
1245}
1246
1247bool
1248SBThread::operator != (const SBThread &rhs) const
1249{
1250    return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get();
1251}
1252
1253bool
1254SBThread::GetStatus (SBStream &status) const
1255{
1256    Stream &strm = status.ref();
1257
1258    ExecutionContext exe_ctx (m_opaque_sp.get());
1259    if (exe_ctx.HasThreadScope())
1260    {
1261        exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1);
1262    }
1263    else
1264        strm.PutCString ("No status");
1265
1266    return true;
1267}
1268
1269bool
1270SBThread::GetDescription (SBStream &description) const
1271{
1272    Stream &strm = description.ref();
1273
1274    ExecutionContext exe_ctx (m_opaque_sp.get());
1275    if (exe_ctx.HasThreadScope())
1276    {
1277        strm.Printf("SBThread: tid = 0x%4.4" PRIx64, exe_ctx.GetThreadPtr()->GetID());
1278    }
1279    else
1280        strm.PutCString ("No value");
1281
1282    return true;
1283}
1284
1285SBThread
1286SBThread::GetExtendedBacktrace (const char *type)
1287{
1288    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1289    Mutex::Locker api_locker;
1290    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1291    SBThread sb_origin_thread;
1292
1293    if (exe_ctx.HasThreadScope())
1294    {
1295        Process::StopLocker stop_locker;
1296        if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1297        {
1298            ThreadSP real_thread(exe_ctx.GetThreadPtr());
1299            if (real_thread)
1300            {
1301                ConstString type_const (type);
1302                SystemRuntime *runtime = exe_ctx.GetProcessPtr()->GetSystemRuntime();
1303                if (runtime)
1304                {
1305                    ThreadSP origin_thread = runtime->GetExtendedBacktrace (real_thread, type_const);
1306                    sb_origin_thread.SetThread (origin_thread);
1307                }
1308            }
1309        }
1310        else
1311        {
1312            if (log)
1313                log->Printf ("SBThread(%p)::GetExtendedBacktrace() => error: process is running", exe_ctx.GetThreadPtr());
1314        }
1315    }
1316
1317    return sb_origin_thread;
1318}
1319