12bdbfd50SJim Ingham //===-- SBThread.cpp --------------------------------------------*- C++ -*-===// 22bdbfd50SJim Ingham // 32bdbfd50SJim Ingham // The LLVM Compiler Infrastructure 42bdbfd50SJim Ingham // 52bdbfd50SJim Ingham // This file is distributed under the University of Illinois Open Source 62bdbfd50SJim Ingham // License. See LICENSE.TXT for details. 72bdbfd50SJim Ingham // 82bdbfd50SJim Ingham //===----------------------------------------------------------------------===// 92bdbfd50SJim Ingham 102bdbfd50SJim Ingham #include "lldb/API/SBThread.h" 112bdbfd50SJim Ingham 122bdbfd50SJim Ingham #include "lldb/API/SBSymbolContext.h" 132bdbfd50SJim Ingham #include "lldb/API/SBFileSpec.h" 142bdbfd50SJim Ingham #include "lldb/API/SBStream.h" 152bdbfd50SJim Ingham #include "lldb/Breakpoint/BreakpointLocation.h" 162bdbfd50SJim Ingham #include "lldb/Core/Debugger.h" 172bdbfd50SJim Ingham #include "lldb/Core/State.h" 182bdbfd50SJim Ingham #include "lldb/Core/Stream.h" 192bdbfd50SJim Ingham #include "lldb/Core/StreamFile.h" 202bdbfd50SJim Ingham #include "lldb/Core/StructuredData.h" 212bdbfd50SJim Ingham #include "lldb/Interpreter/CommandInterpreter.h" 222bdbfd50SJim Ingham #include "lldb/Target/SystemRuntime.h" 232bdbfd50SJim Ingham #include "lldb/Target/Thread.h" 242bdbfd50SJim Ingham #include "lldb/Target/ThreadPlan.h" 252bdbfd50SJim Ingham #include "lldb/Target/Process.h" 262bdbfd50SJim Ingham #include "lldb/Target/Queue.h" 272bdbfd50SJim Ingham #include "lldb/Symbol/SymbolContext.h" 282bdbfd50SJim Ingham #include "lldb/Symbol/CompileUnit.h" 292bdbfd50SJim Ingham #include "lldb/Target/StopInfo.h" 302bdbfd50SJim Ingham #include "lldb/Target/Target.h" 312bdbfd50SJim Ingham #include "lldb/Target/ThreadPlan.h" 322bdbfd50SJim Ingham #include "lldb/Target/ThreadPlanPython.h" 332bdbfd50SJim Ingham #include "lldb/Target/ThreadPlanStepInstruction.h" 342bdbfd50SJim Ingham #include "lldb/Target/ThreadPlanStepOut.h" 352bdbfd50SJim Ingham #include "lldb/Target/ThreadPlanStepRange.h" 362bdbfd50SJim Ingham #include "lldb/Target/ThreadPlanStepInRange.h" 372bdbfd50SJim Ingham 382bdbfd50SJim Ingham 392bdbfd50SJim Ingham #include "lldb/API/SBAddress.h" 402bdbfd50SJim Ingham #include "lldb/API/SBDebugger.h" 412bdbfd50SJim Ingham #include "lldb/API/SBEvent.h" 422bdbfd50SJim Ingham #include "lldb/API/SBFrame.h" 432bdbfd50SJim Ingham #include "lldb/API/SBProcess.h" 442bdbfd50SJim Ingham #include "lldb/API/SBThreadPlan.h" 452bdbfd50SJim Ingham #include "lldb/API/SBValue.h" 462bdbfd50SJim Ingham 472bdbfd50SJim Ingham using namespace lldb; 482bdbfd50SJim Ingham using namespace lldb_private; 492bdbfd50SJim Ingham 502bdbfd50SJim Ingham //---------------------------------------------------------------------- 512bdbfd50SJim Ingham // Constructors 522bdbfd50SJim Ingham //---------------------------------------------------------------------- 532bdbfd50SJim Ingham SBThreadPlan::SBThreadPlan () 542bdbfd50SJim Ingham { 552bdbfd50SJim Ingham } 562bdbfd50SJim Ingham 572bdbfd50SJim Ingham SBThreadPlan::SBThreadPlan (const ThreadPlanSP& lldb_object_sp) : 582bdbfd50SJim Ingham m_opaque_sp (lldb_object_sp) 592bdbfd50SJim Ingham { 602bdbfd50SJim Ingham } 612bdbfd50SJim Ingham 622bdbfd50SJim Ingham SBThreadPlan::SBThreadPlan (const SBThreadPlan &rhs) : 632bdbfd50SJim Ingham m_opaque_sp (rhs.m_opaque_sp) 642bdbfd50SJim Ingham { 652bdbfd50SJim Ingham 662bdbfd50SJim Ingham } 672bdbfd50SJim Ingham 682bdbfd50SJim Ingham SBThreadPlan::SBThreadPlan (lldb::SBThread &sb_thread, const char *class_name) 692bdbfd50SJim Ingham { 702bdbfd50SJim Ingham Thread *thread = sb_thread.get(); 712bdbfd50SJim Ingham if (thread) 722bdbfd50SJim Ingham m_opaque_sp.reset(new ThreadPlanPython(*thread, class_name)); 732bdbfd50SJim Ingham } 742bdbfd50SJim Ingham 752bdbfd50SJim Ingham //---------------------------------------------------------------------- 762bdbfd50SJim Ingham // Assignment operator 772bdbfd50SJim Ingham //---------------------------------------------------------------------- 782bdbfd50SJim Ingham 792bdbfd50SJim Ingham const lldb::SBThreadPlan & 802bdbfd50SJim Ingham SBThreadPlan::operator = (const SBThreadPlan &rhs) 812bdbfd50SJim Ingham { 822bdbfd50SJim Ingham if (this != &rhs) 832bdbfd50SJim Ingham m_opaque_sp = rhs.m_opaque_sp; 842bdbfd50SJim Ingham return *this; 852bdbfd50SJim Ingham } 862bdbfd50SJim Ingham //---------------------------------------------------------------------- 872bdbfd50SJim Ingham // Destructor 882bdbfd50SJim Ingham //---------------------------------------------------------------------- 892bdbfd50SJim Ingham SBThreadPlan::~SBThreadPlan() 902bdbfd50SJim Ingham { 912bdbfd50SJim Ingham } 922bdbfd50SJim Ingham 932bdbfd50SJim Ingham lldb_private::ThreadPlan * 942bdbfd50SJim Ingham SBThreadPlan::get() 952bdbfd50SJim Ingham { 962bdbfd50SJim Ingham return m_opaque_sp.get(); 972bdbfd50SJim Ingham } 982bdbfd50SJim Ingham 992bdbfd50SJim Ingham bool 1002bdbfd50SJim Ingham SBThreadPlan::IsValid() const 1012bdbfd50SJim Ingham { 1022bdbfd50SJim Ingham return m_opaque_sp.get() != NULL; 1032bdbfd50SJim Ingham } 1042bdbfd50SJim Ingham 1052bdbfd50SJim Ingham void 1062bdbfd50SJim Ingham SBThreadPlan::Clear () 1072bdbfd50SJim Ingham { 1082bdbfd50SJim Ingham m_opaque_sp.reset(); 1092bdbfd50SJim Ingham } 1102bdbfd50SJim Ingham 1112bdbfd50SJim Ingham lldb::StopReason 1122bdbfd50SJim Ingham SBThreadPlan::GetStopReason() 1132bdbfd50SJim Ingham { 1142bdbfd50SJim Ingham return eStopReasonNone; 1152bdbfd50SJim Ingham } 1162bdbfd50SJim Ingham 1172bdbfd50SJim Ingham size_t 1182bdbfd50SJim Ingham SBThreadPlan::GetStopReasonDataCount() 1192bdbfd50SJim Ingham { 1202bdbfd50SJim Ingham return 0; 1212bdbfd50SJim Ingham } 1222bdbfd50SJim Ingham 1232bdbfd50SJim Ingham uint64_t 1242bdbfd50SJim Ingham SBThreadPlan::GetStopReasonDataAtIndex(uint32_t idx) 1252bdbfd50SJim Ingham { 1262bdbfd50SJim Ingham return 0; 1272bdbfd50SJim Ingham } 1282bdbfd50SJim Ingham 1292bdbfd50SJim Ingham SBThread 1302bdbfd50SJim Ingham SBThreadPlan::GetThread () const 1312bdbfd50SJim Ingham { 1322bdbfd50SJim Ingham if (m_opaque_sp) 1332bdbfd50SJim Ingham { 1342bdbfd50SJim Ingham return SBThread(m_opaque_sp->GetThread().shared_from_this()); 1352bdbfd50SJim Ingham } 1362bdbfd50SJim Ingham else 1372bdbfd50SJim Ingham return SBThread(); 1382bdbfd50SJim Ingham } 1392bdbfd50SJim Ingham 1402bdbfd50SJim Ingham bool 1412bdbfd50SJim Ingham SBThreadPlan::GetDescription (lldb::SBStream &description) const 1422bdbfd50SJim Ingham { 1432bdbfd50SJim Ingham if (m_opaque_sp) 1442bdbfd50SJim Ingham { 1452bdbfd50SJim Ingham m_opaque_sp->GetDescription(description.get(), eDescriptionLevelFull); 1462bdbfd50SJim Ingham } 1472bdbfd50SJim Ingham else 1482bdbfd50SJim Ingham { 1492bdbfd50SJim Ingham description.Printf("Empty SBThreadPlan"); 1502bdbfd50SJim Ingham } 1512bdbfd50SJim Ingham return true; 1522bdbfd50SJim Ingham } 1532bdbfd50SJim Ingham 1542bdbfd50SJim Ingham void 1552bdbfd50SJim Ingham SBThreadPlan::SetThreadPlan (const ThreadPlanSP& lldb_object_sp) 1562bdbfd50SJim Ingham { 1572bdbfd50SJim Ingham m_opaque_sp = lldb_object_sp; 1582bdbfd50SJim Ingham } 1592bdbfd50SJim Ingham 1602bdbfd50SJim Ingham void 1612bdbfd50SJim Ingham SBThreadPlan::SetPlanComplete (bool success) 1622bdbfd50SJim Ingham { 1632bdbfd50SJim Ingham if (m_opaque_sp) 1642bdbfd50SJim Ingham m_opaque_sp->SetPlanComplete (success); 1652bdbfd50SJim Ingham } 1662bdbfd50SJim Ingham 1672bdbfd50SJim Ingham bool 1682bdbfd50SJim Ingham SBThreadPlan::IsPlanComplete() 1692bdbfd50SJim Ingham { 1702bdbfd50SJim Ingham if (m_opaque_sp) 1712bdbfd50SJim Ingham return m_opaque_sp->IsPlanComplete(); 1722bdbfd50SJim Ingham else 1732bdbfd50SJim Ingham return true; 1742bdbfd50SJim Ingham } 1752bdbfd50SJim Ingham 1762bdbfd50SJim Ingham bool 177*c915a7d2SJim Ingham SBThreadPlan::IsPlanStale() 178*c915a7d2SJim Ingham { 179*c915a7d2SJim Ingham if (m_opaque_sp) 180*c915a7d2SJim Ingham return m_opaque_sp->IsPlanStale(); 181*c915a7d2SJim Ingham else 182*c915a7d2SJim Ingham return true; 183*c915a7d2SJim Ingham } 184*c915a7d2SJim Ingham 185*c915a7d2SJim Ingham bool 1862bdbfd50SJim Ingham SBThreadPlan::IsValid() 1872bdbfd50SJim Ingham { 1882bdbfd50SJim Ingham if (m_opaque_sp) 1892bdbfd50SJim Ingham return m_opaque_sp->ValidatePlan(nullptr); 1902bdbfd50SJim Ingham else 1912bdbfd50SJim Ingham return false; 1922bdbfd50SJim Ingham } 1932bdbfd50SJim Ingham 1942bdbfd50SJim Ingham // This section allows an SBThreadPlan to push another of the common types of plans... 1952bdbfd50SJim Ingham // 1962bdbfd50SJim Ingham // FIXME, you should only be able to queue thread plans from inside the methods of a 1972bdbfd50SJim Ingham // Scripted Thread Plan. Need a way to enforce that. 1982bdbfd50SJim Ingham 1992bdbfd50SJim Ingham SBThreadPlan 2002bdbfd50SJim Ingham SBThreadPlan::QueueThreadPlanForStepOverRange (SBAddress &sb_start_address, 2012bdbfd50SJim Ingham lldb::addr_t size) 2022bdbfd50SJim Ingham { 2032bdbfd50SJim Ingham if (m_opaque_sp) 2042bdbfd50SJim Ingham { 2052bdbfd50SJim Ingham Address *start_address = sb_start_address.get(); 2062bdbfd50SJim Ingham if (!start_address) 2072bdbfd50SJim Ingham { 2082bdbfd50SJim Ingham return SBThreadPlan(); 2092bdbfd50SJim Ingham } 2102bdbfd50SJim Ingham 2112bdbfd50SJim Ingham AddressRange range (*start_address, size); 2122bdbfd50SJim Ingham SymbolContext sc; 2132bdbfd50SJim Ingham start_address->CalculateSymbolContext(&sc); 2142bdbfd50SJim Ingham return SBThreadPlan (m_opaque_sp->GetThread().QueueThreadPlanForStepOverRange (false, 2152bdbfd50SJim Ingham range, 2162bdbfd50SJim Ingham sc, 2172bdbfd50SJim Ingham eAllThreads)); 2182bdbfd50SJim Ingham } 2192bdbfd50SJim Ingham else 2202bdbfd50SJim Ingham { 2212bdbfd50SJim Ingham return SBThreadPlan(); 2222bdbfd50SJim Ingham } 2232bdbfd50SJim Ingham } 2242bdbfd50SJim Ingham 2252bdbfd50SJim Ingham SBThreadPlan 2262bdbfd50SJim Ingham SBThreadPlan::QueueThreadPlanForStepInRange (SBAddress &sb_start_address, 2272bdbfd50SJim Ingham lldb::addr_t size) 2282bdbfd50SJim Ingham { 2292bdbfd50SJim Ingham if (m_opaque_sp) 2302bdbfd50SJim Ingham { 2312bdbfd50SJim Ingham Address *start_address = sb_start_address.get(); 2322bdbfd50SJim Ingham if (!start_address) 2332bdbfd50SJim Ingham { 2342bdbfd50SJim Ingham return SBThreadPlan(); 2352bdbfd50SJim Ingham } 2362bdbfd50SJim Ingham 2372bdbfd50SJim Ingham AddressRange range (*start_address, size); 2382bdbfd50SJim Ingham SymbolContext sc; 2392bdbfd50SJim Ingham start_address->CalculateSymbolContext(&sc); 2402bdbfd50SJim Ingham return SBThreadPlan (m_opaque_sp->GetThread().QueueThreadPlanForStepInRange (false, 2412bdbfd50SJim Ingham range, 2422bdbfd50SJim Ingham sc, 2432bdbfd50SJim Ingham NULL, 2442bdbfd50SJim Ingham eAllThreads)); 2452bdbfd50SJim Ingham } 2462bdbfd50SJim Ingham else 2472bdbfd50SJim Ingham { 2482bdbfd50SJim Ingham return SBThreadPlan(); 2492bdbfd50SJim Ingham } 2502bdbfd50SJim Ingham } 2512bdbfd50SJim Ingham 2522bdbfd50SJim Ingham SBThreadPlan 2532bdbfd50SJim Ingham SBThreadPlan::QueueThreadPlanForStepOut (uint32_t frame_idx_to_step_to, bool first_insn) 2542bdbfd50SJim Ingham { 2552bdbfd50SJim Ingham if (m_opaque_sp) 2562bdbfd50SJim Ingham { 2572bdbfd50SJim Ingham SymbolContext sc; 2582bdbfd50SJim Ingham sc = m_opaque_sp->GetThread().GetStackFrameAtIndex(0)->GetSymbolContext(lldb::eSymbolContextEverything); 2592bdbfd50SJim Ingham return SBThreadPlan (m_opaque_sp->GetThread().QueueThreadPlanForStepOut (false, 2602bdbfd50SJim Ingham &sc, 2612bdbfd50SJim Ingham first_insn, 2622bdbfd50SJim Ingham false, 2632bdbfd50SJim Ingham eVoteYes, 2642bdbfd50SJim Ingham eVoteNoOpinion, 2652bdbfd50SJim Ingham frame_idx_to_step_to)); 2662bdbfd50SJim Ingham } 2672bdbfd50SJim Ingham else 2682bdbfd50SJim Ingham { 2692bdbfd50SJim Ingham return SBThreadPlan(); 2702bdbfd50SJim Ingham } 2712bdbfd50SJim Ingham } 2722bdbfd50SJim Ingham 2732bdbfd50SJim Ingham SBThreadPlan 2742bdbfd50SJim Ingham SBThreadPlan::QueueThreadPlanForRunToAddress (SBAddress sb_address) 2752bdbfd50SJim Ingham { 2762bdbfd50SJim Ingham if (m_opaque_sp) 2772bdbfd50SJim Ingham { 2782bdbfd50SJim Ingham Address *address = sb_address.get(); 2792bdbfd50SJim Ingham if (!address) 2802bdbfd50SJim Ingham return SBThreadPlan(); 2812bdbfd50SJim Ingham 2822bdbfd50SJim Ingham return SBThreadPlan (m_opaque_sp->GetThread().QueueThreadPlanForRunToAddress (false, 2832bdbfd50SJim Ingham *address, 2842bdbfd50SJim Ingham false)); 2852bdbfd50SJim Ingham } 2862bdbfd50SJim Ingham else 2872bdbfd50SJim Ingham { 2882bdbfd50SJim Ingham return SBThreadPlan(); 2892bdbfd50SJim Ingham } 2902bdbfd50SJim Ingham } 2912bdbfd50SJim Ingham 2922bdbfd50SJim Ingham 293