1 //===-- ThreadPlanPython.cpp ------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/Target/ThreadPlan.h"
14 // Other libraries and framework includes
16 #include "lldb/Core/Debugger.h"
17 #include "lldb/Core/State.h"
18 #include "lldb/Interpreter/CommandInterpreter.h"
19 #include "lldb/Interpreter/ScriptInterpreter.h"
20 #include "lldb/Target/Process.h"
21 #include "lldb/Target/RegisterContext.h"
22 #include "lldb/Target/Target.h"
23 #include "lldb/Target/Thread.h"
24 #include "lldb/Target/ThreadPlan.h"
25 #include "lldb/Target/ThreadPlanPython.h"
26 #include "lldb/Utility/Log.h"
29 using namespace lldb_private;
31 //----------------------------------------------------------------------
33 //----------------------------------------------------------------------
35 ThreadPlanPython::ThreadPlanPython(Thread &thread, const char *class_name)
36 : ThreadPlan(ThreadPlan::eKindPython, "Python based Thread Plan", thread,
37 eVoteNoOpinion, eVoteNoOpinion),
38 m_class_name(class_name) {
39 SetIsMasterPlan(true);
40 SetOkayToDiscard(true);
44 ThreadPlanPython::~ThreadPlanPython() {
45 // FIXME, do I need to decrement the ref count on this implementation object
46 // to make it go away?
49 bool ThreadPlanPython::ValidatePlan(Stream *error) {
50 // I have to postpone setting up the implementation till after the constructor
51 // because I need to call
52 // shared_from_this, which you can't do in the constructor. So I'll do it
54 if (m_implementation_sp)
60 void ThreadPlanPython::DidPush() {
61 // We set up the script side in DidPush, so that it can push other plans in
62 // the constructor, and doesn't have to care about the details of DidPush.
64 if (!m_class_name.empty()) {
65 ScriptInterpreter *script_interp = m_thread.GetProcess()
68 .GetCommandInterpreter()
69 .GetScriptInterpreter();
71 m_implementation_sp = script_interp->CreateScriptedThreadPlan(
72 m_class_name.c_str(), this->shared_from_this());
77 bool ThreadPlanPython::ShouldStop(Event *event_ptr) {
78 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
80 log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
81 m_class_name.c_str());
83 bool should_stop = true;
84 if (m_implementation_sp) {
85 ScriptInterpreter *script_interp = m_thread.GetProcess()
88 .GetCommandInterpreter()
89 .GetScriptInterpreter();
92 should_stop = script_interp->ScriptedThreadPlanShouldStop(
93 m_implementation_sp, event_ptr, script_error);
95 SetPlanComplete(false);
101 bool ThreadPlanPython::IsPlanStale() {
102 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
104 log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
105 m_class_name.c_str());
107 bool is_stale = true;
108 if (m_implementation_sp) {
109 ScriptInterpreter *script_interp = m_thread.GetProcess()
112 .GetCommandInterpreter()
113 .GetScriptInterpreter();
116 is_stale = script_interp->ScriptedThreadPlanIsStale(m_implementation_sp,
119 SetPlanComplete(false);
125 bool ThreadPlanPython::DoPlanExplainsStop(Event *event_ptr) {
126 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
128 log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
129 m_class_name.c_str());
131 bool explains_stop = true;
132 if (m_implementation_sp) {
133 ScriptInterpreter *script_interp = m_thread.GetProcess()
136 .GetCommandInterpreter()
137 .GetScriptInterpreter();
140 explains_stop = script_interp->ScriptedThreadPlanExplainsStop(
141 m_implementation_sp, event_ptr, script_error);
143 SetPlanComplete(false);
146 return explains_stop;
149 bool ThreadPlanPython::MischiefManaged() {
150 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
152 log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
153 m_class_name.c_str());
154 bool mischief_managed = true;
155 if (m_implementation_sp) {
156 // I don't really need mischief_managed, since it's simpler to just call
157 // SetPlanComplete in should_stop.
158 mischief_managed = IsPlanComplete();
159 if (mischief_managed)
160 m_implementation_sp.reset();
162 return mischief_managed;
165 lldb::StateType ThreadPlanPython::GetPlanRunState() {
166 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
168 log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
169 m_class_name.c_str());
170 lldb::StateType run_state = eStateRunning;
171 if (m_implementation_sp) {
172 ScriptInterpreter *script_interp = m_thread.GetProcess()
175 .GetCommandInterpreter()
176 .GetScriptInterpreter();
179 run_state = script_interp->ScriptedThreadPlanGetRunState(
180 m_implementation_sp, script_error);
186 // The ones below are not currently exported to Python.
188 bool ThreadPlanPython::StopOthers() {
189 // For now Python plans run all threads, but we should add some controls for
194 void ThreadPlanPython::GetDescription(Stream *s, lldb::DescriptionLevel level) {
195 s->Printf("Python thread plan implemented by class %s.",
196 m_class_name.c_str());
199 bool ThreadPlanPython::WillStop() {
200 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
202 log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
203 m_class_name.c_str());