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"
37*6a831436SKuba Brecka #include "Plugins/Process/Utility/HistoryThread.h"
3830fdc8d8SChris Lattner 
394c5de699SEli Friedman #include "lldb/API/SBAddress.h"
404c5de699SEli Friedman #include "lldb/API/SBDebugger.h"
414f465cffSJim Ingham #include "lldb/API/SBEvent.h"
4273ca05a2SJim Ingham #include "lldb/API/SBFrame.h"
434c5de699SEli Friedman #include "lldb/API/SBProcess.h"
44*6a831436SKuba Brecka #include "lldb/API/SBThreadCollection.h"
452bdbfd50SJim Ingham #include "lldb/API/SBThreadPlan.h"
4673ca05a2SJim Ingham #include "lldb/API/SBValue.h"
4730fdc8d8SChris Lattner 
4830fdc8d8SChris Lattner using namespace lldb;
4930fdc8d8SChris Lattner using namespace lldb_private;
5030fdc8d8SChris Lattner 
514f465cffSJim Ingham const char *
524f465cffSJim Ingham SBThread::GetBroadcasterClassName ()
534f465cffSJim Ingham {
544f465cffSJim Ingham     return Thread::GetStaticBroadcasterClass().AsCString();
554f465cffSJim Ingham }
564f465cffSJim Ingham 
57cfd1acedSGreg Clayton //----------------------------------------------------------------------
58cfd1acedSGreg Clayton // Constructors
59cfd1acedSGreg Clayton //----------------------------------------------------------------------
6030fdc8d8SChris Lattner SBThread::SBThread () :
617fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef())
6230fdc8d8SChris Lattner {
6330fdc8d8SChris Lattner }
6430fdc8d8SChris Lattner 
6530fdc8d8SChris Lattner SBThread::SBThread (const ThreadSP& lldb_object_sp) :
667fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef(lldb_object_sp))
6730fdc8d8SChris Lattner {
6830fdc8d8SChris Lattner }
6930fdc8d8SChris Lattner 
7092ef5735SGreg Clayton SBThread::SBThread (const SBThread &rhs) :
717fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef(*rhs.m_opaque_sp))
7230fdc8d8SChris Lattner {
737fdf9ef1SGreg Clayton 
7430fdc8d8SChris Lattner }
7530fdc8d8SChris Lattner 
7630fdc8d8SChris Lattner //----------------------------------------------------------------------
77cfd1acedSGreg Clayton // Assignment operator
78cfd1acedSGreg Clayton //----------------------------------------------------------------------
79cfd1acedSGreg Clayton 
80cfd1acedSGreg Clayton const lldb::SBThread &
81cfd1acedSGreg Clayton SBThread::operator = (const SBThread &rhs)
82cfd1acedSGreg Clayton {
83cfd1acedSGreg Clayton     if (this != &rhs)
847fdf9ef1SGreg Clayton         *m_opaque_sp = *rhs.m_opaque_sp;
85cfd1acedSGreg Clayton     return *this;
86cfd1acedSGreg Clayton }
87cfd1acedSGreg Clayton 
88cfd1acedSGreg Clayton //----------------------------------------------------------------------
8930fdc8d8SChris Lattner // Destructor
9030fdc8d8SChris Lattner //----------------------------------------------------------------------
9130fdc8d8SChris Lattner SBThread::~SBThread()
9230fdc8d8SChris Lattner {
9330fdc8d8SChris Lattner }
9430fdc8d8SChris Lattner 
95b9ffa98cSJason Molenda lldb::SBQueue
96b9ffa98cSJason Molenda SBThread::GetQueue () const
97b9ffa98cSJason Molenda {
98b9ffa98cSJason Molenda     SBQueue sb_queue;
99b9ffa98cSJason Molenda     QueueSP queue_sp;
100b9ffa98cSJason Molenda     Mutex::Locker api_locker;
101b9ffa98cSJason Molenda     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
102b9ffa98cSJason Molenda 
103b9ffa98cSJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
104b9ffa98cSJason Molenda     if (exe_ctx.HasThreadScope())
105b9ffa98cSJason Molenda     {
106b9ffa98cSJason Molenda         Process::StopLocker stop_locker;
107b9ffa98cSJason Molenda         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
108b9ffa98cSJason Molenda         {
109b9ffa98cSJason Molenda             queue_sp = exe_ctx.GetThreadPtr()->GetQueue();
110b9ffa98cSJason Molenda             if (queue_sp)
111b9ffa98cSJason Molenda             {
112b9ffa98cSJason Molenda                 sb_queue.SetQueue (queue_sp);
113b9ffa98cSJason Molenda             }
114b9ffa98cSJason Molenda         }
115b9ffa98cSJason Molenda         else
116b9ffa98cSJason Molenda         {
117b9ffa98cSJason Molenda             if (log)
118358cf1eaSGreg Clayton                 log->Printf ("SBThread(%p)::GetQueue() => error: process is running",
119b9ffa98cSJason Molenda                              static_cast<void*>(exe_ctx.GetThreadPtr()));
120b9ffa98cSJason Molenda         }
121b9ffa98cSJason Molenda     }
122b9ffa98cSJason Molenda 
123b9ffa98cSJason Molenda     if (log)
124358cf1eaSGreg Clayton         log->Printf ("SBThread(%p)::GetQueue () => SBQueue(%p)",
125b9ffa98cSJason Molenda                      static_cast<void*>(exe_ctx.GetThreadPtr()), static_cast<void*>(queue_sp.get()));
126b9ffa98cSJason Molenda 
127b9ffa98cSJason Molenda     return sb_queue;
128b9ffa98cSJason Molenda }
129b9ffa98cSJason Molenda 
130b9ffa98cSJason Molenda 
13130fdc8d8SChris Lattner bool
13230fdc8d8SChris Lattner SBThread::IsValid() const
13330fdc8d8SChris Lattner {
1347fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() != NULL;
13530fdc8d8SChris Lattner }
13630fdc8d8SChris Lattner 
13748e42549SGreg Clayton void
13848e42549SGreg Clayton SBThread::Clear ()
13948e42549SGreg Clayton {
1407fdf9ef1SGreg Clayton     m_opaque_sp->Clear();
14148e42549SGreg Clayton }
14248e42549SGreg Clayton 
14348e42549SGreg Clayton 
14430fdc8d8SChris Lattner StopReason
14530fdc8d8SChris Lattner SBThread::GetStopReason()
14630fdc8d8SChris Lattner {
1475160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
148ceb6b139SCaroline Tice 
149ceb6b139SCaroline Tice     StopReason reason = eStopReasonInvalid;
1504fc6cb9cSJim Ingham     Mutex::Locker api_locker;
1514fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1524fc6cb9cSJim Ingham 
1531ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
15430fdc8d8SChris Lattner     {
1557fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
1567fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1577fdf9ef1SGreg Clayton         {
15897d5cf05SGreg Clayton             return exe_ctx.GetThreadPtr()->GetStopReason();
15930fdc8d8SChris Lattner         }
160c9858e4dSGreg Clayton         else
161c9858e4dSGreg Clayton         {
162c9858e4dSGreg Clayton             if (log)
163324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopReason() => error: process is running",
164324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
165c9858e4dSGreg Clayton         }
1667fdf9ef1SGreg Clayton     }
167ceb6b139SCaroline Tice 
168ceb6b139SCaroline Tice     if (log)
169324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetStopReason () => %s",
170324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
171750cd175SCaroline Tice                      Thread::StopReasonAsCString (reason));
172ceb6b139SCaroline Tice 
173ceb6b139SCaroline Tice     return reason;
17430fdc8d8SChris Lattner }
17530fdc8d8SChris Lattner 
17630fdc8d8SChris Lattner size_t
1774e78f606SGreg Clayton SBThread::GetStopReasonDataCount ()
1784e78f606SGreg Clayton {
1794fc6cb9cSJim Ingham     Mutex::Locker api_locker;
1804fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1814fc6cb9cSJim Ingham 
1821ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1834e78f606SGreg Clayton     {
1847fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
1857fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1867fdf9ef1SGreg Clayton         {
1871ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
1884e78f606SGreg Clayton             if (stop_info_sp)
1894e78f606SGreg Clayton             {
1904e78f606SGreg Clayton                 StopReason reason = stop_info_sp->GetStopReason();
1914e78f606SGreg Clayton                 switch (reason)
1924e78f606SGreg Clayton                 {
1934e78f606SGreg Clayton                 case eStopReasonInvalid:
1944e78f606SGreg Clayton                 case eStopReasonNone:
1954e78f606SGreg Clayton                 case eStopReasonTrace:
19690ba8115SGreg Clayton                 case eStopReasonExec:
1974e78f606SGreg Clayton                 case eStopReasonPlanComplete:
198f85defaeSAndrew Kaylor                 case eStopReasonThreadExiting:
199afdf842bSKuba Brecka                 case eStopReasonInstrumentation:
2004e78f606SGreg Clayton                     // There is no data for these stop reasons.
2014e78f606SGreg Clayton                     return 0;
2024e78f606SGreg Clayton 
2034e78f606SGreg Clayton                 case eStopReasonBreakpoint:
2044e78f606SGreg Clayton                     {
2054e78f606SGreg Clayton                         break_id_t site_id = stop_info_sp->GetValue();
2061ac04c30SGreg Clayton                         lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
2074e78f606SGreg Clayton                         if (bp_site_sp)
2084e78f606SGreg Clayton                             return bp_site_sp->GetNumberOfOwners () * 2;
2094e78f606SGreg Clayton                         else
2104e78f606SGreg Clayton                             return 0; // Breakpoint must have cleared itself...
2114e78f606SGreg Clayton                     }
2124e78f606SGreg Clayton                     break;
2134e78f606SGreg Clayton 
2144e78f606SGreg Clayton                 case eStopReasonWatchpoint:
215290fa41bSJohnny Chen                     return 1;
2164e78f606SGreg Clayton 
2174e78f606SGreg Clayton                 case eStopReasonSignal:
2184e78f606SGreg Clayton                     return 1;
2194e78f606SGreg Clayton 
2204e78f606SGreg Clayton                 case eStopReasonException:
2214e78f606SGreg Clayton                     return 1;
2224e78f606SGreg Clayton                 }
2234e78f606SGreg Clayton             }
2244e78f606SGreg Clayton         }
225c9858e4dSGreg Clayton         else
226c9858e4dSGreg Clayton         {
2275160ce5cSGreg Clayton             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
228c9858e4dSGreg Clayton             if (log)
229324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopReasonDataCount() => error: process is running",
230324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
231c9858e4dSGreg Clayton         }
2327fdf9ef1SGreg Clayton     }
2334e78f606SGreg Clayton     return 0;
2344e78f606SGreg Clayton }
2354e78f606SGreg Clayton 
2364e78f606SGreg Clayton uint64_t
2374e78f606SGreg Clayton SBThread::GetStopReasonDataAtIndex (uint32_t idx)
2384e78f606SGreg Clayton {
2394fc6cb9cSJim Ingham     Mutex::Locker api_locker;
2404fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
2414fc6cb9cSJim Ingham 
2421ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
2434e78f606SGreg Clayton     {
2447fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
2457fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
2467fdf9ef1SGreg Clayton         {
2471ac04c30SGreg Clayton             Thread *thread = exe_ctx.GetThreadPtr();
2481ac04c30SGreg Clayton             StopInfoSP stop_info_sp = thread->GetStopInfo ();
2494e78f606SGreg Clayton             if (stop_info_sp)
2504e78f606SGreg Clayton             {
2514e78f606SGreg Clayton                 StopReason reason = stop_info_sp->GetStopReason();
2524e78f606SGreg Clayton                 switch (reason)
2534e78f606SGreg Clayton                 {
2544e78f606SGreg Clayton                 case eStopReasonInvalid:
2554e78f606SGreg Clayton                 case eStopReasonNone:
2564e78f606SGreg Clayton                 case eStopReasonTrace:
25790ba8115SGreg Clayton                 case eStopReasonExec:
2584e78f606SGreg Clayton                 case eStopReasonPlanComplete:
259f85defaeSAndrew Kaylor                 case eStopReasonThreadExiting:
260afdf842bSKuba Brecka                 case eStopReasonInstrumentation:
2614e78f606SGreg Clayton                     // There is no data for these stop reasons.
2624e78f606SGreg Clayton                     return 0;
2634e78f606SGreg Clayton 
2644e78f606SGreg Clayton                 case eStopReasonBreakpoint:
2654e78f606SGreg Clayton                     {
2664e78f606SGreg Clayton                         break_id_t site_id = stop_info_sp->GetValue();
2671ac04c30SGreg Clayton                         lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
2684e78f606SGreg Clayton                         if (bp_site_sp)
2694e78f606SGreg Clayton                         {
2704e78f606SGreg Clayton                             uint32_t bp_index = idx / 2;
2714e78f606SGreg Clayton                             BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index));
2724e78f606SGreg Clayton                             if (bp_loc_sp)
2734e78f606SGreg Clayton                             {
2748334e14eSGreg Clayton                                 if (idx & 1)
2754e78f606SGreg Clayton                                 {
2764e78f606SGreg Clayton                                     // Odd idx, return the breakpoint location ID
2774e78f606SGreg Clayton                                     return bp_loc_sp->GetID();
2784e78f606SGreg Clayton                                 }
2794e78f606SGreg Clayton                                 else
2804e78f606SGreg Clayton                                 {
2814e78f606SGreg Clayton                                     // Even idx, return the breakpoint ID
2824e78f606SGreg Clayton                                     return bp_loc_sp->GetBreakpoint().GetID();
2834e78f606SGreg Clayton                                 }
2844e78f606SGreg Clayton                             }
2854e78f606SGreg Clayton                         }
2864e78f606SGreg Clayton                         return LLDB_INVALID_BREAK_ID;
2874e78f606SGreg Clayton                     }
2884e78f606SGreg Clayton                     break;
2894e78f606SGreg Clayton 
2904e78f606SGreg Clayton                 case eStopReasonWatchpoint:
291290fa41bSJohnny Chen                     return stop_info_sp->GetValue();
2924e78f606SGreg Clayton 
2934e78f606SGreg Clayton                 case eStopReasonSignal:
2944e78f606SGreg Clayton                     return stop_info_sp->GetValue();
2954e78f606SGreg Clayton 
2964e78f606SGreg Clayton                 case eStopReasonException:
2974e78f606SGreg Clayton                     return stop_info_sp->GetValue();
2984e78f606SGreg Clayton                 }
2994e78f606SGreg Clayton             }
3004e78f606SGreg Clayton         }
301c9858e4dSGreg Clayton         else
302c9858e4dSGreg Clayton         {
3035160ce5cSGreg Clayton             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
304c9858e4dSGreg Clayton             if (log)
305324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopReasonDataAtIndex() => error: process is running",
306324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
307c9858e4dSGreg Clayton         }
3087fdf9ef1SGreg Clayton     }
3094e78f606SGreg Clayton     return 0;
3104e78f606SGreg Clayton }
3114e78f606SGreg Clayton 
312afdf842bSKuba Brecka bool
313afdf842bSKuba Brecka SBThread::GetStopReasonExtendedInfoAsJSON (lldb::SBStream &stream)
314afdf842bSKuba Brecka {
315afdf842bSKuba Brecka     Stream &strm = stream.ref();
316afdf842bSKuba Brecka 
317afdf842bSKuba Brecka     ExecutionContext exe_ctx (m_opaque_sp.get());
318afdf842bSKuba Brecka     if (! exe_ctx.HasThreadScope())
319afdf842bSKuba Brecka         return false;
320afdf842bSKuba Brecka 
321afdf842bSKuba Brecka 
322afdf842bSKuba Brecka     StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
323afdf842bSKuba Brecka     StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
324afdf842bSKuba Brecka     if (! info)
325afdf842bSKuba Brecka         return false;
326afdf842bSKuba Brecka 
327afdf842bSKuba Brecka     info->Dump(strm);
328afdf842bSKuba Brecka 
329afdf842bSKuba Brecka     return true;
330afdf842bSKuba Brecka }
331afdf842bSKuba Brecka 
332*6a831436SKuba Brecka static void
333*6a831436SKuba Brecka AddThreadsForPath(std::string path, ThreadCollectionSP threads, ProcessSP process_sp, StructuredData::ObjectSP info)
334*6a831436SKuba Brecka {
335*6a831436SKuba Brecka     info->GetObjectForDotSeparatedPath(path)->GetAsArray()->ForEach([process_sp, threads] (StructuredData::Object *o) -> bool {
336*6a831436SKuba Brecka         std::vector<lldb::addr_t> pcs;
337*6a831436SKuba Brecka         o->GetObjectForDotSeparatedPath("trace")->GetAsArray()->ForEach([&pcs] (StructuredData::Object *pc) -> bool {
338*6a831436SKuba Brecka             pcs.push_back(pc->GetAsInteger()->GetValue());
339*6a831436SKuba Brecka             return true;
340*6a831436SKuba Brecka         });
341*6a831436SKuba Brecka 
342*6a831436SKuba Brecka         tid_t tid = o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue();
343*6a831436SKuba Brecka         uint32_t stop_id = 0;
344*6a831436SKuba Brecka         bool stop_id_is_valid = false;
345*6a831436SKuba Brecka         HistoryThread *history_thread = new HistoryThread(*process_sp, tid, pcs, stop_id, stop_id_is_valid);
346*6a831436SKuba Brecka         ThreadSP new_thread_sp(history_thread);
347*6a831436SKuba Brecka         // Save this in the Process' ExtendedThreadList so a strong pointer retains the object
348*6a831436SKuba Brecka         process_sp->GetExtendedThreadList().AddThread(new_thread_sp);
349*6a831436SKuba Brecka         threads->AddThread(new_thread_sp);
350*6a831436SKuba Brecka 
351*6a831436SKuba Brecka         return true;
352*6a831436SKuba Brecka     });
353*6a831436SKuba Brecka }
354*6a831436SKuba Brecka 
355*6a831436SKuba Brecka SBThreadCollection
356*6a831436SKuba Brecka SBThread::GetStopReasonExtendedBacktraces (InstrumentationRuntimeType type)
357*6a831436SKuba Brecka {
358*6a831436SKuba Brecka     ThreadCollectionSP threads;
359*6a831436SKuba Brecka     threads.reset(new ThreadCollection());
360*6a831436SKuba Brecka 
361*6a831436SKuba Brecka     // We currently only support ThreadSanitizer.
362*6a831436SKuba Brecka     if (type != eInstrumentationRuntimeTypeThreadSanitizer)
363*6a831436SKuba Brecka         return threads;
364*6a831436SKuba Brecka 
365*6a831436SKuba Brecka     ExecutionContext exe_ctx (m_opaque_sp.get());
366*6a831436SKuba Brecka     if (! exe_ctx.HasThreadScope())
367*6a831436SKuba Brecka         return SBThreadCollection(threads);
368*6a831436SKuba Brecka 
369*6a831436SKuba Brecka     ProcessSP process_sp = exe_ctx.GetProcessSP();
370*6a831436SKuba Brecka 
371*6a831436SKuba Brecka     StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
372*6a831436SKuba Brecka     StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
373*6a831436SKuba Brecka     if (! info)
374*6a831436SKuba Brecka         return threads;
375*6a831436SKuba Brecka 
376*6a831436SKuba Brecka     if (info->GetObjectForDotSeparatedPath("instrumentation_class")->GetStringValue() != "ThreadSanitizer")
377*6a831436SKuba Brecka         return threads;
378*6a831436SKuba Brecka 
379*6a831436SKuba Brecka     AddThreadsForPath("stacks", threads, process_sp, info);
380*6a831436SKuba Brecka     AddThreadsForPath("mops", threads, process_sp, info);
381*6a831436SKuba Brecka     AddThreadsForPath("locs", threads, process_sp, info);
382*6a831436SKuba Brecka     AddThreadsForPath("mutexes", threads, process_sp, info);
383*6a831436SKuba Brecka     AddThreadsForPath("threads", threads, process_sp, info);
384*6a831436SKuba Brecka 
385*6a831436SKuba Brecka     return threads;
386*6a831436SKuba Brecka }
387*6a831436SKuba Brecka 
3884e78f606SGreg Clayton size_t
38930fdc8d8SChris Lattner SBThread::GetStopDescription (char *dst, size_t dst_len)
39030fdc8d8SChris Lattner {
3915160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
392ceb6b139SCaroline Tice 
3934fc6cb9cSJim Ingham     Mutex::Locker api_locker;
3944fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
3954fc6cb9cSJim Ingham 
3961ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
39730fdc8d8SChris Lattner     {
3987fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
3997fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
4007fdf9ef1SGreg Clayton         {
4017fdf9ef1SGreg Clayton 
4021ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
403b15bfc75SJim Ingham             if (stop_info_sp)
40430fdc8d8SChris Lattner             {
405b15bfc75SJim Ingham                 const char *stop_desc = stop_info_sp->GetDescription();
40630fdc8d8SChris Lattner                 if (stop_desc)
40730fdc8d8SChris Lattner                 {
408ceb6b139SCaroline Tice                     if (log)
4094838131bSGreg Clayton                         log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
410324a1036SSaleem Abdulrasool                                      static_cast<void*>(exe_ctx.GetThreadPtr()),
411324a1036SSaleem Abdulrasool                                      stop_desc);
41230fdc8d8SChris Lattner                     if (dst)
41330fdc8d8SChris Lattner                         return ::snprintf (dst, dst_len, "%s", stop_desc);
41430fdc8d8SChris Lattner                     else
41530fdc8d8SChris Lattner                     {
41630fdc8d8SChris Lattner                         // NULL dst passed in, return the length needed to contain the description
41730fdc8d8SChris Lattner                         return ::strlen (stop_desc) + 1; // Include the NULL byte for size
41830fdc8d8SChris Lattner                     }
41930fdc8d8SChris Lattner                 }
42030fdc8d8SChris Lattner                 else
42130fdc8d8SChris Lattner                 {
42230fdc8d8SChris Lattner                     size_t stop_desc_len = 0;
423b15bfc75SJim Ingham                     switch (stop_info_sp->GetStopReason())
42430fdc8d8SChris Lattner                     {
42530fdc8d8SChris Lattner                     case eStopReasonTrace:
42630fdc8d8SChris Lattner                     case eStopReasonPlanComplete:
42730fdc8d8SChris Lattner                         {
42830fdc8d8SChris Lattner                             static char trace_desc[] = "step";
42930fdc8d8SChris Lattner                             stop_desc = trace_desc;
43030fdc8d8SChris Lattner                             stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size
43130fdc8d8SChris Lattner                         }
43230fdc8d8SChris Lattner                         break;
43330fdc8d8SChris Lattner 
43430fdc8d8SChris Lattner                     case eStopReasonBreakpoint:
43530fdc8d8SChris Lattner                         {
43630fdc8d8SChris Lattner                             static char bp_desc[] = "breakpoint hit";
43730fdc8d8SChris Lattner                             stop_desc = bp_desc;
43830fdc8d8SChris Lattner                             stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
43930fdc8d8SChris Lattner                         }
44030fdc8d8SChris Lattner                         break;
44130fdc8d8SChris Lattner 
44230fdc8d8SChris Lattner                     case eStopReasonWatchpoint:
44330fdc8d8SChris Lattner                         {
44430fdc8d8SChris Lattner                             static char wp_desc[] = "watchpoint hit";
44530fdc8d8SChris Lattner                             stop_desc = wp_desc;
44630fdc8d8SChris Lattner                             stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
44730fdc8d8SChris Lattner                         }
44830fdc8d8SChris Lattner                         break;
44930fdc8d8SChris Lattner 
45030fdc8d8SChris Lattner                     case eStopReasonSignal:
45130fdc8d8SChris Lattner                         {
45298d0a4b3SChaoren Lin                             stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals()->GetSignalAsCString(stop_info_sp->GetValue());
45330fdc8d8SChris Lattner                             if (stop_desc == NULL || stop_desc[0] == '\0')
45430fdc8d8SChris Lattner                             {
45530fdc8d8SChris Lattner                                 static char signal_desc[] = "signal";
45630fdc8d8SChris Lattner                                 stop_desc = signal_desc;
45730fdc8d8SChris Lattner                                 stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size
45830fdc8d8SChris Lattner                             }
45930fdc8d8SChris Lattner                         }
46030fdc8d8SChris Lattner                         break;
46130fdc8d8SChris Lattner 
46230fdc8d8SChris Lattner                     case eStopReasonException:
46330fdc8d8SChris Lattner                         {
46430fdc8d8SChris Lattner                             char exc_desc[] = "exception";
46530fdc8d8SChris Lattner                             stop_desc = exc_desc;
46630fdc8d8SChris Lattner                             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
46730fdc8d8SChris Lattner                         }
46830fdc8d8SChris Lattner                         break;
469c982c768SGreg Clayton 
47090ba8115SGreg Clayton                     case eStopReasonExec:
47190ba8115SGreg Clayton                         {
47290ba8115SGreg Clayton                             char exc_desc[] = "exec";
47390ba8115SGreg Clayton                             stop_desc = exc_desc;
47490ba8115SGreg Clayton                             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
47590ba8115SGreg Clayton                         }
47690ba8115SGreg Clayton                         break;
47790ba8115SGreg Clayton 
478f85defaeSAndrew Kaylor                     case eStopReasonThreadExiting:
479f85defaeSAndrew Kaylor                         {
480f85defaeSAndrew Kaylor                             char limbo_desc[] = "thread exiting";
481f85defaeSAndrew Kaylor                             stop_desc = limbo_desc;
482f85defaeSAndrew Kaylor                             stop_desc_len = sizeof(limbo_desc);
483f85defaeSAndrew Kaylor                         }
484f85defaeSAndrew Kaylor                         break;
485c982c768SGreg Clayton                     default:
486c982c768SGreg Clayton                         break;
48730fdc8d8SChris Lattner                     }
48830fdc8d8SChris Lattner 
48930fdc8d8SChris Lattner                     if (stop_desc && stop_desc[0])
49030fdc8d8SChris Lattner                     {
491ceb6b139SCaroline Tice                         if (log)
49293aa84e8SGreg Clayton                             log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
493324a1036SSaleem Abdulrasool                                          static_cast<void*>(exe_ctx.GetThreadPtr()),
494324a1036SSaleem Abdulrasool                                          stop_desc);
495ceb6b139SCaroline Tice 
49630fdc8d8SChris Lattner                         if (dst)
49730fdc8d8SChris Lattner                             return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte
49830fdc8d8SChris Lattner 
49930fdc8d8SChris Lattner                         if (stop_desc_len == 0)
50030fdc8d8SChris Lattner                             stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte
50130fdc8d8SChris Lattner 
50230fdc8d8SChris Lattner                         return stop_desc_len;
50330fdc8d8SChris Lattner                     }
50430fdc8d8SChris Lattner                 }
50530fdc8d8SChris Lattner             }
50630fdc8d8SChris Lattner         }
507c9858e4dSGreg Clayton         else
508c9858e4dSGreg Clayton         {
5095160ce5cSGreg Clayton             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
510c9858e4dSGreg Clayton             if (log)
511324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopDescription() => error: process is running",
512324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
513c9858e4dSGreg Clayton         }
5147fdf9ef1SGreg Clayton     }
51530fdc8d8SChris Lattner     if (dst)
51630fdc8d8SChris Lattner         *dst = 0;
51730fdc8d8SChris Lattner     return 0;
51830fdc8d8SChris Lattner }
51930fdc8d8SChris Lattner 
52073ca05a2SJim Ingham SBValue
52173ca05a2SJim Ingham SBThread::GetStopReturnValue ()
52273ca05a2SJim Ingham {
5235160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
52473ca05a2SJim Ingham     ValueObjectSP return_valobj_sp;
5254fc6cb9cSJim Ingham     Mutex::Locker api_locker;
5264fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
5274fc6cb9cSJim Ingham 
5281ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
52973ca05a2SJim Ingham     {
5307fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
5317fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
5327fdf9ef1SGreg Clayton         {
5331ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
53473ca05a2SJim Ingham             if (stop_info_sp)
53573ca05a2SJim Ingham             {
53673ca05a2SJim Ingham                 return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
53773ca05a2SJim Ingham             }
53873ca05a2SJim Ingham         }
539c9858e4dSGreg Clayton         else
540c9858e4dSGreg Clayton         {
541c9858e4dSGreg Clayton             if (log)
542324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopReturnValue() => error: process is running",
543324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
544c9858e4dSGreg Clayton         }
5457fdf9ef1SGreg Clayton     }
54673ca05a2SJim Ingham 
54773ca05a2SJim Ingham     if (log)
548324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetStopReturnValue () => %s",
549324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
55073ca05a2SJim Ingham                      return_valobj_sp.get()
55173ca05a2SJim Ingham                         ? return_valobj_sp->GetValueAsCString()
55273ca05a2SJim Ingham                         : "<no return value>");
55373ca05a2SJim Ingham 
55473ca05a2SJim Ingham     return SBValue (return_valobj_sp);
55573ca05a2SJim Ingham }
55673ca05a2SJim Ingham 
55730fdc8d8SChris Lattner void
55830fdc8d8SChris Lattner SBThread::SetThread (const ThreadSP& lldb_object_sp)
55930fdc8d8SChris Lattner {
5607fdf9ef1SGreg Clayton     m_opaque_sp->SetThreadSP (lldb_object_sp);
56130fdc8d8SChris Lattner }
56230fdc8d8SChris Lattner 
56330fdc8d8SChris Lattner lldb::tid_t
56430fdc8d8SChris Lattner SBThread::GetThreadID () const
56530fdc8d8SChris Lattner {
5667fdf9ef1SGreg Clayton     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
56717a6ad05SGreg Clayton     if (thread_sp)
5681ac04c30SGreg Clayton         return thread_sp->GetID();
5691ac04c30SGreg Clayton     return LLDB_INVALID_THREAD_ID;
57030fdc8d8SChris Lattner }
57130fdc8d8SChris Lattner 
57230fdc8d8SChris Lattner uint32_t
57330fdc8d8SChris Lattner SBThread::GetIndexID () const
57430fdc8d8SChris Lattner {
5757fdf9ef1SGreg Clayton     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
57617a6ad05SGreg Clayton     if (thread_sp)
57717a6ad05SGreg Clayton         return thread_sp->GetIndexID();
57830fdc8d8SChris Lattner     return LLDB_INVALID_INDEX32;
57930fdc8d8SChris Lattner }
5801ac04c30SGreg Clayton 
58130fdc8d8SChris Lattner const char *
58230fdc8d8SChris Lattner SBThread::GetName () const
58330fdc8d8SChris Lattner {
5845160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
5854838131bSGreg Clayton     const char *name = NULL;
5864fc6cb9cSJim Ingham     Mutex::Locker api_locker;
5874fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
5884fc6cb9cSJim Ingham 
5891ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
590af67cecdSGreg Clayton     {
5917fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
5927fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
5937fdf9ef1SGreg Clayton         {
5941ac04c30SGreg Clayton             name = exe_ctx.GetThreadPtr()->GetName();
595af67cecdSGreg Clayton         }
596c9858e4dSGreg Clayton         else
597c9858e4dSGreg Clayton         {
598c9858e4dSGreg Clayton             if (log)
599324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetName() => error: process is running",
600324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
601c9858e4dSGreg Clayton         }
6027fdf9ef1SGreg Clayton     }
603ceb6b139SCaroline Tice 
604ceb6b139SCaroline Tice     if (log)
605324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetName () => %s",
606324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
607324a1036SSaleem Abdulrasool                      name ? name : "NULL");
608ceb6b139SCaroline Tice 
6094838131bSGreg Clayton     return name;
61030fdc8d8SChris Lattner }
61130fdc8d8SChris Lattner 
61230fdc8d8SChris Lattner const char *
61330fdc8d8SChris Lattner SBThread::GetQueueName () const
61430fdc8d8SChris Lattner {
6154838131bSGreg Clayton     const char *name = NULL;
6164fc6cb9cSJim Ingham     Mutex::Locker api_locker;
6174fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
6184fc6cb9cSJim Ingham 
6195160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
6201ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
621af67cecdSGreg Clayton     {
6227fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
6237fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
6247fdf9ef1SGreg Clayton         {
6251ac04c30SGreg Clayton             name = exe_ctx.GetThreadPtr()->GetQueueName();
626af67cecdSGreg Clayton         }
627c9858e4dSGreg Clayton         else
628c9858e4dSGreg Clayton         {
629c9858e4dSGreg Clayton             if (log)
630324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetQueueName() => error: process is running",
631324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
632c9858e4dSGreg Clayton         }
6337fdf9ef1SGreg Clayton     }
634ceb6b139SCaroline Tice 
635ceb6b139SCaroline Tice     if (log)
636324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetQueueName () => %s",
637324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
638324a1036SSaleem Abdulrasool                      name ? name : "NULL");
639ceb6b139SCaroline Tice 
6404838131bSGreg Clayton     return name;
64130fdc8d8SChris Lattner }
64230fdc8d8SChris Lattner 
6434fdb5863SJason Molenda lldb::queue_id_t
6444fdb5863SJason Molenda SBThread::GetQueueID () const
6454fdb5863SJason Molenda {
6464fdb5863SJason Molenda     queue_id_t id = LLDB_INVALID_QUEUE_ID;
6474fdb5863SJason Molenda     Mutex::Locker api_locker;
6484fdb5863SJason Molenda     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
6494fdb5863SJason Molenda 
6504fdb5863SJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
6514fdb5863SJason Molenda     if (exe_ctx.HasThreadScope())
6524fdb5863SJason Molenda     {
6534fdb5863SJason Molenda         Process::StopLocker stop_locker;
6544fdb5863SJason Molenda         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
6554fdb5863SJason Molenda         {
6564fdb5863SJason Molenda             id = exe_ctx.GetThreadPtr()->GetQueueID();
6574fdb5863SJason Molenda         }
6584fdb5863SJason Molenda         else
6594fdb5863SJason Molenda         {
6604fdb5863SJason Molenda             if (log)
661324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetQueueID() => error: process is running",
662324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
6634fdb5863SJason Molenda         }
6644fdb5863SJason Molenda     }
6654fdb5863SJason Molenda 
6664fdb5863SJason Molenda     if (log)
667324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetQueueID () => 0x%" PRIx64,
668324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), id);
6694fdb5863SJason Molenda 
6704fdb5863SJason Molenda     return id;
6714fdb5863SJason Molenda }
6724fdb5863SJason Molenda 
673705b1809SJason Molenda bool
674705b1809SJason Molenda SBThread::GetInfoItemByPathAsString (const char *path, SBStream &strm)
675705b1809SJason Molenda {
676705b1809SJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
677705b1809SJason Molenda     bool success = false;
678705b1809SJason Molenda     Mutex::Locker api_locker;
679705b1809SJason Molenda     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
680705b1809SJason Molenda 
681705b1809SJason Molenda     if (exe_ctx.HasThreadScope())
682705b1809SJason Molenda     {
683705b1809SJason Molenda         Process::StopLocker stop_locker;
684705b1809SJason Molenda         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
685705b1809SJason Molenda         {
686705b1809SJason Molenda             Thread *thread = exe_ctx.GetThreadPtr();
687705b1809SJason Molenda             StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo();
688705b1809SJason Molenda             if (info_root_sp)
689705b1809SJason Molenda             {
690705b1809SJason Molenda                 StructuredData::ObjectSP node = info_root_sp->GetObjectForDotSeparatedPath (path);
691705b1809SJason Molenda                 if (node)
692705b1809SJason Molenda                 {
693705b1809SJason Molenda                     if (node->GetType() == StructuredData::Type::eTypeString)
694705b1809SJason Molenda                     {
695705b1809SJason Molenda                         strm.Printf ("%s", node->GetAsString()->GetValue().c_str());
696705b1809SJason Molenda                         success = true;
697705b1809SJason Molenda                     }
698705b1809SJason Molenda                     if (node->GetType() == StructuredData::Type::eTypeInteger)
699705b1809SJason Molenda                     {
700705b1809SJason Molenda                         strm.Printf ("0x%" PRIx64, node->GetAsInteger()->GetValue());
701705b1809SJason Molenda                         success = true;
702705b1809SJason Molenda                     }
703705b1809SJason Molenda                     if (node->GetType() == StructuredData::Type::eTypeFloat)
704705b1809SJason Molenda                     {
705705b1809SJason Molenda                         strm.Printf ("0x%f", node->GetAsFloat()->GetValue());
706705b1809SJason Molenda                         success = true;
707705b1809SJason Molenda                     }
708705b1809SJason Molenda                     if (node->GetType() == StructuredData::Type::eTypeBoolean)
709705b1809SJason Molenda                     {
710705b1809SJason Molenda                         if (node->GetAsBoolean()->GetValue() == true)
711705b1809SJason Molenda                             strm.Printf ("true");
712705b1809SJason Molenda                         else
713705b1809SJason Molenda                             strm.Printf ("false");
714705b1809SJason Molenda                         success = true;
715705b1809SJason Molenda                     }
716705b1809SJason Molenda                     if (node->GetType() == StructuredData::Type::eTypeNull)
717705b1809SJason Molenda                     {
718705b1809SJason Molenda                         strm.Printf ("null");
719705b1809SJason Molenda                         success = true;
720705b1809SJason Molenda                     }
721705b1809SJason Molenda                 }
722705b1809SJason Molenda             }
723705b1809SJason Molenda         }
724705b1809SJason Molenda         else
725705b1809SJason Molenda         {
726705b1809SJason Molenda             if (log)
727705b1809SJason Molenda                 log->Printf ("SBThread(%p)::GetInfoItemByPathAsString() => error: process is running",
728705b1809SJason Molenda                              static_cast<void*>(exe_ctx.GetThreadPtr()));
729705b1809SJason Molenda         }
730705b1809SJason Molenda     }
731705b1809SJason Molenda 
732705b1809SJason Molenda     if (log)
733705b1809SJason Molenda         log->Printf ("SBThread(%p)::GetInfoItemByPathAsString () => %s",
734705b1809SJason Molenda                      static_cast<void*>(exe_ctx.GetThreadPtr()),
735705b1809SJason Molenda                      strm.GetData());
736705b1809SJason Molenda 
737705b1809SJason Molenda     return success;
738705b1809SJason Molenda }
739705b1809SJason Molenda 
740705b1809SJason Molenda 
74164e7ead1SJim Ingham SBError
74264e7ead1SJim Ingham SBThread::ResumeNewPlan (ExecutionContext &exe_ctx, ThreadPlan *new_plan)
74364e7ead1SJim Ingham {
74464e7ead1SJim Ingham     SBError sb_error;
74564e7ead1SJim Ingham 
74664e7ead1SJim Ingham     Process *process = exe_ctx.GetProcessPtr();
74764e7ead1SJim Ingham     if (!process)
74864e7ead1SJim Ingham     {
74964e7ead1SJim Ingham         sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
75064e7ead1SJim Ingham         return sb_error;
75164e7ead1SJim Ingham     }
75264e7ead1SJim Ingham 
75364e7ead1SJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
75464e7ead1SJim Ingham     if (!thread)
75564e7ead1SJim Ingham     {
75664e7ead1SJim Ingham         sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
75764e7ead1SJim Ingham         return sb_error;
75864e7ead1SJim Ingham     }
75964e7ead1SJim Ingham 
76064e7ead1SJim Ingham     // User level plans should be Master Plans so they can be interrupted, other plans executed, and
76164e7ead1SJim Ingham     // then a "continue" will resume the plan.
76264e7ead1SJim Ingham     if (new_plan != NULL)
76364e7ead1SJim Ingham     {
76464e7ead1SJim Ingham         new_plan->SetIsMasterPlan(true);
76564e7ead1SJim Ingham         new_plan->SetOkayToDiscard(false);
76664e7ead1SJim Ingham     }
76764e7ead1SJim Ingham 
76864e7ead1SJim Ingham     // Why do we need to set the current thread by ID here???
76964e7ead1SJim Ingham     process->GetThreadList().SetSelectedThreadByID (thread->GetID());
77064e7ead1SJim Ingham 
771dc6224e0SGreg Clayton     if (process->GetTarget().GetDebugger().GetAsyncExecution ())
772dc6224e0SGreg Clayton         sb_error.ref() = process->Resume ();
773dc6224e0SGreg Clayton     else
774dc6224e0SGreg Clayton         sb_error.ref() = process->ResumeSynchronous (NULL);
77564e7ead1SJim Ingham 
77664e7ead1SJim Ingham     return sb_error;
77764e7ead1SJim Ingham }
77830fdc8d8SChris Lattner 
77930fdc8d8SChris Lattner void
78030fdc8d8SChris Lattner SBThread::StepOver (lldb::RunMode stop_other_threads)
78130fdc8d8SChris Lattner {
7825160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
783ceb6b139SCaroline Tice 
7844fc6cb9cSJim Ingham     Mutex::Locker api_locker;
7854fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
7864fc6cb9cSJim Ingham 
78717a6ad05SGreg Clayton 
788ceb6b139SCaroline Tice     if (log)
789324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')",
790324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
791ceb6b139SCaroline Tice                      Thread::RunModeAsCString (stop_other_threads));
792ceb6b139SCaroline Tice 
7931ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
79430fdc8d8SChris Lattner     {
7951ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
7967ba6e991SJim Ingham         bool abort_other_plans = false;
797b57e4a1bSJason Molenda         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
79830fdc8d8SChris Lattner 
7994d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp;
80030fdc8d8SChris Lattner         if (frame_sp)
80130fdc8d8SChris Lattner         {
80230fdc8d8SChris Lattner             if (frame_sp->HasDebugInformation ())
80330fdc8d8SChris Lattner             {
8044b4b2478SJim Ingham                 const LazyBool avoid_no_debug = eLazyBoolCalculate;
80530fdc8d8SChris Lattner                 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
8064d56e9c1SJim Ingham                 new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
80725d5b10bSJason Molenda                                                                     sc.line_entry,
80830fdc8d8SChris Lattner                                                                     sc,
8094b4b2478SJim Ingham                                                                     stop_other_threads,
8104b4b2478SJim Ingham                                                                     avoid_no_debug);
81130fdc8d8SChris Lattner             }
81230fdc8d8SChris Lattner             else
81330fdc8d8SChris Lattner             {
8144d56e9c1SJim Ingham                 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
81530fdc8d8SChris Lattner                                                                                abort_other_plans,
81630fdc8d8SChris Lattner                                                                                stop_other_threads);
81730fdc8d8SChris Lattner             }
81830fdc8d8SChris Lattner         }
81930fdc8d8SChris Lattner 
82064e7ead1SJim Ingham         // This returns an error, we should use it!
8214d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
82230fdc8d8SChris Lattner     }
82330fdc8d8SChris Lattner }
82430fdc8d8SChris Lattner 
82530fdc8d8SChris Lattner void
82630fdc8d8SChris Lattner SBThread::StepInto (lldb::RunMode stop_other_threads)
82730fdc8d8SChris Lattner {
828c627682eSJim Ingham     StepInto (NULL, stop_other_threads);
829c627682eSJim Ingham }
830c627682eSJim Ingham 
831c627682eSJim Ingham void
832c627682eSJim Ingham SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads)
833c627682eSJim Ingham {
834cbf6f9b2SJim Ingham     SBError error;
835cbf6f9b2SJim Ingham     StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads);
836cbf6f9b2SJim Ingham }
837cbf6f9b2SJim Ingham 
838cbf6f9b2SJim Ingham void
839cbf6f9b2SJim Ingham SBThread::StepInto (const char *target_name, uint32_t end_line, SBError &error, lldb::RunMode stop_other_threads)
840cbf6f9b2SJim Ingham {
8415160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
842ceb6b139SCaroline Tice 
8434fc6cb9cSJim Ingham     Mutex::Locker api_locker;
8444fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
84517a6ad05SGreg Clayton 
84617a6ad05SGreg Clayton     if (log)
847c627682eSJim Ingham         log->Printf ("SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')",
848324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
849c627682eSJim Ingham                      target_name? target_name: "<NULL>",
85017a6ad05SGreg Clayton                      Thread::RunModeAsCString (stop_other_threads));
851c627682eSJim Ingham 
8521ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
85330fdc8d8SChris Lattner     {
8547ba6e991SJim Ingham         bool abort_other_plans = false;
85530fdc8d8SChris Lattner 
8561ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
857b57e4a1bSJason Molenda         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
8584d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp;
85930fdc8d8SChris Lattner 
86030fdc8d8SChris Lattner         if (frame_sp && frame_sp->HasDebugInformation ())
86130fdc8d8SChris Lattner         {
862cbf6f9b2SJim Ingham             SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
863cbf6f9b2SJim Ingham             AddressRange range;
864cbf6f9b2SJim Ingham             if (end_line == LLDB_INVALID_LINE_NUMBER)
865cbf6f9b2SJim Ingham                 range = sc.line_entry.range;
866cbf6f9b2SJim Ingham             else
867cbf6f9b2SJim Ingham             {
868cbf6f9b2SJim Ingham                 if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
869cbf6f9b2SJim Ingham                     return;
870cbf6f9b2SJim Ingham             }
871cbf6f9b2SJim Ingham 
8724b4b2478SJim Ingham             const LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate;
8734b4b2478SJim Ingham             const LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate;
8744d56e9c1SJim Ingham             new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
875cbf6f9b2SJim Ingham                                                               range,
87630fdc8d8SChris Lattner                                                               sc,
877c627682eSJim Ingham                                                               target_name,
878474966a4SGreg Clayton                                                               stop_other_threads,
8794b4b2478SJim Ingham                                                               step_in_avoids_code_without_debug_info,
8804b4b2478SJim Ingham                                                               step_out_avoids_code_without_debug_info);
88130fdc8d8SChris Lattner         }
88230fdc8d8SChris Lattner         else
88330fdc8d8SChris Lattner         {
8844d56e9c1SJim Ingham             new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false,
88530fdc8d8SChris Lattner                                                                            abort_other_plans,
88630fdc8d8SChris Lattner                                                                            stop_other_threads);
88730fdc8d8SChris Lattner         }
88830fdc8d8SChris Lattner 
889cbf6f9b2SJim Ingham         error = ResumeNewPlan (exe_ctx, new_plan_sp.get());
89030fdc8d8SChris Lattner     }
89130fdc8d8SChris Lattner }
89230fdc8d8SChris Lattner 
89330fdc8d8SChris Lattner void
89430fdc8d8SChris Lattner SBThread::StepOut ()
89530fdc8d8SChris Lattner {
8965160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
897ceb6b139SCaroline Tice 
8984fc6cb9cSJim Ingham     Mutex::Locker api_locker;
8994fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
9004fc6cb9cSJim Ingham 
90117a6ad05SGreg Clayton     if (log)
902324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::StepOut ()",
903324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()));
90417a6ad05SGreg Clayton 
9051ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
90630fdc8d8SChris Lattner     {
9077ba6e991SJim Ingham         bool abort_other_plans = false;
90894b09246SJim Ingham         bool stop_other_threads = false;
90930fdc8d8SChris Lattner 
9101ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
9111ac04c30SGreg Clayton 
9124b4b2478SJim Ingham         const LazyBool avoid_no_debug = eLazyBoolCalculate;
9134d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans,
914481cef25SGreg Clayton                                                                     NULL,
915481cef25SGreg Clayton                                                                     false,
916481cef25SGreg Clayton                                                                     stop_other_threads,
917481cef25SGreg Clayton                                                                     eVoteYes,
918481cef25SGreg Clayton                                                                     eVoteNoOpinion,
9194b4b2478SJim Ingham                                                                     0,
9204b4b2478SJim Ingham                                                                     avoid_no_debug));
921481cef25SGreg Clayton 
92264e7ead1SJim Ingham         // This returns an error, we should use it!
9234d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
924481cef25SGreg Clayton     }
925481cef25SGreg Clayton }
926481cef25SGreg Clayton 
927481cef25SGreg Clayton void
928481cef25SGreg Clayton SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame)
929481cef25SGreg Clayton {
9305160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
931481cef25SGreg Clayton 
9324fc6cb9cSJim Ingham     Mutex::Locker api_locker;
9334fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
9344fc6cb9cSJim Ingham 
935989a7558SJim Ingham     if (!sb_frame.IsValid())
936989a7558SJim Ingham     {
937989a7558SJim Ingham         if (log)
938989a7558SJim Ingham             log->Printf("SBThread(%p)::StepOutOfFrame passed an invalid frame, returning.",
939989a7558SJim Ingham                         static_cast<void*>(exe_ctx.GetThreadPtr()));
940989a7558SJim Ingham         return;
941989a7558SJim Ingham     }
942989a7558SJim Ingham 
943b57e4a1bSJason Molenda     StackFrameSP frame_sp (sb_frame.GetFrameSP());
944481cef25SGreg Clayton     if (log)
945481cef25SGreg Clayton     {
946481cef25SGreg Clayton         SBStream frame_desc_strm;
947481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
948324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)",
949324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
950324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
951324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
952481cef25SGreg Clayton     }
953481cef25SGreg Clayton 
9541ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
955481cef25SGreg Clayton     {
9567ba6e991SJim Ingham         bool abort_other_plans = false;
95794b09246SJim Ingham         bool stop_other_threads = false;
9581ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
959989a7558SJim Ingham         if (sb_frame.GetThread().GetThreadID() != thread->GetID())
960989a7558SJim Ingham         {
9611ef6e4c8SBruce Mitchener             log->Printf("SBThread(%p)::StepOutOfFrame passed a frame from another thread (0x%" PRIx64 " vrs. 0x%" PRIx64 ", returning.",
962989a7558SJim Ingham                         static_cast<void*>(exe_ctx.GetThreadPtr()),
963989a7558SJim Ingham                         sb_frame.GetThread().GetThreadID(),
964989a7558SJim Ingham                         thread->GetID());
965989a7558SJim Ingham         }
966481cef25SGreg Clayton 
9674d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans,
968481cef25SGreg Clayton                                                                     NULL,
969481cef25SGreg Clayton                                                                     false,
970481cef25SGreg Clayton                                                                     stop_other_threads,
971481cef25SGreg Clayton                                                                     eVoteYes,
972481cef25SGreg Clayton                                                                     eVoteNoOpinion,
9734d56e9c1SJim Ingham                                                                     frame_sp->GetFrameIndex()));
97430fdc8d8SChris Lattner 
97564e7ead1SJim Ingham         // This returns an error, we should use it!
9764d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
97730fdc8d8SChris Lattner     }
97830fdc8d8SChris Lattner }
97930fdc8d8SChris Lattner 
98030fdc8d8SChris Lattner void
98130fdc8d8SChris Lattner SBThread::StepInstruction (bool step_over)
98230fdc8d8SChris Lattner {
9835160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
984ceb6b139SCaroline Tice 
9854fc6cb9cSJim Ingham     Mutex::Locker api_locker;
9864fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
9874fc6cb9cSJim Ingham 
9881ac04c30SGreg Clayton 
989ceb6b139SCaroline Tice 
99017a6ad05SGreg Clayton     if (log)
991324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)",
992324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), step_over);
99317a6ad05SGreg Clayton 
9941ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
99530fdc8d8SChris Lattner     {
9961ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
9974d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true));
99864e7ead1SJim Ingham 
99964e7ead1SJim Ingham         // This returns an error, we should use it!
10004d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
100130fdc8d8SChris Lattner     }
100230fdc8d8SChris Lattner }
100330fdc8d8SChris Lattner 
100430fdc8d8SChris Lattner void
100530fdc8d8SChris Lattner SBThread::RunToAddress (lldb::addr_t addr)
100630fdc8d8SChris Lattner {
10075160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1008ceb6b139SCaroline Tice 
10094fc6cb9cSJim Ingham     Mutex::Locker api_locker;
10104fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
10114fc6cb9cSJim Ingham 
1012ceb6b139SCaroline Tice 
101317a6ad05SGreg Clayton     if (log)
1014324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")",
1015324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), addr);
101617a6ad05SGreg Clayton 
10171ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
101830fdc8d8SChris Lattner     {
10197ba6e991SJim Ingham         bool abort_other_plans = false;
102030fdc8d8SChris Lattner         bool stop_other_threads = true;
102130fdc8d8SChris Lattner 
1022e72dfb32SGreg Clayton         Address target_addr (addr);
102330fdc8d8SChris Lattner 
10241ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
10251ac04c30SGreg Clayton 
10262bdbfd50SJim Ingham         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress (abort_other_plans,
10272bdbfd50SJim Ingham                                                                          target_addr,
10282bdbfd50SJim Ingham                                                                          stop_other_threads));
102964e7ead1SJim Ingham 
103064e7ead1SJim Ingham         // This returns an error, we should use it!
10314d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
103230fdc8d8SChris Lattner     }
103330fdc8d8SChris Lattner }
103430fdc8d8SChris Lattner 
1035481cef25SGreg Clayton SBError
1036481cef25SGreg Clayton SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
1037481cef25SGreg Clayton                          lldb::SBFileSpec &sb_file_spec,
1038481cef25SGreg Clayton                          uint32_t line)
1039481cef25SGreg Clayton {
1040481cef25SGreg Clayton     SBError sb_error;
10415160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1042481cef25SGreg Clayton     char path[PATH_MAX];
1043481cef25SGreg Clayton 
10444fc6cb9cSJim Ingham     Mutex::Locker api_locker;
10454fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
10464fc6cb9cSJim Ingham 
1047b57e4a1bSJason Molenda     StackFrameSP frame_sp (sb_frame.GetFrameSP());
104817a6ad05SGreg Clayton 
1049481cef25SGreg Clayton     if (log)
1050481cef25SGreg Clayton     {
1051481cef25SGreg Clayton         SBStream frame_desc_strm;
1052481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
1053481cef25SGreg Clayton         sb_file_spec->GetPath (path, sizeof(path));
1054481cef25SGreg Clayton         log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)",
1055324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1056324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
1057324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData(), path, line);
1058481cef25SGreg Clayton     }
1059481cef25SGreg Clayton 
10601ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1061481cef25SGreg Clayton     {
10621ac04c30SGreg Clayton         Target *target = exe_ctx.GetTargetPtr();
10631ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
1064481cef25SGreg Clayton 
1065481cef25SGreg Clayton         if (line == 0)
1066481cef25SGreg Clayton         {
1067481cef25SGreg Clayton             sb_error.SetErrorString("invalid line argument");
1068481cef25SGreg Clayton             return sb_error;
1069481cef25SGreg Clayton         }
1070481cef25SGreg Clayton 
1071b9556accSGreg Clayton         if (!frame_sp)
1072481cef25SGreg Clayton         {
10731ac04c30SGreg Clayton             frame_sp = thread->GetSelectedFrame ();
1074481cef25SGreg Clayton             if (!frame_sp)
10751ac04c30SGreg Clayton                 frame_sp = thread->GetStackFrameAtIndex (0);
1076481cef25SGreg Clayton         }
1077481cef25SGreg Clayton 
1078481cef25SGreg Clayton         SymbolContext frame_sc;
1079481cef25SGreg Clayton         if (!frame_sp)
1080481cef25SGreg Clayton         {
1081481cef25SGreg Clayton             sb_error.SetErrorString("no valid frames in thread to step");
1082481cef25SGreg Clayton             return sb_error;
1083481cef25SGreg Clayton         }
1084481cef25SGreg Clayton 
1085481cef25SGreg Clayton         // If we have a frame, get its line
1086481cef25SGreg Clayton         frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit  |
1087481cef25SGreg Clayton                                                eSymbolContextFunction  |
1088481cef25SGreg Clayton                                                eSymbolContextLineEntry |
1089481cef25SGreg Clayton                                                eSymbolContextSymbol    );
1090481cef25SGreg Clayton 
1091481cef25SGreg Clayton         if (frame_sc.comp_unit == NULL)
1092481cef25SGreg Clayton         {
1093481cef25SGreg Clayton             sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex());
1094481cef25SGreg Clayton             return sb_error;
1095481cef25SGreg Clayton         }
1096481cef25SGreg Clayton 
1097481cef25SGreg Clayton         FileSpec step_file_spec;
1098481cef25SGreg Clayton         if (sb_file_spec.IsValid())
1099481cef25SGreg Clayton         {
1100481cef25SGreg Clayton             // The file spec passed in was valid, so use it
1101481cef25SGreg Clayton             step_file_spec = sb_file_spec.ref();
1102481cef25SGreg Clayton         }
1103481cef25SGreg Clayton         else
1104481cef25SGreg Clayton         {
1105481cef25SGreg Clayton             if (frame_sc.line_entry.IsValid())
1106481cef25SGreg Clayton                 step_file_spec = frame_sc.line_entry.file;
1107481cef25SGreg Clayton             else
1108481cef25SGreg Clayton             {
1109481cef25SGreg Clayton                 sb_error.SetErrorString("invalid file argument or no file for frame");
1110481cef25SGreg Clayton                 return sb_error;
1111481cef25SGreg Clayton             }
1112481cef25SGreg Clayton         }
1113481cef25SGreg Clayton 
11149b70ddb3SJim Ingham         // Grab the current function, then we will make sure the "until" address is
11159b70ddb3SJim Ingham         // within the function.  We discard addresses that are out of the current
11169b70ddb3SJim Ingham         // function, and then if there are no addresses remaining, give an appropriate
11179b70ddb3SJim Ingham         // error message.
11189b70ddb3SJim Ingham 
11199b70ddb3SJim Ingham         bool all_in_function = true;
11209b70ddb3SJim Ingham         AddressRange fun_range = frame_sc.function->GetAddressRange();
11219b70ddb3SJim Ingham 
1122481cef25SGreg Clayton         std::vector<addr_t> step_over_until_addrs;
11237ba6e991SJim Ingham         const bool abort_other_plans = false;
1124c02e3344SJim Ingham         const bool stop_other_threads = false;
1125481cef25SGreg Clayton         const bool check_inlines = true;
1126481cef25SGreg Clayton         const bool exact = false;
1127481cef25SGreg Clayton 
1128481cef25SGreg Clayton         SymbolContextList sc_list;
11299b70ddb3SJim Ingham         const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec,
11309b70ddb3SJim Ingham                                                                                line,
11319b70ddb3SJim Ingham                                                                                check_inlines,
11329b70ddb3SJim Ingham                                                                                exact,
11339b70ddb3SJim Ingham                                                                                eSymbolContextLineEntry,
11349b70ddb3SJim Ingham                                                                                sc_list);
1135481cef25SGreg Clayton         if (num_matches > 0)
1136481cef25SGreg Clayton         {
1137481cef25SGreg Clayton             SymbolContext sc;
1138481cef25SGreg Clayton             for (uint32_t i=0; i<num_matches; ++i)
1139481cef25SGreg Clayton             {
1140481cef25SGreg Clayton                 if (sc_list.GetContextAtIndex(i, sc))
1141481cef25SGreg Clayton                 {
11429b70ddb3SJim Ingham                     addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
1143481cef25SGreg Clayton                     if (step_addr != LLDB_INVALID_ADDRESS)
1144481cef25SGreg Clayton                     {
11459b70ddb3SJim Ingham                         if (fun_range.ContainsLoadAddress(step_addr, target))
1146481cef25SGreg Clayton                             step_over_until_addrs.push_back(step_addr);
11479b70ddb3SJim Ingham                         else
11489b70ddb3SJim Ingham                             all_in_function = false;
1149481cef25SGreg Clayton                     }
1150481cef25SGreg Clayton                 }
1151481cef25SGreg Clayton             }
1152481cef25SGreg Clayton         }
1153481cef25SGreg Clayton 
1154481cef25SGreg Clayton         if (step_over_until_addrs.empty())
1155481cef25SGreg Clayton         {
11569b70ddb3SJim Ingham             if (all_in_function)
11579b70ddb3SJim Ingham             {
1158481cef25SGreg Clayton                 step_file_spec.GetPath (path, sizeof(path));
1159fd54b368SJason Molenda                 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line);
1160481cef25SGreg Clayton             }
1161481cef25SGreg Clayton             else
116286edbf41SGreg Clayton                 sb_error.SetErrorString ("step until target not in current function");
11639b70ddb3SJim Ingham         }
11649b70ddb3SJim Ingham         else
1165481cef25SGreg Clayton         {
11664d56e9c1SJim Ingham             ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil (abort_other_plans,
1167481cef25SGreg Clayton                                                                         &step_over_until_addrs[0],
1168481cef25SGreg Clayton                                                                         step_over_until_addrs.size(),
1169481cef25SGreg Clayton                                                                         stop_other_threads,
11704d56e9c1SJim Ingham                                                                         frame_sp->GetFrameIndex()));
1171481cef25SGreg Clayton 
11724d56e9c1SJim Ingham             sb_error = ResumeNewPlan (exe_ctx, new_plan_sp.get());
1173481cef25SGreg Clayton         }
1174481cef25SGreg Clayton     }
1175481cef25SGreg Clayton     else
1176481cef25SGreg Clayton     {
1177481cef25SGreg Clayton         sb_error.SetErrorString("this SBThread object is invalid");
1178481cef25SGreg Clayton     }
1179481cef25SGreg Clayton     return sb_error;
1180481cef25SGreg Clayton }
1181481cef25SGreg Clayton 
11824413758cSJim Ingham SBError
11832bdbfd50SJim Ingham SBThread::StepUsingScriptedThreadPlan (const char *script_class_name)
11842bdbfd50SJim Ingham {
11852bdbfd50SJim Ingham     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
11862bdbfd50SJim Ingham     SBError sb_error;
11872bdbfd50SJim Ingham 
11882bdbfd50SJim Ingham     Mutex::Locker api_locker;
11892bdbfd50SJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
11902bdbfd50SJim Ingham 
11912bdbfd50SJim Ingham     if (log)
11922bdbfd50SJim Ingham     {
11932bdbfd50SJim Ingham         log->Printf ("SBThread(%p)::StepUsingScriptedThreadPlan: class name: %s",
11942bdbfd50SJim Ingham                      static_cast<void*>(exe_ctx.GetThreadPtr()),
11952bdbfd50SJim Ingham                      script_class_name);
11962bdbfd50SJim Ingham     }
11972bdbfd50SJim Ingham 
11982bdbfd50SJim Ingham 
11992bdbfd50SJim Ingham     if (!exe_ctx.HasThreadScope())
12002bdbfd50SJim Ingham     {
12012bdbfd50SJim Ingham         sb_error.SetErrorString("this SBThread object is invalid");
12022bdbfd50SJim Ingham         return sb_error;
12032bdbfd50SJim Ingham     }
12042bdbfd50SJim Ingham 
12052bdbfd50SJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
12062bdbfd50SJim Ingham     ThreadPlanSP thread_plan_sp = thread->QueueThreadPlanForStepScripted(false, script_class_name, false);
12072bdbfd50SJim Ingham 
12082bdbfd50SJim Ingham     if (thread_plan_sp)
12092bdbfd50SJim Ingham         sb_error = ResumeNewPlan(exe_ctx, thread_plan_sp.get());
12102bdbfd50SJim Ingham     else
12112bdbfd50SJim Ingham     {
12122bdbfd50SJim Ingham         sb_error.SetErrorStringWithFormat("Error queuing thread plan for class: %s.", script_class_name);
12132bdbfd50SJim Ingham         if (log)
12142bdbfd50SJim Ingham         log->Printf ("SBThread(%p)::StepUsingScriptedThreadPlan: Error queuing thread plan for class: %s",
12152bdbfd50SJim Ingham                      static_cast<void*>(exe_ctx.GetThreadPtr()),
12162bdbfd50SJim Ingham                      script_class_name);
12172bdbfd50SJim Ingham     }
12182bdbfd50SJim Ingham 
12192bdbfd50SJim Ingham     return sb_error;
12202bdbfd50SJim Ingham }
12212bdbfd50SJim Ingham 
12222bdbfd50SJim Ingham SBError
1223f86248d9SRichard Mitton SBThread::JumpToLine (lldb::SBFileSpec &file_spec, uint32_t line)
1224f86248d9SRichard Mitton {
1225f86248d9SRichard Mitton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1226f86248d9SRichard Mitton     SBError sb_error;
1227f86248d9SRichard Mitton 
1228f86248d9SRichard Mitton     Mutex::Locker api_locker;
1229f86248d9SRichard Mitton     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1230f86248d9SRichard Mitton 
1231f86248d9SRichard Mitton     if (log)
1232324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::JumpToLine (file+line = %s:%u)",
1233324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1234324a1036SSaleem Abdulrasool                      file_spec->GetPath().c_str(), line);
1235f86248d9SRichard Mitton 
1236f86248d9SRichard Mitton     if (!exe_ctx.HasThreadScope())
1237f86248d9SRichard Mitton     {
1238f86248d9SRichard Mitton         sb_error.SetErrorString("this SBThread object is invalid");
1239f86248d9SRichard Mitton         return sb_error;
1240f86248d9SRichard Mitton     }
1241f86248d9SRichard Mitton 
1242f86248d9SRichard Mitton     Thread *thread = exe_ctx.GetThreadPtr();
1243f86248d9SRichard Mitton 
1244f86248d9SRichard Mitton     Error err = thread->JumpToLine (file_spec.get(), line, true);
1245f86248d9SRichard Mitton     sb_error.SetError (err);
1246f86248d9SRichard Mitton     return sb_error;
1247f86248d9SRichard Mitton }
1248f86248d9SRichard Mitton 
1249f86248d9SRichard Mitton SBError
1250cb640dd8SJim Ingham SBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value)
12514413758cSJim Ingham {
12524413758cSJim Ingham     SBError sb_error;
12534413758cSJim Ingham 
12545160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
12554413758cSJim Ingham 
12564413758cSJim Ingham     Mutex::Locker api_locker;
12574413758cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
12584413758cSJim Ingham 
12594413758cSJim Ingham 
12604413758cSJim Ingham     if (log)
1261324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::ReturnFromFrame (frame=%d)",
1262324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1263324a1036SSaleem Abdulrasool                      frame.GetFrameID());
12644413758cSJim Ingham 
12654413758cSJim Ingham     if (exe_ctx.HasThreadScope())
12664413758cSJim Ingham     {
12674413758cSJim Ingham         Thread *thread = exe_ctx.GetThreadPtr();
1268cb640dd8SJim Ingham         sb_error.SetError (thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
12694413758cSJim Ingham     }
12704413758cSJim Ingham 
12714413758cSJim Ingham     return sb_error;
12724413758cSJim Ingham }
12734413758cSJim Ingham 
1274481cef25SGreg Clayton 
1275722a0cdcSGreg Clayton bool
1276722a0cdcSGreg Clayton SBThread::Suspend()
1277722a0cdcSGreg Clayton {
12785160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
12797fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
1280c9858e4dSGreg Clayton     bool result = false;
12811ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1282722a0cdcSGreg Clayton     {
1283c9858e4dSGreg Clayton         Process::StopLocker stop_locker;
1284c9858e4dSGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1285c9858e4dSGreg Clayton         {
12861ac04c30SGreg Clayton             exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended);
1287c9858e4dSGreg Clayton             result = true;
1288722a0cdcSGreg Clayton         }
1289c9858e4dSGreg Clayton         else
1290c9858e4dSGreg Clayton         {
1291c9858e4dSGreg Clayton             if (log)
1292324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::Suspend() => error: process is running",
1293324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1294c9858e4dSGreg Clayton         }
1295c9858e4dSGreg Clayton     }
1296c9858e4dSGreg Clayton     if (log)
1297324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::Suspend() => %i",
1298324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), result);
1299c9858e4dSGreg Clayton     return result;
1300722a0cdcSGreg Clayton }
1301722a0cdcSGreg Clayton 
1302722a0cdcSGreg Clayton bool
1303722a0cdcSGreg Clayton SBThread::Resume ()
1304722a0cdcSGreg Clayton {
13055160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
13067fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
1307c9858e4dSGreg Clayton     bool result = false;
13081ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1309722a0cdcSGreg Clayton     {
1310c9858e4dSGreg Clayton         Process::StopLocker stop_locker;
1311c9858e4dSGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1312c9858e4dSGreg Clayton         {
13136c9ed91cSJim Ingham             const bool override_suspend = true;
13146c9ed91cSJim Ingham             exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning, override_suspend);
1315c9858e4dSGreg Clayton             result = true;
1316722a0cdcSGreg Clayton         }
1317c9858e4dSGreg Clayton         else
1318c9858e4dSGreg Clayton         {
1319c9858e4dSGreg Clayton             if (log)
1320324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::Resume() => error: process is running",
1321324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1322c9858e4dSGreg Clayton         }
1323c9858e4dSGreg Clayton     }
1324c9858e4dSGreg Clayton     if (log)
1325324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::Resume() => %i",
1326324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), result);
1327c9858e4dSGreg Clayton     return result;
1328722a0cdcSGreg Clayton }
1329722a0cdcSGreg Clayton 
1330722a0cdcSGreg Clayton bool
1331722a0cdcSGreg Clayton SBThread::IsSuspended()
1332722a0cdcSGreg Clayton {
13337fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
13341ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
13351ac04c30SGreg Clayton         return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended;
1336722a0cdcSGreg Clayton     return false;
1337722a0cdcSGreg Clayton }
1338722a0cdcSGreg Clayton 
1339a75418dbSAndrew Kaylor bool
1340a75418dbSAndrew Kaylor SBThread::IsStopped()
1341a75418dbSAndrew Kaylor {
1342a75418dbSAndrew Kaylor     ExecutionContext exe_ctx (m_opaque_sp.get());
1343a75418dbSAndrew Kaylor     if (exe_ctx.HasThreadScope())
1344a75418dbSAndrew Kaylor         return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1345a75418dbSAndrew Kaylor     return false;
1346a75418dbSAndrew Kaylor }
1347a75418dbSAndrew Kaylor 
134830fdc8d8SChris Lattner SBProcess
134930fdc8d8SChris Lattner SBThread::GetProcess ()
135030fdc8d8SChris Lattner {
1351b9556accSGreg Clayton     SBProcess sb_process;
13527fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
13531ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
135430fdc8d8SChris Lattner     {
135530fdc8d8SChris Lattner         // Have to go up to the target so we can get a shared pointer to our process...
13561ac04c30SGreg Clayton         sb_process.SetSP (exe_ctx.GetProcessSP());
135730fdc8d8SChris Lattner     }
1358ceb6b139SCaroline Tice 
13595160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1360ceb6b139SCaroline Tice     if (log)
1361ceb6b139SCaroline Tice     {
1362481cef25SGreg Clayton         SBStream frame_desc_strm;
1363b9556accSGreg Clayton         sb_process.GetDescription (frame_desc_strm);
1364324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s",
1365324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1366324a1036SSaleem Abdulrasool                      static_cast<void*>(sb_process.GetSP().get()),
1367324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
1368ceb6b139SCaroline Tice     }
1369ceb6b139SCaroline Tice 
1370b9556accSGreg Clayton     return sb_process;
137130fdc8d8SChris Lattner }
137230fdc8d8SChris Lattner 
137330fdc8d8SChris Lattner uint32_t
137430fdc8d8SChris Lattner SBThread::GetNumFrames ()
137530fdc8d8SChris Lattner {
13765160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1377ceb6b139SCaroline Tice 
1378ceb6b139SCaroline Tice     uint32_t num_frames = 0;
13794fc6cb9cSJim Ingham     Mutex::Locker api_locker;
13804fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
13814fc6cb9cSJim Ingham 
13821ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1383af67cecdSGreg Clayton     {
13847fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
13857fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
13867fdf9ef1SGreg Clayton         {
13871ac04c30SGreg Clayton             num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1388af67cecdSGreg Clayton         }
1389c9858e4dSGreg Clayton         else
1390c9858e4dSGreg Clayton         {
1391c9858e4dSGreg Clayton             if (log)
1392324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running",
1393324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1394c9858e4dSGreg Clayton         }
13957fdf9ef1SGreg Clayton     }
1396ceb6b139SCaroline Tice 
1397ceb6b139SCaroline Tice     if (log)
1398324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetNumFrames () => %u",
1399324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), num_frames);
1400ceb6b139SCaroline Tice 
1401ceb6b139SCaroline Tice     return num_frames;
140230fdc8d8SChris Lattner }
140330fdc8d8SChris Lattner 
140430fdc8d8SChris Lattner SBFrame
140530fdc8d8SChris Lattner SBThread::GetFrameAtIndex (uint32_t idx)
140630fdc8d8SChris Lattner {
14075160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1408ceb6b139SCaroline Tice 
140930fdc8d8SChris Lattner     SBFrame sb_frame;
1410b57e4a1bSJason Molenda     StackFrameSP frame_sp;
14114fc6cb9cSJim Ingham     Mutex::Locker api_locker;
14124fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
14134fc6cb9cSJim Ingham 
14141ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1415af67cecdSGreg Clayton     {
14167fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
14177fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
14187fdf9ef1SGreg Clayton         {
14191ac04c30SGreg Clayton             frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx);
1420b9556accSGreg Clayton             sb_frame.SetFrameSP (frame_sp);
1421af67cecdSGreg Clayton         }
1422c9858e4dSGreg Clayton         else
1423c9858e4dSGreg Clayton         {
1424c9858e4dSGreg Clayton             if (log)
1425324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running",
1426324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1427c9858e4dSGreg Clayton         }
14287fdf9ef1SGreg Clayton     }
1429ceb6b139SCaroline Tice 
1430ceb6b139SCaroline Tice     if (log)
1431ceb6b139SCaroline Tice     {
1432481cef25SGreg Clayton         SBStream frame_desc_strm;
1433481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
14344838131bSGreg Clayton         log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
1435324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), idx,
1436324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
1437324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
1438ceb6b139SCaroline Tice     }
1439ceb6b139SCaroline Tice 
144030fdc8d8SChris Lattner     return sb_frame;
144130fdc8d8SChris Lattner }
144230fdc8d8SChris Lattner 
1443f028a1fbSGreg Clayton lldb::SBFrame
1444f028a1fbSGreg Clayton SBThread::GetSelectedFrame ()
1445f028a1fbSGreg Clayton {
14465160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1447f028a1fbSGreg Clayton 
1448f028a1fbSGreg Clayton     SBFrame sb_frame;
1449b57e4a1bSJason Molenda     StackFrameSP frame_sp;
14504fc6cb9cSJim Ingham     Mutex::Locker api_locker;
14514fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
14524fc6cb9cSJim Ingham 
14531ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1454af67cecdSGreg Clayton     {
14557fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
14567fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
14577fdf9ef1SGreg Clayton         {
14581ac04c30SGreg Clayton             frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame ();
1459b9556accSGreg Clayton             sb_frame.SetFrameSP (frame_sp);
1460af67cecdSGreg Clayton         }
1461c9858e4dSGreg Clayton         else
1462c9858e4dSGreg Clayton         {
1463c9858e4dSGreg Clayton             if (log)
1464324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running",
1465324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1466c9858e4dSGreg Clayton         }
14677fdf9ef1SGreg Clayton     }
1468f028a1fbSGreg Clayton 
1469f028a1fbSGreg Clayton     if (log)
1470f028a1fbSGreg Clayton     {
1471481cef25SGreg Clayton         SBStream frame_desc_strm;
1472481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
1473f028a1fbSGreg Clayton         log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
1474324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1475324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
1476324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
1477f028a1fbSGreg Clayton     }
1478f028a1fbSGreg Clayton 
1479f028a1fbSGreg Clayton     return sb_frame;
1480f028a1fbSGreg Clayton }
1481f028a1fbSGreg Clayton 
1482f028a1fbSGreg Clayton lldb::SBFrame
1483f028a1fbSGreg Clayton SBThread::SetSelectedFrame (uint32_t idx)
1484f028a1fbSGreg Clayton {
14855160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1486f028a1fbSGreg Clayton 
1487f028a1fbSGreg Clayton     SBFrame sb_frame;
1488b57e4a1bSJason Molenda     StackFrameSP frame_sp;
14894fc6cb9cSJim Ingham     Mutex::Locker api_locker;
14904fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
14914fc6cb9cSJim Ingham 
14921ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1493f028a1fbSGreg Clayton     {
14947fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
14957fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
14967fdf9ef1SGreg Clayton         {
14971ac04c30SGreg Clayton             Thread *thread = exe_ctx.GetThreadPtr();
14981ac04c30SGreg Clayton             frame_sp = thread->GetStackFrameAtIndex (idx);
1499f028a1fbSGreg Clayton             if (frame_sp)
1500f028a1fbSGreg Clayton             {
15011ac04c30SGreg Clayton                 thread->SetSelectedFrame (frame_sp.get());
1502b9556accSGreg Clayton                 sb_frame.SetFrameSP (frame_sp);
1503f028a1fbSGreg Clayton             }
1504f028a1fbSGreg Clayton         }
1505c9858e4dSGreg Clayton         else
1506c9858e4dSGreg Clayton         {
1507c9858e4dSGreg Clayton             if (log)
1508324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running",
1509324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1510c9858e4dSGreg Clayton         }
15117fdf9ef1SGreg Clayton     }
1512f028a1fbSGreg Clayton 
1513f028a1fbSGreg Clayton     if (log)
1514f028a1fbSGreg Clayton     {
1515481cef25SGreg Clayton         SBStream frame_desc_strm;
1516481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
1517f028a1fbSGreg Clayton         log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
1518324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), idx,
1519324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
1520324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
1521f028a1fbSGreg Clayton     }
1522f028a1fbSGreg Clayton     return sb_frame;
1523f028a1fbSGreg Clayton }
1524f028a1fbSGreg Clayton 
15254f465cffSJim Ingham bool
15264f465cffSJim Ingham SBThread::EventIsThreadEvent (const SBEvent &event)
15274f465cffSJim Ingham {
15284f465cffSJim Ingham     return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL;
15294f465cffSJim Ingham }
15304f465cffSJim Ingham 
15314f465cffSJim Ingham SBFrame
15324f465cffSJim Ingham SBThread::GetStackFrameFromEvent (const SBEvent &event)
15334f465cffSJim Ingham {
15344f465cffSJim Ingham     return Thread::ThreadEventData::GetStackFrameFromEvent (event.get());
15354f465cffSJim Ingham 
15364f465cffSJim Ingham }
15374f465cffSJim Ingham 
15384f465cffSJim Ingham SBThread
15394f465cffSJim Ingham SBThread::GetThreadFromEvent (const SBEvent &event)
15404f465cffSJim Ingham {
15414f465cffSJim Ingham     return Thread::ThreadEventData::GetThreadFromEvent (event.get());
15424f465cffSJim Ingham }
1543f028a1fbSGreg Clayton 
154430fdc8d8SChris Lattner bool
154530fdc8d8SChris Lattner SBThread::operator == (const SBThread &rhs) const
154630fdc8d8SChris Lattner {
15477fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get();
154830fdc8d8SChris Lattner }
154930fdc8d8SChris Lattner 
155030fdc8d8SChris Lattner bool
155130fdc8d8SChris Lattner SBThread::operator != (const SBThread &rhs) const
155230fdc8d8SChris Lattner {
15537fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get();
155430fdc8d8SChris Lattner }
1555dde9cff3SCaroline Tice 
1556dde9cff3SCaroline Tice bool
15574f465cffSJim Ingham SBThread::GetStatus (SBStream &status) const
15584f465cffSJim Ingham {
15594f465cffSJim Ingham     Stream &strm = status.ref();
15604f465cffSJim Ingham 
15614f465cffSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get());
15624f465cffSJim Ingham     if (exe_ctx.HasThreadScope())
15634f465cffSJim Ingham     {
15644f465cffSJim Ingham         exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1);
15654f465cffSJim Ingham     }
15664f465cffSJim Ingham     else
15674f465cffSJim Ingham         strm.PutCString ("No status");
15684f465cffSJim Ingham 
15694f465cffSJim Ingham     return true;
15704f465cffSJim Ingham }
15714f465cffSJim Ingham 
15724f465cffSJim Ingham bool
1573ceb6b139SCaroline Tice SBThread::GetDescription (SBStream &description) const
1574ceb6b139SCaroline Tice {
1575da7bc7d0SGreg Clayton     Stream &strm = description.ref();
1576da7bc7d0SGreg Clayton 
15777fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
15781ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1579ceb6b139SCaroline Tice     {
1580603985fcSJim Ingham         exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm, LLDB_INVALID_THREAD_ID);
1581603985fcSJim Ingham         //strm.Printf("SBThread: tid = 0x%4.4" PRIx64, exe_ctx.GetThreadPtr()->GetID());
1582ceb6b139SCaroline Tice     }
1583ceb6b139SCaroline Tice     else
1584da7bc7d0SGreg Clayton         strm.PutCString ("No value");
1585ceb6b139SCaroline Tice 
1586ceb6b139SCaroline Tice     return true;
1587ceb6b139SCaroline Tice }
15885dd4916fSJason Molenda 
15895dd4916fSJason Molenda SBThread
1590008c45f1SJason Molenda SBThread::GetExtendedBacktraceThread (const char *type)
15915dd4916fSJason Molenda {
15925dd4916fSJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
15935dd4916fSJason Molenda     Mutex::Locker api_locker;
15945dd4916fSJason Molenda     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
15955dd4916fSJason Molenda     SBThread sb_origin_thread;
15965dd4916fSJason Molenda 
15975dd4916fSJason Molenda     if (exe_ctx.HasThreadScope())
15985dd4916fSJason Molenda     {
15995dd4916fSJason Molenda         Process::StopLocker stop_locker;
16005dd4916fSJason Molenda         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
16015dd4916fSJason Molenda         {
16027a2f7904SJason Molenda             ThreadSP real_thread(exe_ctx.GetThreadSP());
16035dd4916fSJason Molenda             if (real_thread)
16045dd4916fSJason Molenda             {
16055dd4916fSJason Molenda                 ConstString type_const (type);
16067a2f7904SJason Molenda                 Process *process = exe_ctx.GetProcessPtr();
16077a2f7904SJason Molenda                 if (process)
16087a2f7904SJason Molenda                 {
16097a2f7904SJason Molenda                     SystemRuntime *runtime = process->GetSystemRuntime();
16105dd4916fSJason Molenda                     if (runtime)
16115dd4916fSJason Molenda                     {
1612008c45f1SJason Molenda                         ThreadSP new_thread_sp (runtime->GetExtendedBacktraceThread (real_thread, type_const));
1613a6e9130dSJason Molenda                         if (new_thread_sp)
1614a6e9130dSJason Molenda                         {
16157a2f7904SJason Molenda                             // Save this in the Process' ExtendedThreadList so a strong pointer retains the
16167a2f7904SJason Molenda                             // object.
16177a2f7904SJason Molenda                             process->GetExtendedThreadList().AddThread (new_thread_sp);
16187a2f7904SJason Molenda                             sb_origin_thread.SetThread (new_thread_sp);
1619a6e9130dSJason Molenda                             if (log)
1620a6e9130dSJason Molenda                             {
1621a6e9130dSJason Molenda                                 const char *queue_name = new_thread_sp->GetQueueName();
1622a6e9130dSJason Molenda                                 if (queue_name == NULL)
1623a6e9130dSJason Molenda                                     queue_name = "";
16242bdbfd50SJim Ingham                                 log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => new extended Thread "
16252bdbfd50SJim Ingham                                              "created (%p) with queue_id 0x%" PRIx64 " queue name '%s'",
1626324a1036SSaleem Abdulrasool                                              static_cast<void*>(exe_ctx.GetThreadPtr()),
1627324a1036SSaleem Abdulrasool                                              static_cast<void*>(new_thread_sp.get()),
1628324a1036SSaleem Abdulrasool                                              new_thread_sp->GetQueueID(),
1629324a1036SSaleem Abdulrasool                                              queue_name);
1630a6e9130dSJason Molenda                             }
1631a6e9130dSJason Molenda                         }
16327a2f7904SJason Molenda                     }
16335dd4916fSJason Molenda                 }
16345dd4916fSJason Molenda             }
16355dd4916fSJason Molenda         }
16365dd4916fSJason Molenda         else
16375dd4916fSJason Molenda         {
16385dd4916fSJason Molenda             if (log)
1639324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => error: process is running",
1640324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
16415dd4916fSJason Molenda         }
16425dd4916fSJason Molenda     }
16435dd4916fSJason Molenda 
1644ac605f4aSJason Molenda     if (log && sb_origin_thread.IsValid() == false)
1645324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a Valid thread",
1646324a1036SSaleem Abdulrasool                     static_cast<void*>(exe_ctx.GetThreadPtr()));
16475dd4916fSJason Molenda     return sb_origin_thread;
16485dd4916fSJason Molenda }
16498ee9cb58SJason Molenda 
16508ee9cb58SJason Molenda uint32_t
16518ee9cb58SJason Molenda SBThread::GetExtendedBacktraceOriginatingIndexID ()
16528ee9cb58SJason Molenda {
16538ee9cb58SJason Molenda     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
16548ee9cb58SJason Molenda     if (thread_sp)
16558ee9cb58SJason Molenda         return thread_sp->GetExtendedBacktraceOriginatingIndexID();
16568ee9cb58SJason Molenda     return LLDB_INVALID_INDEX32;
16578ee9cb58SJason Molenda }
1658b4892cd2SJason Molenda 
1659b4892cd2SJason Molenda bool
1660b4892cd2SJason Molenda SBThread::SafeToCallFunctions ()
1661b4892cd2SJason Molenda {
1662b4892cd2SJason Molenda     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1663b4892cd2SJason Molenda     if (thread_sp)
1664b4892cd2SJason Molenda         return thread_sp->SafeToCallFunctions();
1665b4892cd2SJason Molenda     return true;
1666b4892cd2SJason Molenda }
16672bdbfd50SJim Ingham 
16682bdbfd50SJim Ingham lldb_private::Thread *
16692bdbfd50SJim Ingham SBThread::operator->()
16702bdbfd50SJim Ingham {
16712bdbfd50SJim Ingham     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
16722bdbfd50SJim Ingham     if (thread_sp)
16732bdbfd50SJim Ingham         return thread_sp.get();
16742bdbfd50SJim Ingham     else
16752bdbfd50SJim Ingham         return NULL;
16762bdbfd50SJim Ingham }
16772bdbfd50SJim Ingham 
16782bdbfd50SJim Ingham lldb_private::Thread *
16792bdbfd50SJim Ingham SBThread::get()
16802bdbfd50SJim Ingham {
16812bdbfd50SJim Ingham     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
16822bdbfd50SJim Ingham     if (thread_sp)
16832bdbfd50SJim Ingham         return thread_sp.get();
16842bdbfd50SJim Ingham     else
16852bdbfd50SJim Ingham         return NULL;
16862bdbfd50SJim Ingham }
16872bdbfd50SJim Ingham 
1688