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