]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Target/ThreadPlanPython.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Target / ThreadPlanPython.cpp
1 //===-- ThreadPlanPython.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
10 #include "lldb/Target/ThreadPlan.h"
11
12 #include "lldb/Core/Debugger.h"
13 #include "lldb/Interpreter/CommandInterpreter.h"
14 #include "lldb/Interpreter/ScriptInterpreter.h"
15 #include "lldb/Target/Process.h"
16 #include "lldb/Target/RegisterContext.h"
17 #include "lldb/Target/Target.h"
18 #include "lldb/Target/Thread.h"
19 #include "lldb/Target/ThreadPlan.h"
20 #include "lldb/Target/ThreadPlanPython.h"
21 #include "lldb/Utility/Log.h"
22 #include "lldb/Utility/State.h"
23
24 using namespace lldb;
25 using namespace lldb_private;
26
27 //----------------------------------------------------------------------
28 // ThreadPlanPython
29 //----------------------------------------------------------------------
30
31 ThreadPlanPython::ThreadPlanPython(Thread &thread, const char *class_name)
32     : ThreadPlan(ThreadPlan::eKindPython, "Python based Thread Plan", thread,
33                  eVoteNoOpinion, eVoteNoOpinion),
34       m_class_name(class_name), m_did_push(false) {
35   SetIsMasterPlan(true);
36   SetOkayToDiscard(true);
37   SetPrivate(false);
38 }
39
40 ThreadPlanPython::~ThreadPlanPython() {
41   // FIXME, do I need to decrement the ref count on this implementation object
42   // to make it go away?
43 }
44
45 bool ThreadPlanPython::ValidatePlan(Stream *error) {
46   if (!m_did_push)
47     return true;
48
49   if (!m_implementation_sp) {
50     if (error)
51       error->Printf("Python thread plan does not have an implementation");
52     return false;
53   }
54
55   return true;
56 }
57
58 void ThreadPlanPython::DidPush() {
59   // We set up the script side in DidPush, so that it can push other plans in
60   // the constructor, and doesn't have to care about the details of DidPush.
61   m_did_push = true;
62   if (!m_class_name.empty()) {
63     ScriptInterpreter *script_interp = m_thread.GetProcess()
64                                            ->GetTarget()
65                                            .GetDebugger()
66                                            .GetCommandInterpreter()
67                                            .GetScriptInterpreter();
68     if (script_interp) {
69       m_implementation_sp = script_interp->CreateScriptedThreadPlan(
70           m_class_name.c_str(), this->shared_from_this());
71     }
72   }
73 }
74
75 bool ThreadPlanPython::ShouldStop(Event *event_ptr) {
76   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
77   if (log)
78     log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
79                 m_class_name.c_str());
80
81   bool should_stop = true;
82   if (m_implementation_sp) {
83     ScriptInterpreter *script_interp = m_thread.GetProcess()
84                                            ->GetTarget()
85                                            .GetDebugger()
86                                            .GetCommandInterpreter()
87                                            .GetScriptInterpreter();
88     if (script_interp) {
89       bool script_error;
90       should_stop = script_interp->ScriptedThreadPlanShouldStop(
91           m_implementation_sp, event_ptr, script_error);
92       if (script_error)
93         SetPlanComplete(false);
94     }
95   }
96   return should_stop;
97 }
98
99 bool ThreadPlanPython::IsPlanStale() {
100   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
101   if (log)
102     log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
103                 m_class_name.c_str());
104
105   bool is_stale = true;
106   if (m_implementation_sp) {
107     ScriptInterpreter *script_interp = m_thread.GetProcess()
108                                            ->GetTarget()
109                                            .GetDebugger()
110                                            .GetCommandInterpreter()
111                                            .GetScriptInterpreter();
112     if (script_interp) {
113       bool script_error;
114       is_stale = script_interp->ScriptedThreadPlanIsStale(m_implementation_sp,
115                                                           script_error);
116       if (script_error)
117         SetPlanComplete(false);
118     }
119   }
120   return is_stale;
121 }
122
123 bool ThreadPlanPython::DoPlanExplainsStop(Event *event_ptr) {
124   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
125   if (log)
126     log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
127                 m_class_name.c_str());
128
129   bool explains_stop = true;
130   if (m_implementation_sp) {
131     ScriptInterpreter *script_interp = m_thread.GetProcess()
132                                            ->GetTarget()
133                                            .GetDebugger()
134                                            .GetCommandInterpreter()
135                                            .GetScriptInterpreter();
136     if (script_interp) {
137       bool script_error;
138       explains_stop = script_interp->ScriptedThreadPlanExplainsStop(
139           m_implementation_sp, event_ptr, script_error);
140       if (script_error)
141         SetPlanComplete(false);
142     }
143   }
144   return explains_stop;
145 }
146
147 bool ThreadPlanPython::MischiefManaged() {
148   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
149   if (log)
150     log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
151                 m_class_name.c_str());
152   bool mischief_managed = true;
153   if (m_implementation_sp) {
154     // I don't really need mischief_managed, since it's simpler to just call
155     // SetPlanComplete in should_stop.
156     mischief_managed = IsPlanComplete();
157     if (mischief_managed)
158       m_implementation_sp.reset();
159   }
160   return mischief_managed;
161 }
162
163 lldb::StateType ThreadPlanPython::GetPlanRunState() {
164   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
165   if (log)
166     log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
167                 m_class_name.c_str());
168   lldb::StateType run_state = eStateRunning;
169   if (m_implementation_sp) {
170     ScriptInterpreter *script_interp = m_thread.GetProcess()
171                                            ->GetTarget()
172                                            .GetDebugger()
173                                            .GetCommandInterpreter()
174                                            .GetScriptInterpreter();
175     if (script_interp) {
176       bool script_error;
177       run_state = script_interp->ScriptedThreadPlanGetRunState(
178           m_implementation_sp, script_error);
179     }
180   }
181   return run_state;
182 }
183
184 // The ones below are not currently exported to Python.
185
186 bool ThreadPlanPython::StopOthers() {
187   // For now Python plans run all threads, but we should add some controls for
188   // this.
189   return false;
190 }
191
192 void ThreadPlanPython::GetDescription(Stream *s, lldb::DescriptionLevel level) {
193   s->Printf("Python thread plan implemented by class %s.",
194             m_class_name.c_str());
195 }
196
197 bool ThreadPlanPython::WillStop() {
198   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
199   if (log)
200     log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
201                 m_class_name.c_str());
202   return true;
203 }