130fdc8d8SChris Lattner //===-- SBThread.cpp --------------------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 104c5de699SEli Friedman #include "lldb/API/SBThread.h" 1130fdc8d8SChris Lattner 1230fdc8d8SChris Lattner #include "lldb/API/SBSymbolContext.h" 1330fdc8d8SChris Lattner #include "lldb/API/SBFileSpec.h" 14dde9cff3SCaroline Tice #include "lldb/API/SBStream.h" 154e78f606SGreg Clayton #include "lldb/Breakpoint/BreakpointLocation.h" 166611103cSGreg Clayton #include "lldb/Core/Debugger.h" 17a75418dbSAndrew Kaylor #include "lldb/Core/State.h" 1830fdc8d8SChris Lattner #include "lldb/Core/Stream.h" 1930fdc8d8SChris Lattner #include "lldb/Core/StreamFile.h" 20705b1809SJason Molenda #include "lldb/Core/StructuredData.h" 21a78bd7ffSZachary Turner #include "lldb/Core/ValueObject.h" 226611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h" 2393749ab3SZachary Turner #include "lldb/Symbol/SymbolContext.h" 2493749ab3SZachary Turner #include "lldb/Symbol/CompileUnit.h" 255dd4916fSJason Molenda #include "lldb/Target/SystemRuntime.h" 2630fdc8d8SChris Lattner #include "lldb/Target/Thread.h" 2730fdc8d8SChris Lattner #include "lldb/Target/Process.h" 28b9ffa98cSJason Molenda #include "lldb/Target/Queue.h" 2993749ab3SZachary Turner #include "lldb/Target/UnixSignals.h" 30f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h" 3130fdc8d8SChris Lattner #include "lldb/Target/Target.h" 3230fdc8d8SChris Lattner #include "lldb/Target/ThreadPlan.h" 3330fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h" 3430fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOut.h" 3530fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepRange.h" 3630fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInRange.h" 3730fdc8d8SChris Lattner 384c5de699SEli Friedman #include "lldb/API/SBAddress.h" 394c5de699SEli Friedman #include "lldb/API/SBDebugger.h" 404f465cffSJim Ingham #include "lldb/API/SBEvent.h" 4173ca05a2SJim Ingham #include "lldb/API/SBFrame.h" 424c5de699SEli Friedman #include "lldb/API/SBProcess.h" 436a831436SKuba Brecka #include "lldb/API/SBThreadCollection.h" 442bdbfd50SJim Ingham #include "lldb/API/SBThreadPlan.h" 4573ca05a2SJim Ingham #include "lldb/API/SBValue.h" 4630fdc8d8SChris Lattner 4730fdc8d8SChris Lattner using namespace lldb; 4830fdc8d8SChris Lattner using namespace lldb_private; 4930fdc8d8SChris Lattner 504f465cffSJim Ingham const char * 514f465cffSJim Ingham SBThread::GetBroadcasterClassName () 524f465cffSJim Ingham { 534f465cffSJim Ingham return Thread::GetStaticBroadcasterClass().AsCString(); 544f465cffSJim Ingham } 554f465cffSJim Ingham 56cfd1acedSGreg Clayton //---------------------------------------------------------------------- 57cfd1acedSGreg Clayton // Constructors 58cfd1acedSGreg Clayton //---------------------------------------------------------------------- 5930fdc8d8SChris Lattner SBThread::SBThread () : 607fdf9ef1SGreg Clayton m_opaque_sp (new ExecutionContextRef()) 6130fdc8d8SChris Lattner { 6230fdc8d8SChris Lattner } 6330fdc8d8SChris Lattner 6430fdc8d8SChris Lattner SBThread::SBThread (const ThreadSP& lldb_object_sp) : 657fdf9ef1SGreg Clayton m_opaque_sp (new ExecutionContextRef(lldb_object_sp)) 6630fdc8d8SChris Lattner { 6730fdc8d8SChris Lattner } 6830fdc8d8SChris Lattner 6992ef5735SGreg Clayton SBThread::SBThread (const SBThread &rhs) : 707fdf9ef1SGreg Clayton m_opaque_sp (new ExecutionContextRef(*rhs.m_opaque_sp)) 7130fdc8d8SChris Lattner { 727fdf9ef1SGreg Clayton 7330fdc8d8SChris Lattner } 7430fdc8d8SChris Lattner 7530fdc8d8SChris Lattner //---------------------------------------------------------------------- 76cfd1acedSGreg Clayton // Assignment operator 77cfd1acedSGreg Clayton //---------------------------------------------------------------------- 78cfd1acedSGreg Clayton 79cfd1acedSGreg Clayton const lldb::SBThread & 80cfd1acedSGreg Clayton SBThread::operator = (const SBThread &rhs) 81cfd1acedSGreg Clayton { 82cfd1acedSGreg Clayton if (this != &rhs) 837fdf9ef1SGreg Clayton *m_opaque_sp = *rhs.m_opaque_sp; 84cfd1acedSGreg Clayton return *this; 85cfd1acedSGreg Clayton } 86cfd1acedSGreg Clayton 87cfd1acedSGreg Clayton //---------------------------------------------------------------------- 8830fdc8d8SChris Lattner // Destructor 8930fdc8d8SChris Lattner //---------------------------------------------------------------------- 9030fdc8d8SChris Lattner SBThread::~SBThread() 9130fdc8d8SChris Lattner { 9230fdc8d8SChris Lattner } 9330fdc8d8SChris Lattner 94b9ffa98cSJason Molenda lldb::SBQueue 95b9ffa98cSJason Molenda SBThread::GetQueue () const 96b9ffa98cSJason Molenda { 97b9ffa98cSJason Molenda SBQueue sb_queue; 98b9ffa98cSJason Molenda QueueSP queue_sp; 99bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 100bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 101b9ffa98cSJason Molenda 102b9ffa98cSJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 103b9ffa98cSJason Molenda if (exe_ctx.HasThreadScope()) 104b9ffa98cSJason Molenda { 105b9ffa98cSJason Molenda Process::StopLocker stop_locker; 106b9ffa98cSJason Molenda if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 107b9ffa98cSJason Molenda { 108b9ffa98cSJason Molenda queue_sp = exe_ctx.GetThreadPtr()->GetQueue(); 109b9ffa98cSJason Molenda if (queue_sp) 110b9ffa98cSJason Molenda { 111b9ffa98cSJason Molenda sb_queue.SetQueue (queue_sp); 112b9ffa98cSJason Molenda } 113b9ffa98cSJason Molenda } 114b9ffa98cSJason Molenda else 115b9ffa98cSJason Molenda { 116b9ffa98cSJason Molenda if (log) 117358cf1eaSGreg Clayton log->Printf ("SBThread(%p)::GetQueue() => error: process is running", 118b9ffa98cSJason Molenda static_cast<void*>(exe_ctx.GetThreadPtr())); 119b9ffa98cSJason Molenda } 120b9ffa98cSJason Molenda } 121b9ffa98cSJason Molenda 122b9ffa98cSJason Molenda if (log) 123358cf1eaSGreg Clayton log->Printf ("SBThread(%p)::GetQueue () => SBQueue(%p)", 124b9ffa98cSJason Molenda static_cast<void*>(exe_ctx.GetThreadPtr()), static_cast<void*>(queue_sp.get())); 125b9ffa98cSJason Molenda 126b9ffa98cSJason Molenda return sb_queue; 127b9ffa98cSJason Molenda } 128b9ffa98cSJason Molenda 129b9ffa98cSJason Molenda 13030fdc8d8SChris Lattner bool 13130fdc8d8SChris Lattner SBThread::IsValid() const 13230fdc8d8SChris Lattner { 133bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 134bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1357fa7dc36SJim Ingham 1367fa7dc36SJim Ingham Target *target = exe_ctx.GetTargetPtr(); 1377fa7dc36SJim Ingham Process *process = exe_ctx.GetProcessPtr(); 1387fa7dc36SJim Ingham if (target && process) 1397fa7dc36SJim Ingham { 1407fa7dc36SJim Ingham Process::StopLocker stop_locker; 1417fa7dc36SJim Ingham if (stop_locker.TryLock(&process->GetRunLock())) 1427fdf9ef1SGreg Clayton return m_opaque_sp->GetThreadSP().get() != NULL; 14330fdc8d8SChris Lattner } 1447fa7dc36SJim Ingham // Without a valid target & process, this thread can't be valid. 1457fa7dc36SJim Ingham return false; 1467fa7dc36SJim Ingham } 14730fdc8d8SChris Lattner 14848e42549SGreg Clayton void 14948e42549SGreg Clayton SBThread::Clear () 15048e42549SGreg Clayton { 1517fdf9ef1SGreg Clayton m_opaque_sp->Clear(); 15248e42549SGreg Clayton } 15348e42549SGreg Clayton 15448e42549SGreg Clayton 15530fdc8d8SChris Lattner StopReason 15630fdc8d8SChris Lattner SBThread::GetStopReason() 15730fdc8d8SChris Lattner { 1585160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 159ceb6b139SCaroline Tice 160ceb6b139SCaroline Tice StopReason reason = eStopReasonInvalid; 161bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 162bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1634fc6cb9cSJim Ingham 1641ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 16530fdc8d8SChris Lattner { 1667fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1677fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1687fdf9ef1SGreg Clayton { 16997d5cf05SGreg Clayton return exe_ctx.GetThreadPtr()->GetStopReason(); 17030fdc8d8SChris Lattner } 171c9858e4dSGreg Clayton else 172c9858e4dSGreg Clayton { 173c9858e4dSGreg Clayton if (log) 174324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetStopReason() => error: process is running", 175324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 176c9858e4dSGreg Clayton } 1777fdf9ef1SGreg Clayton } 178ceb6b139SCaroline Tice 179ceb6b139SCaroline Tice if (log) 180324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetStopReason () => %s", 181324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 182750cd175SCaroline Tice Thread::StopReasonAsCString (reason)); 183ceb6b139SCaroline Tice 184ceb6b139SCaroline Tice return reason; 18530fdc8d8SChris Lattner } 18630fdc8d8SChris Lattner 18730fdc8d8SChris Lattner size_t 1884e78f606SGreg Clayton SBThread::GetStopReasonDataCount () 1894e78f606SGreg Clayton { 190bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 191bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1924fc6cb9cSJim Ingham 1931ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1944e78f606SGreg Clayton { 1957fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1967fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1977fdf9ef1SGreg Clayton { 1981ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); 1994e78f606SGreg Clayton if (stop_info_sp) 2004e78f606SGreg Clayton { 2014e78f606SGreg Clayton StopReason reason = stop_info_sp->GetStopReason(); 2024e78f606SGreg Clayton switch (reason) 2034e78f606SGreg Clayton { 2044e78f606SGreg Clayton case eStopReasonInvalid: 2054e78f606SGreg Clayton case eStopReasonNone: 2064e78f606SGreg Clayton case eStopReasonTrace: 20790ba8115SGreg Clayton case eStopReasonExec: 2084e78f606SGreg Clayton case eStopReasonPlanComplete: 209f85defaeSAndrew Kaylor case eStopReasonThreadExiting: 210afdf842bSKuba Brecka case eStopReasonInstrumentation: 2114e78f606SGreg Clayton // There is no data for these stop reasons. 2124e78f606SGreg Clayton return 0; 2134e78f606SGreg Clayton 2144e78f606SGreg Clayton case eStopReasonBreakpoint: 2154e78f606SGreg Clayton { 2164e78f606SGreg Clayton break_id_t site_id = stop_info_sp->GetValue(); 2171ac04c30SGreg Clayton lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id)); 2184e78f606SGreg Clayton if (bp_site_sp) 2194e78f606SGreg Clayton return bp_site_sp->GetNumberOfOwners () * 2; 2204e78f606SGreg Clayton else 2214e78f606SGreg Clayton return 0; // Breakpoint must have cleared itself... 2224e78f606SGreg Clayton } 2234e78f606SGreg Clayton break; 2244e78f606SGreg Clayton 2254e78f606SGreg Clayton case eStopReasonWatchpoint: 226290fa41bSJohnny Chen return 1; 2274e78f606SGreg Clayton 2284e78f606SGreg Clayton case eStopReasonSignal: 2294e78f606SGreg Clayton return 1; 2304e78f606SGreg Clayton 2314e78f606SGreg Clayton case eStopReasonException: 2324e78f606SGreg Clayton return 1; 2334e78f606SGreg Clayton } 2344e78f606SGreg Clayton } 2354e78f606SGreg Clayton } 236c9858e4dSGreg Clayton else 237c9858e4dSGreg Clayton { 2385160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 239c9858e4dSGreg Clayton if (log) 240324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetStopReasonDataCount() => error: process is running", 241324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 242c9858e4dSGreg Clayton } 2437fdf9ef1SGreg Clayton } 2444e78f606SGreg Clayton return 0; 2454e78f606SGreg Clayton } 2464e78f606SGreg Clayton 2474e78f606SGreg Clayton uint64_t 2484e78f606SGreg Clayton SBThread::GetStopReasonDataAtIndex (uint32_t idx) 2494e78f606SGreg Clayton { 250bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 251bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 2524fc6cb9cSJim Ingham 2531ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 2544e78f606SGreg Clayton { 2557fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 2567fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 2577fdf9ef1SGreg Clayton { 2581ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 2591ac04c30SGreg Clayton StopInfoSP stop_info_sp = thread->GetStopInfo (); 2604e78f606SGreg Clayton if (stop_info_sp) 2614e78f606SGreg Clayton { 2624e78f606SGreg Clayton StopReason reason = stop_info_sp->GetStopReason(); 2634e78f606SGreg Clayton switch (reason) 2644e78f606SGreg Clayton { 2654e78f606SGreg Clayton case eStopReasonInvalid: 2664e78f606SGreg Clayton case eStopReasonNone: 2674e78f606SGreg Clayton case eStopReasonTrace: 26890ba8115SGreg Clayton case eStopReasonExec: 2694e78f606SGreg Clayton case eStopReasonPlanComplete: 270f85defaeSAndrew Kaylor case eStopReasonThreadExiting: 271afdf842bSKuba Brecka case eStopReasonInstrumentation: 2724e78f606SGreg Clayton // There is no data for these stop reasons. 2734e78f606SGreg Clayton return 0; 2744e78f606SGreg Clayton 2754e78f606SGreg Clayton case eStopReasonBreakpoint: 2764e78f606SGreg Clayton { 2774e78f606SGreg Clayton break_id_t site_id = stop_info_sp->GetValue(); 2781ac04c30SGreg Clayton lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id)); 2794e78f606SGreg Clayton if (bp_site_sp) 2804e78f606SGreg Clayton { 2814e78f606SGreg Clayton uint32_t bp_index = idx / 2; 2824e78f606SGreg Clayton BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index)); 2834e78f606SGreg Clayton if (bp_loc_sp) 2844e78f606SGreg Clayton { 2858334e14eSGreg Clayton if (idx & 1) 2864e78f606SGreg Clayton { 2874e78f606SGreg Clayton // Odd idx, return the breakpoint location ID 2884e78f606SGreg Clayton return bp_loc_sp->GetID(); 2894e78f606SGreg Clayton } 2904e78f606SGreg Clayton else 2914e78f606SGreg Clayton { 2924e78f606SGreg Clayton // Even idx, return the breakpoint ID 2934e78f606SGreg Clayton return bp_loc_sp->GetBreakpoint().GetID(); 2944e78f606SGreg Clayton } 2954e78f606SGreg Clayton } 2964e78f606SGreg Clayton } 2974e78f606SGreg Clayton return LLDB_INVALID_BREAK_ID; 2984e78f606SGreg Clayton } 2994e78f606SGreg Clayton break; 3004e78f606SGreg Clayton 3014e78f606SGreg Clayton case eStopReasonWatchpoint: 302290fa41bSJohnny Chen return stop_info_sp->GetValue(); 3034e78f606SGreg Clayton 3044e78f606SGreg Clayton case eStopReasonSignal: 3054e78f606SGreg Clayton return stop_info_sp->GetValue(); 3064e78f606SGreg Clayton 3074e78f606SGreg Clayton case eStopReasonException: 3084e78f606SGreg Clayton return stop_info_sp->GetValue(); 3094e78f606SGreg Clayton } 3104e78f606SGreg Clayton } 3114e78f606SGreg Clayton } 312c9858e4dSGreg Clayton else 313c9858e4dSGreg Clayton { 3145160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 315c9858e4dSGreg Clayton if (log) 316324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetStopReasonDataAtIndex() => error: process is running", 317324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 318c9858e4dSGreg Clayton } 3197fdf9ef1SGreg Clayton } 3204e78f606SGreg Clayton return 0; 3214e78f606SGreg Clayton } 3224e78f606SGreg Clayton 323afdf842bSKuba Brecka bool 324afdf842bSKuba Brecka SBThread::GetStopReasonExtendedInfoAsJSON (lldb::SBStream &stream) 325afdf842bSKuba Brecka { 326afdf842bSKuba Brecka Stream &strm = stream.ref(); 327afdf842bSKuba Brecka 328b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 329b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 330b2e7d28eSJim Ingham 331afdf842bSKuba Brecka if (! exe_ctx.HasThreadScope()) 332afdf842bSKuba Brecka return false; 333afdf842bSKuba Brecka 334afdf842bSKuba Brecka 335afdf842bSKuba Brecka StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo(); 336afdf842bSKuba Brecka StructuredData::ObjectSP info = stop_info->GetExtendedInfo(); 337afdf842bSKuba Brecka if (! info) 338afdf842bSKuba Brecka return false; 339afdf842bSKuba Brecka 340afdf842bSKuba Brecka info->Dump(strm); 341afdf842bSKuba Brecka 342afdf842bSKuba Brecka return true; 343afdf842bSKuba Brecka } 344afdf842bSKuba Brecka 3456a831436SKuba Brecka SBThreadCollection 3466a831436SKuba Brecka SBThread::GetStopReasonExtendedBacktraces (InstrumentationRuntimeType type) 3476a831436SKuba Brecka { 3486a831436SKuba Brecka ThreadCollectionSP threads; 3496a831436SKuba Brecka threads.reset(new ThreadCollection()); 3506a831436SKuba Brecka 3516a831436SKuba Brecka // We currently only support ThreadSanitizer. 3526a831436SKuba Brecka if (type != eInstrumentationRuntimeTypeThreadSanitizer) 3536a831436SKuba Brecka return threads; 3546a831436SKuba Brecka 355b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 356b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 357b2e7d28eSJim Ingham 3586a831436SKuba Brecka if (! exe_ctx.HasThreadScope()) 3591aad8fb7SKuba Brecka return threads; 3606a831436SKuba Brecka 3616a831436SKuba Brecka ProcessSP process_sp = exe_ctx.GetProcessSP(); 3626a831436SKuba Brecka 3636a831436SKuba Brecka StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo(); 3646a831436SKuba Brecka StructuredData::ObjectSP info = stop_info->GetExtendedInfo(); 3656a831436SKuba Brecka if (! info) 3666a831436SKuba Brecka return threads; 3676a831436SKuba Brecka 3681aad8fb7SKuba Brecka return process_sp->GetInstrumentationRuntime(type)->GetBacktracesFromExtendedStopInfo(info); 3696a831436SKuba Brecka } 3706a831436SKuba Brecka 3714e78f606SGreg Clayton size_t 37230fdc8d8SChris Lattner SBThread::GetStopDescription (char *dst, size_t dst_len) 37330fdc8d8SChris Lattner { 3745160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 375ceb6b139SCaroline Tice 376bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 377bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 3784fc6cb9cSJim Ingham 3791ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 38030fdc8d8SChris Lattner { 3817fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 3827fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 3837fdf9ef1SGreg Clayton { 3847fdf9ef1SGreg Clayton 3851ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); 386b15bfc75SJim Ingham if (stop_info_sp) 38730fdc8d8SChris Lattner { 388b15bfc75SJim Ingham const char *stop_desc = stop_info_sp->GetDescription(); 38930fdc8d8SChris Lattner if (stop_desc) 39030fdc8d8SChris Lattner { 391ceb6b139SCaroline Tice if (log) 3924838131bSGreg Clayton log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"", 393324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 394324a1036SSaleem Abdulrasool stop_desc); 39530fdc8d8SChris Lattner if (dst) 39630fdc8d8SChris Lattner return ::snprintf (dst, dst_len, "%s", stop_desc); 39730fdc8d8SChris Lattner else 39830fdc8d8SChris Lattner { 39930fdc8d8SChris Lattner // NULL dst passed in, return the length needed to contain the description 40030fdc8d8SChris Lattner return ::strlen (stop_desc) + 1; // Include the NULL byte for size 40130fdc8d8SChris Lattner } 40230fdc8d8SChris Lattner } 40330fdc8d8SChris Lattner else 40430fdc8d8SChris Lattner { 40530fdc8d8SChris Lattner size_t stop_desc_len = 0; 406b15bfc75SJim Ingham switch (stop_info_sp->GetStopReason()) 40730fdc8d8SChris Lattner { 40830fdc8d8SChris Lattner case eStopReasonTrace: 40930fdc8d8SChris Lattner case eStopReasonPlanComplete: 41030fdc8d8SChris Lattner { 41130fdc8d8SChris Lattner static char trace_desc[] = "step"; 41230fdc8d8SChris Lattner stop_desc = trace_desc; 41330fdc8d8SChris Lattner stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size 41430fdc8d8SChris Lattner } 41530fdc8d8SChris Lattner break; 41630fdc8d8SChris Lattner 41730fdc8d8SChris Lattner case eStopReasonBreakpoint: 41830fdc8d8SChris Lattner { 41930fdc8d8SChris Lattner static char bp_desc[] = "breakpoint hit"; 42030fdc8d8SChris Lattner stop_desc = bp_desc; 42130fdc8d8SChris Lattner stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size 42230fdc8d8SChris Lattner } 42330fdc8d8SChris Lattner break; 42430fdc8d8SChris Lattner 42530fdc8d8SChris Lattner case eStopReasonWatchpoint: 42630fdc8d8SChris Lattner { 42730fdc8d8SChris Lattner static char wp_desc[] = "watchpoint hit"; 42830fdc8d8SChris Lattner stop_desc = wp_desc; 42930fdc8d8SChris Lattner stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size 43030fdc8d8SChris Lattner } 43130fdc8d8SChris Lattner break; 43230fdc8d8SChris Lattner 43330fdc8d8SChris Lattner case eStopReasonSignal: 43430fdc8d8SChris Lattner { 43598d0a4b3SChaoren Lin stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals()->GetSignalAsCString(stop_info_sp->GetValue()); 43630fdc8d8SChris Lattner if (stop_desc == NULL || stop_desc[0] == '\0') 43730fdc8d8SChris Lattner { 43830fdc8d8SChris Lattner static char signal_desc[] = "signal"; 43930fdc8d8SChris Lattner stop_desc = signal_desc; 44030fdc8d8SChris Lattner stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size 44130fdc8d8SChris Lattner } 44230fdc8d8SChris Lattner } 44330fdc8d8SChris Lattner break; 44430fdc8d8SChris Lattner 44530fdc8d8SChris Lattner case eStopReasonException: 44630fdc8d8SChris Lattner { 44730fdc8d8SChris Lattner char exc_desc[] = "exception"; 44830fdc8d8SChris Lattner stop_desc = exc_desc; 44930fdc8d8SChris Lattner stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size 45030fdc8d8SChris Lattner } 45130fdc8d8SChris Lattner break; 452c982c768SGreg Clayton 45390ba8115SGreg Clayton case eStopReasonExec: 45490ba8115SGreg Clayton { 45590ba8115SGreg Clayton char exc_desc[] = "exec"; 45690ba8115SGreg Clayton stop_desc = exc_desc; 45790ba8115SGreg Clayton stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size 45890ba8115SGreg Clayton } 45990ba8115SGreg Clayton break; 46090ba8115SGreg Clayton 461f85defaeSAndrew Kaylor case eStopReasonThreadExiting: 462f85defaeSAndrew Kaylor { 463f85defaeSAndrew Kaylor char limbo_desc[] = "thread exiting"; 464f85defaeSAndrew Kaylor stop_desc = limbo_desc; 465f85defaeSAndrew Kaylor stop_desc_len = sizeof(limbo_desc); 466f85defaeSAndrew Kaylor } 467f85defaeSAndrew Kaylor break; 468c982c768SGreg Clayton default: 469c982c768SGreg Clayton break; 47030fdc8d8SChris Lattner } 47130fdc8d8SChris Lattner 47230fdc8d8SChris Lattner if (stop_desc && stop_desc[0]) 47330fdc8d8SChris Lattner { 474ceb6b139SCaroline Tice if (log) 47593aa84e8SGreg Clayton log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'", 476324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 477324a1036SSaleem Abdulrasool stop_desc); 478ceb6b139SCaroline Tice 47930fdc8d8SChris Lattner if (dst) 48030fdc8d8SChris Lattner return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte 48130fdc8d8SChris Lattner 48230fdc8d8SChris Lattner if (stop_desc_len == 0) 48330fdc8d8SChris Lattner stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte 48430fdc8d8SChris Lattner 48530fdc8d8SChris Lattner return stop_desc_len; 48630fdc8d8SChris Lattner } 48730fdc8d8SChris Lattner } 48830fdc8d8SChris Lattner } 48930fdc8d8SChris Lattner } 490c9858e4dSGreg Clayton else 491c9858e4dSGreg Clayton { 4925160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 493c9858e4dSGreg Clayton if (log) 494324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetStopDescription() => error: process is running", 495324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 496c9858e4dSGreg Clayton } 4977fdf9ef1SGreg Clayton } 49830fdc8d8SChris Lattner if (dst) 49930fdc8d8SChris Lattner *dst = 0; 50030fdc8d8SChris Lattner return 0; 50130fdc8d8SChris Lattner } 50230fdc8d8SChris Lattner 50373ca05a2SJim Ingham SBValue 50473ca05a2SJim Ingham SBThread::GetStopReturnValue () 50573ca05a2SJim Ingham { 5065160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 50773ca05a2SJim Ingham ValueObjectSP return_valobj_sp; 508bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 509bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 5104fc6cb9cSJim Ingham 5111ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 51273ca05a2SJim Ingham { 5137fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 5147fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 5157fdf9ef1SGreg Clayton { 5161ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); 51773ca05a2SJim Ingham if (stop_info_sp) 51873ca05a2SJim Ingham { 51973ca05a2SJim Ingham return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp); 52073ca05a2SJim Ingham } 52173ca05a2SJim Ingham } 522c9858e4dSGreg Clayton else 523c9858e4dSGreg Clayton { 524c9858e4dSGreg Clayton if (log) 525324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetStopReturnValue() => error: process is running", 526324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 527c9858e4dSGreg Clayton } 5287fdf9ef1SGreg Clayton } 52973ca05a2SJim Ingham 53073ca05a2SJim Ingham if (log) 531324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", 532324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 53373ca05a2SJim Ingham return_valobj_sp.get() 53473ca05a2SJim Ingham ? return_valobj_sp->GetValueAsCString() 53573ca05a2SJim Ingham : "<no return value>"); 53673ca05a2SJim Ingham 53773ca05a2SJim Ingham return SBValue (return_valobj_sp); 53873ca05a2SJim Ingham } 53973ca05a2SJim Ingham 54030fdc8d8SChris Lattner void 54130fdc8d8SChris Lattner SBThread::SetThread (const ThreadSP& lldb_object_sp) 54230fdc8d8SChris Lattner { 5437fdf9ef1SGreg Clayton m_opaque_sp->SetThreadSP (lldb_object_sp); 54430fdc8d8SChris Lattner } 54530fdc8d8SChris Lattner 54630fdc8d8SChris Lattner lldb::tid_t 54730fdc8d8SChris Lattner SBThread::GetThreadID () const 54830fdc8d8SChris Lattner { 5497fdf9ef1SGreg Clayton ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 55017a6ad05SGreg Clayton if (thread_sp) 5511ac04c30SGreg Clayton return thread_sp->GetID(); 5521ac04c30SGreg Clayton return LLDB_INVALID_THREAD_ID; 55330fdc8d8SChris Lattner } 55430fdc8d8SChris Lattner 55530fdc8d8SChris Lattner uint32_t 55630fdc8d8SChris Lattner SBThread::GetIndexID () const 55730fdc8d8SChris Lattner { 5587fdf9ef1SGreg Clayton ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 55917a6ad05SGreg Clayton if (thread_sp) 56017a6ad05SGreg Clayton return thread_sp->GetIndexID(); 56130fdc8d8SChris Lattner return LLDB_INVALID_INDEX32; 56230fdc8d8SChris Lattner } 5631ac04c30SGreg Clayton 56430fdc8d8SChris Lattner const char * 56530fdc8d8SChris Lattner SBThread::GetName () const 56630fdc8d8SChris Lattner { 5675160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 5684838131bSGreg Clayton const char *name = NULL; 569bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 570bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 5714fc6cb9cSJim Ingham 5721ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 573af67cecdSGreg Clayton { 5747fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 5757fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 5767fdf9ef1SGreg Clayton { 5771ac04c30SGreg Clayton name = exe_ctx.GetThreadPtr()->GetName(); 578af67cecdSGreg Clayton } 579c9858e4dSGreg Clayton else 580c9858e4dSGreg Clayton { 581c9858e4dSGreg Clayton if (log) 582324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetName() => error: process is running", 583324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 584c9858e4dSGreg Clayton } 5857fdf9ef1SGreg Clayton } 586ceb6b139SCaroline Tice 587ceb6b139SCaroline Tice if (log) 588324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetName () => %s", 589324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 590324a1036SSaleem Abdulrasool name ? name : "NULL"); 591ceb6b139SCaroline Tice 5924838131bSGreg Clayton return name; 59330fdc8d8SChris Lattner } 59430fdc8d8SChris Lattner 59530fdc8d8SChris Lattner const char * 59630fdc8d8SChris Lattner SBThread::GetQueueName () const 59730fdc8d8SChris Lattner { 5984838131bSGreg Clayton const char *name = NULL; 599bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 600bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 6014fc6cb9cSJim Ingham 6025160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 6031ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 604af67cecdSGreg Clayton { 6057fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 6067fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 6077fdf9ef1SGreg Clayton { 6081ac04c30SGreg Clayton name = exe_ctx.GetThreadPtr()->GetQueueName(); 609af67cecdSGreg Clayton } 610c9858e4dSGreg Clayton else 611c9858e4dSGreg Clayton { 612c9858e4dSGreg Clayton if (log) 613324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetQueueName() => error: process is running", 614324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 615c9858e4dSGreg Clayton } 6167fdf9ef1SGreg Clayton } 617ceb6b139SCaroline Tice 618ceb6b139SCaroline Tice if (log) 619324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetQueueName () => %s", 620324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 621324a1036SSaleem Abdulrasool name ? name : "NULL"); 622ceb6b139SCaroline Tice 6234838131bSGreg Clayton return name; 62430fdc8d8SChris Lattner } 62530fdc8d8SChris Lattner 6264fdb5863SJason Molenda lldb::queue_id_t 6274fdb5863SJason Molenda SBThread::GetQueueID () const 6284fdb5863SJason Molenda { 6294fdb5863SJason Molenda queue_id_t id = LLDB_INVALID_QUEUE_ID; 630bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 631bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 6324fdb5863SJason Molenda 6334fdb5863SJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 6344fdb5863SJason Molenda if (exe_ctx.HasThreadScope()) 6354fdb5863SJason Molenda { 6364fdb5863SJason Molenda Process::StopLocker stop_locker; 6374fdb5863SJason Molenda if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 6384fdb5863SJason Molenda { 6394fdb5863SJason Molenda id = exe_ctx.GetThreadPtr()->GetQueueID(); 6404fdb5863SJason Molenda } 6414fdb5863SJason Molenda else 6424fdb5863SJason Molenda { 6434fdb5863SJason Molenda if (log) 644324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetQueueID() => error: process is running", 645324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 6464fdb5863SJason Molenda } 6474fdb5863SJason Molenda } 6484fdb5863SJason Molenda 6494fdb5863SJason Molenda if (log) 650324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetQueueID () => 0x%" PRIx64, 651324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), id); 6524fdb5863SJason Molenda 6534fdb5863SJason Molenda return id; 6544fdb5863SJason Molenda } 6554fdb5863SJason Molenda 656705b1809SJason Molenda bool 657705b1809SJason Molenda SBThread::GetInfoItemByPathAsString (const char *path, SBStream &strm) 658705b1809SJason Molenda { 659705b1809SJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 660705b1809SJason Molenda bool success = false; 661bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 662bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 663705b1809SJason Molenda 664705b1809SJason Molenda if (exe_ctx.HasThreadScope()) 665705b1809SJason Molenda { 666705b1809SJason Molenda Process::StopLocker stop_locker; 667705b1809SJason Molenda if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 668705b1809SJason Molenda { 669705b1809SJason Molenda Thread *thread = exe_ctx.GetThreadPtr(); 670705b1809SJason Molenda StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo(); 671705b1809SJason Molenda if (info_root_sp) 672705b1809SJason Molenda { 673705b1809SJason Molenda StructuredData::ObjectSP node = info_root_sp->GetObjectForDotSeparatedPath (path); 674705b1809SJason Molenda if (node) 675705b1809SJason Molenda { 676705b1809SJason Molenda if (node->GetType() == StructuredData::Type::eTypeString) 677705b1809SJason Molenda { 678705b1809SJason Molenda strm.Printf ("%s", node->GetAsString()->GetValue().c_str()); 679705b1809SJason Molenda success = true; 680705b1809SJason Molenda } 681705b1809SJason Molenda if (node->GetType() == StructuredData::Type::eTypeInteger) 682705b1809SJason Molenda { 683705b1809SJason Molenda strm.Printf ("0x%" PRIx64, node->GetAsInteger()->GetValue()); 684705b1809SJason Molenda success = true; 685705b1809SJason Molenda } 686705b1809SJason Molenda if (node->GetType() == StructuredData::Type::eTypeFloat) 687705b1809SJason Molenda { 688705b1809SJason Molenda strm.Printf ("0x%f", node->GetAsFloat()->GetValue()); 689705b1809SJason Molenda success = true; 690705b1809SJason Molenda } 691705b1809SJason Molenda if (node->GetType() == StructuredData::Type::eTypeBoolean) 692705b1809SJason Molenda { 693705b1809SJason Molenda if (node->GetAsBoolean()->GetValue() == true) 694705b1809SJason Molenda strm.Printf ("true"); 695705b1809SJason Molenda else 696705b1809SJason Molenda strm.Printf ("false"); 697705b1809SJason Molenda success = true; 698705b1809SJason Molenda } 699705b1809SJason Molenda if (node->GetType() == StructuredData::Type::eTypeNull) 700705b1809SJason Molenda { 701705b1809SJason Molenda strm.Printf ("null"); 702705b1809SJason Molenda success = true; 703705b1809SJason Molenda } 704705b1809SJason Molenda } 705705b1809SJason Molenda } 706705b1809SJason Molenda } 707705b1809SJason Molenda else 708705b1809SJason Molenda { 709705b1809SJason Molenda if (log) 710705b1809SJason Molenda log->Printf ("SBThread(%p)::GetInfoItemByPathAsString() => error: process is running", 711705b1809SJason Molenda static_cast<void*>(exe_ctx.GetThreadPtr())); 712705b1809SJason Molenda } 713705b1809SJason Molenda } 714705b1809SJason Molenda 715705b1809SJason Molenda if (log) 716705b1809SJason Molenda log->Printf ("SBThread(%p)::GetInfoItemByPathAsString () => %s", 717705b1809SJason Molenda static_cast<void*>(exe_ctx.GetThreadPtr()), 718705b1809SJason Molenda strm.GetData()); 719705b1809SJason Molenda 720705b1809SJason Molenda return success; 721705b1809SJason Molenda } 722705b1809SJason Molenda 723705b1809SJason Molenda 72464e7ead1SJim Ingham SBError 72564e7ead1SJim Ingham SBThread::ResumeNewPlan (ExecutionContext &exe_ctx, ThreadPlan *new_plan) 72664e7ead1SJim Ingham { 72764e7ead1SJim Ingham SBError sb_error; 72864e7ead1SJim Ingham 72964e7ead1SJim Ingham Process *process = exe_ctx.GetProcessPtr(); 73064e7ead1SJim Ingham if (!process) 73164e7ead1SJim Ingham { 73264e7ead1SJim Ingham sb_error.SetErrorString("No process in SBThread::ResumeNewPlan"); 73364e7ead1SJim Ingham return sb_error; 73464e7ead1SJim Ingham } 73564e7ead1SJim Ingham 73664e7ead1SJim Ingham Thread *thread = exe_ctx.GetThreadPtr(); 73764e7ead1SJim Ingham if (!thread) 73864e7ead1SJim Ingham { 73964e7ead1SJim Ingham sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan"); 74064e7ead1SJim Ingham return sb_error; 74164e7ead1SJim Ingham } 74264e7ead1SJim Ingham 74364e7ead1SJim Ingham // User level plans should be Master Plans so they can be interrupted, other plans executed, and 74464e7ead1SJim Ingham // then a "continue" will resume the plan. 74564e7ead1SJim Ingham if (new_plan != NULL) 74664e7ead1SJim Ingham { 74764e7ead1SJim Ingham new_plan->SetIsMasterPlan(true); 74864e7ead1SJim Ingham new_plan->SetOkayToDiscard(false); 74964e7ead1SJim Ingham } 75064e7ead1SJim Ingham 75164e7ead1SJim Ingham // Why do we need to set the current thread by ID here??? 75264e7ead1SJim Ingham process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 75364e7ead1SJim Ingham 754dc6224e0SGreg Clayton if (process->GetTarget().GetDebugger().GetAsyncExecution ()) 755dc6224e0SGreg Clayton sb_error.ref() = process->Resume (); 756dc6224e0SGreg Clayton else 757dc6224e0SGreg Clayton sb_error.ref() = process->ResumeSynchronous (NULL); 75864e7ead1SJim Ingham 75964e7ead1SJim Ingham return sb_error; 76064e7ead1SJim Ingham } 76130fdc8d8SChris Lattner 76230fdc8d8SChris Lattner void 76330fdc8d8SChris Lattner SBThread::StepOver (lldb::RunMode stop_other_threads) 76430fdc8d8SChris Lattner { 7655160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 766ceb6b139SCaroline Tice 767bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 768bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 76917a6ad05SGreg Clayton 770ceb6b139SCaroline Tice if (log) 771324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", 772324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 773ceb6b139SCaroline Tice Thread::RunModeAsCString (stop_other_threads)); 774ceb6b139SCaroline Tice 7751ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 77630fdc8d8SChris Lattner { 7771ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 7787ba6e991SJim Ingham bool abort_other_plans = false; 779b57e4a1bSJason Molenda StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0)); 78030fdc8d8SChris Lattner 7814d56e9c1SJim Ingham ThreadPlanSP new_plan_sp; 78230fdc8d8SChris Lattner if (frame_sp) 78330fdc8d8SChris Lattner { 78430fdc8d8SChris Lattner if (frame_sp->HasDebugInformation ()) 78530fdc8d8SChris Lattner { 7864b4b2478SJim Ingham const LazyBool avoid_no_debug = eLazyBoolCalculate; 78730fdc8d8SChris Lattner SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 7884d56e9c1SJim Ingham new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans, 78925d5b10bSJason Molenda sc.line_entry, 79030fdc8d8SChris Lattner sc, 7914b4b2478SJim Ingham stop_other_threads, 7924b4b2478SJim Ingham avoid_no_debug); 79330fdc8d8SChris Lattner } 79430fdc8d8SChris Lattner else 79530fdc8d8SChris Lattner { 7964d56e9c1SJim Ingham new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, 79730fdc8d8SChris Lattner abort_other_plans, 79830fdc8d8SChris Lattner stop_other_threads); 79930fdc8d8SChris Lattner } 80030fdc8d8SChris Lattner } 80130fdc8d8SChris Lattner 80264e7ead1SJim Ingham // This returns an error, we should use it! 8034d56e9c1SJim Ingham ResumeNewPlan (exe_ctx, new_plan_sp.get()); 80430fdc8d8SChris Lattner } 80530fdc8d8SChris Lattner } 80630fdc8d8SChris Lattner 80730fdc8d8SChris Lattner void 80830fdc8d8SChris Lattner SBThread::StepInto (lldb::RunMode stop_other_threads) 80930fdc8d8SChris Lattner { 810c627682eSJim Ingham StepInto (NULL, stop_other_threads); 811c627682eSJim Ingham } 812c627682eSJim Ingham 813c627682eSJim Ingham void 814c627682eSJim Ingham SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads) 815c627682eSJim Ingham { 816cbf6f9b2SJim Ingham SBError error; 817cbf6f9b2SJim Ingham StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads); 818cbf6f9b2SJim Ingham } 819cbf6f9b2SJim Ingham 820cbf6f9b2SJim Ingham void 821cbf6f9b2SJim Ingham SBThread::StepInto (const char *target_name, uint32_t end_line, SBError &error, lldb::RunMode stop_other_threads) 822cbf6f9b2SJim Ingham { 8235160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 824ceb6b139SCaroline Tice 825bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 826bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 82717a6ad05SGreg Clayton 82817a6ad05SGreg Clayton if (log) 829c627682eSJim Ingham log->Printf ("SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')", 830324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 831c627682eSJim Ingham target_name? target_name: "<NULL>", 83217a6ad05SGreg Clayton Thread::RunModeAsCString (stop_other_threads)); 833c627682eSJim Ingham 8341ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 83530fdc8d8SChris Lattner { 8367ba6e991SJim Ingham bool abort_other_plans = false; 83730fdc8d8SChris Lattner 8381ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 839b57e4a1bSJason Molenda StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0)); 8404d56e9c1SJim Ingham ThreadPlanSP new_plan_sp; 84130fdc8d8SChris Lattner 84230fdc8d8SChris Lattner if (frame_sp && frame_sp->HasDebugInformation ()) 84330fdc8d8SChris Lattner { 844cbf6f9b2SJim Ingham SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 845cbf6f9b2SJim Ingham AddressRange range; 846cbf6f9b2SJim Ingham if (end_line == LLDB_INVALID_LINE_NUMBER) 847cbf6f9b2SJim Ingham range = sc.line_entry.range; 848cbf6f9b2SJim Ingham else 849cbf6f9b2SJim Ingham { 850cbf6f9b2SJim Ingham if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref())) 851cbf6f9b2SJim Ingham return; 852cbf6f9b2SJim Ingham } 853cbf6f9b2SJim Ingham 8544b4b2478SJim Ingham const LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate; 8554b4b2478SJim Ingham const LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate; 8564d56e9c1SJim Ingham new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans, 857cbf6f9b2SJim Ingham range, 85830fdc8d8SChris Lattner sc, 859c627682eSJim Ingham target_name, 860474966a4SGreg Clayton stop_other_threads, 8614b4b2478SJim Ingham step_in_avoids_code_without_debug_info, 8624b4b2478SJim Ingham step_out_avoids_code_without_debug_info); 86330fdc8d8SChris Lattner } 86430fdc8d8SChris Lattner else 86530fdc8d8SChris Lattner { 8664d56e9c1SJim Ingham new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, 86730fdc8d8SChris Lattner abort_other_plans, 86830fdc8d8SChris Lattner stop_other_threads); 86930fdc8d8SChris Lattner } 87030fdc8d8SChris Lattner 871cbf6f9b2SJim Ingham error = ResumeNewPlan (exe_ctx, new_plan_sp.get()); 87230fdc8d8SChris Lattner } 87330fdc8d8SChris Lattner } 87430fdc8d8SChris Lattner 87530fdc8d8SChris Lattner void 87630fdc8d8SChris Lattner SBThread::StepOut () 87730fdc8d8SChris Lattner { 8785160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 879ceb6b139SCaroline Tice 880bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 881bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 8824fc6cb9cSJim Ingham 88317a6ad05SGreg Clayton if (log) 884324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::StepOut ()", 885324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 88617a6ad05SGreg Clayton 8871ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 88830fdc8d8SChris Lattner { 8897ba6e991SJim Ingham bool abort_other_plans = false; 89094b09246SJim Ingham bool stop_other_threads = false; 89130fdc8d8SChris Lattner 8921ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 8931ac04c30SGreg Clayton 8944b4b2478SJim Ingham const LazyBool avoid_no_debug = eLazyBoolCalculate; 8954d56e9c1SJim Ingham ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans, 896481cef25SGreg Clayton NULL, 897481cef25SGreg Clayton false, 898481cef25SGreg Clayton stop_other_threads, 899481cef25SGreg Clayton eVoteYes, 900481cef25SGreg Clayton eVoteNoOpinion, 9014b4b2478SJim Ingham 0, 9024b4b2478SJim Ingham avoid_no_debug)); 903481cef25SGreg Clayton 90464e7ead1SJim Ingham // This returns an error, we should use it! 9054d56e9c1SJim Ingham ResumeNewPlan (exe_ctx, new_plan_sp.get()); 906481cef25SGreg Clayton } 907481cef25SGreg Clayton } 908481cef25SGreg Clayton 909481cef25SGreg Clayton void 910481cef25SGreg Clayton SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame) 911481cef25SGreg Clayton { 9125160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 913481cef25SGreg Clayton 914bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 915bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 9164fc6cb9cSJim Ingham 917989a7558SJim Ingham if (!sb_frame.IsValid()) 918989a7558SJim Ingham { 919989a7558SJim Ingham if (log) 920989a7558SJim Ingham log->Printf("SBThread(%p)::StepOutOfFrame passed an invalid frame, returning.", 921989a7558SJim Ingham static_cast<void*>(exe_ctx.GetThreadPtr())); 922989a7558SJim Ingham return; 923989a7558SJim Ingham } 924989a7558SJim Ingham 925b57e4a1bSJason Molenda StackFrameSP frame_sp (sb_frame.GetFrameSP()); 926481cef25SGreg Clayton if (log) 927481cef25SGreg Clayton { 928481cef25SGreg Clayton SBStream frame_desc_strm; 929481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 930324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", 931324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 932324a1036SSaleem Abdulrasool static_cast<void*>(frame_sp.get()), 933324a1036SSaleem Abdulrasool frame_desc_strm.GetData()); 934481cef25SGreg Clayton } 935481cef25SGreg Clayton 9361ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 937481cef25SGreg Clayton { 9387ba6e991SJim Ingham bool abort_other_plans = false; 93994b09246SJim Ingham bool stop_other_threads = false; 9401ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 941989a7558SJim Ingham if (sb_frame.GetThread().GetThreadID() != thread->GetID()) 942989a7558SJim Ingham { 9431ef6e4c8SBruce Mitchener log->Printf("SBThread(%p)::StepOutOfFrame passed a frame from another thread (0x%" PRIx64 " vrs. 0x%" PRIx64 ", returning.", 944989a7558SJim Ingham static_cast<void*>(exe_ctx.GetThreadPtr()), 945989a7558SJim Ingham sb_frame.GetThread().GetThreadID(), 946989a7558SJim Ingham thread->GetID()); 947989a7558SJim Ingham } 948481cef25SGreg Clayton 9494d56e9c1SJim Ingham ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans, 950481cef25SGreg Clayton NULL, 951481cef25SGreg Clayton false, 952481cef25SGreg Clayton stop_other_threads, 953481cef25SGreg Clayton eVoteYes, 954481cef25SGreg Clayton eVoteNoOpinion, 9554d56e9c1SJim Ingham frame_sp->GetFrameIndex())); 95630fdc8d8SChris Lattner 95764e7ead1SJim Ingham // This returns an error, we should use it! 9584d56e9c1SJim Ingham ResumeNewPlan (exe_ctx, new_plan_sp.get()); 95930fdc8d8SChris Lattner } 96030fdc8d8SChris Lattner } 96130fdc8d8SChris Lattner 96230fdc8d8SChris Lattner void 96330fdc8d8SChris Lattner SBThread::StepInstruction (bool step_over) 96430fdc8d8SChris Lattner { 9655160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 966ceb6b139SCaroline Tice 967bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 968bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 969ceb6b139SCaroline Tice 97017a6ad05SGreg Clayton if (log) 971324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", 972324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), step_over); 97317a6ad05SGreg Clayton 9741ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 97530fdc8d8SChris Lattner { 9761ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 9774d56e9c1SJim Ingham ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true)); 97864e7ead1SJim Ingham 97964e7ead1SJim Ingham // This returns an error, we should use it! 9804d56e9c1SJim Ingham ResumeNewPlan (exe_ctx, new_plan_sp.get()); 98130fdc8d8SChris Lattner } 98230fdc8d8SChris Lattner } 98330fdc8d8SChris Lattner 98430fdc8d8SChris Lattner void 98530fdc8d8SChris Lattner SBThread::RunToAddress (lldb::addr_t addr) 98630fdc8d8SChris Lattner { 9875160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 988ceb6b139SCaroline Tice 989bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 990bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 991ceb6b139SCaroline Tice 99217a6ad05SGreg Clayton if (log) 993324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")", 994324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), addr); 99517a6ad05SGreg Clayton 9961ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 99730fdc8d8SChris Lattner { 9987ba6e991SJim Ingham bool abort_other_plans = false; 99930fdc8d8SChris Lattner bool stop_other_threads = true; 100030fdc8d8SChris Lattner 1001e72dfb32SGreg Clayton Address target_addr (addr); 100230fdc8d8SChris Lattner 10031ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 10041ac04c30SGreg Clayton 10052bdbfd50SJim Ingham ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress (abort_other_plans, 10062bdbfd50SJim Ingham target_addr, 10072bdbfd50SJim Ingham stop_other_threads)); 100864e7ead1SJim Ingham 100964e7ead1SJim Ingham // This returns an error, we should use it! 10104d56e9c1SJim Ingham ResumeNewPlan (exe_ctx, new_plan_sp.get()); 101130fdc8d8SChris Lattner } 101230fdc8d8SChris Lattner } 101330fdc8d8SChris Lattner 1014481cef25SGreg Clayton SBError 1015481cef25SGreg Clayton SBThread::StepOverUntil (lldb::SBFrame &sb_frame, 1016481cef25SGreg Clayton lldb::SBFileSpec &sb_file_spec, 1017481cef25SGreg Clayton uint32_t line) 1018481cef25SGreg Clayton { 1019481cef25SGreg Clayton SBError sb_error; 10205160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1021481cef25SGreg Clayton char path[PATH_MAX]; 1022481cef25SGreg Clayton 1023bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1024bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 10254fc6cb9cSJim Ingham 1026b57e4a1bSJason Molenda StackFrameSP frame_sp (sb_frame.GetFrameSP()); 102717a6ad05SGreg Clayton 1028481cef25SGreg Clayton if (log) 1029481cef25SGreg Clayton { 1030481cef25SGreg Clayton SBStream frame_desc_strm; 1031481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 1032481cef25SGreg Clayton sb_file_spec->GetPath (path, sizeof(path)); 1033481cef25SGreg Clayton log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)", 1034324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 1035324a1036SSaleem Abdulrasool static_cast<void*>(frame_sp.get()), 1036324a1036SSaleem Abdulrasool frame_desc_strm.GetData(), path, line); 1037481cef25SGreg Clayton } 1038481cef25SGreg Clayton 10391ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1040481cef25SGreg Clayton { 10411ac04c30SGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 10421ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 1043481cef25SGreg Clayton 1044481cef25SGreg Clayton if (line == 0) 1045481cef25SGreg Clayton { 1046481cef25SGreg Clayton sb_error.SetErrorString("invalid line argument"); 1047481cef25SGreg Clayton return sb_error; 1048481cef25SGreg Clayton } 1049481cef25SGreg Clayton 1050b9556accSGreg Clayton if (!frame_sp) 1051481cef25SGreg Clayton { 10521ac04c30SGreg Clayton frame_sp = thread->GetSelectedFrame (); 1053481cef25SGreg Clayton if (!frame_sp) 10541ac04c30SGreg Clayton frame_sp = thread->GetStackFrameAtIndex (0); 1055481cef25SGreg Clayton } 1056481cef25SGreg Clayton 1057481cef25SGreg Clayton SymbolContext frame_sc; 1058481cef25SGreg Clayton if (!frame_sp) 1059481cef25SGreg Clayton { 1060481cef25SGreg Clayton sb_error.SetErrorString("no valid frames in thread to step"); 1061481cef25SGreg Clayton return sb_error; 1062481cef25SGreg Clayton } 1063481cef25SGreg Clayton 1064481cef25SGreg Clayton // If we have a frame, get its line 1065481cef25SGreg Clayton frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit | 1066481cef25SGreg Clayton eSymbolContextFunction | 1067481cef25SGreg Clayton eSymbolContextLineEntry | 1068481cef25SGreg Clayton eSymbolContextSymbol ); 1069481cef25SGreg Clayton 1070481cef25SGreg Clayton if (frame_sc.comp_unit == NULL) 1071481cef25SGreg Clayton { 1072481cef25SGreg Clayton sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex()); 1073481cef25SGreg Clayton return sb_error; 1074481cef25SGreg Clayton } 1075481cef25SGreg Clayton 1076481cef25SGreg Clayton FileSpec step_file_spec; 1077481cef25SGreg Clayton if (sb_file_spec.IsValid()) 1078481cef25SGreg Clayton { 1079481cef25SGreg Clayton // The file spec passed in was valid, so use it 1080481cef25SGreg Clayton step_file_spec = sb_file_spec.ref(); 1081481cef25SGreg Clayton } 1082481cef25SGreg Clayton else 1083481cef25SGreg Clayton { 1084481cef25SGreg Clayton if (frame_sc.line_entry.IsValid()) 1085481cef25SGreg Clayton step_file_spec = frame_sc.line_entry.file; 1086481cef25SGreg Clayton else 1087481cef25SGreg Clayton { 1088481cef25SGreg Clayton sb_error.SetErrorString("invalid file argument or no file for frame"); 1089481cef25SGreg Clayton return sb_error; 1090481cef25SGreg Clayton } 1091481cef25SGreg Clayton } 1092481cef25SGreg Clayton 10939b70ddb3SJim Ingham // Grab the current function, then we will make sure the "until" address is 10949b70ddb3SJim Ingham // within the function. We discard addresses that are out of the current 10959b70ddb3SJim Ingham // function, and then if there are no addresses remaining, give an appropriate 10969b70ddb3SJim Ingham // error message. 10979b70ddb3SJim Ingham 10989b70ddb3SJim Ingham bool all_in_function = true; 10999b70ddb3SJim Ingham AddressRange fun_range = frame_sc.function->GetAddressRange(); 11009b70ddb3SJim Ingham 1101481cef25SGreg Clayton std::vector<addr_t> step_over_until_addrs; 11027ba6e991SJim Ingham const bool abort_other_plans = false; 1103c02e3344SJim Ingham const bool stop_other_threads = false; 1104481cef25SGreg Clayton const bool check_inlines = true; 1105481cef25SGreg Clayton const bool exact = false; 1106481cef25SGreg Clayton 1107481cef25SGreg Clayton SymbolContextList sc_list; 11089b70ddb3SJim Ingham const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec, 11099b70ddb3SJim Ingham line, 11109b70ddb3SJim Ingham check_inlines, 11119b70ddb3SJim Ingham exact, 11129b70ddb3SJim Ingham eSymbolContextLineEntry, 11139b70ddb3SJim Ingham sc_list); 1114481cef25SGreg Clayton if (num_matches > 0) 1115481cef25SGreg Clayton { 1116481cef25SGreg Clayton SymbolContext sc; 1117481cef25SGreg Clayton for (uint32_t i=0; i<num_matches; ++i) 1118481cef25SGreg Clayton { 1119481cef25SGreg Clayton if (sc_list.GetContextAtIndex(i, sc)) 1120481cef25SGreg Clayton { 11219b70ddb3SJim Ingham addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target); 1122481cef25SGreg Clayton if (step_addr != LLDB_INVALID_ADDRESS) 1123481cef25SGreg Clayton { 11249b70ddb3SJim Ingham if (fun_range.ContainsLoadAddress(step_addr, target)) 1125481cef25SGreg Clayton step_over_until_addrs.push_back(step_addr); 11269b70ddb3SJim Ingham else 11279b70ddb3SJim Ingham all_in_function = false; 1128481cef25SGreg Clayton } 1129481cef25SGreg Clayton } 1130481cef25SGreg Clayton } 1131481cef25SGreg Clayton } 1132481cef25SGreg Clayton 1133481cef25SGreg Clayton if (step_over_until_addrs.empty()) 1134481cef25SGreg Clayton { 11359b70ddb3SJim Ingham if (all_in_function) 11369b70ddb3SJim Ingham { 1137481cef25SGreg Clayton step_file_spec.GetPath (path, sizeof(path)); 1138fd54b368SJason Molenda sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line); 1139481cef25SGreg Clayton } 1140481cef25SGreg Clayton else 114186edbf41SGreg Clayton sb_error.SetErrorString ("step until target not in current function"); 11429b70ddb3SJim Ingham } 11439b70ddb3SJim Ingham else 1144481cef25SGreg Clayton { 11454d56e9c1SJim Ingham ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil (abort_other_plans, 1146481cef25SGreg Clayton &step_over_until_addrs[0], 1147481cef25SGreg Clayton step_over_until_addrs.size(), 1148481cef25SGreg Clayton stop_other_threads, 11494d56e9c1SJim Ingham frame_sp->GetFrameIndex())); 1150481cef25SGreg Clayton 11514d56e9c1SJim Ingham sb_error = ResumeNewPlan (exe_ctx, new_plan_sp.get()); 1152481cef25SGreg Clayton } 1153481cef25SGreg Clayton } 1154481cef25SGreg Clayton else 1155481cef25SGreg Clayton { 1156481cef25SGreg Clayton sb_error.SetErrorString("this SBThread object is invalid"); 1157481cef25SGreg Clayton } 1158481cef25SGreg Clayton return sb_error; 1159481cef25SGreg Clayton } 1160481cef25SGreg Clayton 11614413758cSJim Ingham SBError 11622bdbfd50SJim Ingham SBThread::StepUsingScriptedThreadPlan (const char *script_class_name) 11632bdbfd50SJim Ingham { 1164*000ca185SOleksiy Vyalov return StepUsingScriptedThreadPlan(script_class_name, true); 1165c915a7d2SJim Ingham } 1166c915a7d2SJim Ingham 1167c915a7d2SJim Ingham SBError 1168c915a7d2SJim Ingham SBThread::StepUsingScriptedThreadPlan (const char *script_class_name, bool resume_immediately) 1169c915a7d2SJim Ingham { 11702bdbfd50SJim Ingham Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 11712bdbfd50SJim Ingham SBError sb_error; 11722bdbfd50SJim Ingham 1173bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1174bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 11752bdbfd50SJim Ingham 11762bdbfd50SJim Ingham if (log) 11772bdbfd50SJim Ingham { 11782bdbfd50SJim Ingham log->Printf ("SBThread(%p)::StepUsingScriptedThreadPlan: class name: %s", 11792bdbfd50SJim Ingham static_cast<void*>(exe_ctx.GetThreadPtr()), 11802bdbfd50SJim Ingham script_class_name); 11812bdbfd50SJim Ingham } 11822bdbfd50SJim Ingham 11832bdbfd50SJim Ingham 11842bdbfd50SJim Ingham if (!exe_ctx.HasThreadScope()) 11852bdbfd50SJim Ingham { 11862bdbfd50SJim Ingham sb_error.SetErrorString("this SBThread object is invalid"); 11872bdbfd50SJim Ingham return sb_error; 11882bdbfd50SJim Ingham } 11892bdbfd50SJim Ingham 11902bdbfd50SJim Ingham Thread *thread = exe_ctx.GetThreadPtr(); 11912bdbfd50SJim Ingham ThreadPlanSP thread_plan_sp = thread->QueueThreadPlanForStepScripted(false, script_class_name, false); 11922bdbfd50SJim Ingham 1193c915a7d2SJim Ingham if (!thread_plan_sp) 1194c915a7d2SJim Ingham { 1195c915a7d2SJim Ingham sb_error.SetErrorStringWithFormat("Error queueing thread plan for class: %s", script_class_name); 1196c915a7d2SJim Ingham return sb_error; 1197c915a7d2SJim Ingham } 1198c915a7d2SJim Ingham 1199c915a7d2SJim Ingham if (!resume_immediately) 1200c915a7d2SJim Ingham { 1201c915a7d2SJim Ingham return sb_error; 1202c915a7d2SJim Ingham } 1203c915a7d2SJim Ingham 12042bdbfd50SJim Ingham if (thread_plan_sp) 12052bdbfd50SJim Ingham sb_error = ResumeNewPlan(exe_ctx, thread_plan_sp.get()); 12062bdbfd50SJim Ingham else 12072bdbfd50SJim Ingham { 1208c915a7d2SJim Ingham sb_error.SetErrorStringWithFormat("Error resuming thread plan for class: %s.", script_class_name); 12092bdbfd50SJim Ingham if (log) 12102bdbfd50SJim Ingham log->Printf ("SBThread(%p)::StepUsingScriptedThreadPlan: Error queuing thread plan for class: %s", 12112bdbfd50SJim Ingham static_cast<void*>(exe_ctx.GetThreadPtr()), 12122bdbfd50SJim Ingham script_class_name); 12132bdbfd50SJim Ingham } 12142bdbfd50SJim Ingham 12152bdbfd50SJim Ingham return sb_error; 12162bdbfd50SJim Ingham } 12172bdbfd50SJim Ingham 12182bdbfd50SJim Ingham SBError 1219f86248d9SRichard Mitton SBThread::JumpToLine (lldb::SBFileSpec &file_spec, uint32_t line) 1220f86248d9SRichard Mitton { 1221f86248d9SRichard Mitton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1222f86248d9SRichard Mitton SBError sb_error; 1223f86248d9SRichard Mitton 1224bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1225bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1226f86248d9SRichard Mitton 1227f86248d9SRichard Mitton if (log) 1228324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::JumpToLine (file+line = %s:%u)", 1229324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 1230324a1036SSaleem Abdulrasool file_spec->GetPath().c_str(), line); 1231f86248d9SRichard Mitton 1232f86248d9SRichard Mitton if (!exe_ctx.HasThreadScope()) 1233f86248d9SRichard Mitton { 1234f86248d9SRichard Mitton sb_error.SetErrorString("this SBThread object is invalid"); 1235f86248d9SRichard Mitton return sb_error; 1236f86248d9SRichard Mitton } 1237f86248d9SRichard Mitton 1238f86248d9SRichard Mitton Thread *thread = exe_ctx.GetThreadPtr(); 1239f86248d9SRichard Mitton 1240f86248d9SRichard Mitton Error err = thread->JumpToLine (file_spec.get(), line, true); 1241f86248d9SRichard Mitton sb_error.SetError (err); 1242f86248d9SRichard Mitton return sb_error; 1243f86248d9SRichard Mitton } 1244f86248d9SRichard Mitton 1245f86248d9SRichard Mitton SBError 1246cb640dd8SJim Ingham SBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value) 12474413758cSJim Ingham { 12484413758cSJim Ingham SBError sb_error; 12494413758cSJim Ingham 12505160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 12514413758cSJim Ingham 1252bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1253bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 12544413758cSJim Ingham 12554413758cSJim Ingham if (log) 1256324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::ReturnFromFrame (frame=%d)", 1257324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 1258324a1036SSaleem Abdulrasool frame.GetFrameID()); 12594413758cSJim Ingham 12604413758cSJim Ingham if (exe_ctx.HasThreadScope()) 12614413758cSJim Ingham { 12624413758cSJim Ingham Thread *thread = exe_ctx.GetThreadPtr(); 1263cb640dd8SJim Ingham sb_error.SetError (thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP())); 12644413758cSJim Ingham } 12654413758cSJim Ingham 12664413758cSJim Ingham return sb_error; 12674413758cSJim Ingham } 12684413758cSJim Ingham 12694ac8e93aSJim Ingham SBError 12704ac8e93aSJim Ingham SBThread::UnwindInnermostExpression() 12714ac8e93aSJim Ingham { 12724ac8e93aSJim Ingham SBError sb_error; 12734ac8e93aSJim Ingham 12744ac8e93aSJim Ingham Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 12754ac8e93aSJim Ingham 12764ac8e93aSJim Ingham std::unique_lock<std::recursive_mutex> lock; 12774ac8e93aSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 12784ac8e93aSJim Ingham 12794ac8e93aSJim Ingham if (log) 12804ac8e93aSJim Ingham log->Printf ("SBThread(%p)::UnwindExpressionEvaluation", 12814ac8e93aSJim Ingham static_cast<void*>(exe_ctx.GetThreadPtr())); 12824ac8e93aSJim Ingham 12834ac8e93aSJim Ingham if (exe_ctx.HasThreadScope()) 12844ac8e93aSJim Ingham { 12854ac8e93aSJim Ingham Thread *thread = exe_ctx.GetThreadPtr(); 12864ac8e93aSJim Ingham sb_error.SetError (thread->UnwindInnermostExpression()); 12874ac8e93aSJim Ingham if (sb_error.Success()) 12884ac8e93aSJim Ingham thread->SetSelectedFrameByIndex(0, false); 12894ac8e93aSJim Ingham } 12904ac8e93aSJim Ingham 12914ac8e93aSJim Ingham return sb_error; 12924ac8e93aSJim Ingham 12934ac8e93aSJim Ingham } 1294481cef25SGreg Clayton 1295722a0cdcSGreg Clayton bool 1296722a0cdcSGreg Clayton SBThread::Suspend() 1297722a0cdcSGreg Clayton { 12985160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1299b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1300b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1301b2e7d28eSJim Ingham 1302c9858e4dSGreg Clayton bool result = false; 13031ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1304722a0cdcSGreg Clayton { 1305c9858e4dSGreg Clayton Process::StopLocker stop_locker; 1306c9858e4dSGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1307c9858e4dSGreg Clayton { 13081ac04c30SGreg Clayton exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended); 1309c9858e4dSGreg Clayton result = true; 1310722a0cdcSGreg Clayton } 1311c9858e4dSGreg Clayton else 1312c9858e4dSGreg Clayton { 1313c9858e4dSGreg Clayton if (log) 1314324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::Suspend() => error: process is running", 1315324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 1316c9858e4dSGreg Clayton } 1317c9858e4dSGreg Clayton } 1318c9858e4dSGreg Clayton if (log) 1319324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::Suspend() => %i", 1320324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), result); 1321c9858e4dSGreg Clayton return result; 1322722a0cdcSGreg Clayton } 1323722a0cdcSGreg Clayton 1324722a0cdcSGreg Clayton bool 1325722a0cdcSGreg Clayton SBThread::Resume () 1326722a0cdcSGreg Clayton { 13275160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1328b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1329b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1330b2e7d28eSJim Ingham 1331c9858e4dSGreg Clayton bool result = false; 13321ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1333722a0cdcSGreg Clayton { 1334c9858e4dSGreg Clayton Process::StopLocker stop_locker; 1335c9858e4dSGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1336c9858e4dSGreg Clayton { 13376c9ed91cSJim Ingham const bool override_suspend = true; 13386c9ed91cSJim Ingham exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning, override_suspend); 1339c9858e4dSGreg Clayton result = true; 1340722a0cdcSGreg Clayton } 1341c9858e4dSGreg Clayton else 1342c9858e4dSGreg Clayton { 1343c9858e4dSGreg Clayton if (log) 1344324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::Resume() => error: process is running", 1345324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 1346c9858e4dSGreg Clayton } 1347c9858e4dSGreg Clayton } 1348c9858e4dSGreg Clayton if (log) 1349324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::Resume() => %i", 1350324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), result); 1351c9858e4dSGreg Clayton return result; 1352722a0cdcSGreg Clayton } 1353722a0cdcSGreg Clayton 1354722a0cdcSGreg Clayton bool 1355722a0cdcSGreg Clayton SBThread::IsSuspended() 1356722a0cdcSGreg Clayton { 1357b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1358b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1359b2e7d28eSJim Ingham 13601ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 13611ac04c30SGreg Clayton return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended; 1362722a0cdcSGreg Clayton return false; 1363722a0cdcSGreg Clayton } 1364722a0cdcSGreg Clayton 1365a75418dbSAndrew Kaylor bool 1366a75418dbSAndrew Kaylor SBThread::IsStopped() 1367a75418dbSAndrew Kaylor { 1368b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1369b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1370b2e7d28eSJim Ingham 1371a75418dbSAndrew Kaylor if (exe_ctx.HasThreadScope()) 1372a75418dbSAndrew Kaylor return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true); 1373a75418dbSAndrew Kaylor return false; 1374a75418dbSAndrew Kaylor } 1375a75418dbSAndrew Kaylor 137630fdc8d8SChris Lattner SBProcess 137730fdc8d8SChris Lattner SBThread::GetProcess () 137830fdc8d8SChris Lattner { 1379b9556accSGreg Clayton SBProcess sb_process; 1380b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1381b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1382b2e7d28eSJim Ingham 13831ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 138430fdc8d8SChris Lattner { 138530fdc8d8SChris Lattner // Have to go up to the target so we can get a shared pointer to our process... 13861ac04c30SGreg Clayton sb_process.SetSP (exe_ctx.GetProcessSP()); 138730fdc8d8SChris Lattner } 1388ceb6b139SCaroline Tice 13895160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1390ceb6b139SCaroline Tice if (log) 1391ceb6b139SCaroline Tice { 1392481cef25SGreg Clayton SBStream frame_desc_strm; 1393b9556accSGreg Clayton sb_process.GetDescription (frame_desc_strm); 1394324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", 1395324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 1396324a1036SSaleem Abdulrasool static_cast<void*>(sb_process.GetSP().get()), 1397324a1036SSaleem Abdulrasool frame_desc_strm.GetData()); 1398ceb6b139SCaroline Tice } 1399ceb6b139SCaroline Tice 1400b9556accSGreg Clayton return sb_process; 140130fdc8d8SChris Lattner } 140230fdc8d8SChris Lattner 140330fdc8d8SChris Lattner uint32_t 140430fdc8d8SChris Lattner SBThread::GetNumFrames () 140530fdc8d8SChris Lattner { 14065160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1407ceb6b139SCaroline Tice 1408ceb6b139SCaroline Tice uint32_t num_frames = 0; 1409bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1410bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 14114fc6cb9cSJim Ingham 14121ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1413af67cecdSGreg Clayton { 14147fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 14157fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 14167fdf9ef1SGreg Clayton { 14171ac04c30SGreg Clayton num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount(); 1418af67cecdSGreg Clayton } 1419c9858e4dSGreg Clayton else 1420c9858e4dSGreg Clayton { 1421c9858e4dSGreg Clayton if (log) 1422324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running", 1423324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 1424c9858e4dSGreg Clayton } 14257fdf9ef1SGreg Clayton } 1426ceb6b139SCaroline Tice 1427ceb6b139SCaroline Tice if (log) 1428324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetNumFrames () => %u", 1429324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), num_frames); 1430ceb6b139SCaroline Tice 1431ceb6b139SCaroline Tice return num_frames; 143230fdc8d8SChris Lattner } 143330fdc8d8SChris Lattner 143430fdc8d8SChris Lattner SBFrame 143530fdc8d8SChris Lattner SBThread::GetFrameAtIndex (uint32_t idx) 143630fdc8d8SChris Lattner { 14375160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1438ceb6b139SCaroline Tice 143930fdc8d8SChris Lattner SBFrame sb_frame; 1440b57e4a1bSJason Molenda StackFrameSP frame_sp; 1441bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1442bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 14434fc6cb9cSJim Ingham 14441ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1445af67cecdSGreg Clayton { 14467fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 14477fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 14487fdf9ef1SGreg Clayton { 14491ac04c30SGreg Clayton frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx); 1450b9556accSGreg Clayton sb_frame.SetFrameSP (frame_sp); 1451af67cecdSGreg Clayton } 1452c9858e4dSGreg Clayton else 1453c9858e4dSGreg Clayton { 1454c9858e4dSGreg Clayton if (log) 1455324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running", 1456324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 1457c9858e4dSGreg Clayton } 14587fdf9ef1SGreg Clayton } 1459ceb6b139SCaroline Tice 1460ceb6b139SCaroline Tice if (log) 1461ceb6b139SCaroline Tice { 1462481cef25SGreg Clayton SBStream frame_desc_strm; 1463481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 14644838131bSGreg Clayton log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s", 1465324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), idx, 1466324a1036SSaleem Abdulrasool static_cast<void*>(frame_sp.get()), 1467324a1036SSaleem Abdulrasool frame_desc_strm.GetData()); 1468ceb6b139SCaroline Tice } 1469ceb6b139SCaroline Tice 147030fdc8d8SChris Lattner return sb_frame; 147130fdc8d8SChris Lattner } 147230fdc8d8SChris Lattner 1473f028a1fbSGreg Clayton lldb::SBFrame 1474f028a1fbSGreg Clayton SBThread::GetSelectedFrame () 1475f028a1fbSGreg Clayton { 14765160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1477f028a1fbSGreg Clayton 1478f028a1fbSGreg Clayton SBFrame sb_frame; 1479b57e4a1bSJason Molenda StackFrameSP frame_sp; 1480bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1481bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 14824fc6cb9cSJim Ingham 14831ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1484af67cecdSGreg Clayton { 14857fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 14867fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 14877fdf9ef1SGreg Clayton { 14881ac04c30SGreg Clayton frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame (); 1489b9556accSGreg Clayton sb_frame.SetFrameSP (frame_sp); 1490af67cecdSGreg Clayton } 1491c9858e4dSGreg Clayton else 1492c9858e4dSGreg Clayton { 1493c9858e4dSGreg Clayton if (log) 1494324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running", 1495324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 1496c9858e4dSGreg Clayton } 14977fdf9ef1SGreg Clayton } 1498f028a1fbSGreg Clayton 1499f028a1fbSGreg Clayton if (log) 1500f028a1fbSGreg Clayton { 1501481cef25SGreg Clayton SBStream frame_desc_strm; 1502481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 1503f028a1fbSGreg Clayton log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s", 1504324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 1505324a1036SSaleem Abdulrasool static_cast<void*>(frame_sp.get()), 1506324a1036SSaleem Abdulrasool frame_desc_strm.GetData()); 1507f028a1fbSGreg Clayton } 1508f028a1fbSGreg Clayton 1509f028a1fbSGreg Clayton return sb_frame; 1510f028a1fbSGreg Clayton } 1511f028a1fbSGreg Clayton 1512f028a1fbSGreg Clayton lldb::SBFrame 1513f028a1fbSGreg Clayton SBThread::SetSelectedFrame (uint32_t idx) 1514f028a1fbSGreg Clayton { 15155160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1516f028a1fbSGreg Clayton 1517f028a1fbSGreg Clayton SBFrame sb_frame; 1518b57e4a1bSJason Molenda StackFrameSP frame_sp; 1519bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1520bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 15214fc6cb9cSJim Ingham 15221ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1523f028a1fbSGreg Clayton { 15247fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 15257fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 15267fdf9ef1SGreg Clayton { 15271ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 15281ac04c30SGreg Clayton frame_sp = thread->GetStackFrameAtIndex (idx); 1529f028a1fbSGreg Clayton if (frame_sp) 1530f028a1fbSGreg Clayton { 15311ac04c30SGreg Clayton thread->SetSelectedFrame (frame_sp.get()); 1532b9556accSGreg Clayton sb_frame.SetFrameSP (frame_sp); 1533f028a1fbSGreg Clayton } 1534f028a1fbSGreg Clayton } 1535c9858e4dSGreg Clayton else 1536c9858e4dSGreg Clayton { 1537c9858e4dSGreg Clayton if (log) 1538324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running", 1539324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 1540c9858e4dSGreg Clayton } 15417fdf9ef1SGreg Clayton } 1542f028a1fbSGreg Clayton 1543f028a1fbSGreg Clayton if (log) 1544f028a1fbSGreg Clayton { 1545481cef25SGreg Clayton SBStream frame_desc_strm; 1546481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 1547f028a1fbSGreg Clayton log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s", 1548324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), idx, 1549324a1036SSaleem Abdulrasool static_cast<void*>(frame_sp.get()), 1550324a1036SSaleem Abdulrasool frame_desc_strm.GetData()); 1551f028a1fbSGreg Clayton } 1552f028a1fbSGreg Clayton return sb_frame; 1553f028a1fbSGreg Clayton } 1554f028a1fbSGreg Clayton 15554f465cffSJim Ingham bool 15564f465cffSJim Ingham SBThread::EventIsThreadEvent (const SBEvent &event) 15574f465cffSJim Ingham { 15584f465cffSJim Ingham return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL; 15594f465cffSJim Ingham } 15604f465cffSJim Ingham 15614f465cffSJim Ingham SBFrame 15624f465cffSJim Ingham SBThread::GetStackFrameFromEvent (const SBEvent &event) 15634f465cffSJim Ingham { 15644f465cffSJim Ingham return Thread::ThreadEventData::GetStackFrameFromEvent (event.get()); 15654f465cffSJim Ingham 15664f465cffSJim Ingham } 15674f465cffSJim Ingham 15684f465cffSJim Ingham SBThread 15694f465cffSJim Ingham SBThread::GetThreadFromEvent (const SBEvent &event) 15704f465cffSJim Ingham { 15714f465cffSJim Ingham return Thread::ThreadEventData::GetThreadFromEvent (event.get()); 15724f465cffSJim Ingham } 1573f028a1fbSGreg Clayton 157430fdc8d8SChris Lattner bool 157530fdc8d8SChris Lattner SBThread::operator == (const SBThread &rhs) const 157630fdc8d8SChris Lattner { 15777fdf9ef1SGreg Clayton return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get(); 157830fdc8d8SChris Lattner } 157930fdc8d8SChris Lattner 158030fdc8d8SChris Lattner bool 158130fdc8d8SChris Lattner SBThread::operator != (const SBThread &rhs) const 158230fdc8d8SChris Lattner { 15837fdf9ef1SGreg Clayton return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get(); 158430fdc8d8SChris Lattner } 1585dde9cff3SCaroline Tice 1586dde9cff3SCaroline Tice bool 15874f465cffSJim Ingham SBThread::GetStatus (SBStream &status) const 15884f465cffSJim Ingham { 15894f465cffSJim Ingham Stream &strm = status.ref(); 15904f465cffSJim Ingham 1591b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1592b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1593b2e7d28eSJim Ingham 15944f465cffSJim Ingham if (exe_ctx.HasThreadScope()) 15954f465cffSJim Ingham { 15964f465cffSJim Ingham exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1); 15974f465cffSJim Ingham } 15984f465cffSJim Ingham else 15994f465cffSJim Ingham strm.PutCString ("No status"); 16004f465cffSJim Ingham 16014f465cffSJim Ingham return true; 16024f465cffSJim Ingham } 16034f465cffSJim Ingham 16044f465cffSJim Ingham bool 1605ceb6b139SCaroline Tice SBThread::GetDescription (SBStream &description) const 1606ceb6b139SCaroline Tice { 1607da7bc7d0SGreg Clayton Stream &strm = description.ref(); 1608da7bc7d0SGreg Clayton 1609b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1610b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1611b2e7d28eSJim Ingham 16121ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1613ceb6b139SCaroline Tice { 1614603985fcSJim Ingham exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm, LLDB_INVALID_THREAD_ID); 1615603985fcSJim Ingham //strm.Printf("SBThread: tid = 0x%4.4" PRIx64, exe_ctx.GetThreadPtr()->GetID()); 1616ceb6b139SCaroline Tice } 1617ceb6b139SCaroline Tice else 1618da7bc7d0SGreg Clayton strm.PutCString ("No value"); 1619ceb6b139SCaroline Tice 1620ceb6b139SCaroline Tice return true; 1621ceb6b139SCaroline Tice } 16225dd4916fSJason Molenda 16235dd4916fSJason Molenda SBThread 1624008c45f1SJason Molenda SBThread::GetExtendedBacktraceThread (const char *type) 16255dd4916fSJason Molenda { 16265dd4916fSJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1627bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1628bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 16295dd4916fSJason Molenda SBThread sb_origin_thread; 16305dd4916fSJason Molenda 16315dd4916fSJason Molenda if (exe_ctx.HasThreadScope()) 16325dd4916fSJason Molenda { 16335dd4916fSJason Molenda Process::StopLocker stop_locker; 16345dd4916fSJason Molenda if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 16355dd4916fSJason Molenda { 16367a2f7904SJason Molenda ThreadSP real_thread(exe_ctx.GetThreadSP()); 16375dd4916fSJason Molenda if (real_thread) 16385dd4916fSJason Molenda { 16395dd4916fSJason Molenda ConstString type_const (type); 16407a2f7904SJason Molenda Process *process = exe_ctx.GetProcessPtr(); 16417a2f7904SJason Molenda if (process) 16427a2f7904SJason Molenda { 16437a2f7904SJason Molenda SystemRuntime *runtime = process->GetSystemRuntime(); 16445dd4916fSJason Molenda if (runtime) 16455dd4916fSJason Molenda { 1646008c45f1SJason Molenda ThreadSP new_thread_sp (runtime->GetExtendedBacktraceThread (real_thread, type_const)); 1647a6e9130dSJason Molenda if (new_thread_sp) 1648a6e9130dSJason Molenda { 16497a2f7904SJason Molenda // Save this in the Process' ExtendedThreadList so a strong pointer retains the 16507a2f7904SJason Molenda // object. 16517a2f7904SJason Molenda process->GetExtendedThreadList().AddThread (new_thread_sp); 16527a2f7904SJason Molenda sb_origin_thread.SetThread (new_thread_sp); 1653a6e9130dSJason Molenda if (log) 1654a6e9130dSJason Molenda { 1655a6e9130dSJason Molenda const char *queue_name = new_thread_sp->GetQueueName(); 1656a6e9130dSJason Molenda if (queue_name == NULL) 1657a6e9130dSJason Molenda queue_name = ""; 16582bdbfd50SJim Ingham log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => new extended Thread " 16592bdbfd50SJim Ingham "created (%p) with queue_id 0x%" PRIx64 " queue name '%s'", 1660324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 1661324a1036SSaleem Abdulrasool static_cast<void*>(new_thread_sp.get()), 1662324a1036SSaleem Abdulrasool new_thread_sp->GetQueueID(), 1663324a1036SSaleem Abdulrasool queue_name); 1664a6e9130dSJason Molenda } 1665a6e9130dSJason Molenda } 16667a2f7904SJason Molenda } 16675dd4916fSJason Molenda } 16685dd4916fSJason Molenda } 16695dd4916fSJason Molenda } 16705dd4916fSJason Molenda else 16715dd4916fSJason Molenda { 16725dd4916fSJason Molenda if (log) 1673324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => error: process is running", 1674324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 16755dd4916fSJason Molenda } 16765dd4916fSJason Molenda } 16775dd4916fSJason Molenda 1678ac605f4aSJason Molenda if (log && sb_origin_thread.IsValid() == false) 1679324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a Valid thread", 1680324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 16815dd4916fSJason Molenda return sb_origin_thread; 16825dd4916fSJason Molenda } 16838ee9cb58SJason Molenda 16848ee9cb58SJason Molenda uint32_t 16858ee9cb58SJason Molenda SBThread::GetExtendedBacktraceOriginatingIndexID () 16868ee9cb58SJason Molenda { 16878ee9cb58SJason Molenda ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 16888ee9cb58SJason Molenda if (thread_sp) 16898ee9cb58SJason Molenda return thread_sp->GetExtendedBacktraceOriginatingIndexID(); 16908ee9cb58SJason Molenda return LLDB_INVALID_INDEX32; 16918ee9cb58SJason Molenda } 1692b4892cd2SJason Molenda 1693b4892cd2SJason Molenda bool 1694b4892cd2SJason Molenda SBThread::SafeToCallFunctions () 1695b4892cd2SJason Molenda { 1696b4892cd2SJason Molenda ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 1697b4892cd2SJason Molenda if (thread_sp) 1698b4892cd2SJason Molenda return thread_sp->SafeToCallFunctions(); 1699b4892cd2SJason Molenda return true; 1700b4892cd2SJason Molenda } 17012bdbfd50SJim Ingham 17022bdbfd50SJim Ingham lldb_private::Thread * 17032bdbfd50SJim Ingham SBThread::operator->() 17042bdbfd50SJim Ingham { 17052bdbfd50SJim Ingham ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 17062bdbfd50SJim Ingham if (thread_sp) 17072bdbfd50SJim Ingham return thread_sp.get(); 17082bdbfd50SJim Ingham else 17092bdbfd50SJim Ingham return NULL; 17102bdbfd50SJim Ingham } 17112bdbfd50SJim Ingham 17122bdbfd50SJim Ingham lldb_private::Thread * 17132bdbfd50SJim Ingham SBThread::get() 17142bdbfd50SJim Ingham { 17152bdbfd50SJim Ingham ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 17162bdbfd50SJim Ingham if (thread_sp) 17172bdbfd50SJim Ingham return thread_sp.get(); 17182bdbfd50SJim Ingham else 17192bdbfd50SJim Ingham return NULL; 17202bdbfd50SJim Ingham } 17212bdbfd50SJim Ingham 1722