1435933ddSDimitry Andric //===-- SBThreadPlan.cpp ----------------------------------------*- C++ -*-===//
27aa51b79SEd Maste //
37aa51b79SEd Maste // The LLVM Compiler Infrastructure
47aa51b79SEd Maste //
57aa51b79SEd Maste // This file is distributed under the University of Illinois Open Source
67aa51b79SEd Maste // License. See LICENSE.TXT for details.
77aa51b79SEd Maste //
87aa51b79SEd Maste //===----------------------------------------------------------------------===//
97aa51b79SEd Maste
107aa51b79SEd Maste #include "lldb/API/SBThread.h"
117aa51b79SEd Maste
127aa51b79SEd Maste #include "lldb/API/SBFileSpec.h"
137aa51b79SEd Maste #include "lldb/API/SBStream.h"
14435933ddSDimitry Andric #include "lldb/API/SBSymbolContext.h"
157aa51b79SEd Maste #include "lldb/Breakpoint/BreakpointLocation.h"
167aa51b79SEd Maste #include "lldb/Core/Debugger.h"
177aa51b79SEd Maste #include "lldb/Core/StreamFile.h"
187aa51b79SEd Maste #include "lldb/Interpreter/CommandInterpreter.h"
19435933ddSDimitry Andric #include "lldb/Symbol/CompileUnit.h"
20435933ddSDimitry Andric #include "lldb/Symbol/SymbolContext.h"
217aa51b79SEd Maste #include "lldb/Target/Process.h"
227aa51b79SEd Maste #include "lldb/Target/Queue.h"
237aa51b79SEd Maste #include "lldb/Target/StopInfo.h"
24435933ddSDimitry Andric #include "lldb/Target/SystemRuntime.h"
257aa51b79SEd Maste #include "lldb/Target/Target.h"
26435933ddSDimitry Andric #include "lldb/Target/Thread.h"
27435933ddSDimitry Andric #include "lldb/Target/ThreadPlan.h"
287aa51b79SEd Maste #include "lldb/Target/ThreadPlanPython.h"
29435933ddSDimitry Andric #include "lldb/Target/ThreadPlanStepInRange.h"
307aa51b79SEd Maste #include "lldb/Target/ThreadPlanStepInstruction.h"
317aa51b79SEd Maste #include "lldb/Target/ThreadPlanStepOut.h"
327aa51b79SEd Maste #include "lldb/Target/ThreadPlanStepRange.h"
33*b5893f02SDimitry Andric #include "lldb/Utility/State.h"
34f678e45dSDimitry Andric #include "lldb/Utility/Stream.h"
35a580b014SDimitry Andric #include "lldb/Utility/StructuredData.h"
367aa51b79SEd Maste
377aa51b79SEd Maste #include "lldb/API/SBAddress.h"
387aa51b79SEd Maste #include "lldb/API/SBDebugger.h"
397aa51b79SEd Maste #include "lldb/API/SBEvent.h"
407aa51b79SEd Maste #include "lldb/API/SBFrame.h"
417aa51b79SEd Maste #include "lldb/API/SBProcess.h"
427aa51b79SEd Maste #include "lldb/API/SBThreadPlan.h"
437aa51b79SEd Maste #include "lldb/API/SBValue.h"
447aa51b79SEd Maste
457aa51b79SEd Maste using namespace lldb;
467aa51b79SEd Maste using namespace lldb_private;
477aa51b79SEd Maste
487aa51b79SEd Maste //----------------------------------------------------------------------
497aa51b79SEd Maste // Constructors
507aa51b79SEd Maste //----------------------------------------------------------------------
SBThreadPlan()51435933ddSDimitry Andric SBThreadPlan::SBThreadPlan() {}
527aa51b79SEd Maste
SBThreadPlan(const ThreadPlanSP & lldb_object_sp)53435933ddSDimitry Andric SBThreadPlan::SBThreadPlan(const ThreadPlanSP &lldb_object_sp)
54435933ddSDimitry Andric : m_opaque_sp(lldb_object_sp) {}
557aa51b79SEd Maste
SBThreadPlan(const SBThreadPlan & rhs)56435933ddSDimitry Andric SBThreadPlan::SBThreadPlan(const SBThreadPlan &rhs)
57435933ddSDimitry Andric : m_opaque_sp(rhs.m_opaque_sp) {}
587aa51b79SEd Maste
SBThreadPlan(lldb::SBThread & sb_thread,const char * class_name)59435933ddSDimitry Andric SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name) {
607aa51b79SEd Maste Thread *thread = sb_thread.get();
617aa51b79SEd Maste if (thread)
627aa51b79SEd Maste m_opaque_sp.reset(new ThreadPlanPython(*thread, class_name));
637aa51b79SEd Maste }
647aa51b79SEd Maste
657aa51b79SEd Maste //----------------------------------------------------------------------
667aa51b79SEd Maste // Assignment operator
677aa51b79SEd Maste //----------------------------------------------------------------------
687aa51b79SEd Maste
operator =(const SBThreadPlan & rhs)69435933ddSDimitry Andric const lldb::SBThreadPlan &SBThreadPlan::operator=(const SBThreadPlan &rhs) {
707aa51b79SEd Maste if (this != &rhs)
717aa51b79SEd Maste m_opaque_sp = rhs.m_opaque_sp;
727aa51b79SEd Maste return *this;
737aa51b79SEd Maste }
747aa51b79SEd Maste //----------------------------------------------------------------------
757aa51b79SEd Maste // Destructor
767aa51b79SEd Maste //----------------------------------------------------------------------
~SBThreadPlan()77435933ddSDimitry Andric SBThreadPlan::~SBThreadPlan() {}
787aa51b79SEd Maste
get()79435933ddSDimitry Andric lldb_private::ThreadPlan *SBThreadPlan::get() { return m_opaque_sp.get(); }
807aa51b79SEd Maste
IsValid() const81435933ddSDimitry Andric bool SBThreadPlan::IsValid() const { return m_opaque_sp.get() != NULL; }
827aa51b79SEd Maste
Clear()83435933ddSDimitry Andric void SBThreadPlan::Clear() { m_opaque_sp.reset(); }
847aa51b79SEd Maste
GetStopReason()85435933ddSDimitry Andric lldb::StopReason SBThreadPlan::GetStopReason() { return eStopReasonNone; }
867aa51b79SEd Maste
GetStopReasonDataCount()87435933ddSDimitry Andric size_t SBThreadPlan::GetStopReasonDataCount() { return 0; }
887aa51b79SEd Maste
GetStopReasonDataAtIndex(uint32_t idx)89435933ddSDimitry Andric uint64_t SBThreadPlan::GetStopReasonDataAtIndex(uint32_t idx) { return 0; }
907aa51b79SEd Maste
GetThread() const91435933ddSDimitry Andric SBThread SBThreadPlan::GetThread() const {
92435933ddSDimitry Andric if (m_opaque_sp) {
937aa51b79SEd Maste return SBThread(m_opaque_sp->GetThread().shared_from_this());
94435933ddSDimitry Andric } else
957aa51b79SEd Maste return SBThread();
967aa51b79SEd Maste }
977aa51b79SEd Maste
GetDescription(lldb::SBStream & description) const98435933ddSDimitry Andric bool SBThreadPlan::GetDescription(lldb::SBStream &description) const {
99435933ddSDimitry Andric if (m_opaque_sp) {
1007aa51b79SEd Maste m_opaque_sp->GetDescription(description.get(), eDescriptionLevelFull);
101435933ddSDimitry Andric } else {
1027aa51b79SEd Maste description.Printf("Empty SBThreadPlan");
1037aa51b79SEd Maste }
1047aa51b79SEd Maste return true;
1057aa51b79SEd Maste }
1067aa51b79SEd Maste
SetThreadPlan(const ThreadPlanSP & lldb_object_sp)107435933ddSDimitry Andric void SBThreadPlan::SetThreadPlan(const ThreadPlanSP &lldb_object_sp) {
1087aa51b79SEd Maste m_opaque_sp = lldb_object_sp;
1097aa51b79SEd Maste }
1107aa51b79SEd Maste
SetPlanComplete(bool success)111435933ddSDimitry Andric void SBThreadPlan::SetPlanComplete(bool success) {
1127aa51b79SEd Maste if (m_opaque_sp)
1137aa51b79SEd Maste m_opaque_sp->SetPlanComplete(success);
1147aa51b79SEd Maste }
1157aa51b79SEd Maste
IsPlanComplete()116435933ddSDimitry Andric bool SBThreadPlan::IsPlanComplete() {
1177aa51b79SEd Maste if (m_opaque_sp)
1187aa51b79SEd Maste return m_opaque_sp->IsPlanComplete();
1197aa51b79SEd Maste else
1207aa51b79SEd Maste return true;
1217aa51b79SEd Maste }
1227aa51b79SEd Maste
IsPlanStale()123435933ddSDimitry Andric bool SBThreadPlan::IsPlanStale() {
124435933ddSDimitry Andric if (m_opaque_sp)
125435933ddSDimitry Andric return m_opaque_sp->IsPlanStale();
126435933ddSDimitry Andric else
127435933ddSDimitry Andric return true;
128435933ddSDimitry Andric }
129435933ddSDimitry Andric
IsValid()130435933ddSDimitry Andric bool SBThreadPlan::IsValid() {
1317aa51b79SEd Maste if (m_opaque_sp)
1327aa51b79SEd Maste return m_opaque_sp->ValidatePlan(nullptr);
1337aa51b79SEd Maste else
1347aa51b79SEd Maste return false;
1357aa51b79SEd Maste }
1367aa51b79SEd Maste
137435933ddSDimitry Andric // This section allows an SBThreadPlan to push another of the common types of
138435933ddSDimitry Andric // plans...
1397aa51b79SEd Maste //
140435933ddSDimitry Andric // FIXME, you should only be able to queue thread plans from inside the methods
1414ba319b5SDimitry Andric // of a Scripted Thread Plan. Need a way to enforce that.
1427aa51b79SEd Maste
1437aa51b79SEd Maste SBThreadPlan
QueueThreadPlanForStepOverRange(SBAddress & sb_start_address,lldb::addr_t size)1447aa51b79SEd Maste SBThreadPlan::QueueThreadPlanForStepOverRange(SBAddress &sb_start_address,
145435933ddSDimitry Andric lldb::addr_t size) {
146*b5893f02SDimitry Andric SBError error;
147*b5893f02SDimitry Andric return QueueThreadPlanForStepOverRange(sb_start_address, size, error);
148*b5893f02SDimitry Andric }
149*b5893f02SDimitry Andric
QueueThreadPlanForStepOverRange(SBAddress & sb_start_address,lldb::addr_t size,SBError & error)150*b5893f02SDimitry Andric SBThreadPlan SBThreadPlan::QueueThreadPlanForStepOverRange(
151*b5893f02SDimitry Andric SBAddress &sb_start_address, lldb::addr_t size, SBError &error) {
152435933ddSDimitry Andric if (m_opaque_sp) {
1537aa51b79SEd Maste Address *start_address = sb_start_address.get();
154435933ddSDimitry Andric if (!start_address) {
1557aa51b79SEd Maste return SBThreadPlan();
1567aa51b79SEd Maste }
1577aa51b79SEd Maste
1587aa51b79SEd Maste AddressRange range(*start_address, size);
1597aa51b79SEd Maste SymbolContext sc;
1607aa51b79SEd Maste start_address->CalculateSymbolContext(&sc);
161*b5893f02SDimitry Andric Status plan_status;
162*b5893f02SDimitry Andric
163*b5893f02SDimitry Andric SBThreadPlan plan =
164*b5893f02SDimitry Andric SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepOverRange(
165*b5893f02SDimitry Andric false, range, sc, eAllThreads, plan_status));
166*b5893f02SDimitry Andric
167*b5893f02SDimitry Andric if (plan_status.Fail())
168*b5893f02SDimitry Andric error.SetErrorString(plan_status.AsCString());
169*b5893f02SDimitry Andric
170*b5893f02SDimitry Andric return plan;
171435933ddSDimitry Andric } else {
1727aa51b79SEd Maste return SBThreadPlan();
1737aa51b79SEd Maste }
1747aa51b79SEd Maste }
1757aa51b79SEd Maste
1767aa51b79SEd Maste SBThreadPlan
QueueThreadPlanForStepInRange(SBAddress & sb_start_address,lldb::addr_t size)1777aa51b79SEd Maste SBThreadPlan::QueueThreadPlanForStepInRange(SBAddress &sb_start_address,
178435933ddSDimitry Andric lldb::addr_t size) {
179*b5893f02SDimitry Andric SBError error;
180*b5893f02SDimitry Andric return QueueThreadPlanForStepInRange(sb_start_address, size, error);
181*b5893f02SDimitry Andric }
182*b5893f02SDimitry Andric
183*b5893f02SDimitry Andric SBThreadPlan
QueueThreadPlanForStepInRange(SBAddress & sb_start_address,lldb::addr_t size,SBError & error)184*b5893f02SDimitry Andric SBThreadPlan::QueueThreadPlanForStepInRange(SBAddress &sb_start_address,
185*b5893f02SDimitry Andric lldb::addr_t size, SBError &error) {
186435933ddSDimitry Andric if (m_opaque_sp) {
1877aa51b79SEd Maste Address *start_address = sb_start_address.get();
188435933ddSDimitry Andric if (!start_address) {
1897aa51b79SEd Maste return SBThreadPlan();
1907aa51b79SEd Maste }
1917aa51b79SEd Maste
1927aa51b79SEd Maste AddressRange range(*start_address, size);
1937aa51b79SEd Maste SymbolContext sc;
1947aa51b79SEd Maste start_address->CalculateSymbolContext(&sc);
195*b5893f02SDimitry Andric
196*b5893f02SDimitry Andric Status plan_status;
197*b5893f02SDimitry Andric SBThreadPlan plan =
198*b5893f02SDimitry Andric SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepInRange(
199*b5893f02SDimitry Andric false, range, sc, NULL, eAllThreads, plan_status));
200*b5893f02SDimitry Andric
201*b5893f02SDimitry Andric if (plan_status.Fail())
202*b5893f02SDimitry Andric error.SetErrorString(plan_status.AsCString());
203*b5893f02SDimitry Andric
204*b5893f02SDimitry Andric return plan;
205435933ddSDimitry Andric } else {
2067aa51b79SEd Maste return SBThreadPlan();
2077aa51b79SEd Maste }
2087aa51b79SEd Maste }
2097aa51b79SEd Maste
2107aa51b79SEd Maste SBThreadPlan
QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to,bool first_insn)211435933ddSDimitry Andric SBThreadPlan::QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to,
212435933ddSDimitry Andric bool first_insn) {
213*b5893f02SDimitry Andric SBError error;
214*b5893f02SDimitry Andric return QueueThreadPlanForStepOut(frame_idx_to_step_to, first_insn, error);
215*b5893f02SDimitry Andric }
216*b5893f02SDimitry Andric
217*b5893f02SDimitry Andric SBThreadPlan
QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to,bool first_insn,SBError & error)218*b5893f02SDimitry Andric SBThreadPlan::QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to,
219*b5893f02SDimitry Andric bool first_insn, SBError &error) {
220435933ddSDimitry Andric if (m_opaque_sp) {
2217aa51b79SEd Maste SymbolContext sc;
222435933ddSDimitry Andric sc = m_opaque_sp->GetThread().GetStackFrameAtIndex(0)->GetSymbolContext(
223435933ddSDimitry Andric lldb::eSymbolContextEverything);
224*b5893f02SDimitry Andric
225*b5893f02SDimitry Andric Status plan_status;
226*b5893f02SDimitry Andric SBThreadPlan plan =
227*b5893f02SDimitry Andric SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepOut(
228435933ddSDimitry Andric false, &sc, first_insn, false, eVoteYes, eVoteNoOpinion,
229*b5893f02SDimitry Andric frame_idx_to_step_to, plan_status));
230*b5893f02SDimitry Andric
231*b5893f02SDimitry Andric if (plan_status.Fail())
232*b5893f02SDimitry Andric error.SetErrorString(plan_status.AsCString());
233*b5893f02SDimitry Andric
234*b5893f02SDimitry Andric return plan;
235435933ddSDimitry Andric } else {
2367aa51b79SEd Maste return SBThreadPlan();
2377aa51b79SEd Maste }
2387aa51b79SEd Maste }
2397aa51b79SEd Maste
2407aa51b79SEd Maste SBThreadPlan
QueueThreadPlanForRunToAddress(SBAddress sb_address)241435933ddSDimitry Andric SBThreadPlan::QueueThreadPlanForRunToAddress(SBAddress sb_address) {
242*b5893f02SDimitry Andric SBError error;
243*b5893f02SDimitry Andric return QueueThreadPlanForRunToAddress(sb_address, error);
244*b5893f02SDimitry Andric }
245*b5893f02SDimitry Andric
QueueThreadPlanForRunToAddress(SBAddress sb_address,SBError & error)246*b5893f02SDimitry Andric SBThreadPlan SBThreadPlan::QueueThreadPlanForRunToAddress(SBAddress sb_address,
247*b5893f02SDimitry Andric SBError &error) {
248435933ddSDimitry Andric if (m_opaque_sp) {
2497aa51b79SEd Maste Address *address = sb_address.get();
2507aa51b79SEd Maste if (!address)
2517aa51b79SEd Maste return SBThreadPlan();
2527aa51b79SEd Maste
253*b5893f02SDimitry Andric Status plan_status;
254*b5893f02SDimitry Andric SBThreadPlan plan =
255*b5893f02SDimitry Andric SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForRunToAddress(
256*b5893f02SDimitry Andric false, *address, false, plan_status));
257*b5893f02SDimitry Andric
258*b5893f02SDimitry Andric if (plan_status.Fail())
259*b5893f02SDimitry Andric error.SetErrorString(plan_status.AsCString());
260*b5893f02SDimitry Andric
261*b5893f02SDimitry Andric return plan;
262*b5893f02SDimitry Andric } else {
263*b5893f02SDimitry Andric return SBThreadPlan();
264*b5893f02SDimitry Andric }
265*b5893f02SDimitry Andric }
266*b5893f02SDimitry Andric
267*b5893f02SDimitry Andric SBThreadPlan
QueueThreadPlanForStepScripted(const char * script_class_name)268*b5893f02SDimitry Andric SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name) {
269*b5893f02SDimitry Andric SBError error;
270*b5893f02SDimitry Andric return QueueThreadPlanForStepScripted(script_class_name, error);
271*b5893f02SDimitry Andric }
272*b5893f02SDimitry Andric
273*b5893f02SDimitry Andric SBThreadPlan
QueueThreadPlanForStepScripted(const char * script_class_name,SBError & error)274*b5893f02SDimitry Andric SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name,
275*b5893f02SDimitry Andric SBError &error) {
276*b5893f02SDimitry Andric if (m_opaque_sp) {
277*b5893f02SDimitry Andric Status plan_status;
278*b5893f02SDimitry Andric SBThreadPlan plan =
279*b5893f02SDimitry Andric SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepScripted(
280*b5893f02SDimitry Andric false, script_class_name, false, plan_status));
281*b5893f02SDimitry Andric
282*b5893f02SDimitry Andric if (plan_status.Fail())
283*b5893f02SDimitry Andric error.SetErrorString(plan_status.AsCString());
284*b5893f02SDimitry Andric
285*b5893f02SDimitry Andric return plan;
286435933ddSDimitry Andric } else {
2877aa51b79SEd Maste return SBThreadPlan();
2887aa51b79SEd Maste }
2897aa51b79SEd Maste }
290