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