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