virtual StructuredData::ObjectSP
CreateScriptedThreadPlan(const char *class_name,
+ std::string &error_str,
lldb::ThreadPlanSP thread_plan_sp) {
return StructuredData::ObjectSP();
}
private:
std::string m_class_name;
+ std::string m_error_str;
StructuredData::ObjectSP m_implementation_sp;
bool m_did_push;
def setUp(self):
TestBase.setUp(self)
+ self.main_source_file = lldb.SBFileSpec("main.c")
self.runCmd("command script import Steps.py")
def step_out_with_scripted_plan(self, name):
- (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here", self.main_source_file)
+ (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self,
+ "Set a breakpoint here",
+ self.main_source_file)
frame = thread.GetFrameAtIndex(0)
self.assertEqual("foo", frame.GetFunctionName())
frame = thread.GetFrameAtIndex(0)
self.assertEqual("main", frame.GetFunctionName())
+
+ def test_misspelled_plan_name(self):
+ """Test that we get a useful error if we misspell the plan class name"""
+ self.build()
+ (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self,
+ "Set a breakpoint here",
+ self.main_source_file)
+ stop_id = process.GetStopID()
+ # Pass a non-existent class for the plan class:
+ err = thread.StepUsingScriptedThreadPlan("NoSuchModule.NoSuchPlan")
+
+ # Make sure we got a good error:
+ self.assertTrue(err.Fail(), "We got a failure state")
+ msg = err.GetCString()
+ self.assertTrue("NoSuchModule.NoSuchPlan" in msg, "Mentioned missing class")
+
+ # Make sure we didn't let the process run:
+ self.assertEqual(stop_id, process.GetStopID(), "Process didn't run")
(
const char *python_class_name,
const char *session_dictionary_name,
+ std::string &error_string,
const lldb::ThreadPlanSP& thread_plan_sp
)
{
auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict);
- if (!pfunc.IsAllocated())
+ if (!pfunc.IsAllocated()) {
+ error_string.append("could not find script class: ");
+ error_string.append(python_class_name);
return nullptr;
+ }
PythonObject tp_arg(PyRefType::Owned, SBTypeToSWIGWrapper(tp_value));
extern "C" void *LLDBSwigPythonCreateScriptedThreadPlan(
const char *python_class_name, const char *session_dictionary_name,
+ std::string &error_string,
const lldb::ThreadPlanSP &thread_plan_sp);
extern "C" bool LLDBSWIGPythonCallThreadPlan(void *implementor,
}
StructuredData::ObjectSP ScriptInterpreterPythonImpl::CreateScriptedThreadPlan(
- const char *class_name, lldb::ThreadPlanSP thread_plan_sp) {
+ const char *class_name, std::string &error_str,
+ lldb::ThreadPlanSP thread_plan_sp) {
if (class_name == nullptr || class_name[0] == '\0')
return StructuredData::ObjectSP();
if (!thread_plan_sp.get())
- return StructuredData::ObjectSP();
+ return {};
Debugger &debugger = thread_plan_sp->GetTarget().GetDebugger();
ScriptInterpreter *script_interpreter = debugger.GetScriptInterpreter();
static_cast<ScriptInterpreterPythonImpl *>(script_interpreter);
if (!script_interpreter)
- return StructuredData::ObjectSP();
+ return {};
void *ret_val;
{
Locker py_lock(this,
Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
-
ret_val = LLDBSwigPythonCreateScriptedThreadPlan(
class_name, python_interpreter->m_dictionary_name.c_str(),
- thread_plan_sp);
+ error_str, thread_plan_sp);
+ if (!ret_val)
+ return {};
}
return StructuredData::ObjectSP(new StructuredPythonObject(ret_val));
StructuredData::ObjectSP
CreateScriptedThreadPlan(const char *class_name,
+ std::string &error_str,
lldb::ThreadPlanSP thread_plan) override;
bool ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp,
if (!m_implementation_sp) {
if (error)
- error->Printf("Python thread plan does not have an implementation");
+ error->Printf("Error constructing Python ThreadPlan: %s",
+ m_error_str.empty() ? "<unknown error>"
+ : m_error_str.c_str());
return false;
}
.GetScriptInterpreter();
if (script_interp) {
m_implementation_sp = script_interp->CreateScriptedThreadPlan(
- m_class_name.c_str(), this->shared_from_this());
+ m_class_name.c_str(), m_error_str, this->shared_from_this());
}
}
}
extern "C" void *LLDBSwigPythonCreateScriptedThreadPlan(
const char *python_class_name, const char *session_dictionary_name,
+ std::string &error_string,
const lldb::ThreadPlanSP &thread_plan_sp) {
return nullptr;
}