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