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