blob: 8cb3ada428e29e31bd3f2699e042cfaf68e5808a [file] [log] [blame]
Jim Ingham2bdbfd52014-09-29 23:17:18 +00001//===-- ThreadPlan.cpp ------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Jim Ingham2bdbfd52014-09-29 23:17:18 +000010#include "lldb/Target/ThreadPlan.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/Core/Debugger.h"
17#include "lldb/Core/Log.h"
18#include "lldb/Core/State.h"
19#include "lldb/Interpreter/CommandInterpreter.h"
20#include "lldb/Interpreter/ScriptInterpreter.h"
Jim Ingham2bdbfd52014-09-29 23:17:18 +000021#include "lldb/Target/RegisterContext.h"
22#include "lldb/Target/Thread.h"
23#include "lldb/Target/ThreadPlan.h"
24#include "lldb/Target/ThreadPlanPython.h"
25#include "lldb/Target/Process.h"
26#include "lldb/Target/Target.h"
27
28using namespace lldb;
29using namespace lldb_private;
30
31//----------------------------------------------------------------------
32// ThreadPlanPython
33//----------------------------------------------------------------------
34
35ThreadPlanPython::ThreadPlanPython (Thread &thread, const char *class_name) :
36 ThreadPlan (ThreadPlan::eKindPython,
37 "Python based Thread Plan",
38 thread,
39 eVoteNoOpinion,
40 eVoteNoOpinion),
41 m_class_name (class_name)
42{
43 SetIsMasterPlan (true);
44 SetOkayToDiscard (true);
45 SetPrivate (false);
46}
47
48ThreadPlanPython::~ThreadPlanPython ()
49{
50 // FIXME, do I need to decrement the ref count on this implementation object to make it go away?
51}
52
53bool
54ThreadPlanPython::ValidatePlan (Stream *error)
55{
56 // I have to postpone setting up the implementation till after the constructor because I need to call
57 // shared_from_this, which you can't do in the constructor. So I'll do it here.
58 if (m_implementation_sp)
59 return true;
60 else
61 return false;
62}
63
64void
65ThreadPlanPython::DidPush()
66{
67 // We set up the script side in DidPush, so that it can push other plans in the constructor,
68 // and doesn't have to care about the details of DidPush.
69
70 if (!m_class_name.empty())
71 {
72 ScriptInterpreter *script_interp = m_thread.GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
73 if (script_interp)
74 {
75 m_implementation_sp = script_interp->CreateScriptedThreadPlan (m_class_name.c_str(), this->shared_from_this());
76 }
77 }
78}
79
80bool
81ThreadPlanPython::ShouldStop (Event *event_ptr)
82{
83 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
84 if (log)
85 log->Printf ("%s called on Python Thread Plan: %s )",
86 __PRETTY_FUNCTION__, m_class_name.c_str());
87
88 bool should_stop = true;
89 if (m_implementation_sp)
90 {
91 ScriptInterpreter *script_interp = m_thread.GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
92 if (script_interp)
93 {
94 bool script_error;
95 should_stop = script_interp->ScriptedThreadPlanShouldStop (m_implementation_sp, event_ptr, script_error);
96 if (script_error)
97 SetPlanComplete(false);
98 }
99 }
100 return should_stop;
101}
102
103bool
104ThreadPlanPython::DoPlanExplainsStop (Event *event_ptr)
105{
106 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
107 if (log)
108 log->Printf ("%s called on Python Thread Plan: %s )",
109 __PRETTY_FUNCTION__, m_class_name.c_str());
110
111 bool explains_stop = true;
112 if (m_implementation_sp)
113 {
114 ScriptInterpreter *script_interp = m_thread.GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
115 if (script_interp)
116 {
117 bool script_error;
118 explains_stop = script_interp->ScriptedThreadPlanExplainsStop (m_implementation_sp, event_ptr, script_error);
119 if (script_error)
120 SetPlanComplete(false);
121 }
122 }
123 return explains_stop;
124}
125
126bool
127ThreadPlanPython::MischiefManaged ()
128{
129 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
130 if (log)
131 log->Printf ("%s called on Python Thread Plan: %s )",
132 __PRETTY_FUNCTION__, m_class_name.c_str());
133 bool mischief_managed = true;
134 if (m_implementation_sp)
135 {
136 // I don't really need mischief_managed, since it's simpler to just call SetPlanComplete in should_stop.
137 mischief_managed = IsPlanComplete();
138 if (mischief_managed)
139 m_implementation_sp.reset();
140 }
141 return mischief_managed;
142}
143
144lldb::StateType
145ThreadPlanPython::GetPlanRunState ()
146{
147 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
148 if (log)
149 log->Printf ("%s called on Python Thread Plan: %s )",
150 __PRETTY_FUNCTION__,
151 m_class_name.c_str());
152 lldb::StateType run_state = eStateRunning;
153 if (m_implementation_sp)
154 {
155 ScriptInterpreter *script_interp = m_thread.GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
156 if (script_interp)
157 {
158 bool script_error;
159 run_state = script_interp->ScriptedThreadPlanGetRunState (m_implementation_sp, script_error);
160 }
161 }
162 return run_state;
163}
164
165// The ones below are not currently exported to Python.
166
167bool
168ThreadPlanPython::StopOthers ()
169{
170 // For now Python plans run all threads, but we should add some controls for this.
171 return false;
172}
173
174void
175ThreadPlanPython::GetDescription (Stream *s,
176 lldb::DescriptionLevel level)
177{
178 s->Printf ("Python thread plan implemented by class %s.", m_class_name.c_str());
179}
180
181bool
182ThreadPlanPython::WillStop ()
183{
184 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
185 if (log)
186 log->Printf ("%s called on Python Thread Plan: %s )",
187 __PRETTY_FUNCTION__, m_class_name.c_str());
188 return true;
189}