summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Interpreter/ScriptInterpreter.h1
-rw-r--r--lldb/include/lldb/Target/ThreadPlanPython.h1
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/step_scripted/TestStepScripted.py23
-rw-r--r--lldb/scripts/Python/python-wrapper.swig6
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp13
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h1
-rw-r--r--lldb/source/Target/ThreadPlanPython.cpp6
-rw-r--r--lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp1
8 files changed, 43 insertions, 9 deletions
diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h
index 44c7554910e..9c68ffb0717 100644
--- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h
+++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h
@@ -208,6 +208,7 @@ public:
virtual StructuredData::ObjectSP
CreateScriptedThreadPlan(const char *class_name,
+ std::string &error_str,
lldb::ThreadPlanSP thread_plan_sp) {
return StructuredData::ObjectSP();
}
diff --git a/lldb/include/lldb/Target/ThreadPlanPython.h b/lldb/include/lldb/Target/ThreadPlanPython.h
index 3825bf6ee4f..58eb33e2c5b 100644
--- a/lldb/include/lldb/Target/ThreadPlanPython.h
+++ b/lldb/include/lldb/Target/ThreadPlanPython.h
@@ -55,6 +55,7 @@ protected:
private:
std::string m_class_name;
+ std::string m_error_str;
StructuredData::ObjectSP m_implementation_sp;
bool m_did_push;
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/step_scripted/TestStepScripted.py b/lldb/packages/Python/lldbsuite/test/functionalities/step_scripted/TestStepScripted.py
index a111ede6739..ce5f33f0bc9 100644
--- a/lldb/packages/Python/lldbsuite/test/functionalities/step_scripted/TestStepScripted.py
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/step_scripted/TestStepScripted.py
@@ -26,10 +26,13 @@ class StepScriptedTestCase(TestBase):
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())
@@ -39,3 +42,21 @@ class StepScriptedTestCase(TestBase):
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")
diff --git a/lldb/scripts/Python/python-wrapper.swig b/lldb/scripts/Python/python-wrapper.swig
index 8509899df27..8a99daa90c8 100644
--- a/lldb/scripts/Python/python-wrapper.swig
+++ b/lldb/scripts/Python/python-wrapper.swig
@@ -250,6 +250,7 @@ LLDBSwigPythonCreateScriptedThreadPlan
(
const char *python_class_name,
const char *session_dictionary_name,
+ std::string &error_string,
const lldb::ThreadPlanSP& thread_plan_sp
)
{
@@ -267,8 +268,11 @@ LLDBSwigPythonCreateScriptedThreadPlan
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));
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index 4019a572f22..4438a9b1dbe 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -97,6 +97,7 @@ LLDBSwigPythonCreateCommandObject(const char *python_class_name,
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,
@@ -1844,12 +1845,13 @@ StructuredData::DictionarySP ScriptInterpreterPythonImpl::OSPlugin_CreateThread(
}
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();
@@ -1857,17 +1859,18 @@ StructuredData::ObjectSP ScriptInterpreterPythonImpl::CreateScriptedThreadPlan(
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));
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
index e81c3b0851f..9cf32059a50 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
@@ -78,6 +78,7 @@ public:
StructuredData::ObjectSP
CreateScriptedThreadPlan(const char *class_name,
+ std::string &error_str,
lldb::ThreadPlanSP thread_plan) override;
bool ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp,
diff --git a/lldb/source/Target/ThreadPlanPython.cpp b/lldb/source/Target/ThreadPlanPython.cpp
index cc0f55bf8d8..ff57e0a25ff 100644
--- a/lldb/source/Target/ThreadPlanPython.cpp
+++ b/lldb/source/Target/ThreadPlanPython.cpp
@@ -45,7 +45,9 @@ bool ThreadPlanPython::ValidatePlan(Stream *error) {
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;
}
@@ -63,7 +65,7 @@ void ThreadPlanPython::DidPush() {
.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());
}
}
}
diff --git a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
index f6b617d26ae..3ccda8c6fed 100644
--- a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
+++ b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
@@ -95,6 +95,7 @@ LLDBSwigPythonCreateCommandObject(const char *python_class_name,
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;
}
OpenPOWER on IntegriCloud