[Lldb-commits] [lldb] r373675 - Pass an SBStructuredData to scripted ThreadPlans on use.
Jim Ingham via lldb-commits
lldb-commits at lists.llvm.org
Thu Oct 3 15:50:18 PDT 2019
Author: jingham
Date: Thu Oct 3 15:50:18 2019
New Revision: 373675
URL: http://llvm.org/viewvc/llvm-project?rev=373675&view=rev
Log:
Pass an SBStructuredData to scripted ThreadPlans on use.
This will allow us to write reusable scripted ThreadPlans, since
you can use key/value pairs with known keys in the plan to parametrize
its behavior.
Differential Revision: https://reviews.llvm.org/D68366
Modified:
lldb/trunk/include/lldb/API/SBStructuredData.h
lldb/trunk/include/lldb/API/SBThread.h
lldb/trunk/include/lldb/API/SBThreadPlan.h
lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
lldb/trunk/include/lldb/Target/Thread.h
lldb/trunk/include/lldb/Target/ThreadPlanPython.h
lldb/trunk/packages/Python/lldbsuite/test/commands/help/TestHelp.py
lldb/trunk/packages/Python/lldbsuite/test/functionalities/step_scripted/Steps.py
lldb/trunk/packages/Python/lldbsuite/test/functionalities/step_scripted/TestStepScripted.py
lldb/trunk/scripts/Python/python-wrapper.swig
lldb/trunk/scripts/interface/SBThread.i
lldb/trunk/scripts/interface/SBThreadPlan.i
lldb/trunk/source/API/SBThread.cpp
lldb/trunk/source/API/SBThreadPlan.cpp
lldb/trunk/source/Commands/CommandObjectThread.cpp
lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
lldb/trunk/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
lldb/trunk/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
lldb/trunk/source/Target/Thread.cpp
lldb/trunk/source/Target/ThreadPlanPython.cpp
lldb/trunk/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
Modified: lldb/trunk/include/lldb/API/SBStructuredData.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBStructuredData.h?rev=373675&r1=373674&r2=373675&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBStructuredData.h (original)
+++ lldb/trunk/include/lldb/API/SBStructuredData.h Thu Oct 3 15:50:18 2019
@@ -91,6 +91,8 @@ protected:
friend class SBTraceOptions;
friend class SBDebugger;
friend class SBTarget;
+ friend class SBThread;
+ friend class SBThreadPlan;
StructuredDataImplUP m_impl_up;
};
Modified: lldb/trunk/include/lldb/API/SBThread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBThread.h?rev=373675&r1=373674&r2=373675&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBThread.h (original)
+++ lldb/trunk/include/lldb/API/SBThread.h Thu Oct 3 15:50:18 2019
@@ -122,6 +122,10 @@ public:
SBError StepUsingScriptedThreadPlan(const char *script_class_name,
bool resume_immediately);
+ SBError StepUsingScriptedThreadPlan(const char *script_class_name,
+ lldb::SBStructuredData &args_data,
+ bool resume_immediately);
+
SBError JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line);
void RunToAddress(lldb::addr_t addr);
Modified: lldb/trunk/include/lldb/API/SBThreadPlan.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBThreadPlan.h?rev=373675&r1=373674&r2=373675&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBThreadPlan.h (original)
+++ lldb/trunk/include/lldb/API/SBThreadPlan.h Thu Oct 3 15:50:18 2019
@@ -28,6 +28,9 @@ public:
SBThreadPlan(lldb::SBThread &thread, const char *class_name);
+ SBThreadPlan(lldb::SBThread &thread, const char *class_name,
+ lldb::SBStructuredData &args_data);
+
~SBThreadPlan();
explicit operator bool() const;
@@ -100,6 +103,9 @@ public:
SBThreadPlan QueueThreadPlanForStepScripted(const char *script_class_name);
SBThreadPlan QueueThreadPlanForStepScripted(const char *script_class_name,
SBError &error);
+ SBThreadPlan QueueThreadPlanForStepScripted(const char *script_class_name,
+ lldb::SBStructuredData &args_data,
+ SBError &error);
private:
friend class SBBreakpoint;
Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h?rev=373675&r1=373674&r2=373675&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h Thu Oct 3 15:50:18 2019
@@ -208,6 +208,7 @@ public:
virtual StructuredData::ObjectSP
CreateScriptedThreadPlan(const char *class_name,
+ StructuredDataImpl *args_data,
std::string &error_str,
lldb::ThreadPlanSP thread_plan_sp) {
return StructuredData::ObjectSP();
Modified: lldb/trunk/include/lldb/Target/Thread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Thread.h?rev=373675&r1=373674&r2=373675&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Thread.h (original)
+++ lldb/trunk/include/lldb/Target/Thread.h Thu Oct 3 15:50:18 2019
@@ -899,6 +899,7 @@ public:
virtual lldb::ThreadPlanSP
QueueThreadPlanForStepScripted(bool abort_other_plans, const char *class_name,
+ StructuredData::ObjectSP extra_args_sp,
bool stop_other_threads, Status &status);
// Thread Plan accessors:
Modified: lldb/trunk/include/lldb/Target/ThreadPlanPython.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanPython.h?rev=373675&r1=373674&r2=373675&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanPython.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanPython.h Thu Oct 3 15:50:18 2019
@@ -12,6 +12,8 @@
#include <string>
+#include "lldb/lldb-forward.h"
+
#include "lldb/Target/Process.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
@@ -29,7 +31,8 @@ namespace lldb_private {
class ThreadPlanPython : public ThreadPlan {
public:
- ThreadPlanPython(Thread &thread, const char *class_name);
+ ThreadPlanPython(Thread &thread, const char *class_name,
+ StructuredDataImpl *args_data);
~ThreadPlanPython() override;
void GetDescription(Stream *s, lldb::DescriptionLevel level) override;
@@ -55,6 +58,10 @@ protected:
private:
std::string m_class_name;
+ StructuredDataImpl *m_args_data; // We own this, but the implementation
+ // has to manage the UP (since that is
+ // how it gets stored in the
+ // SBStructuredData).
std::string m_error_str;
StructuredData::ObjectSP m_implementation_sp;
bool m_did_push;
Modified: lldb/trunk/packages/Python/lldbsuite/test/commands/help/TestHelp.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/commands/help/TestHelp.py?rev=373675&r1=373674&r2=373675&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/commands/help/TestHelp.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/commands/help/TestHelp.py Thu Oct 3 15:50:18 2019
@@ -188,7 +188,7 @@ class HelpCommandTestCase(TestBase):
def test_help_next_shows_options(self):
"""Test that 'help next' shows all the options for thread step-over"""
self.expect("help next",
- substrs=['--python-class', '--run-mode'], matching=True)
+ substrs=['--step-out-avoids-no-debug', '--run-mode'], matching=True)
@no_debug_info_test
def test_help_provides_alternatives(self):
Modified: lldb/trunk/packages/Python/lldbsuite/test/functionalities/step_scripted/Steps.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/step_scripted/Steps.py?rev=373675&r1=373674&r2=373675&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/step_scripted/Steps.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/step_scripted/Steps.py Thu Oct 3 15:50:18 2019
@@ -38,18 +38,29 @@ class StepScripted(StepWithChild):
# This plan does a step-over until a variable changes value.
class StepUntil(StepWithChild):
- def __init__(self, thread_plan, dict):
+ def __init__(self, thread_plan, args_data, dict):
self.frame = thread_plan.GetThread().frames[0]
self.target = thread_plan.GetThread().GetProcess().GetTarget()
- self.value = self.frame.FindVariable("foo")
+ func_entry = args_data.GetValueForKey("variable_name")
+
+ if not func_entry.IsValid():
+ print("Did not get a valid entry for variable_name")
+ func_name = func_entry.GetStringValue(100)
+
+ self.value = self.frame.FindVariable(func_name)
+ if self.value.GetError().Fail():
+ print("Failed to get foo value: %s"%(self.value.GetError().GetCString()))
+ else:
+ print("'foo' value: %d"%(self.value.GetValueAsUnsigned()))
+
StepWithChild.__init__(self, thread_plan)
+
def queue_child_thread_plan(self):
le = self.frame.GetLineEntry()
start_addr = le.GetStartAddress()
start = start_addr.GetLoadAddress(self.target)
end = le.GetEndAddress().GetLoadAddress(self.target)
- print("Stepping from 0x%x to 0x%x (0x%x)"%(start, end, end - start))
return self.thread_plan.QueueThreadPlanForStepOverRange(start_addr,
end - start)
Modified: lldb/trunk/packages/Python/lldbsuite/test/functionalities/step_scripted/TestStepScripted.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/step_scripted/TestStepScripted.py?rev=373675&r1=373674&r2=373675&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/step_scripted/TestStepScripted.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/step_scripted/TestStepScripted.py Thu Oct 3 15:50:18 2019
@@ -63,7 +63,14 @@ class StepScriptedTestCase(TestBase):
self.assertEqual(stop_id, process.GetStopID(), "Process didn't run")
def test_checking_variable(self):
- """Test that we can call SBValue API's from a scripted thread plan"""
+ """Test that we can call SBValue API's from a scripted thread plan - using SBAPI's to step"""
+ self.do_test_checking_variable(False)
+
+ def test_checking_variable_cli(self):
+ """Test that we can call SBValue API's from a scripted thread plan - using cli to step"""
+ self.do_test_checking_variable(True)
+
+ def do_test_checking_variable(self, use_cli):
self.build()
(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self,
"Set a breakpoint here",
@@ -75,8 +82,21 @@ class StepScriptedTestCase(TestBase):
self.assertTrue(foo_val.GetError().Success(), "Got the foo variable")
self.assertEqual(foo_val.GetValueAsUnsigned(), 10, "foo starts at 10")
- err = thread.StepUsingScriptedThreadPlan("Steps.StepUntil")
- self.assertTrue(err.Success(), err.GetCString())
+ if use_cli:
+ result = lldb.SBCommandReturnObject()
+ self.dbg.GetCommandInterpreter().HandleCommand(
+ "thread step-scripted -C Steps.StepUntil -k variable_name -v foo",
+ result)
+ self.assertTrue(result.Succeeded())
+ else:
+ args_data = lldb.SBStructuredData()
+ data = lldb.SBStream()
+ data.Print('{"variable_name" : "foo"}')
+ error = args_data.SetFromJSON(data)
+ self.assertTrue(error.Success(), "Made the args_data correctly")
+
+ err = thread.StepUsingScriptedThreadPlan("Steps.StepUntil", args_data, True)
+ self.assertTrue(err.Success(), err.GetCString())
# We should not have exited:
self.assertEqual(process.GetState(), lldb.eStateStopped, "We are stopped")
Modified: lldb/trunk/scripts/Python/python-wrapper.swig
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/python-wrapper.swig?rev=373675&r1=373674&r2=373675&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/python-wrapper.swig (original)
+++ lldb/trunk/scripts/Python/python-wrapper.swig Thu Oct 3 15:50:18 2019
@@ -250,6 +250,7 @@ LLDBSwigPythonCreateScriptedThreadPlan
(
const char *python_class_name,
const char *session_dictionary_name,
+ lldb_private::StructuredDataImpl *args_impl,
std::string &error_string,
const lldb::ThreadPlanSP& thread_plan_sp
)
@@ -279,7 +280,23 @@ LLDBSwigPythonCreateScriptedThreadPlan
if (!tp_arg.IsAllocated())
Py_RETURN_NONE;
- PythonObject result = pfunc(tp_arg, dict);
+ PythonObject result = {};
+ size_t init_num_args = pfunc.GetNumInitArguments().count;
+ if (init_num_args == 3) {
+ if (args_impl != nullptr) {
+ error_string.assign("args passed, but __init__ does not take an args dictionary");
+ Py_RETURN_NONE;
+ }
+ result = pfunc(tp_arg, dict);
+ } else if (init_num_args = 4) {
+ lldb::SBStructuredData *args_value = new lldb::SBStructuredData(args_impl);
+ PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(args_value));
+ result = pfunc(tp_arg, args_arg, dict);
+ } else {
+ error_string.assign("wrong number of arguments in __init__, should be 1 or 2 (not including self & dict)");
+ Py_RETURN_NONE;
+ }
+
// FIXME: At this point we should check that the class we found supports all the methods
// that we need.
Modified: lldb/trunk/scripts/interface/SBThread.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/interface/SBThread.i?rev=373675&r1=373674&r2=373675&view=diff
==============================================================================
--- lldb/trunk/scripts/interface/SBThread.i (original)
+++ lldb/trunk/scripts/interface/SBThread.i Thu Oct 3 15:50:18 2019
@@ -254,6 +254,11 @@ public:
StepUsingScriptedThreadPlan (const char *script_class_name, bool resume_immediately);
SBError
+ StepUsingScriptedThreadPlan(const char *script_class_name,
+ lldb::SBStructuredData &args_data,
+ bool resume_immediately);
+
+ SBError
JumpToLine (lldb::SBFileSpec &file_spec, uint32_t line);
void
Modified: lldb/trunk/scripts/interface/SBThreadPlan.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/interface/SBThreadPlan.i?rev=373675&r1=373674&r2=373675&view=diff
==============================================================================
--- lldb/trunk/scripts/interface/SBThreadPlan.i (original)
+++ lldb/trunk/scripts/interface/SBThreadPlan.i Thu Oct 3 15:50:18 2019
@@ -109,6 +109,14 @@ public:
SBThreadPlan
QueueThreadPlanForStepScripted(const char *script_class_name);
+ SBThreadPlan
+ QueueThreadPlanForStepScripted(const char *script_class_name,
+ SBError &error);
+ SBThreadPlan
+ QueueThreadPlanForStepScripted(const char *script_class_name,
+ SBStructuredData &args_data,
+ SBError &error);
+
protected:
friend class SBBreakpoint;
Modified: lldb/trunk/source/API/SBThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBThread.cpp?rev=373675&r1=373674&r2=373675&view=diff
==============================================================================
--- lldb/trunk/source/API/SBThread.cpp (original)
+++ lldb/trunk/source/API/SBThread.cpp Thu Oct 3 15:50:18 2019
@@ -16,6 +16,7 @@
#include "lldb/API/SBFrame.h"
#include "lldb/API/SBProcess.h"
#include "lldb/API/SBStream.h"
+#include "lldb/API/SBStructuredData.h"
#include "lldb/API/SBSymbolContext.h"
#include "lldb/API/SBThreadCollection.h"
#include "lldb/API/SBThreadPlan.h"
@@ -23,6 +24,7 @@
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/StreamFile.h"
+#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Symbol/CompileUnit.h"
@@ -965,9 +967,24 @@ SBError SBThread::StepUsingScriptedThrea
}
SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
+ bool resume_immediately) {
+ LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
+ (const char *, bool), script_class_name,
+ resume_immediately);
+
+ lldb::SBStructuredData no_data;
+ return LLDB_RECORD_RESULT(
+ StepUsingScriptedThreadPlan(script_class_name,
+ no_data,
+ resume_immediately));
+}
+
+SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
+ SBStructuredData &args_data,
bool resume_immediately) {
LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
- (const char *, bool), script_class_name,
+ (const char *, lldb::SBStructuredData &, bool),
+ script_class_name, args_data,
resume_immediately);
SBError error;
@@ -982,8 +999,10 @@ SBError SBThread::StepUsingScriptedThrea
Thread *thread = exe_ctx.GetThreadPtr();
Status new_plan_status;
+ StructuredData::ObjectSP obj_sp = args_data.m_impl_up->GetObjectSP();
+
ThreadPlanSP new_plan_sp = thread->QueueThreadPlanForStepScripted(
- false, script_class_name, false, new_plan_status);
+ false, script_class_name, obj_sp, false, new_plan_status);
if (new_plan_status.Fail()) {
error.SetErrorString(new_plan_status.AsCString());
@@ -1460,6 +1479,8 @@ void RegisterMethods<SBThread>(Registry
(const char *));
LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
(const char *, bool));
+ LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
+ (const char *, SBStructuredData &, bool));
LLDB_REGISTER_METHOD(lldb::SBError, SBThread, JumpToLine,
(lldb::SBFileSpec &, uint32_t));
LLDB_REGISTER_METHOD(lldb::SBError, SBThread, ReturnFromFrame,
Modified: lldb/trunk/source/API/SBThreadPlan.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBThreadPlan.cpp?rev=373675&r1=373674&r2=373675&view=diff
==============================================================================
--- lldb/trunk/source/API/SBThreadPlan.cpp (original)
+++ lldb/trunk/source/API/SBThreadPlan.cpp Thu Oct 3 15:50:18 2019
@@ -11,10 +11,12 @@
#include "lldb/API/SBFileSpec.h"
#include "lldb/API/SBStream.h"
+#include "lldb/API/SBStructuredData.h"
#include "lldb/API/SBSymbolContext.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/StreamFile.h"
+#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/SymbolContext.h"
@@ -67,7 +69,20 @@ SBThreadPlan::SBThreadPlan(lldb::SBThrea
Thread *thread = sb_thread.get();
if (thread)
- m_opaque_sp = std::make_shared<ThreadPlanPython>(*thread, class_name);
+ m_opaque_sp = std::make_shared<ThreadPlanPython>(*thread, class_name,
+ nullptr);
+}
+
+SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name,
+ lldb::SBStructuredData &args_data) {
+ LLDB_RECORD_CONSTRUCTOR(SBThreadPlan, (lldb::SBThread &, const char *,
+ SBStructuredData &),
+ sb_thread, class_name, args_data);
+
+ Thread *thread = sb_thread.get();
+ if (thread)
+ m_opaque_sp = std::make_shared<ThreadPlanPython>(*thread, class_name,
+ args_data.m_impl_up.get());
}
// Assignment operator
@@ -368,9 +383,35 @@ SBThreadPlan::QueueThreadPlanForStepScri
if (m_opaque_sp) {
Status plan_status;
+ StructuredData::ObjectSP empty_args;
SBThreadPlan plan =
SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepScripted(
- false, script_class_name, false, plan_status));
+ false, script_class_name, empty_args, false, plan_status));
+
+ if (plan_status.Fail())
+ error.SetErrorString(plan_status.AsCString());
+
+ return LLDB_RECORD_RESULT(plan);
+ } else {
+ return LLDB_RECORD_RESULT(SBThreadPlan());
+ }
+}
+
+SBThreadPlan
+SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name,
+ lldb::SBStructuredData &args_data,
+ SBError &error) {
+ LLDB_RECORD_METHOD(lldb::SBThreadPlan, SBThreadPlan,
+ QueueThreadPlanForStepScripted,
+ (const char *, lldb::SBStructuredData &, lldb::SBError &),
+ script_class_name, args_data, error);
+
+ if (m_opaque_sp) {
+ Status plan_status;
+ StructuredData::ObjectSP args_obj = args_data.m_impl_up->GetObjectSP();
+ SBThreadPlan plan =
+ SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepScripted(
+ false, script_class_name, args_obj, false, plan_status));
if (plan_status.Fail())
error.SetErrorString(plan_status.AsCString());
@@ -390,6 +431,8 @@ void RegisterMethods<SBThreadPlan>(Regis
LLDB_REGISTER_CONSTRUCTOR(SBThreadPlan, (const lldb::ThreadPlanSP &));
LLDB_REGISTER_CONSTRUCTOR(SBThreadPlan, (const lldb::SBThreadPlan &));
LLDB_REGISTER_CONSTRUCTOR(SBThreadPlan, (lldb::SBThread &, const char *));
+ LLDB_REGISTER_CONSTRUCTOR(SBThreadPlan, (lldb::SBThread &, const char *,
+ lldb::SBStructuredData &));
LLDB_REGISTER_METHOD(const lldb::SBThreadPlan &,
SBThreadPlan, operator=,(const lldb::SBThreadPlan &));
LLDB_REGISTER_METHOD_CONST(bool, SBThreadPlan, IsValid, ());
@@ -433,6 +476,10 @@ void RegisterMethods<SBThreadPlan>(Regis
LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan,
QueueThreadPlanForStepScripted,
(const char *, lldb::SBError &));
+ LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan,
+ QueueThreadPlanForStepScripted,
+ (const char *, lldb::SBStructuredData &,
+ lldb::SBError &));
}
}
Modified: lldb/trunk/source/Commands/CommandObjectThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectThread.cpp?rev=373675&r1=373674&r2=373675&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectThread.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectThread.cpp Thu Oct 3 15:50:18 2019
@@ -16,6 +16,7 @@
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionArgParser.h"
+#include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
@@ -401,127 +402,122 @@ static constexpr OptionEnumValues TriRun
#define LLDB_OPTIONS_thread_step_scope
#include "CommandOptions.inc"
-class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed {
+class ThreadStepScopeOptionGroup : public OptionGroup {
public:
- class CommandOptions : public Options {
- public:
- CommandOptions() : Options() {
- // Keep default values of all options in one place: OptionParsingStarting
- // ()
- OptionParsingStarting(nullptr);
- }
-
- ~CommandOptions() override = default;
-
- Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
- ExecutionContext *execution_context) override {
- Status error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option) {
- case 'a': {
- bool success;
- bool avoid_no_debug =
- OptionArgParser::ToBoolean(option_arg, true, &success);
- if (!success)
- error.SetErrorStringWithFormat(
- "invalid boolean value for option '%c'", short_option);
- else {
- m_step_in_avoid_no_debug =
- avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
- }
- } break;
-
- case 'A': {
- bool success;
- bool avoid_no_debug =
- OptionArgParser::ToBoolean(option_arg, true, &success);
- if (!success)
- error.SetErrorStringWithFormat(
- "invalid boolean value for option '%c'", short_option);
- else {
- m_step_out_avoid_no_debug =
- avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
- }
- } break;
-
- case 'c':
- if (option_arg.getAsInteger(0, m_step_count))
- error.SetErrorStringWithFormat("invalid step count '%s'",
- option_arg.str().c_str());
- break;
+ ThreadStepScopeOptionGroup() : OptionGroup() {
+ // Keep default values of all options in one place: OptionParsingStarting
+ // ()
+ OptionParsingStarting(nullptr);
+ }
- case 'C':
- m_class_name.clear();
- m_class_name.assign(option_arg);
- break;
+ ~ThreadStepScopeOptionGroup() override = default;
- case 'm': {
- auto enum_values = GetDefinitions()[option_idx].enum_values;
- m_run_mode = (lldb::RunMode)OptionArgParser::ToOptionEnum(
- option_arg, enum_values, eOnlyDuringStepping, error);
- } break;
-
- case 'e':
- if (option_arg == "block") {
- m_end_line_is_block_end = true;
- break;
- }
- if (option_arg.getAsInteger(0, m_end_line))
- error.SetErrorStringWithFormat("invalid end line number '%s'",
- option_arg.str().c_str());
- break;
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_thread_step_scope_options);
+ }
- case 'r':
- m_avoid_regexp.clear();
- m_avoid_regexp.assign(option_arg);
- break;
+ Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Status error;
+ const int short_option
+ = g_thread_step_scope_options[option_idx].short_option;
- case 't':
- m_step_in_target.clear();
- m_step_in_target.assign(option_arg);
+ switch (short_option) {
+ case 'a': {
+ bool success;
+ bool avoid_no_debug =
+ OptionArgParser::ToBoolean(option_arg, true, &success);
+ if (!success)
+ error.SetErrorStringWithFormat(
+ "invalid boolean value for option '%c'", short_option);
+ else {
+ m_step_in_avoid_no_debug =
+ avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
+ }
+ } break;
+
+ case 'A': {
+ bool success;
+ bool avoid_no_debug =
+ OptionArgParser::ToBoolean(option_arg, true, &success);
+ if (!success)
+ error.SetErrorStringWithFormat(
+ "invalid boolean value for option '%c'", short_option);
+ else {
+ m_step_out_avoid_no_debug =
+ avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
+ }
+ } break;
+
+ case 'c':
+ if (option_arg.getAsInteger(0, m_step_count))
+ error.SetErrorStringWithFormat("invalid step count '%s'",
+ option_arg.str().c_str());
+ break;
+
+ case 'm': {
+ auto enum_values = GetDefinitions()[option_idx].enum_values;
+ m_run_mode = (lldb::RunMode)OptionArgParser::ToOptionEnum(
+ option_arg, enum_values, eOnlyDuringStepping, error);
+ } break;
+
+ case 'e':
+ if (option_arg == "block") {
+ m_end_line_is_block_end = true;
break;
-
- default:
- llvm_unreachable("Unimplemented option");
}
- return error;
- }
-
- void OptionParsingStarting(ExecutionContext *execution_context) override {
- m_step_in_avoid_no_debug = eLazyBoolCalculate;
- m_step_out_avoid_no_debug = eLazyBoolCalculate;
- m_run_mode = eOnlyDuringStepping;
-
- // Check if we are in Non-Stop mode
- TargetSP target_sp =
- execution_context ? execution_context->GetTargetSP() : TargetSP();
- if (target_sp && target_sp->GetNonStopModeEnabled())
- m_run_mode = eOnlyThisThread;
+ if (option_arg.getAsInteger(0, m_end_line))
+ error.SetErrorStringWithFormat("invalid end line number '%s'",
+ option_arg.str().c_str());
+ break;
+ case 'r':
m_avoid_regexp.clear();
+ m_avoid_regexp.assign(option_arg);
+ break;
+
+ case 't':
m_step_in_target.clear();
- m_class_name.clear();
- m_step_count = 1;
- m_end_line = LLDB_INVALID_LINE_NUMBER;
- m_end_line_is_block_end = false;
- }
+ m_step_in_target.assign(option_arg);
+ break;
- llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
- return llvm::makeArrayRef(g_thread_step_scope_options);
+ default:
+ llvm_unreachable("Unimplemented option");
}
+ return error;
+ }
- // Instance variables to hold the values for command options.
- LazyBool m_step_in_avoid_no_debug;
- LazyBool m_step_out_avoid_no_debug;
- RunMode m_run_mode;
- std::string m_avoid_regexp;
- std::string m_step_in_target;
- std::string m_class_name;
- uint32_t m_step_count;
- uint32_t m_end_line;
- bool m_end_line_is_block_end;
- };
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_step_in_avoid_no_debug = eLazyBoolCalculate;
+ m_step_out_avoid_no_debug = eLazyBoolCalculate;
+ m_run_mode = eOnlyDuringStepping;
+
+ // Check if we are in Non-Stop mode
+ TargetSP target_sp =
+ execution_context ? execution_context->GetTargetSP() : TargetSP();
+ if (target_sp && target_sp->GetNonStopModeEnabled())
+ m_run_mode = eOnlyThisThread;
+
+ m_avoid_regexp.clear();
+ m_step_in_target.clear();
+ m_step_count = 1;
+ m_end_line = LLDB_INVALID_LINE_NUMBER;
+ m_end_line_is_block_end = false;
+ }
+
+ // Instance variables to hold the values for command options.
+ LazyBool m_step_in_avoid_no_debug;
+ LazyBool m_step_out_avoid_no_debug;
+ RunMode m_run_mode;
+ std::string m_avoid_regexp;
+ std::string m_step_in_target;
+ uint32_t m_step_count;
+ uint32_t m_end_line;
+ bool m_end_line_is_block_end;
+};
+
+class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed {
+public:
CommandObjectThreadStepWithTypeAndScope(CommandInterpreter &interpreter,
const char *name, const char *help,
@@ -533,7 +529,8 @@ public:
eCommandTryTargetAPILock |
eCommandProcessMustBeLaunched |
eCommandProcessMustBePaused),
- m_step_type(step_type), m_step_scope(step_scope), m_options() {
+ m_step_type(step_type), m_step_scope(step_scope), m_options(),
+ m_class_options("scripted step", 'C') {
CommandArgumentEntry arg;
CommandArgumentData thread_id_arg;
@@ -547,11 +544,19 @@ public:
// Push the data for the first argument into the m_arguments vector.
m_arguments.push_back(arg);
+
+ if (step_type == eStepTypeScripted) {
+ m_all_options.Append(&m_class_options, LLDB_OPT_SET_1, LLDB_OPT_SET_1);
+ }
+ m_all_options.Append(&m_options);
+ m_all_options.Finalize();
}
~CommandObjectThreadStepWithTypeAndScope() override = default;
- Options *GetOptions() override { return &m_options; }
+ Options *GetOptions() override {
+ return &m_all_options;
+ }
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
@@ -591,15 +596,15 @@ protected:
}
if (m_step_type == eStepTypeScripted) {
- if (m_options.m_class_name.empty()) {
+ if (m_class_options.GetClassName().empty()) {
result.AppendErrorWithFormat("empty class name for scripted step.");
result.SetStatus(eReturnStatusFailed);
return false;
} else if (!GetDebugger().GetScriptInterpreter()->CheckObjectExists(
- m_options.m_class_name.c_str())) {
+ m_class_options.GetClassName().c_str())) {
result.AppendErrorWithFormat(
"class for scripted step: \"%s\" does not exist.",
- m_options.m_class_name.c_str());
+ m_class_options.GetClassName().c_str());
result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -715,7 +720,8 @@ protected:
m_options.m_step_out_avoid_no_debug);
} else if (m_step_type == eStepTypeScripted) {
new_plan_sp = thread->QueueThreadPlanForStepScripted(
- abort_other_plans, m_options.m_class_name.c_str(),
+ abort_other_plans, m_class_options.GetClassName().c_str(),
+ m_class_options.GetStructuredData(),
bool_stop_other_threads, new_plan_status);
} else {
result.AppendError("step type is not supported");
@@ -783,7 +789,9 @@ protected:
protected:
StepType m_step_type;
StepScope m_step_scope;
- CommandOptions m_options;
+ ThreadStepScopeOptionGroup m_options;
+ OptionGroupPythonClassWithDict m_class_options;
+ OptionGroupOptions m_all_options;
};
// CommandObjectThreadContinue
@@ -2060,7 +2068,11 @@ CommandObjectMultiwordThread::CommandObj
"step-scripted",
CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
interpreter, "thread step-scripted",
- "Step as instructed by the script class passed in the -C option.",
+ "Step as instructed by the script class passed in the -C option. "
+ "You can also specify a dictionary of key (-k) and value (-v) pairs "
+ "that will be used to populate an SBStructuredData Dictionary, which "
+ "will be passed to the constructor of the class implementing the "
+ "scripted step. See the Python Reference for more details.",
nullptr, eStepTypeScripted, eStepScopeSource)));
LoadSubCommand("plan", CommandObjectSP(new CommandObjectMultiwordThreadPlan(
Modified: lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp?rev=373675&r1=373674&r2=373675&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp (original)
+++ lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp Thu Oct 3 15:50:18 2019
@@ -887,6 +887,23 @@ void PythonCallable::Reset(PyRefType typ
PythonObject::Reset(PyRefType::Borrowed, result.get());
}
+PythonCallable::ArgInfo PythonCallable::GetNumInitArguments() const {
+ ArgInfo result = {0, false, false, false};
+ if (!IsValid())
+ return result;
+ PyObject *py_func_obj = m_py_obj;
+ if (!PyClass_Check(m_py_obj))
+ return result;
+
+ PythonObject __init__ = GetAttributeValue("__init__");
+ if (__init__.IsValid() ) {
+ auto __init_callable__ = __init__.AsType<PythonCallable>();
+ if (__init_callable__.IsValid())
+ return __init_callable__.GetNumArguments();
+ }
+ return result;
+}
+
PythonCallable::ArgInfo PythonCallable::GetNumArguments() const {
ArgInfo result = {0, false, false, false};
if (!IsValid())
Modified: lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h?rev=373675&r1=373674&r2=373675&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h (original)
+++ lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h Thu Oct 3 15:50:18 2019
@@ -438,6 +438,10 @@ public:
void Reset(PyRefType type, PyObject *py_obj) override;
ArgInfo GetNumArguments() const;
+
+ // If the callable is a Py_Class, then find the number of arguments
+ // of the __init__ method.
+ ArgInfo GetNumInitArguments() const;
PythonObject operator()();
Modified: lldb/trunk/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp?rev=373675&r1=373674&r2=373675&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp (original)
+++ lldb/trunk/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp Thu Oct 3 15:50:18 2019
@@ -97,6 +97,7 @@ LLDBSwigPythonCreateCommandObject(const
extern "C" void *LLDBSwigPythonCreateScriptedThreadPlan(
const char *python_class_name, const char *session_dictionary_name,
+ StructuredDataImpl *args_data,
std::string &error_string,
const lldb::ThreadPlanSP &thread_plan_sp);
@@ -1845,7 +1846,8 @@ StructuredData::DictionarySP ScriptInter
}
StructuredData::ObjectSP ScriptInterpreterPythonImpl::CreateScriptedThreadPlan(
- const char *class_name, std::string &error_str,
+ const char *class_name, StructuredDataImpl *args_data,
+ std::string &error_str,
lldb::ThreadPlanSP thread_plan_sp) {
if (class_name == nullptr || class_name[0] == '\0')
return StructuredData::ObjectSP();
@@ -1868,7 +1870,7 @@ StructuredData::ObjectSP ScriptInterpret
Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
ret_val = LLDBSwigPythonCreateScriptedThreadPlan(
class_name, python_interpreter->m_dictionary_name.c_str(),
- error_str, thread_plan_sp);
+ args_data, error_str, thread_plan_sp);
if (!ret_val)
return {};
}
Modified: lldb/trunk/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h?rev=373675&r1=373674&r2=373675&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h (original)
+++ lldb/trunk/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h Thu Oct 3 15:50:18 2019
@@ -78,6 +78,7 @@ public:
StructuredData::ObjectSP
CreateScriptedThreadPlan(const char *class_name,
+ StructuredDataImpl *args_data,
std::string &error_str,
lldb::ThreadPlanSP thread_plan) override;
Modified: lldb/trunk/source/Target/Thread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Thread.cpp?rev=373675&r1=373674&r2=373675&view=diff
==============================================================================
--- lldb/trunk/source/Target/Thread.cpp (original)
+++ lldb/trunk/source/Target/Thread.cpp Thu Oct 3 15:50:18 2019
@@ -13,6 +13,7 @@
#include "lldb/Core/Debugger.h"
#include "lldb/Core/FormatEntity.h"
#include "lldb/Core/Module.h"
+#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Host/Host.h"
#include "lldb/Interpreter/OptionValueFileSpecList.h"
@@ -1482,9 +1483,18 @@ ThreadPlanSP Thread::QueueThreadPlanForS
}
lldb::ThreadPlanSP Thread::QueueThreadPlanForStepScripted(
- bool abort_other_plans, const char *class_name, bool stop_other_threads,
+ bool abort_other_plans, const char *class_name,
+ StructuredData::ObjectSP extra_args_sp, bool stop_other_threads,
Status &status) {
- ThreadPlanSP thread_plan_sp(new ThreadPlanPython(*this, class_name));
+
+ StructuredDataImpl *extra_args_impl = nullptr;
+ if (extra_args_sp) {
+ extra_args_impl = new StructuredDataImpl();
+ extra_args_impl->SetObjectSP(extra_args_sp);
+ }
+
+ ThreadPlanSP thread_plan_sp(new ThreadPlanPython(*this, class_name,
+ extra_args_impl));
status = QueueThreadPlan(thread_plan_sp, abort_other_plans);
return thread_plan_sp;
Modified: lldb/trunk/source/Target/ThreadPlanPython.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanPython.cpp?rev=373675&r1=373674&r2=373675&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanPython.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanPython.cpp Thu Oct 3 15:50:18 2019
@@ -25,10 +25,11 @@ using namespace lldb_private;
// ThreadPlanPython
-ThreadPlanPython::ThreadPlanPython(Thread &thread, const char *class_name)
+ThreadPlanPython::ThreadPlanPython(Thread &thread, const char *class_name,
+ StructuredDataImpl *args_data)
: ThreadPlan(ThreadPlan::eKindPython, "Python based Thread Plan", thread,
eVoteNoOpinion, eVoteNoOpinion),
- m_class_name(class_name), m_did_push(false) {
+ m_class_name(class_name), m_args_data(args_data), m_did_push(false) {
SetIsMasterPlan(true);
SetOkayToDiscard(true);
SetPrivate(false);
@@ -65,7 +66,8 @@ void ThreadPlanPython::DidPush() {
.GetScriptInterpreter();
if (script_interp) {
m_implementation_sp = script_interp->CreateScriptedThreadPlan(
- m_class_name.c_str(), m_error_str, this->shared_from_this());
+ m_class_name.c_str(), m_args_data, m_error_str,
+ this->shared_from_this());
}
}
}
Modified: lldb/trunk/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp?rev=373675&r1=373674&r2=373675&view=diff
==============================================================================
--- lldb/trunk/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp (original)
+++ lldb/trunk/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp Thu Oct 3 15:50:18 2019
@@ -95,6 +95,7 @@ LLDBSwigPythonCreateCommandObject(const
extern "C" void *LLDBSwigPythonCreateScriptedThreadPlan(
const char *python_class_name, const char *session_dictionary_name,
+ StructuredDataImpl *args_data,
std::string &error_string,
const lldb::ThreadPlanSP &thread_plan_sp) {
return nullptr;
More information about the lldb-commits
mailing list