LLDB  mainline
ThreadPlanPython.cpp
Go to the documentation of this file.
1 //===-- ThreadPlanPython.cpp ------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 
11 #include "lldb/Core/Debugger.h"
14 #include "lldb/Target/Process.h"
16 #include "lldb/Target/Target.h"
17 #include "lldb/Target/Thread.h"
18 #include "lldb/Target/ThreadPlan.h"
20 #include "lldb/Utility/Log.h"
21 #include "lldb/Utility/State.h"
22 
23 using namespace lldb;
24 using namespace lldb_private;
25 
26 // ThreadPlanPython
27 
28 ThreadPlanPython::ThreadPlanPython(Thread &thread, const char *class_name)
29  : ThreadPlan(ThreadPlan::eKindPython, "Python based Thread Plan", thread,
31  m_class_name(class_name), m_did_push(false) {
32  SetIsMasterPlan(true);
33  SetOkayToDiscard(true);
34  SetPrivate(false);
35 }
36 
38  // FIXME, do I need to decrement the ref count on this implementation object
39  // to make it go away?
40 }
41 
43  if (!m_did_push)
44  return true;
45 
46  if (!m_implementation_sp) {
47  if (error)
48  error->Printf("Python thread plan does not have an implementation");
49  return false;
50  }
51 
52  return true;
53 }
54 
56  // We set up the script side in DidPush, so that it can push other plans in
57  // the constructor, and doesn't have to care about the details of DidPush.
58  m_did_push = true;
59  if (!m_class_name.empty()) {
60  ScriptInterpreter *script_interp = m_thread.GetProcess()
61  ->GetTarget()
62  .GetDebugger()
63  .GetScriptInterpreter();
64  if (script_interp) {
65  m_implementation_sp = script_interp->CreateScriptedThreadPlan(
66  m_class_name.c_str(), this->shared_from_this());
67  }
68  }
69 }
70 
73  if (log)
74  log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
75  m_class_name.c_str());
76 
77  bool should_stop = true;
78  if (m_implementation_sp) {
79  ScriptInterpreter *script_interp = m_thread.GetProcess()
80  ->GetTarget()
81  .GetDebugger()
82  .GetScriptInterpreter();
83  if (script_interp) {
84  bool script_error;
85  should_stop = script_interp->ScriptedThreadPlanShouldStop(
86  m_implementation_sp, event_ptr, script_error);
87  if (script_error)
88  SetPlanComplete(false);
89  }
90  }
91  return should_stop;
92 }
93 
96  if (log)
97  log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
98  m_class_name.c_str());
99 
100  bool is_stale = true;
101  if (m_implementation_sp) {
102  ScriptInterpreter *script_interp = m_thread.GetProcess()
103  ->GetTarget()
104  .GetDebugger()
105  .GetScriptInterpreter();
106  if (script_interp) {
107  bool script_error;
108  is_stale = script_interp->ScriptedThreadPlanIsStale(m_implementation_sp,
109  script_error);
110  if (script_error)
111  SetPlanComplete(false);
112  }
113  }
114  return is_stale;
115 }
116 
119  if (log)
120  log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
121  m_class_name.c_str());
122 
123  bool explains_stop = true;
124  if (m_implementation_sp) {
125  ScriptInterpreter *script_interp = m_thread.GetProcess()
126  ->GetTarget()
127  .GetDebugger()
128  .GetScriptInterpreter();
129  if (script_interp) {
130  bool script_error;
131  explains_stop = script_interp->ScriptedThreadPlanExplainsStop(
132  m_implementation_sp, event_ptr, script_error);
133  if (script_error)
134  SetPlanComplete(false);
135  }
136  }
137  return explains_stop;
138 }
139 
142  if (log)
143  log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
144  m_class_name.c_str());
145  bool mischief_managed = true;
146  if (m_implementation_sp) {
147  // I don't really need mischief_managed, since it's simpler to just call
148  // SetPlanComplete in should_stop.
149  mischief_managed = IsPlanComplete();
150  if (mischief_managed)
151  m_implementation_sp.reset();
152  }
153  return mischief_managed;
154 }
155 
158  if (log)
159  log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
160  m_class_name.c_str());
161  lldb::StateType run_state = eStateRunning;
162  if (m_implementation_sp) {
163  ScriptInterpreter *script_interp = m_thread.GetProcess()
164  ->GetTarget()
165  .GetDebugger()
166  .GetScriptInterpreter();
167  if (script_interp) {
168  bool script_error;
169  run_state = script_interp->ScriptedThreadPlanGetRunState(
170  m_implementation_sp, script_error);
171  }
172  }
173  return run_state;
174 }
175 
176 // The ones below are not currently exported to Python.
177 
179  // For now Python plans run all threads, but we should add some controls for
180  // this.
181  return false;
182 }
183 
185  s->Printf("Python thread plan implemented by class %s.",
186  m_class_name.c_str());
187 }
188 
191  if (log)
192  log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
193  m_class_name.c_str());
194  return true;
195 }
void SetOkayToDiscard(bool value)
Definition: ThreadPlan.h:444
virtual lldb::StateType ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp, bool &script_error)
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
virtual bool ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error)
virtual bool ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp, bool &script_error)
bool ShouldStop(Event *event_ptr) override
virtual StructuredData::ObjectSP CreateScriptedThreadPlan(const char *class_name, lldb::ThreadPlanSP thread_plan_sp)
virtual bool ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error)
Log * GetLogIfAllCategoriesSet(uint32_t mask)
Definition: Logging.cpp:57
#define LIBLLDB_LOG_THREAD
Definition: Logging.h:16
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:106
bool ValidatePlan(Stream *error) override
Returns whether this plan could be successfully created.
void SetPlanComplete(bool success=true)
Definition: ThreadPlan.cpp:51
lldb::ProcessSP GetProcess() const
Definition: Thread.h:154
Definition: SBAddress.h:15
bool DoPlanExplainsStop(Event *event_ptr) override
void GetDescription(Stream *s, lldb::DescriptionLevel level) override
Print a description of this thread to the stream s.
bool SetIsMasterPlan(bool value)
Definition: ThreadPlan.h:436
void SetPrivate(bool input)
Definition: ThreadPlan.h:457
void Printf(const char *format,...) __attribute__((format(printf
Definition: Log.cpp:113
lldb::StateType GetPlanRunState() override
Process or thread is running and can't be examined.