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