]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Target/ThreadPlanPython.cpp
Merge ^/head r306412 through r306905.
[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/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"
21 #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
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,
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
48 ThreadPlanPython::~ThreadPlanPython ()
49 {
50     // FIXME, do I need to decrement the ref count on this implementation object to make it go away?
51 }
52
53 bool
54 ThreadPlanPython::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
64 void
65 ThreadPlanPython::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
80 bool
81 ThreadPlanPython::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
103 bool
104 ThreadPlanPython::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
126 bool
127 ThreadPlanPython::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
144 lldb::StateType
145 ThreadPlanPython::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
167 bool
168 ThreadPlanPython::StopOthers ()
169 {
170     // For now Python plans run all threads, but we should add some controls for this.
171     return false;
172 }
173
174 void
175 ThreadPlanPython::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
181 bool
182 ThreadPlanPython::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 }