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