130fdc8d8SChris Lattner //===-- SBThread.cpp --------------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
104c5de699SEli Friedman #include "lldb/API/SBThread.h"
1130fdc8d8SChris Lattner 
1230fdc8d8SChris Lattner #include "lldb/API/SBSymbolContext.h"
1330fdc8d8SChris Lattner #include "lldb/API/SBFileSpec.h"
14dde9cff3SCaroline Tice #include "lldb/API/SBStream.h"
154e78f606SGreg Clayton #include "lldb/Breakpoint/BreakpointLocation.h"
166611103cSGreg Clayton #include "lldb/Core/Debugger.h"
17a75418dbSAndrew Kaylor #include "lldb/Core/State.h"
1830fdc8d8SChris Lattner #include "lldb/Core/Stream.h"
1930fdc8d8SChris Lattner #include "lldb/Core/StreamFile.h"
20705b1809SJason Molenda #include "lldb/Core/StructuredData.h"
21a78bd7ffSZachary Turner #include "lldb/Core/ValueObject.h"
226611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
2393749ab3SZachary Turner #include "lldb/Symbol/SymbolContext.h"
2493749ab3SZachary Turner #include "lldb/Symbol/CompileUnit.h"
255dd4916fSJason Molenda #include "lldb/Target/SystemRuntime.h"
2630fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
2730fdc8d8SChris Lattner #include "lldb/Target/Process.h"
28b9ffa98cSJason Molenda #include "lldb/Target/Queue.h"
2993749ab3SZachary Turner #include "lldb/Target/UnixSignals.h"
30f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h"
3130fdc8d8SChris Lattner #include "lldb/Target/Target.h"
3230fdc8d8SChris Lattner #include "lldb/Target/ThreadPlan.h"
3330fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h"
3430fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOut.h"
3530fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepRange.h"
3630fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInRange.h"
3730fdc8d8SChris Lattner 
384c5de699SEli Friedman #include "lldb/API/SBAddress.h"
394c5de699SEli Friedman #include "lldb/API/SBDebugger.h"
404f465cffSJim Ingham #include "lldb/API/SBEvent.h"
4173ca05a2SJim Ingham #include "lldb/API/SBFrame.h"
424c5de699SEli Friedman #include "lldb/API/SBProcess.h"
436a831436SKuba Brecka #include "lldb/API/SBThreadCollection.h"
442bdbfd50SJim Ingham #include "lldb/API/SBThreadPlan.h"
4573ca05a2SJim Ingham #include "lldb/API/SBValue.h"
4630fdc8d8SChris Lattner 
4730fdc8d8SChris Lattner using namespace lldb;
4830fdc8d8SChris Lattner using namespace lldb_private;
4930fdc8d8SChris Lattner 
504f465cffSJim Ingham const char *
514f465cffSJim Ingham SBThread::GetBroadcasterClassName ()
524f465cffSJim Ingham {
534f465cffSJim Ingham     return Thread::GetStaticBroadcasterClass().AsCString();
544f465cffSJim Ingham }
554f465cffSJim Ingham 
56cfd1acedSGreg Clayton //----------------------------------------------------------------------
57cfd1acedSGreg Clayton // Constructors
58cfd1acedSGreg Clayton //----------------------------------------------------------------------
5930fdc8d8SChris Lattner SBThread::SBThread () :
607fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef())
6130fdc8d8SChris Lattner {
6230fdc8d8SChris Lattner }
6330fdc8d8SChris Lattner 
6430fdc8d8SChris Lattner SBThread::SBThread (const ThreadSP& lldb_object_sp) :
657fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef(lldb_object_sp))
6630fdc8d8SChris Lattner {
6730fdc8d8SChris Lattner }
6830fdc8d8SChris Lattner 
6992ef5735SGreg Clayton SBThread::SBThread (const SBThread &rhs) :
707fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef(*rhs.m_opaque_sp))
7130fdc8d8SChris Lattner {
727fdf9ef1SGreg Clayton 
7330fdc8d8SChris Lattner }
7430fdc8d8SChris Lattner 
7530fdc8d8SChris Lattner //----------------------------------------------------------------------
76cfd1acedSGreg Clayton // Assignment operator
77cfd1acedSGreg Clayton //----------------------------------------------------------------------
78cfd1acedSGreg Clayton 
79cfd1acedSGreg Clayton const lldb::SBThread &
80cfd1acedSGreg Clayton SBThread::operator = (const SBThread &rhs)
81cfd1acedSGreg Clayton {
82cfd1acedSGreg Clayton     if (this != &rhs)
837fdf9ef1SGreg Clayton         *m_opaque_sp = *rhs.m_opaque_sp;
84cfd1acedSGreg Clayton     return *this;
85cfd1acedSGreg Clayton }
86cfd1acedSGreg Clayton 
87cfd1acedSGreg Clayton //----------------------------------------------------------------------
8830fdc8d8SChris Lattner // Destructor
8930fdc8d8SChris Lattner //----------------------------------------------------------------------
9030fdc8d8SChris Lattner SBThread::~SBThread()
9130fdc8d8SChris Lattner {
9230fdc8d8SChris Lattner }
9330fdc8d8SChris Lattner 
94b9ffa98cSJason Molenda lldb::SBQueue
95b9ffa98cSJason Molenda SBThread::GetQueue () const
96b9ffa98cSJason Molenda {
97b9ffa98cSJason Molenda     SBQueue sb_queue;
98b9ffa98cSJason Molenda     QueueSP queue_sp;
99bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
100bb19a13cSSaleem Abdulrasool     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
101b9ffa98cSJason Molenda 
102b9ffa98cSJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
103b9ffa98cSJason Molenda     if (exe_ctx.HasThreadScope())
104b9ffa98cSJason Molenda     {
105b9ffa98cSJason Molenda         Process::StopLocker stop_locker;
106b9ffa98cSJason Molenda         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
107b9ffa98cSJason Molenda         {
108b9ffa98cSJason Molenda             queue_sp = exe_ctx.GetThreadPtr()->GetQueue();
109b9ffa98cSJason Molenda             if (queue_sp)
110b9ffa98cSJason Molenda             {
111b9ffa98cSJason Molenda                 sb_queue.SetQueue (queue_sp);
112b9ffa98cSJason Molenda             }
113b9ffa98cSJason Molenda         }
114b9ffa98cSJason Molenda         else
115b9ffa98cSJason Molenda         {
116b9ffa98cSJason Molenda             if (log)
117358cf1eaSGreg Clayton                 log->Printf ("SBThread(%p)::GetQueue() => error: process is running",
118b9ffa98cSJason Molenda                              static_cast<void*>(exe_ctx.GetThreadPtr()));
119b9ffa98cSJason Molenda         }
120b9ffa98cSJason Molenda     }
121b9ffa98cSJason Molenda 
122b9ffa98cSJason Molenda     if (log)
123358cf1eaSGreg Clayton         log->Printf ("SBThread(%p)::GetQueue () => SBQueue(%p)",
124b9ffa98cSJason Molenda                      static_cast<void*>(exe_ctx.GetThreadPtr()), static_cast<void*>(queue_sp.get()));
125b9ffa98cSJason Molenda 
126b9ffa98cSJason Molenda     return sb_queue;
127b9ffa98cSJason Molenda }
128b9ffa98cSJason Molenda 
129b9ffa98cSJason Molenda 
13030fdc8d8SChris Lattner bool
13130fdc8d8SChris Lattner SBThread::IsValid() const
13230fdc8d8SChris Lattner {
133bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
134bb19a13cSSaleem Abdulrasool     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1357fa7dc36SJim Ingham 
1367fa7dc36SJim Ingham     Target *target = exe_ctx.GetTargetPtr();
1377fa7dc36SJim Ingham     Process *process = exe_ctx.GetProcessPtr();
1387fa7dc36SJim Ingham     if (target && process)
1397fa7dc36SJim Ingham     {
1407fa7dc36SJim Ingham         Process::StopLocker stop_locker;
1417fa7dc36SJim Ingham         if (stop_locker.TryLock(&process->GetRunLock()))
1427fdf9ef1SGreg Clayton         return m_opaque_sp->GetThreadSP().get() != NULL;
14330fdc8d8SChris Lattner     }
1447fa7dc36SJim Ingham     // Without a valid target & process, this thread can't be valid.
1457fa7dc36SJim Ingham     return false;
1467fa7dc36SJim Ingham }
14730fdc8d8SChris Lattner 
14848e42549SGreg Clayton void
14948e42549SGreg Clayton SBThread::Clear ()
15048e42549SGreg Clayton {
1517fdf9ef1SGreg Clayton     m_opaque_sp->Clear();
15248e42549SGreg Clayton }
15348e42549SGreg Clayton 
15448e42549SGreg Clayton 
15530fdc8d8SChris Lattner StopReason
15630fdc8d8SChris Lattner SBThread::GetStopReason()
15730fdc8d8SChris Lattner {
1585160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
159ceb6b139SCaroline Tice 
160ceb6b139SCaroline Tice     StopReason reason = eStopReasonInvalid;
161bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
162bb19a13cSSaleem Abdulrasool     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1634fc6cb9cSJim Ingham 
1641ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
16530fdc8d8SChris Lattner     {
1667fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
1677fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1687fdf9ef1SGreg Clayton         {
16997d5cf05SGreg Clayton             return exe_ctx.GetThreadPtr()->GetStopReason();
17030fdc8d8SChris Lattner         }
171c9858e4dSGreg Clayton         else
172c9858e4dSGreg Clayton         {
173c9858e4dSGreg Clayton             if (log)
174324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopReason() => error: process is running",
175324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
176c9858e4dSGreg Clayton         }
1777fdf9ef1SGreg Clayton     }
178ceb6b139SCaroline Tice 
179ceb6b139SCaroline Tice     if (log)
180324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetStopReason () => %s",
181324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
182750cd175SCaroline Tice                      Thread::StopReasonAsCString (reason));
183ceb6b139SCaroline Tice 
184ceb6b139SCaroline Tice     return reason;
18530fdc8d8SChris Lattner }
18630fdc8d8SChris Lattner 
18730fdc8d8SChris Lattner size_t
1884e78f606SGreg Clayton SBThread::GetStopReasonDataCount ()
1894e78f606SGreg Clayton {
190bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
191bb19a13cSSaleem Abdulrasool     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1924fc6cb9cSJim Ingham 
1931ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1944e78f606SGreg Clayton     {
1957fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
1967fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1977fdf9ef1SGreg Clayton         {
1981ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
1994e78f606SGreg Clayton             if (stop_info_sp)
2004e78f606SGreg Clayton             {
2014e78f606SGreg Clayton                 StopReason reason = stop_info_sp->GetStopReason();
2024e78f606SGreg Clayton                 switch (reason)
2034e78f606SGreg Clayton                 {
2044e78f606SGreg Clayton                 case eStopReasonInvalid:
2054e78f606SGreg Clayton                 case eStopReasonNone:
2064e78f606SGreg Clayton                 case eStopReasonTrace:
20790ba8115SGreg Clayton                 case eStopReasonExec:
2084e78f606SGreg Clayton                 case eStopReasonPlanComplete:
209f85defaeSAndrew Kaylor                 case eStopReasonThreadExiting:
210afdf842bSKuba Brecka                 case eStopReasonInstrumentation:
2114e78f606SGreg Clayton                     // There is no data for these stop reasons.
2124e78f606SGreg Clayton                     return 0;
2134e78f606SGreg Clayton 
2144e78f606SGreg Clayton                 case eStopReasonBreakpoint:
2154e78f606SGreg Clayton                     {
2164e78f606SGreg Clayton                         break_id_t site_id = stop_info_sp->GetValue();
2171ac04c30SGreg Clayton                         lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
2184e78f606SGreg Clayton                         if (bp_site_sp)
2194e78f606SGreg Clayton                             return bp_site_sp->GetNumberOfOwners () * 2;
2204e78f606SGreg Clayton                         else
2214e78f606SGreg Clayton                             return 0; // Breakpoint must have cleared itself...
2224e78f606SGreg Clayton                     }
2234e78f606SGreg Clayton                     break;
2244e78f606SGreg Clayton 
2254e78f606SGreg Clayton                 case eStopReasonWatchpoint:
226290fa41bSJohnny Chen                     return 1;
2274e78f606SGreg Clayton 
2284e78f606SGreg Clayton                 case eStopReasonSignal:
2294e78f606SGreg Clayton                     return 1;
2304e78f606SGreg Clayton 
2314e78f606SGreg Clayton                 case eStopReasonException:
2324e78f606SGreg Clayton                     return 1;
2334e78f606SGreg Clayton                 }
2344e78f606SGreg Clayton             }
2354e78f606SGreg Clayton         }
236c9858e4dSGreg Clayton         else
237c9858e4dSGreg Clayton         {
2385160ce5cSGreg Clayton             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
239c9858e4dSGreg Clayton             if (log)
240324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopReasonDataCount() => error: process is running",
241324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
242c9858e4dSGreg Clayton         }
2437fdf9ef1SGreg Clayton     }
2444e78f606SGreg Clayton     return 0;
2454e78f606SGreg Clayton }
2464e78f606SGreg Clayton 
2474e78f606SGreg Clayton uint64_t
2484e78f606SGreg Clayton SBThread::GetStopReasonDataAtIndex (uint32_t idx)
2494e78f606SGreg Clayton {
250bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
251bb19a13cSSaleem Abdulrasool     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
2524fc6cb9cSJim Ingham 
2531ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
2544e78f606SGreg Clayton     {
2557fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
2567fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
2577fdf9ef1SGreg Clayton         {
2581ac04c30SGreg Clayton             Thread *thread = exe_ctx.GetThreadPtr();
2591ac04c30SGreg Clayton             StopInfoSP stop_info_sp = thread->GetStopInfo ();
2604e78f606SGreg Clayton             if (stop_info_sp)
2614e78f606SGreg Clayton             {
2624e78f606SGreg Clayton                 StopReason reason = stop_info_sp->GetStopReason();
2634e78f606SGreg Clayton                 switch (reason)
2644e78f606SGreg Clayton                 {
2654e78f606SGreg Clayton                 case eStopReasonInvalid:
2664e78f606SGreg Clayton                 case eStopReasonNone:
2674e78f606SGreg Clayton                 case eStopReasonTrace:
26890ba8115SGreg Clayton                 case eStopReasonExec:
2694e78f606SGreg Clayton                 case eStopReasonPlanComplete:
270f85defaeSAndrew Kaylor                 case eStopReasonThreadExiting:
271afdf842bSKuba Brecka                 case eStopReasonInstrumentation:
2724e78f606SGreg Clayton                     // There is no data for these stop reasons.
2734e78f606SGreg Clayton                     return 0;
2744e78f606SGreg Clayton 
2754e78f606SGreg Clayton                 case eStopReasonBreakpoint:
2764e78f606SGreg Clayton                     {
2774e78f606SGreg Clayton                         break_id_t site_id = stop_info_sp->GetValue();
2781ac04c30SGreg Clayton                         lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
2794e78f606SGreg Clayton                         if (bp_site_sp)
2804e78f606SGreg Clayton                         {
2814e78f606SGreg Clayton                             uint32_t bp_index = idx / 2;
2824e78f606SGreg Clayton                             BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index));
2834e78f606SGreg Clayton                             if (bp_loc_sp)
2844e78f606SGreg Clayton                             {
2858334e14eSGreg Clayton                                 if (idx & 1)
2864e78f606SGreg Clayton                                 {
2874e78f606SGreg Clayton                                     // Odd idx, return the breakpoint location ID
2884e78f606SGreg Clayton                                     return bp_loc_sp->GetID();
2894e78f606SGreg Clayton                                 }
2904e78f606SGreg Clayton                                 else
2914e78f606SGreg Clayton                                 {
2924e78f606SGreg Clayton                                     // Even idx, return the breakpoint ID
2934e78f606SGreg Clayton                                     return bp_loc_sp->GetBreakpoint().GetID();
2944e78f606SGreg Clayton                                 }
2954e78f606SGreg Clayton                             }
2964e78f606SGreg Clayton                         }
2974e78f606SGreg Clayton                         return LLDB_INVALID_BREAK_ID;
2984e78f606SGreg Clayton                     }
2994e78f606SGreg Clayton                     break;
3004e78f606SGreg Clayton 
3014e78f606SGreg Clayton                 case eStopReasonWatchpoint:
302290fa41bSJohnny Chen                     return stop_info_sp->GetValue();
3034e78f606SGreg Clayton 
3044e78f606SGreg Clayton                 case eStopReasonSignal:
3054e78f606SGreg Clayton                     return stop_info_sp->GetValue();
3064e78f606SGreg Clayton 
3074e78f606SGreg Clayton                 case eStopReasonException:
3084e78f606SGreg Clayton                     return stop_info_sp->GetValue();
3094e78f606SGreg Clayton                 }
3104e78f606SGreg Clayton             }
3114e78f606SGreg Clayton         }
312c9858e4dSGreg Clayton         else
313c9858e4dSGreg Clayton         {
3145160ce5cSGreg Clayton             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
315c9858e4dSGreg Clayton             if (log)
316324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopReasonDataAtIndex() => error: process is running",
317324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
318c9858e4dSGreg Clayton         }
3197fdf9ef1SGreg Clayton     }
3204e78f606SGreg Clayton     return 0;
3214e78f606SGreg Clayton }
3224e78f606SGreg Clayton 
323afdf842bSKuba Brecka bool
324afdf842bSKuba Brecka SBThread::GetStopReasonExtendedInfoAsJSON (lldb::SBStream &stream)
325afdf842bSKuba Brecka {
326afdf842bSKuba Brecka     Stream &strm = stream.ref();
327afdf842bSKuba Brecka 
328*b2e7d28eSJim Ingham     std::unique_lock<std::recursive_mutex> lock;
329*b2e7d28eSJim Ingham     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
330*b2e7d28eSJim Ingham 
331afdf842bSKuba Brecka     if (! exe_ctx.HasThreadScope())
332afdf842bSKuba Brecka         return false;
333afdf842bSKuba Brecka 
334afdf842bSKuba Brecka 
335afdf842bSKuba Brecka     StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
336afdf842bSKuba Brecka     StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
337afdf842bSKuba Brecka     if (! info)
338afdf842bSKuba Brecka         return false;
339afdf842bSKuba Brecka 
340afdf842bSKuba Brecka     info->Dump(strm);
341afdf842bSKuba Brecka 
342afdf842bSKuba Brecka     return true;
343afdf842bSKuba Brecka }
344afdf842bSKuba Brecka 
3456a831436SKuba Brecka SBThreadCollection
3466a831436SKuba Brecka SBThread::GetStopReasonExtendedBacktraces (InstrumentationRuntimeType type)
3476a831436SKuba Brecka {
3486a831436SKuba Brecka     ThreadCollectionSP threads;
3496a831436SKuba Brecka     threads.reset(new ThreadCollection());
3506a831436SKuba Brecka 
3516a831436SKuba Brecka     // We currently only support ThreadSanitizer.
3526a831436SKuba Brecka     if (type != eInstrumentationRuntimeTypeThreadSanitizer)
3536a831436SKuba Brecka         return threads;
3546a831436SKuba Brecka 
355*b2e7d28eSJim Ingham     std::unique_lock<std::recursive_mutex> lock;
356*b2e7d28eSJim Ingham     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
357*b2e7d28eSJim Ingham 
3586a831436SKuba Brecka     if (! exe_ctx.HasThreadScope())
3591aad8fb7SKuba Brecka         return threads;
3606a831436SKuba Brecka 
3616a831436SKuba Brecka     ProcessSP process_sp = exe_ctx.GetProcessSP();
3626a831436SKuba Brecka 
3636a831436SKuba Brecka     StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
3646a831436SKuba Brecka     StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
3656a831436SKuba Brecka     if (! info)
3666a831436SKuba Brecka         return threads;
3676a831436SKuba Brecka 
3681aad8fb7SKuba Brecka     return process_sp->GetInstrumentationRuntime(type)->GetBacktracesFromExtendedStopInfo(info);
3696a831436SKuba Brecka }
3706a831436SKuba Brecka 
3714e78f606SGreg Clayton size_t
37230fdc8d8SChris Lattner SBThread::GetStopDescription (char *dst, size_t dst_len)
37330fdc8d8SChris Lattner {
3745160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
375ceb6b139SCaroline Tice 
376bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
377bb19a13cSSaleem Abdulrasool     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
3784fc6cb9cSJim Ingham 
3791ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
38030fdc8d8SChris Lattner     {
3817fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
3827fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
3837fdf9ef1SGreg Clayton         {
3847fdf9ef1SGreg Clayton 
3851ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
386b15bfc75SJim Ingham             if (stop_info_sp)
38730fdc8d8SChris Lattner             {
388b15bfc75SJim Ingham                 const char *stop_desc = stop_info_sp->GetDescription();
38930fdc8d8SChris Lattner                 if (stop_desc)
39030fdc8d8SChris Lattner                 {
391ceb6b139SCaroline Tice                     if (log)
3924838131bSGreg Clayton                         log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
393324a1036SSaleem Abdulrasool                                      static_cast<void*>(exe_ctx.GetThreadPtr()),
394324a1036SSaleem Abdulrasool                                      stop_desc);
39530fdc8d8SChris Lattner                     if (dst)
39630fdc8d8SChris Lattner                         return ::snprintf (dst, dst_len, "%s", stop_desc);
39730fdc8d8SChris Lattner                     else
39830fdc8d8SChris Lattner                     {
39930fdc8d8SChris Lattner                         // NULL dst passed in, return the length needed to contain the description
40030fdc8d8SChris Lattner                         return ::strlen (stop_desc) + 1; // Include the NULL byte for size
40130fdc8d8SChris Lattner                     }
40230fdc8d8SChris Lattner                 }
40330fdc8d8SChris Lattner                 else
40430fdc8d8SChris Lattner                 {
40530fdc8d8SChris Lattner                     size_t stop_desc_len = 0;
406b15bfc75SJim Ingham                     switch (stop_info_sp->GetStopReason())
40730fdc8d8SChris Lattner                     {
40830fdc8d8SChris Lattner                     case eStopReasonTrace:
40930fdc8d8SChris Lattner                     case eStopReasonPlanComplete:
41030fdc8d8SChris Lattner                         {
41130fdc8d8SChris Lattner                             static char trace_desc[] = "step";
41230fdc8d8SChris Lattner                             stop_desc = trace_desc;
41330fdc8d8SChris Lattner                             stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size
41430fdc8d8SChris Lattner                         }
41530fdc8d8SChris Lattner                         break;
41630fdc8d8SChris Lattner 
41730fdc8d8SChris Lattner                     case eStopReasonBreakpoint:
41830fdc8d8SChris Lattner                         {
41930fdc8d8SChris Lattner                             static char bp_desc[] = "breakpoint hit";
42030fdc8d8SChris Lattner                             stop_desc = bp_desc;
42130fdc8d8SChris Lattner                             stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
42230fdc8d8SChris Lattner                         }
42330fdc8d8SChris Lattner                         break;
42430fdc8d8SChris Lattner 
42530fdc8d8SChris Lattner                     case eStopReasonWatchpoint:
42630fdc8d8SChris Lattner                         {
42730fdc8d8SChris Lattner                             static char wp_desc[] = "watchpoint hit";
42830fdc8d8SChris Lattner                             stop_desc = wp_desc;
42930fdc8d8SChris Lattner                             stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
43030fdc8d8SChris Lattner                         }
43130fdc8d8SChris Lattner                         break;
43230fdc8d8SChris Lattner 
43330fdc8d8SChris Lattner                     case eStopReasonSignal:
43430fdc8d8SChris Lattner                         {
43598d0a4b3SChaoren Lin                             stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals()->GetSignalAsCString(stop_info_sp->GetValue());
43630fdc8d8SChris Lattner                             if (stop_desc == NULL || stop_desc[0] == '\0')
43730fdc8d8SChris Lattner                             {
43830fdc8d8SChris Lattner                                 static char signal_desc[] = "signal";
43930fdc8d8SChris Lattner                                 stop_desc = signal_desc;
44030fdc8d8SChris Lattner                                 stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size
44130fdc8d8SChris Lattner                             }
44230fdc8d8SChris Lattner                         }
44330fdc8d8SChris Lattner                         break;
44430fdc8d8SChris Lattner 
44530fdc8d8SChris Lattner                     case eStopReasonException:
44630fdc8d8SChris Lattner                         {
44730fdc8d8SChris Lattner                             char exc_desc[] = "exception";
44830fdc8d8SChris Lattner                             stop_desc = exc_desc;
44930fdc8d8SChris Lattner                             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
45030fdc8d8SChris Lattner                         }
45130fdc8d8SChris Lattner                         break;
452c982c768SGreg Clayton 
45390ba8115SGreg Clayton                     case eStopReasonExec:
45490ba8115SGreg Clayton                         {
45590ba8115SGreg Clayton                             char exc_desc[] = "exec";
45690ba8115SGreg Clayton                             stop_desc = exc_desc;
45790ba8115SGreg Clayton                             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
45890ba8115SGreg Clayton                         }
45990ba8115SGreg Clayton                         break;
46090ba8115SGreg Clayton 
461f85defaeSAndrew Kaylor                     case eStopReasonThreadExiting:
462f85defaeSAndrew Kaylor                         {
463f85defaeSAndrew Kaylor                             char limbo_desc[] = "thread exiting";
464f85defaeSAndrew Kaylor                             stop_desc = limbo_desc;
465f85defaeSAndrew Kaylor                             stop_desc_len = sizeof(limbo_desc);
466f85defaeSAndrew Kaylor                         }
467f85defaeSAndrew Kaylor                         break;
468c982c768SGreg Clayton                     default:
469c982c768SGreg Clayton                         break;
47030fdc8d8SChris Lattner                     }
47130fdc8d8SChris Lattner 
47230fdc8d8SChris Lattner                     if (stop_desc && stop_desc[0])
47330fdc8d8SChris Lattner                     {
474ceb6b139SCaroline Tice                         if (log)
47593aa84e8SGreg Clayton                             log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
476324a1036SSaleem Abdulrasool                                          static_cast<void*>(exe_ctx.GetThreadPtr()),
477324a1036SSaleem Abdulrasool                                          stop_desc);
478ceb6b139SCaroline Tice 
47930fdc8d8SChris Lattner                         if (dst)
48030fdc8d8SChris Lattner                             return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte
48130fdc8d8SChris Lattner 
48230fdc8d8SChris Lattner                         if (stop_desc_len == 0)
48330fdc8d8SChris Lattner                             stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte
48430fdc8d8SChris Lattner 
48530fdc8d8SChris Lattner                         return stop_desc_len;
48630fdc8d8SChris Lattner                     }
48730fdc8d8SChris Lattner                 }
48830fdc8d8SChris Lattner             }
48930fdc8d8SChris Lattner         }
490c9858e4dSGreg Clayton         else
491c9858e4dSGreg Clayton         {
4925160ce5cSGreg Clayton             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
493c9858e4dSGreg Clayton             if (log)
494324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopDescription() => error: process is running",
495324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
496c9858e4dSGreg Clayton         }
4977fdf9ef1SGreg Clayton     }
49830fdc8d8SChris Lattner     if (dst)
49930fdc8d8SChris Lattner         *dst = 0;
50030fdc8d8SChris Lattner     return 0;
50130fdc8d8SChris Lattner }
50230fdc8d8SChris Lattner 
50373ca05a2SJim Ingham SBValue
50473ca05a2SJim Ingham SBThread::GetStopReturnValue ()
50573ca05a2SJim Ingham {
5065160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
50773ca05a2SJim Ingham     ValueObjectSP return_valobj_sp;
508bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
509bb19a13cSSaleem Abdulrasool     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
5104fc6cb9cSJim Ingham 
5111ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
51273ca05a2SJim Ingham     {
5137fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
5147fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
5157fdf9ef1SGreg Clayton         {
5161ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
51773ca05a2SJim Ingham             if (stop_info_sp)
51873ca05a2SJim Ingham             {
51973ca05a2SJim Ingham                 return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
52073ca05a2SJim Ingham             }
52173ca05a2SJim Ingham         }
522c9858e4dSGreg Clayton         else
523c9858e4dSGreg Clayton         {
524c9858e4dSGreg Clayton             if (log)
525324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopReturnValue() => error: process is running",
526324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
527c9858e4dSGreg Clayton         }
5287fdf9ef1SGreg Clayton     }
52973ca05a2SJim Ingham 
53073ca05a2SJim Ingham     if (log)
531324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetStopReturnValue () => %s",
532324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
53373ca05a2SJim Ingham                      return_valobj_sp.get()
53473ca05a2SJim Ingham                         ? return_valobj_sp->GetValueAsCString()
53573ca05a2SJim Ingham                         : "<no return value>");
53673ca05a2SJim Ingham 
53773ca05a2SJim Ingham     return SBValue (return_valobj_sp);
53873ca05a2SJim Ingham }
53973ca05a2SJim Ingham 
54030fdc8d8SChris Lattner void
54130fdc8d8SChris Lattner SBThread::SetThread (const ThreadSP& lldb_object_sp)
54230fdc8d8SChris Lattner {
5437fdf9ef1SGreg Clayton     m_opaque_sp->SetThreadSP (lldb_object_sp);
54430fdc8d8SChris Lattner }
54530fdc8d8SChris Lattner 
54630fdc8d8SChris Lattner lldb::tid_t
54730fdc8d8SChris Lattner SBThread::GetThreadID () const
54830fdc8d8SChris Lattner {
5497fdf9ef1SGreg Clayton     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
55017a6ad05SGreg Clayton     if (thread_sp)
5511ac04c30SGreg Clayton         return thread_sp->GetID();
5521ac04c30SGreg Clayton     return LLDB_INVALID_THREAD_ID;
55330fdc8d8SChris Lattner }
55430fdc8d8SChris Lattner 
55530fdc8d8SChris Lattner uint32_t
55630fdc8d8SChris Lattner SBThread::GetIndexID () const
55730fdc8d8SChris Lattner {
5587fdf9ef1SGreg Clayton     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
55917a6ad05SGreg Clayton     if (thread_sp)
56017a6ad05SGreg Clayton         return thread_sp->GetIndexID();
56130fdc8d8SChris Lattner     return LLDB_INVALID_INDEX32;
56230fdc8d8SChris Lattner }
5631ac04c30SGreg Clayton 
56430fdc8d8SChris Lattner const char *
56530fdc8d8SChris Lattner SBThread::GetName () const
56630fdc8d8SChris Lattner {
5675160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
5684838131bSGreg Clayton     const char *name = NULL;
569bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
570bb19a13cSSaleem Abdulrasool     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
5714fc6cb9cSJim Ingham 
5721ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
573af67cecdSGreg Clayton     {
5747fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
5757fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
5767fdf9ef1SGreg Clayton         {
5771ac04c30SGreg Clayton             name = exe_ctx.GetThreadPtr()->GetName();
578af67cecdSGreg Clayton         }
579c9858e4dSGreg Clayton         else
580c9858e4dSGreg Clayton         {
581c9858e4dSGreg Clayton             if (log)
582324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetName() => error: process is running",
583324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
584c9858e4dSGreg Clayton         }
5857fdf9ef1SGreg Clayton     }
586ceb6b139SCaroline Tice 
587ceb6b139SCaroline Tice     if (log)
588324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetName () => %s",
589324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
590324a1036SSaleem Abdulrasool                      name ? name : "NULL");
591ceb6b139SCaroline Tice 
5924838131bSGreg Clayton     return name;
59330fdc8d8SChris Lattner }
59430fdc8d8SChris Lattner 
59530fdc8d8SChris Lattner const char *
59630fdc8d8SChris Lattner SBThread::GetQueueName () const
59730fdc8d8SChris Lattner {
5984838131bSGreg Clayton     const char *name = NULL;
599bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
600bb19a13cSSaleem Abdulrasool     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
6014fc6cb9cSJim Ingham 
6025160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
6031ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
604af67cecdSGreg Clayton     {
6057fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
6067fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
6077fdf9ef1SGreg Clayton         {
6081ac04c30SGreg Clayton             name = exe_ctx.GetThreadPtr()->GetQueueName();
609af67cecdSGreg Clayton         }
610c9858e4dSGreg Clayton         else
611c9858e4dSGreg Clayton         {
612c9858e4dSGreg Clayton             if (log)
613324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetQueueName() => error: process is running",
614324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
615c9858e4dSGreg Clayton         }
6167fdf9ef1SGreg Clayton     }
617ceb6b139SCaroline Tice 
618ceb6b139SCaroline Tice     if (log)
619324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetQueueName () => %s",
620324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
621324a1036SSaleem Abdulrasool                      name ? name : "NULL");
622ceb6b139SCaroline Tice 
6234838131bSGreg Clayton     return name;
62430fdc8d8SChris Lattner }
62530fdc8d8SChris Lattner 
6264fdb5863SJason Molenda lldb::queue_id_t
6274fdb5863SJason Molenda SBThread::GetQueueID () const
6284fdb5863SJason Molenda {
6294fdb5863SJason Molenda     queue_id_t id = LLDB_INVALID_QUEUE_ID;
630bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
631bb19a13cSSaleem Abdulrasool     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
6324fdb5863SJason Molenda 
6334fdb5863SJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
6344fdb5863SJason Molenda     if (exe_ctx.HasThreadScope())
6354fdb5863SJason Molenda     {
6364fdb5863SJason Molenda         Process::StopLocker stop_locker;
6374fdb5863SJason Molenda         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
6384fdb5863SJason Molenda         {
6394fdb5863SJason Molenda             id = exe_ctx.GetThreadPtr()->GetQueueID();
6404fdb5863SJason Molenda         }
6414fdb5863SJason Molenda         else
6424fdb5863SJason Molenda         {
6434fdb5863SJason Molenda             if (log)
644324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetQueueID() => error: process is running",
645324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
6464fdb5863SJason Molenda         }
6474fdb5863SJason Molenda     }
6484fdb5863SJason Molenda 
6494fdb5863SJason Molenda     if (log)
650324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetQueueID () => 0x%" PRIx64,
651324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), id);
6524fdb5863SJason Molenda 
6534fdb5863SJason Molenda     return id;
6544fdb5863SJason Molenda }
6554fdb5863SJason Molenda 
656705b1809SJason Molenda bool
657705b1809SJason Molenda SBThread::GetInfoItemByPathAsString (const char *path, SBStream &strm)
658705b1809SJason Molenda {
659705b1809SJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
660705b1809SJason Molenda     bool success = false;
661bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
662bb19a13cSSaleem Abdulrasool     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
663705b1809SJason Molenda 
664705b1809SJason Molenda     if (exe_ctx.HasThreadScope())
665705b1809SJason Molenda     {
666705b1809SJason Molenda         Process::StopLocker stop_locker;
667705b1809SJason Molenda         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
668705b1809SJason Molenda         {
669705b1809SJason Molenda             Thread *thread = exe_ctx.GetThreadPtr();
670705b1809SJason Molenda             StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo();
671705b1809SJason Molenda             if (info_root_sp)
672705b1809SJason Molenda             {
673705b1809SJason Molenda                 StructuredData::ObjectSP node = info_root_sp->GetObjectForDotSeparatedPath (path);
674705b1809SJason Molenda                 if (node)
675705b1809SJason Molenda                 {
676705b1809SJason Molenda                     if (node->GetType() == StructuredData::Type::eTypeString)
677705b1809SJason Molenda                     {
678705b1809SJason Molenda                         strm.Printf ("%s", node->GetAsString()->GetValue().c_str());
679705b1809SJason Molenda                         success = true;
680705b1809SJason Molenda                     }
681705b1809SJason Molenda                     if (node->GetType() == StructuredData::Type::eTypeInteger)
682705b1809SJason Molenda                     {
683705b1809SJason Molenda                         strm.Printf ("0x%" PRIx64, node->GetAsInteger()->GetValue());
684705b1809SJason Molenda                         success = true;
685705b1809SJason Molenda                     }
686705b1809SJason Molenda                     if (node->GetType() == StructuredData::Type::eTypeFloat)
687705b1809SJason Molenda                     {
688705b1809SJason Molenda                         strm.Printf ("0x%f", node->GetAsFloat()->GetValue());
689705b1809SJason Molenda                         success = true;
690705b1809SJason Molenda                     }
691705b1809SJason Molenda                     if (node->GetType() == StructuredData::Type::eTypeBoolean)
692705b1809SJason Molenda                     {
693705b1809SJason Molenda                         if (node->GetAsBoolean()->GetValue() == true)
694705b1809SJason Molenda                             strm.Printf ("true");
695705b1809SJason Molenda                         else
696705b1809SJason Molenda                             strm.Printf ("false");
697705b1809SJason Molenda                         success = true;
698705b1809SJason Molenda                     }
699705b1809SJason Molenda                     if (node->GetType() == StructuredData::Type::eTypeNull)
700705b1809SJason Molenda                     {
701705b1809SJason Molenda                         strm.Printf ("null");
702705b1809SJason Molenda                         success = true;
703705b1809SJason Molenda                     }
704705b1809SJason Molenda                 }
705705b1809SJason Molenda             }
706705b1809SJason Molenda         }
707705b1809SJason Molenda         else
708705b1809SJason Molenda         {
709705b1809SJason Molenda             if (log)
710705b1809SJason Molenda                 log->Printf ("SBThread(%p)::GetInfoItemByPathAsString() => error: process is running",
711705b1809SJason Molenda                              static_cast<void*>(exe_ctx.GetThreadPtr()));
712705b1809SJason Molenda         }
713705b1809SJason Molenda     }
714705b1809SJason Molenda 
715705b1809SJason Molenda     if (log)
716705b1809SJason Molenda         log->Printf ("SBThread(%p)::GetInfoItemByPathAsString () => %s",
717705b1809SJason Molenda                      static_cast<void*>(exe_ctx.GetThreadPtr()),
718705b1809SJason Molenda                      strm.GetData());
719705b1809SJason Molenda 
720705b1809SJason Molenda     return success;
721705b1809SJason Molenda }
722705b1809SJason Molenda 
723705b1809SJason Molenda 
72464e7ead1SJim Ingham SBError
72564e7ead1SJim Ingham SBThread::ResumeNewPlan (ExecutionContext &exe_ctx, ThreadPlan *new_plan)
72664e7ead1SJim Ingham {
72764e7ead1SJim Ingham     SBError sb_error;
72864e7ead1SJim Ingham 
72964e7ead1SJim Ingham     Process *process = exe_ctx.GetProcessPtr();
73064e7ead1SJim Ingham     if (!process)
73164e7ead1SJim Ingham     {
73264e7ead1SJim Ingham         sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
73364e7ead1SJim Ingham         return sb_error;
73464e7ead1SJim Ingham     }
73564e7ead1SJim Ingham 
73664e7ead1SJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
73764e7ead1SJim Ingham     if (!thread)
73864e7ead1SJim Ingham     {
73964e7ead1SJim Ingham         sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
74064e7ead1SJim Ingham         return sb_error;
74164e7ead1SJim Ingham     }
74264e7ead1SJim Ingham 
74364e7ead1SJim Ingham     // User level plans should be Master Plans so they can be interrupted, other plans executed, and
74464e7ead1SJim Ingham     // then a "continue" will resume the plan.
74564e7ead1SJim Ingham     if (new_plan != NULL)
74664e7ead1SJim Ingham     {
74764e7ead1SJim Ingham         new_plan->SetIsMasterPlan(true);
74864e7ead1SJim Ingham         new_plan->SetOkayToDiscard(false);
74964e7ead1SJim Ingham     }
75064e7ead1SJim Ingham 
75164e7ead1SJim Ingham     // Why do we need to set the current thread by ID here???
75264e7ead1SJim Ingham     process->GetThreadList().SetSelectedThreadByID (thread->GetID());
75364e7ead1SJim Ingham 
754dc6224e0SGreg Clayton     if (process->GetTarget().GetDebugger().GetAsyncExecution ())
755dc6224e0SGreg Clayton         sb_error.ref() = process->Resume ();
756dc6224e0SGreg Clayton     else
757dc6224e0SGreg Clayton         sb_error.ref() = process->ResumeSynchronous (NULL);
75864e7ead1SJim Ingham 
75964e7ead1SJim Ingham     return sb_error;
76064e7ead1SJim Ingham }
76130fdc8d8SChris Lattner 
76230fdc8d8SChris Lattner void
76330fdc8d8SChris Lattner SBThread::StepOver (lldb::RunMode stop_other_threads)
76430fdc8d8SChris Lattner {
7655160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
766ceb6b139SCaroline Tice 
767bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
768bb19a13cSSaleem Abdulrasool     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
76917a6ad05SGreg Clayton 
770ceb6b139SCaroline Tice     if (log)
771324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')",
772324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
773ceb6b139SCaroline Tice                      Thread::RunModeAsCString (stop_other_threads));
774ceb6b139SCaroline Tice 
7751ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
77630fdc8d8SChris Lattner     {
7771ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
7787ba6e991SJim Ingham         bool abort_other_plans = false;
779b57e4a1bSJason Molenda         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
78030fdc8d8SChris Lattner 
7814d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp;
78230fdc8d8SChris Lattner         if (frame_sp)
78330fdc8d8SChris Lattner         {
78430fdc8d8SChris Lattner             if (frame_sp->HasDebugInformation ())
78530fdc8d8SChris Lattner             {
7864b4b2478SJim Ingham                 const LazyBool avoid_no_debug = eLazyBoolCalculate;
78730fdc8d8SChris Lattner                 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
7884d56e9c1SJim Ingham                 new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
78925d5b10bSJason Molenda                                                                     sc.line_entry,
79030fdc8d8SChris Lattner                                                                     sc,
7914b4b2478SJim Ingham                                                                     stop_other_threads,
7924b4b2478SJim Ingham                                                                     avoid_no_debug);
79330fdc8d8SChris Lattner             }
79430fdc8d8SChris Lattner             else
79530fdc8d8SChris Lattner             {
7964d56e9c1SJim Ingham                 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
79730fdc8d8SChris Lattner                                                                                abort_other_plans,
79830fdc8d8SChris Lattner                                                                                stop_other_threads);
79930fdc8d8SChris Lattner             }
80030fdc8d8SChris Lattner         }
80130fdc8d8SChris Lattner 
80264e7ead1SJim Ingham         // This returns an error, we should use it!
8034d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
80430fdc8d8SChris Lattner     }
80530fdc8d8SChris Lattner }
80630fdc8d8SChris Lattner 
80730fdc8d8SChris Lattner void
80830fdc8d8SChris Lattner SBThread::StepInto (lldb::RunMode stop_other_threads)
80930fdc8d8SChris Lattner {
810c627682eSJim Ingham     StepInto (NULL, stop_other_threads);
811c627682eSJim Ingham }
812c627682eSJim Ingham 
813c627682eSJim Ingham void
814c627682eSJim Ingham SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads)
815c627682eSJim Ingham {
816cbf6f9b2SJim Ingham     SBError error;
817cbf6f9b2SJim Ingham     StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads);
818cbf6f9b2SJim Ingham }
819cbf6f9b2SJim Ingham 
820cbf6f9b2SJim Ingham void
821cbf6f9b2SJim Ingham SBThread::StepInto (const char *target_name, uint32_t end_line, SBError &error, lldb::RunMode stop_other_threads)
822cbf6f9b2SJim Ingham {
8235160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
824ceb6b139SCaroline Tice 
825bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
826bb19a13cSSaleem Abdulrasool     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
82717a6ad05SGreg Clayton 
82817a6ad05SGreg Clayton     if (log)
829c627682eSJim Ingham         log->Printf ("SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')",
830324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
831c627682eSJim Ingham                      target_name? target_name: "<NULL>",
83217a6ad05SGreg Clayton                      Thread::RunModeAsCString (stop_other_threads));
833c627682eSJim Ingham 
8341ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
83530fdc8d8SChris Lattner     {
8367ba6e991SJim Ingham         bool abort_other_plans = false;
83730fdc8d8SChris Lattner 
8381ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
839b57e4a1bSJason Molenda         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
8404d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp;
84130fdc8d8SChris Lattner 
84230fdc8d8SChris Lattner         if (frame_sp && frame_sp->HasDebugInformation ())
84330fdc8d8SChris Lattner         {
844cbf6f9b2SJim Ingham             SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
845cbf6f9b2SJim Ingham             AddressRange range;
846cbf6f9b2SJim Ingham             if (end_line == LLDB_INVALID_LINE_NUMBER)
847cbf6f9b2SJim Ingham                 range = sc.line_entry.range;
848cbf6f9b2SJim Ingham             else
849cbf6f9b2SJim Ingham             {
850cbf6f9b2SJim Ingham                 if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
851cbf6f9b2SJim Ingham                     return;
852cbf6f9b2SJim Ingham             }
853cbf6f9b2SJim Ingham 
8544b4b2478SJim Ingham             const LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate;
8554b4b2478SJim Ingham             const LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate;
8564d56e9c1SJim Ingham             new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
857cbf6f9b2SJim Ingham                                                               range,
85830fdc8d8SChris Lattner                                                               sc,
859c627682eSJim Ingham                                                               target_name,
860474966a4SGreg Clayton                                                               stop_other_threads,
8614b4b2478SJim Ingham                                                               step_in_avoids_code_without_debug_info,
8624b4b2478SJim Ingham                                                               step_out_avoids_code_without_debug_info);
86330fdc8d8SChris Lattner         }
86430fdc8d8SChris Lattner         else
86530fdc8d8SChris Lattner         {
8664d56e9c1SJim Ingham             new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false,
86730fdc8d8SChris Lattner                                                                            abort_other_plans,
86830fdc8d8SChris Lattner                                                                            stop_other_threads);
86930fdc8d8SChris Lattner         }
87030fdc8d8SChris Lattner 
871cbf6f9b2SJim Ingham         error = ResumeNewPlan (exe_ctx, new_plan_sp.get());
87230fdc8d8SChris Lattner     }
87330fdc8d8SChris Lattner }
87430fdc8d8SChris Lattner 
87530fdc8d8SChris Lattner void
87630fdc8d8SChris Lattner SBThread::StepOut ()
87730fdc8d8SChris Lattner {
8785160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
879ceb6b139SCaroline Tice 
880bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
881bb19a13cSSaleem Abdulrasool     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
8824fc6cb9cSJim Ingham 
88317a6ad05SGreg Clayton     if (log)
884324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::StepOut ()",
885324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()));
88617a6ad05SGreg Clayton 
8871ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
88830fdc8d8SChris Lattner     {
8897ba6e991SJim Ingham         bool abort_other_plans = false;
89094b09246SJim Ingham         bool stop_other_threads = false;
89130fdc8d8SChris Lattner 
8921ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
8931ac04c30SGreg Clayton 
8944b4b2478SJim Ingham         const LazyBool avoid_no_debug = eLazyBoolCalculate;
8954d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans,
896481cef25SGreg Clayton                                                                     NULL,
897481cef25SGreg Clayton                                                                     false,
898481cef25SGreg Clayton                                                                     stop_other_threads,
899481cef25SGreg Clayton                                                                     eVoteYes,
900481cef25SGreg Clayton                                                                     eVoteNoOpinion,
9014b4b2478SJim Ingham                                                                     0,
9024b4b2478SJim Ingham                                                                     avoid_no_debug));
903481cef25SGreg Clayton 
90464e7ead1SJim Ingham         // This returns an error, we should use it!
9054d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
906481cef25SGreg Clayton     }
907481cef25SGreg Clayton }
908481cef25SGreg Clayton 
909481cef25SGreg Clayton void
910481cef25SGreg Clayton SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame)
911481cef25SGreg Clayton {
9125160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
913481cef25SGreg Clayton 
914bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
915bb19a13cSSaleem Abdulrasool     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
9164fc6cb9cSJim Ingham 
917989a7558SJim Ingham     if (!sb_frame.IsValid())
918989a7558SJim Ingham     {
919989a7558SJim Ingham         if (log)
920989a7558SJim Ingham             log->Printf("SBThread(%p)::StepOutOfFrame passed an invalid frame, returning.",
921989a7558SJim Ingham                         static_cast<void*>(exe_ctx.GetThreadPtr()));
922989a7558SJim Ingham         return;
923989a7558SJim Ingham     }
924989a7558SJim Ingham 
925b57e4a1bSJason Molenda     StackFrameSP frame_sp (sb_frame.GetFrameSP());
926481cef25SGreg Clayton     if (log)
927481cef25SGreg Clayton     {
928481cef25SGreg Clayton         SBStream frame_desc_strm;
929481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
930324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)",
931324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
932324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
933324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
934481cef25SGreg Clayton     }
935481cef25SGreg Clayton 
9361ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
937481cef25SGreg Clayton     {
9387ba6e991SJim Ingham         bool abort_other_plans = false;
93994b09246SJim Ingham         bool stop_other_threads = false;
9401ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
941989a7558SJim Ingham         if (sb_frame.GetThread().GetThreadID() != thread->GetID())
942989a7558SJim Ingham         {
9431ef6e4c8SBruce Mitchener             log->Printf("SBThread(%p)::StepOutOfFrame passed a frame from another thread (0x%" PRIx64 " vrs. 0x%" PRIx64 ", returning.",
944989a7558SJim Ingham                         static_cast<void*>(exe_ctx.GetThreadPtr()),
945989a7558SJim Ingham                         sb_frame.GetThread().GetThreadID(),
946989a7558SJim Ingham                         thread->GetID());
947989a7558SJim Ingham         }
948481cef25SGreg Clayton 
9494d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans,
950481cef25SGreg Clayton                                                                     NULL,
951481cef25SGreg Clayton                                                                     false,
952481cef25SGreg Clayton                                                                     stop_other_threads,
953481cef25SGreg Clayton                                                                     eVoteYes,
954481cef25SGreg Clayton                                                                     eVoteNoOpinion,
9554d56e9c1SJim Ingham                                                                     frame_sp->GetFrameIndex()));
95630fdc8d8SChris Lattner 
95764e7ead1SJim Ingham         // This returns an error, we should use it!
9584d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
95930fdc8d8SChris Lattner     }
96030fdc8d8SChris Lattner }
96130fdc8d8SChris Lattner 
96230fdc8d8SChris Lattner void
96330fdc8d8SChris Lattner SBThread::StepInstruction (bool step_over)
96430fdc8d8SChris Lattner {
9655160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
966ceb6b139SCaroline Tice 
967bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
968bb19a13cSSaleem Abdulrasool     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
969ceb6b139SCaroline Tice 
97017a6ad05SGreg Clayton     if (log)
971324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)",
972324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), step_over);
97317a6ad05SGreg Clayton 
9741ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
97530fdc8d8SChris Lattner     {
9761ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
9774d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true));
97864e7ead1SJim Ingham 
97964e7ead1SJim Ingham         // This returns an error, we should use it!
9804d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
98130fdc8d8SChris Lattner     }
98230fdc8d8SChris Lattner }
98330fdc8d8SChris Lattner 
98430fdc8d8SChris Lattner void
98530fdc8d8SChris Lattner SBThread::RunToAddress (lldb::addr_t addr)
98630fdc8d8SChris Lattner {
9875160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
988ceb6b139SCaroline Tice 
989bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
990bb19a13cSSaleem Abdulrasool     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
991ceb6b139SCaroline Tice 
99217a6ad05SGreg Clayton     if (log)
993324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")",
994324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), addr);
99517a6ad05SGreg Clayton 
9961ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
99730fdc8d8SChris Lattner     {
9987ba6e991SJim Ingham         bool abort_other_plans = false;
99930fdc8d8SChris Lattner         bool stop_other_threads = true;
100030fdc8d8SChris Lattner 
1001e72dfb32SGreg Clayton         Address target_addr (addr);
100230fdc8d8SChris Lattner 
10031ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
10041ac04c30SGreg Clayton 
10052bdbfd50SJim Ingham         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress (abort_other_plans,
10062bdbfd50SJim Ingham                                                                          target_addr,
10072bdbfd50SJim Ingham                                                                          stop_other_threads));
100864e7ead1SJim Ingham 
100964e7ead1SJim Ingham         // This returns an error, we should use it!
10104d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
101130fdc8d8SChris Lattner     }
101230fdc8d8SChris Lattner }
101330fdc8d8SChris Lattner 
1014481cef25SGreg Clayton SBError
1015481cef25SGreg Clayton SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
1016481cef25SGreg Clayton                          lldb::SBFileSpec &sb_file_spec,
1017481cef25SGreg Clayton                          uint32_t line)
1018481cef25SGreg Clayton {
1019481cef25SGreg Clayton     SBError sb_error;
10205160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1021481cef25SGreg Clayton     char path[PATH_MAX];
1022481cef25SGreg Clayton 
1023bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
1024bb19a13cSSaleem Abdulrasool     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
10254fc6cb9cSJim Ingham 
1026b57e4a1bSJason Molenda     StackFrameSP frame_sp (sb_frame.GetFrameSP());
102717a6ad05SGreg Clayton 
1028481cef25SGreg Clayton     if (log)
1029481cef25SGreg Clayton     {
1030481cef25SGreg Clayton         SBStream frame_desc_strm;
1031481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
1032481cef25SGreg Clayton         sb_file_spec->GetPath (path, sizeof(path));
1033481cef25SGreg Clayton         log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)",
1034324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1035324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
1036324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData(), path, line);
1037481cef25SGreg Clayton     }
1038481cef25SGreg Clayton 
10391ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1040481cef25SGreg Clayton     {
10411ac04c30SGreg Clayton         Target *target = exe_ctx.GetTargetPtr();
10421ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
1043481cef25SGreg Clayton 
1044481cef25SGreg Clayton         if (line == 0)
1045481cef25SGreg Clayton         {
1046481cef25SGreg Clayton             sb_error.SetErrorString("invalid line argument");
1047481cef25SGreg Clayton             return sb_error;
1048481cef25SGreg Clayton         }
1049481cef25SGreg Clayton 
1050b9556accSGreg Clayton         if (!frame_sp)
1051481cef25SGreg Clayton         {
10521ac04c30SGreg Clayton             frame_sp = thread->GetSelectedFrame ();
1053481cef25SGreg Clayton             if (!frame_sp)
10541ac04c30SGreg Clayton                 frame_sp = thread->GetStackFrameAtIndex (0);
1055481cef25SGreg Clayton         }
1056481cef25SGreg Clayton 
1057481cef25SGreg Clayton         SymbolContext frame_sc;
1058481cef25SGreg Clayton         if (!frame_sp)
1059481cef25SGreg Clayton         {
1060481cef25SGreg Clayton             sb_error.SetErrorString("no valid frames in thread to step");
1061481cef25SGreg Clayton             return sb_error;
1062481cef25SGreg Clayton         }
1063481cef25SGreg Clayton 
1064481cef25SGreg Clayton         // If we have a frame, get its line
1065481cef25SGreg Clayton         frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit  |
1066481cef25SGreg Clayton                                                eSymbolContextFunction  |
1067481cef25SGreg Clayton                                                eSymbolContextLineEntry |
1068481cef25SGreg Clayton                                                eSymbolContextSymbol    );
1069481cef25SGreg Clayton 
1070481cef25SGreg Clayton         if (frame_sc.comp_unit == NULL)
1071481cef25SGreg Clayton         {
1072481cef25SGreg Clayton             sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex());
1073481cef25SGreg Clayton             return sb_error;
1074481cef25SGreg Clayton         }
1075481cef25SGreg Clayton 
1076481cef25SGreg Clayton         FileSpec step_file_spec;
1077481cef25SGreg Clayton         if (sb_file_spec.IsValid())
1078481cef25SGreg Clayton         {
1079481cef25SGreg Clayton             // The file spec passed in was valid, so use it
1080481cef25SGreg Clayton             step_file_spec = sb_file_spec.ref();
1081481cef25SGreg Clayton         }
1082481cef25SGreg Clayton         else
1083481cef25SGreg Clayton         {
1084481cef25SGreg Clayton             if (frame_sc.line_entry.IsValid())
1085481cef25SGreg Clayton                 step_file_spec = frame_sc.line_entry.file;
1086481cef25SGreg Clayton             else
1087481cef25SGreg Clayton             {
1088481cef25SGreg Clayton                 sb_error.SetErrorString("invalid file argument or no file for frame");
1089481cef25SGreg Clayton                 return sb_error;
1090481cef25SGreg Clayton             }
1091481cef25SGreg Clayton         }
1092481cef25SGreg Clayton 
10939b70ddb3SJim Ingham         // Grab the current function, then we will make sure the "until" address is
10949b70ddb3SJim Ingham         // within the function.  We discard addresses that are out of the current
10959b70ddb3SJim Ingham         // function, and then if there are no addresses remaining, give an appropriate
10969b70ddb3SJim Ingham         // error message.
10979b70ddb3SJim Ingham 
10989b70ddb3SJim Ingham         bool all_in_function = true;
10999b70ddb3SJim Ingham         AddressRange fun_range = frame_sc.function->GetAddressRange();
11009b70ddb3SJim Ingham 
1101481cef25SGreg Clayton         std::vector<addr_t> step_over_until_addrs;
11027ba6e991SJim Ingham         const bool abort_other_plans = false;
1103c02e3344SJim Ingham         const bool stop_other_threads = false;
1104481cef25SGreg Clayton         const bool check_inlines = true;
1105481cef25SGreg Clayton         const bool exact = false;
1106481cef25SGreg Clayton 
1107481cef25SGreg Clayton         SymbolContextList sc_list;
11089b70ddb3SJim Ingham         const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec,
11099b70ddb3SJim Ingham                                                                                line,
11109b70ddb3SJim Ingham                                                                                check_inlines,
11119b70ddb3SJim Ingham                                                                                exact,
11129b70ddb3SJim Ingham                                                                                eSymbolContextLineEntry,
11139b70ddb3SJim Ingham                                                                                sc_list);
1114481cef25SGreg Clayton         if (num_matches > 0)
1115481cef25SGreg Clayton         {
1116481cef25SGreg Clayton             SymbolContext sc;
1117481cef25SGreg Clayton             for (uint32_t i=0; i<num_matches; ++i)
1118481cef25SGreg Clayton             {
1119481cef25SGreg Clayton                 if (sc_list.GetContextAtIndex(i, sc))
1120481cef25SGreg Clayton                 {
11219b70ddb3SJim Ingham                     addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
1122481cef25SGreg Clayton                     if (step_addr != LLDB_INVALID_ADDRESS)
1123481cef25SGreg Clayton                     {
11249b70ddb3SJim Ingham                         if (fun_range.ContainsLoadAddress(step_addr, target))
1125481cef25SGreg Clayton                             step_over_until_addrs.push_back(step_addr);
11269b70ddb3SJim Ingham                         else
11279b70ddb3SJim Ingham                             all_in_function = false;
1128481cef25SGreg Clayton                     }
1129481cef25SGreg Clayton                 }
1130481cef25SGreg Clayton             }
1131481cef25SGreg Clayton         }
1132481cef25SGreg Clayton 
1133481cef25SGreg Clayton         if (step_over_until_addrs.empty())
1134481cef25SGreg Clayton         {
11359b70ddb3SJim Ingham             if (all_in_function)
11369b70ddb3SJim Ingham             {
1137481cef25SGreg Clayton                 step_file_spec.GetPath (path, sizeof(path));
1138fd54b368SJason Molenda                 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line);
1139481cef25SGreg Clayton             }
1140481cef25SGreg Clayton             else
114186edbf41SGreg Clayton                 sb_error.SetErrorString ("step until target not in current function");
11429b70ddb3SJim Ingham         }
11439b70ddb3SJim Ingham         else
1144481cef25SGreg Clayton         {
11454d56e9c1SJim Ingham             ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil (abort_other_plans,
1146481cef25SGreg Clayton                                                                         &step_over_until_addrs[0],
1147481cef25SGreg Clayton                                                                         step_over_until_addrs.size(),
1148481cef25SGreg Clayton                                                                         stop_other_threads,
11494d56e9c1SJim Ingham                                                                         frame_sp->GetFrameIndex()));
1150481cef25SGreg Clayton 
11514d56e9c1SJim Ingham             sb_error = ResumeNewPlan (exe_ctx, new_plan_sp.get());
1152481cef25SGreg Clayton         }
1153481cef25SGreg Clayton     }
1154481cef25SGreg Clayton     else
1155481cef25SGreg Clayton     {
1156481cef25SGreg Clayton         sb_error.SetErrorString("this SBThread object is invalid");
1157481cef25SGreg Clayton     }
1158481cef25SGreg Clayton     return sb_error;
1159481cef25SGreg Clayton }
1160481cef25SGreg Clayton 
11614413758cSJim Ingham SBError
11622bdbfd50SJim Ingham SBThread::StepUsingScriptedThreadPlan (const char *script_class_name)
11632bdbfd50SJim Ingham {
11642bdbfd50SJim Ingham     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
11652bdbfd50SJim Ingham     SBError sb_error;
11662bdbfd50SJim Ingham 
1167bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
1168bb19a13cSSaleem Abdulrasool     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11692bdbfd50SJim Ingham 
11702bdbfd50SJim Ingham     if (log)
11712bdbfd50SJim Ingham     {
11722bdbfd50SJim Ingham         log->Printf ("SBThread(%p)::StepUsingScriptedThreadPlan: class name: %s",
11732bdbfd50SJim Ingham                      static_cast<void*>(exe_ctx.GetThreadPtr()),
11742bdbfd50SJim Ingham                      script_class_name);
11752bdbfd50SJim Ingham     }
11762bdbfd50SJim Ingham 
11772bdbfd50SJim Ingham 
11782bdbfd50SJim Ingham     if (!exe_ctx.HasThreadScope())
11792bdbfd50SJim Ingham     {
11802bdbfd50SJim Ingham         sb_error.SetErrorString("this SBThread object is invalid");
11812bdbfd50SJim Ingham         return sb_error;
11822bdbfd50SJim Ingham     }
11832bdbfd50SJim Ingham 
11842bdbfd50SJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
11852bdbfd50SJim Ingham     ThreadPlanSP thread_plan_sp = thread->QueueThreadPlanForStepScripted(false, script_class_name, false);
11862bdbfd50SJim Ingham 
11872bdbfd50SJim Ingham     if (thread_plan_sp)
11882bdbfd50SJim Ingham         sb_error = ResumeNewPlan(exe_ctx, thread_plan_sp.get());
11892bdbfd50SJim Ingham     else
11902bdbfd50SJim Ingham     {
11912bdbfd50SJim Ingham         sb_error.SetErrorStringWithFormat("Error queuing thread plan for class: %s.", script_class_name);
11922bdbfd50SJim Ingham         if (log)
11932bdbfd50SJim Ingham         log->Printf ("SBThread(%p)::StepUsingScriptedThreadPlan: Error queuing thread plan for class: %s",
11942bdbfd50SJim Ingham                      static_cast<void*>(exe_ctx.GetThreadPtr()),
11952bdbfd50SJim Ingham                      script_class_name);
11962bdbfd50SJim Ingham     }
11972bdbfd50SJim Ingham 
11982bdbfd50SJim Ingham     return sb_error;
11992bdbfd50SJim Ingham }
12002bdbfd50SJim Ingham 
12012bdbfd50SJim Ingham SBError
1202f86248d9SRichard Mitton SBThread::JumpToLine (lldb::SBFileSpec &file_spec, uint32_t line)
1203f86248d9SRichard Mitton {
1204f86248d9SRichard Mitton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1205f86248d9SRichard Mitton     SBError sb_error;
1206f86248d9SRichard Mitton 
1207bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
1208bb19a13cSSaleem Abdulrasool     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1209f86248d9SRichard Mitton 
1210f86248d9SRichard Mitton     if (log)
1211324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::JumpToLine (file+line = %s:%u)",
1212324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1213324a1036SSaleem Abdulrasool                      file_spec->GetPath().c_str(), line);
1214f86248d9SRichard Mitton 
1215f86248d9SRichard Mitton     if (!exe_ctx.HasThreadScope())
1216f86248d9SRichard Mitton     {
1217f86248d9SRichard Mitton         sb_error.SetErrorString("this SBThread object is invalid");
1218f86248d9SRichard Mitton         return sb_error;
1219f86248d9SRichard Mitton     }
1220f86248d9SRichard Mitton 
1221f86248d9SRichard Mitton     Thread *thread = exe_ctx.GetThreadPtr();
1222f86248d9SRichard Mitton 
1223f86248d9SRichard Mitton     Error err = thread->JumpToLine (file_spec.get(), line, true);
1224f86248d9SRichard Mitton     sb_error.SetError (err);
1225f86248d9SRichard Mitton     return sb_error;
1226f86248d9SRichard Mitton }
1227f86248d9SRichard Mitton 
1228f86248d9SRichard Mitton SBError
1229cb640dd8SJim Ingham SBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value)
12304413758cSJim Ingham {
12314413758cSJim Ingham     SBError sb_error;
12324413758cSJim Ingham 
12335160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
12344413758cSJim Ingham 
1235bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
1236bb19a13cSSaleem Abdulrasool     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
12374413758cSJim Ingham 
12384413758cSJim Ingham     if (log)
1239324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::ReturnFromFrame (frame=%d)",
1240324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1241324a1036SSaleem Abdulrasool                      frame.GetFrameID());
12424413758cSJim Ingham 
12434413758cSJim Ingham     if (exe_ctx.HasThreadScope())
12444413758cSJim Ingham     {
12454413758cSJim Ingham         Thread *thread = exe_ctx.GetThreadPtr();
1246cb640dd8SJim Ingham         sb_error.SetError (thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
12474413758cSJim Ingham     }
12484413758cSJim Ingham 
12494413758cSJim Ingham     return sb_error;
12504413758cSJim Ingham }
12514413758cSJim Ingham 
1252481cef25SGreg Clayton 
1253722a0cdcSGreg Clayton bool
1254722a0cdcSGreg Clayton SBThread::Suspend()
1255722a0cdcSGreg Clayton {
12565160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1257*b2e7d28eSJim Ingham     std::unique_lock<std::recursive_mutex> lock;
1258*b2e7d28eSJim Ingham     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1259*b2e7d28eSJim Ingham 
1260c9858e4dSGreg Clayton     bool result = false;
12611ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1262722a0cdcSGreg Clayton     {
1263c9858e4dSGreg Clayton         Process::StopLocker stop_locker;
1264c9858e4dSGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1265c9858e4dSGreg Clayton         {
12661ac04c30SGreg Clayton             exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended);
1267c9858e4dSGreg Clayton             result = true;
1268722a0cdcSGreg Clayton         }
1269c9858e4dSGreg Clayton         else
1270c9858e4dSGreg Clayton         {
1271c9858e4dSGreg Clayton             if (log)
1272324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::Suspend() => error: process is running",
1273324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1274c9858e4dSGreg Clayton         }
1275c9858e4dSGreg Clayton     }
1276c9858e4dSGreg Clayton     if (log)
1277324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::Suspend() => %i",
1278324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), result);
1279c9858e4dSGreg Clayton     return result;
1280722a0cdcSGreg Clayton }
1281722a0cdcSGreg Clayton 
1282722a0cdcSGreg Clayton bool
1283722a0cdcSGreg Clayton SBThread::Resume ()
1284722a0cdcSGreg Clayton {
12855160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1286*b2e7d28eSJim Ingham     std::unique_lock<std::recursive_mutex> lock;
1287*b2e7d28eSJim Ingham     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1288*b2e7d28eSJim Ingham 
1289c9858e4dSGreg Clayton     bool result = false;
12901ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1291722a0cdcSGreg Clayton     {
1292c9858e4dSGreg Clayton         Process::StopLocker stop_locker;
1293c9858e4dSGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1294c9858e4dSGreg Clayton         {
12956c9ed91cSJim Ingham             const bool override_suspend = true;
12966c9ed91cSJim Ingham             exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning, override_suspend);
1297c9858e4dSGreg Clayton             result = true;
1298722a0cdcSGreg Clayton         }
1299c9858e4dSGreg Clayton         else
1300c9858e4dSGreg Clayton         {
1301c9858e4dSGreg Clayton             if (log)
1302324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::Resume() => error: process is running",
1303324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1304c9858e4dSGreg Clayton         }
1305c9858e4dSGreg Clayton     }
1306c9858e4dSGreg Clayton     if (log)
1307324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::Resume() => %i",
1308324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), result);
1309c9858e4dSGreg Clayton     return result;
1310722a0cdcSGreg Clayton }
1311722a0cdcSGreg Clayton 
1312722a0cdcSGreg Clayton bool
1313722a0cdcSGreg Clayton SBThread::IsSuspended()
1314722a0cdcSGreg Clayton {
1315*b2e7d28eSJim Ingham     std::unique_lock<std::recursive_mutex> lock;
1316*b2e7d28eSJim Ingham     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1317*b2e7d28eSJim Ingham 
13181ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
13191ac04c30SGreg Clayton         return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended;
1320722a0cdcSGreg Clayton     return false;
1321722a0cdcSGreg Clayton }
1322722a0cdcSGreg Clayton 
1323a75418dbSAndrew Kaylor bool
1324a75418dbSAndrew Kaylor SBThread::IsStopped()
1325a75418dbSAndrew Kaylor {
1326*b2e7d28eSJim Ingham     std::unique_lock<std::recursive_mutex> lock;
1327*b2e7d28eSJim Ingham     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1328*b2e7d28eSJim Ingham 
1329a75418dbSAndrew Kaylor     if (exe_ctx.HasThreadScope())
1330a75418dbSAndrew Kaylor         return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1331a75418dbSAndrew Kaylor     return false;
1332a75418dbSAndrew Kaylor }
1333a75418dbSAndrew Kaylor 
133430fdc8d8SChris Lattner SBProcess
133530fdc8d8SChris Lattner SBThread::GetProcess ()
133630fdc8d8SChris Lattner {
1337b9556accSGreg Clayton     SBProcess sb_process;
1338*b2e7d28eSJim Ingham     std::unique_lock<std::recursive_mutex> lock;
1339*b2e7d28eSJim Ingham     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1340*b2e7d28eSJim Ingham 
13411ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
134230fdc8d8SChris Lattner     {
134330fdc8d8SChris Lattner         // Have to go up to the target so we can get a shared pointer to our process...
13441ac04c30SGreg Clayton         sb_process.SetSP (exe_ctx.GetProcessSP());
134530fdc8d8SChris Lattner     }
1346ceb6b139SCaroline Tice 
13475160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1348ceb6b139SCaroline Tice     if (log)
1349ceb6b139SCaroline Tice     {
1350481cef25SGreg Clayton         SBStream frame_desc_strm;
1351b9556accSGreg Clayton         sb_process.GetDescription (frame_desc_strm);
1352324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s",
1353324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1354324a1036SSaleem Abdulrasool                      static_cast<void*>(sb_process.GetSP().get()),
1355324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
1356ceb6b139SCaroline Tice     }
1357ceb6b139SCaroline Tice 
1358b9556accSGreg Clayton     return sb_process;
135930fdc8d8SChris Lattner }
136030fdc8d8SChris Lattner 
136130fdc8d8SChris Lattner uint32_t
136230fdc8d8SChris Lattner SBThread::GetNumFrames ()
136330fdc8d8SChris Lattner {
13645160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1365ceb6b139SCaroline Tice 
1366ceb6b139SCaroline Tice     uint32_t num_frames = 0;
1367bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
1368bb19a13cSSaleem Abdulrasool     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
13694fc6cb9cSJim Ingham 
13701ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1371af67cecdSGreg Clayton     {
13727fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
13737fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
13747fdf9ef1SGreg Clayton         {
13751ac04c30SGreg Clayton             num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1376af67cecdSGreg Clayton         }
1377c9858e4dSGreg Clayton         else
1378c9858e4dSGreg Clayton         {
1379c9858e4dSGreg Clayton             if (log)
1380324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running",
1381324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1382c9858e4dSGreg Clayton         }
13837fdf9ef1SGreg Clayton     }
1384ceb6b139SCaroline Tice 
1385ceb6b139SCaroline Tice     if (log)
1386324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetNumFrames () => %u",
1387324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), num_frames);
1388ceb6b139SCaroline Tice 
1389ceb6b139SCaroline Tice     return num_frames;
139030fdc8d8SChris Lattner }
139130fdc8d8SChris Lattner 
139230fdc8d8SChris Lattner SBFrame
139330fdc8d8SChris Lattner SBThread::GetFrameAtIndex (uint32_t idx)
139430fdc8d8SChris Lattner {
13955160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1396ceb6b139SCaroline Tice 
139730fdc8d8SChris Lattner     SBFrame sb_frame;
1398b57e4a1bSJason Molenda     StackFrameSP frame_sp;
1399bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
1400bb19a13cSSaleem Abdulrasool     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
14014fc6cb9cSJim Ingham 
14021ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1403af67cecdSGreg Clayton     {
14047fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
14057fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
14067fdf9ef1SGreg Clayton         {
14071ac04c30SGreg Clayton             frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx);
1408b9556accSGreg Clayton             sb_frame.SetFrameSP (frame_sp);
1409af67cecdSGreg Clayton         }
1410c9858e4dSGreg Clayton         else
1411c9858e4dSGreg Clayton         {
1412c9858e4dSGreg Clayton             if (log)
1413324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running",
1414324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1415c9858e4dSGreg Clayton         }
14167fdf9ef1SGreg Clayton     }
1417ceb6b139SCaroline Tice 
1418ceb6b139SCaroline Tice     if (log)
1419ceb6b139SCaroline Tice     {
1420481cef25SGreg Clayton         SBStream frame_desc_strm;
1421481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
14224838131bSGreg Clayton         log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
1423324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), idx,
1424324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
1425324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
1426ceb6b139SCaroline Tice     }
1427ceb6b139SCaroline Tice 
142830fdc8d8SChris Lattner     return sb_frame;
142930fdc8d8SChris Lattner }
143030fdc8d8SChris Lattner 
1431f028a1fbSGreg Clayton lldb::SBFrame
1432f028a1fbSGreg Clayton SBThread::GetSelectedFrame ()
1433f028a1fbSGreg Clayton {
14345160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1435f028a1fbSGreg Clayton 
1436f028a1fbSGreg Clayton     SBFrame sb_frame;
1437b57e4a1bSJason Molenda     StackFrameSP frame_sp;
1438bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
1439bb19a13cSSaleem Abdulrasool     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
14404fc6cb9cSJim Ingham 
14411ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1442af67cecdSGreg Clayton     {
14437fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
14447fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
14457fdf9ef1SGreg Clayton         {
14461ac04c30SGreg Clayton             frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame ();
1447b9556accSGreg Clayton             sb_frame.SetFrameSP (frame_sp);
1448af67cecdSGreg Clayton         }
1449c9858e4dSGreg Clayton         else
1450c9858e4dSGreg Clayton         {
1451c9858e4dSGreg Clayton             if (log)
1452324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running",
1453324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1454c9858e4dSGreg Clayton         }
14557fdf9ef1SGreg Clayton     }
1456f028a1fbSGreg Clayton 
1457f028a1fbSGreg Clayton     if (log)
1458f028a1fbSGreg Clayton     {
1459481cef25SGreg Clayton         SBStream frame_desc_strm;
1460481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
1461f028a1fbSGreg Clayton         log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
1462324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1463324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
1464324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
1465f028a1fbSGreg Clayton     }
1466f028a1fbSGreg Clayton 
1467f028a1fbSGreg Clayton     return sb_frame;
1468f028a1fbSGreg Clayton }
1469f028a1fbSGreg Clayton 
1470f028a1fbSGreg Clayton lldb::SBFrame
1471f028a1fbSGreg Clayton SBThread::SetSelectedFrame (uint32_t idx)
1472f028a1fbSGreg Clayton {
14735160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1474f028a1fbSGreg Clayton 
1475f028a1fbSGreg Clayton     SBFrame sb_frame;
1476b57e4a1bSJason Molenda     StackFrameSP frame_sp;
1477bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
1478bb19a13cSSaleem Abdulrasool     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
14794fc6cb9cSJim Ingham 
14801ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1481f028a1fbSGreg Clayton     {
14827fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
14837fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
14847fdf9ef1SGreg Clayton         {
14851ac04c30SGreg Clayton             Thread *thread = exe_ctx.GetThreadPtr();
14861ac04c30SGreg Clayton             frame_sp = thread->GetStackFrameAtIndex (idx);
1487f028a1fbSGreg Clayton             if (frame_sp)
1488f028a1fbSGreg Clayton             {
14891ac04c30SGreg Clayton                 thread->SetSelectedFrame (frame_sp.get());
1490b9556accSGreg Clayton                 sb_frame.SetFrameSP (frame_sp);
1491f028a1fbSGreg Clayton             }
1492f028a1fbSGreg Clayton         }
1493c9858e4dSGreg Clayton         else
1494c9858e4dSGreg Clayton         {
1495c9858e4dSGreg Clayton             if (log)
1496324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running",
1497324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1498c9858e4dSGreg Clayton         }
14997fdf9ef1SGreg Clayton     }
1500f028a1fbSGreg Clayton 
1501f028a1fbSGreg Clayton     if (log)
1502f028a1fbSGreg Clayton     {
1503481cef25SGreg Clayton         SBStream frame_desc_strm;
1504481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
1505f028a1fbSGreg Clayton         log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
1506324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), idx,
1507324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
1508324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
1509f028a1fbSGreg Clayton     }
1510f028a1fbSGreg Clayton     return sb_frame;
1511f028a1fbSGreg Clayton }
1512f028a1fbSGreg Clayton 
15134f465cffSJim Ingham bool
15144f465cffSJim Ingham SBThread::EventIsThreadEvent (const SBEvent &event)
15154f465cffSJim Ingham {
15164f465cffSJim Ingham     return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL;
15174f465cffSJim Ingham }
15184f465cffSJim Ingham 
15194f465cffSJim Ingham SBFrame
15204f465cffSJim Ingham SBThread::GetStackFrameFromEvent (const SBEvent &event)
15214f465cffSJim Ingham {
15224f465cffSJim Ingham     return Thread::ThreadEventData::GetStackFrameFromEvent (event.get());
15234f465cffSJim Ingham 
15244f465cffSJim Ingham }
15254f465cffSJim Ingham 
15264f465cffSJim Ingham SBThread
15274f465cffSJim Ingham SBThread::GetThreadFromEvent (const SBEvent &event)
15284f465cffSJim Ingham {
15294f465cffSJim Ingham     return Thread::ThreadEventData::GetThreadFromEvent (event.get());
15304f465cffSJim Ingham }
1531f028a1fbSGreg Clayton 
153230fdc8d8SChris Lattner bool
153330fdc8d8SChris Lattner SBThread::operator == (const SBThread &rhs) const
153430fdc8d8SChris Lattner {
15357fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get();
153630fdc8d8SChris Lattner }
153730fdc8d8SChris Lattner 
153830fdc8d8SChris Lattner bool
153930fdc8d8SChris Lattner SBThread::operator != (const SBThread &rhs) const
154030fdc8d8SChris Lattner {
15417fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get();
154230fdc8d8SChris Lattner }
1543dde9cff3SCaroline Tice 
1544dde9cff3SCaroline Tice bool
15454f465cffSJim Ingham SBThread::GetStatus (SBStream &status) const
15464f465cffSJim Ingham {
15474f465cffSJim Ingham     Stream &strm = status.ref();
15484f465cffSJim Ingham 
1549*b2e7d28eSJim Ingham     std::unique_lock<std::recursive_mutex> lock;
1550*b2e7d28eSJim Ingham     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1551*b2e7d28eSJim Ingham 
15524f465cffSJim Ingham     if (exe_ctx.HasThreadScope())
15534f465cffSJim Ingham     {
15544f465cffSJim Ingham         exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1);
15554f465cffSJim Ingham     }
15564f465cffSJim Ingham     else
15574f465cffSJim Ingham         strm.PutCString ("No status");
15584f465cffSJim Ingham 
15594f465cffSJim Ingham     return true;
15604f465cffSJim Ingham }
15614f465cffSJim Ingham 
15624f465cffSJim Ingham bool
1563ceb6b139SCaroline Tice SBThread::GetDescription (SBStream &description) const
1564ceb6b139SCaroline Tice {
1565da7bc7d0SGreg Clayton     Stream &strm = description.ref();
1566da7bc7d0SGreg Clayton 
1567*b2e7d28eSJim Ingham     std::unique_lock<std::recursive_mutex> lock;
1568*b2e7d28eSJim Ingham     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1569*b2e7d28eSJim Ingham 
15701ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1571ceb6b139SCaroline Tice     {
1572603985fcSJim Ingham         exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm, LLDB_INVALID_THREAD_ID);
1573603985fcSJim Ingham         //strm.Printf("SBThread: tid = 0x%4.4" PRIx64, exe_ctx.GetThreadPtr()->GetID());
1574ceb6b139SCaroline Tice     }
1575ceb6b139SCaroline Tice     else
1576da7bc7d0SGreg Clayton         strm.PutCString ("No value");
1577ceb6b139SCaroline Tice 
1578ceb6b139SCaroline Tice     return true;
1579ceb6b139SCaroline Tice }
15805dd4916fSJason Molenda 
15815dd4916fSJason Molenda SBThread
1582008c45f1SJason Molenda SBThread::GetExtendedBacktraceThread (const char *type)
15835dd4916fSJason Molenda {
15845dd4916fSJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1585bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
1586bb19a13cSSaleem Abdulrasool     ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
15875dd4916fSJason Molenda     SBThread sb_origin_thread;
15885dd4916fSJason Molenda 
15895dd4916fSJason Molenda     if (exe_ctx.HasThreadScope())
15905dd4916fSJason Molenda     {
15915dd4916fSJason Molenda         Process::StopLocker stop_locker;
15925dd4916fSJason Molenda         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
15935dd4916fSJason Molenda         {
15947a2f7904SJason Molenda             ThreadSP real_thread(exe_ctx.GetThreadSP());
15955dd4916fSJason Molenda             if (real_thread)
15965dd4916fSJason Molenda             {
15975dd4916fSJason Molenda                 ConstString type_const (type);
15987a2f7904SJason Molenda                 Process *process = exe_ctx.GetProcessPtr();
15997a2f7904SJason Molenda                 if (process)
16007a2f7904SJason Molenda                 {
16017a2f7904SJason Molenda                     SystemRuntime *runtime = process->GetSystemRuntime();
16025dd4916fSJason Molenda                     if (runtime)
16035dd4916fSJason Molenda                     {
1604008c45f1SJason Molenda                         ThreadSP new_thread_sp (runtime->GetExtendedBacktraceThread (real_thread, type_const));
1605a6e9130dSJason Molenda                         if (new_thread_sp)
1606a6e9130dSJason Molenda                         {
16077a2f7904SJason Molenda                             // Save this in the Process' ExtendedThreadList so a strong pointer retains the
16087a2f7904SJason Molenda                             // object.
16097a2f7904SJason Molenda                             process->GetExtendedThreadList().AddThread (new_thread_sp);
16107a2f7904SJason Molenda                             sb_origin_thread.SetThread (new_thread_sp);
1611a6e9130dSJason Molenda                             if (log)
1612a6e9130dSJason Molenda                             {
1613a6e9130dSJason Molenda                                 const char *queue_name = new_thread_sp->GetQueueName();
1614a6e9130dSJason Molenda                                 if (queue_name == NULL)
1615a6e9130dSJason Molenda                                     queue_name = "";
16162bdbfd50SJim Ingham                                 log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => new extended Thread "
16172bdbfd50SJim Ingham                                              "created (%p) with queue_id 0x%" PRIx64 " queue name '%s'",
1618324a1036SSaleem Abdulrasool                                              static_cast<void*>(exe_ctx.GetThreadPtr()),
1619324a1036SSaleem Abdulrasool                                              static_cast<void*>(new_thread_sp.get()),
1620324a1036SSaleem Abdulrasool                                              new_thread_sp->GetQueueID(),
1621324a1036SSaleem Abdulrasool                                              queue_name);
1622a6e9130dSJason Molenda                             }
1623a6e9130dSJason Molenda                         }
16247a2f7904SJason Molenda                     }
16255dd4916fSJason Molenda                 }
16265dd4916fSJason Molenda             }
16275dd4916fSJason Molenda         }
16285dd4916fSJason Molenda         else
16295dd4916fSJason Molenda         {
16305dd4916fSJason Molenda             if (log)
1631324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => error: process is running",
1632324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
16335dd4916fSJason Molenda         }
16345dd4916fSJason Molenda     }
16355dd4916fSJason Molenda 
1636ac605f4aSJason Molenda     if (log && sb_origin_thread.IsValid() == false)
1637324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a Valid thread",
1638324a1036SSaleem Abdulrasool                     static_cast<void*>(exe_ctx.GetThreadPtr()));
16395dd4916fSJason Molenda     return sb_origin_thread;
16405dd4916fSJason Molenda }
16418ee9cb58SJason Molenda 
16428ee9cb58SJason Molenda uint32_t
16438ee9cb58SJason Molenda SBThread::GetExtendedBacktraceOriginatingIndexID ()
16448ee9cb58SJason Molenda {
16458ee9cb58SJason Molenda     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
16468ee9cb58SJason Molenda     if (thread_sp)
16478ee9cb58SJason Molenda         return thread_sp->GetExtendedBacktraceOriginatingIndexID();
16488ee9cb58SJason Molenda     return LLDB_INVALID_INDEX32;
16498ee9cb58SJason Molenda }
1650b4892cd2SJason Molenda 
1651b4892cd2SJason Molenda bool
1652b4892cd2SJason Molenda SBThread::SafeToCallFunctions ()
1653b4892cd2SJason Molenda {
1654b4892cd2SJason Molenda     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1655b4892cd2SJason Molenda     if (thread_sp)
1656b4892cd2SJason Molenda         return thread_sp->SafeToCallFunctions();
1657b4892cd2SJason Molenda     return true;
1658b4892cd2SJason Molenda }
16592bdbfd50SJim Ingham 
16602bdbfd50SJim Ingham lldb_private::Thread *
16612bdbfd50SJim Ingham SBThread::operator->()
16622bdbfd50SJim Ingham {
16632bdbfd50SJim Ingham     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
16642bdbfd50SJim Ingham     if (thread_sp)
16652bdbfd50SJim Ingham         return thread_sp.get();
16662bdbfd50SJim Ingham     else
16672bdbfd50SJim Ingham         return NULL;
16682bdbfd50SJim Ingham }
16692bdbfd50SJim Ingham 
16702bdbfd50SJim Ingham lldb_private::Thread *
16712bdbfd50SJim Ingham SBThread::get()
16722bdbfd50SJim Ingham {
16732bdbfd50SJim Ingham     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
16742bdbfd50SJim Ingham     if (thread_sp)
16752bdbfd50SJim Ingham         return thread_sp.get();
16762bdbfd50SJim Ingham     else
16772bdbfd50SJim Ingham         return NULL;
16782bdbfd50SJim Ingham }
16792bdbfd50SJim Ingham 
1680