[Lldb-commits] [lldb] [lldb] Consolidate ScriptedThreadPlan state into ScriptedMetadata (PR #199064)
Med Ismail Bennani via lldb-commits
lldb-commits at lists.llvm.org
Thu May 21 09:13:14 PDT 2026
https://github.com/medismailben updated https://github.com/llvm/llvm-project/pull/199064
>From f405a2b3e8b6f2e2a4c758cb81fd0579a9b6f9d2 Mon Sep 17 00:00:00 2001
From: Med Ismail Bennani <ismail at bennani.ma>
Date: Thu, 21 May 2026 09:11:17 -0700
Subject: [PATCH] [lldb] Consolidate ScriptedThreadPlan state into
ScriptedMetadata
This is a follow-up to 1b4a578a9f77.
Replace ScriptedThreadPlan's separate `m_class_name` and `m_args_data`
members with a single `m_scripted_metadata`, and update its constructor,
Thread::QueueThreadPlanForStepScripted and the SB/CLI callers to take a
`const ScriptedMetadata &` directly. Drop the now-redundant `args_sp`
parameter from ScriptedThreadPlanInterface::CreatePluginObject; the
Python override constructs a StructuredDataImpl from the metadata's
args dict for the dispatched call.
ScriptedThreadPlan keeps its own `m_scripted_metadata` member because
the interface's metadata is only set when `DidPush()` calls
`CreatePluginObject`, so the plan needs to hold the metadata between
construction and `DidPush()`.
Signed-off-by: Med Ismail Bennani <ismail at bennani.ma>
---
.../Interfaces/ScriptedThreadPlanInterface.h | 3 +-
lldb/include/lldb/Target/ScriptedThreadPlan.h | 9 ++--
lldb/include/lldb/Target/Thread.h | 5 +-
lldb/source/API/SBThread.cpp | 7 ++-
lldb/source/API/SBThreadPlan.cpp | 34 ++++++++++----
lldb/source/Commands/CommandObjectThread.cpp | 5 +-
.../ScriptedThreadPlanPythonInterface.cpp | 3 +-
.../ScriptedThreadPlanPythonInterface.h | 3 +-
lldb/source/Target/ScriptedThreadPlan.cpp | 47 ++++++++++---------
lldb/source/Target/Thread.cpp | 9 ++--
10 files changed, 76 insertions(+), 49 deletions(-)
diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadPlanInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadPlanInterface.h
index c81166c9c6c35..6c9acc1d8691f 100644
--- a/lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadPlanInterface.h
+++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadPlanInterface.h
@@ -18,8 +18,7 @@ class ScriptedThreadPlanInterface : public ScriptedInterface {
public:
virtual llvm::Expected<StructuredData::GenericSP>
CreatePluginObject(const ScriptedMetadata &scripted_metadata,
- lldb::ThreadPlanSP thread_plan_sp,
- const StructuredDataImpl &args_sp) = 0;
+ lldb::ThreadPlanSP thread_plan_sp) = 0;
virtual llvm::Expected<bool> ExplainsStop(Event *event) { return true; }
diff --git a/lldb/include/lldb/Target/ScriptedThreadPlan.h b/lldb/include/lldb/Target/ScriptedThreadPlan.h
index 7532b6b0a41c5..99f0c3f7d41ba 100644
--- a/lldb/include/lldb/Target/ScriptedThreadPlan.h
+++ b/lldb/include/lldb/Target/ScriptedThreadPlan.h
@@ -19,6 +19,7 @@
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
#include "lldb/Target/ThreadPlanTracer.h"
+#include "lldb/Utility/ScriptedMetadata.h"
#include "lldb/Utility/StructuredData.h"
#include "lldb/Utility/UserID.h"
#include "lldb/lldb-forward.h"
@@ -28,8 +29,7 @@ namespace lldb_private {
class ScriptedThreadPlan : public ThreadPlan {
public:
- ScriptedThreadPlan(Thread &thread, const char *class_name,
- const StructuredDataImpl &args_data);
+ ScriptedThreadPlan(Thread &thread, const ScriptedMetadata &scripted_metadata);
void GetDescription(Stream *s, lldb::DescriptionLevel level) override;
@@ -58,9 +58,10 @@ class ScriptedThreadPlan : public ThreadPlan {
ScriptInterpreter *GetScriptInterpreter();
+ llvm::StringRef GetScriptClassName() const;
+
private:
- std::string m_class_name;
- StructuredDataImpl m_args_data;
+ ScriptedMetadata m_scripted_metadata;
std::string m_error_str;
StructuredData::ObjectSP m_implementation_sp;
StreamString m_stop_description; // Cache the stop description here
diff --git a/lldb/include/lldb/Target/Thread.h b/lldb/include/lldb/Target/Thread.h
index 58bd6960a803d..8664c2148b463 100644
--- a/lldb/include/lldb/Target/Thread.h
+++ b/lldb/include/lldb/Target/Thread.h
@@ -24,6 +24,7 @@
#include "lldb/Utility/Broadcaster.h"
#include "lldb/Utility/CompletionRequest.h"
#include "lldb/Utility/Event.h"
+#include "lldb/Utility/ScriptedMetadata.h"
#include "lldb/Utility/StructuredData.h"
#include "lldb/Utility/UnimplementedError.h"
#include "lldb/Utility/UserID.h"
@@ -1009,8 +1010,8 @@ class Thread : public std::enable_shared_from_this<Thread>,
bool stop_others, uint32_t frame_idx, Status &status);
virtual lldb::ThreadPlanSP
- QueueThreadPlanForStepScripted(bool abort_other_plans, const char *class_name,
- StructuredData::ObjectSP extra_args_sp,
+ QueueThreadPlanForStepScripted(bool abort_other_plans,
+ const ScriptedMetadata &scripted_metadata,
bool stop_other_threads, Status &status);
// Thread Plan accessors:
diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp
index 8f672ae539780..fafb533771e56 100644
--- a/lldb/source/API/SBThread.cpp
+++ b/lldb/source/API/SBThread.cpp
@@ -897,8 +897,13 @@ SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
Status new_plan_status;
StructuredData::ObjectSP obj_sp = args_data.m_impl_up->GetObjectSP();
+ StructuredData::DictionarySP args_dict_sp;
+ if (obj_sp && obj_sp->GetType() == lldb::eStructuredDataTypeDictionary)
+ args_dict_sp = std::static_pointer_cast<StructuredData::Dictionary>(obj_sp);
+
+ ScriptedMetadata scripted_metadata(script_class_name, args_dict_sp);
ThreadPlanSP new_plan_sp = thread->QueueThreadPlanForStepScripted(
- false, script_class_name, obj_sp, false, new_plan_status);
+ false, scripted_metadata, false, new_plan_status);
if (new_plan_status.Fail()) {
error = Status::FromErrorString(new_plan_status.AsCString());
diff --git a/lldb/source/API/SBThreadPlan.cpp b/lldb/source/API/SBThreadPlan.cpp
index c8ca6c81a3efb..88cf87c9dbe60 100644
--- a/lldb/source/API/SBThreadPlan.cpp
+++ b/lldb/source/API/SBThreadPlan.cpp
@@ -65,9 +65,11 @@ SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name) {
LLDB_INSTRUMENT_VA(this, sb_thread, class_name);
Thread *thread = sb_thread.get();
- if (thread)
- m_opaque_wp = std::make_shared<ScriptedThreadPlan>(*thread, class_name,
- StructuredDataImpl());
+ if (thread) {
+ ScriptedMetadata scripted_metadata(class_name, {});
+ m_opaque_wp =
+ std::make_shared<ScriptedThreadPlan>(*thread, scripted_metadata);
+ }
}
SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name,
@@ -75,9 +77,17 @@ SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name,
LLDB_INSTRUMENT_VA(this, sb_thread, class_name, args_data);
Thread *thread = sb_thread.get();
- if (thread)
- m_opaque_wp = std::make_shared<ScriptedThreadPlan>(*thread, class_name,
- *args_data.m_impl_up);
+ if (thread) {
+ StructuredData::ObjectSP args_obj = args_data.m_impl_up->GetObjectSP();
+ StructuredData::DictionarySP args_dict_sp;
+ if (args_obj &&
+ args_obj->GetType() == lldb::eStructuredDataTypeDictionary)
+ args_dict_sp =
+ std::static_pointer_cast<StructuredData::Dictionary>(args_obj);
+ ScriptedMetadata scripted_metadata(class_name, args_dict_sp);
+ m_opaque_wp =
+ std::make_shared<ScriptedThreadPlan>(*thread, scripted_metadata);
+ }
}
// Assignment operator
@@ -397,10 +407,10 @@ SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name,
ThreadPlanSP thread_plan_sp(GetSP());
if (thread_plan_sp) {
Status plan_status;
- StructuredData::ObjectSP empty_args;
+ ScriptedMetadata scripted_metadata(script_class_name, {});
SBThreadPlan plan =
SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForStepScripted(
- false, script_class_name, empty_args, false, plan_status));
+ false, scripted_metadata, false, plan_status));
if (plan_status.Fail())
error.SetErrorString(plan_status.AsCString());
@@ -422,9 +432,15 @@ SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name,
if (thread_plan_sp) {
Status plan_status;
StructuredData::ObjectSP args_obj = args_data.m_impl_up->GetObjectSP();
+ StructuredData::DictionarySP args_dict_sp;
+ if (args_obj &&
+ args_obj->GetType() == lldb::eStructuredDataTypeDictionary)
+ args_dict_sp =
+ std::static_pointer_cast<StructuredData::Dictionary>(args_obj);
+ ScriptedMetadata scripted_metadata(script_class_name, args_dict_sp);
SBThreadPlan plan =
SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForStepScripted(
- false, script_class_name, args_obj, false, plan_status));
+ false, scripted_metadata, false, plan_status));
if (plan_status.Fail())
error.SetErrorString(plan_status.AsCString());
diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp
index 229e29fcb26c4..1cf9cefd87193 100644
--- a/lldb/source/Commands/CommandObjectThread.cpp
+++ b/lldb/source/Commands/CommandObjectThread.cpp
@@ -745,9 +745,10 @@ class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed {
thread->GetSelectedFrameIndex(DoNoSelectMostRelevantFrame),
new_plan_status, m_options.m_step_out_avoid_no_debug);
} else if (m_step_type == eStepTypeScripted) {
+ ScriptedMetadata scripted_metadata(m_class_options.GetName(),
+ m_class_options.GetStructuredData());
new_plan_sp = thread->QueueThreadPlanForStepScripted(
- abort_other_plans, m_class_options.GetName().c_str(),
- m_class_options.GetStructuredData(), bool_stop_other_threads,
+ abort_other_plans, scripted_metadata, bool_stop_other_threads,
new_plan_status);
} else {
result.AppendError("step type is not supported");
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPlanPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPlanPythonInterface.cpp
index cce342c4b3eb8..007765daef818 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPlanPythonInterface.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPlanPythonInterface.cpp
@@ -28,7 +28,8 @@ ScriptedThreadPlanPythonInterface::ScriptedThreadPlanPythonInterface(
llvm::Expected<StructuredData::GenericSP>
ScriptedThreadPlanPythonInterface::CreatePluginObject(
const ScriptedMetadata &scripted_metadata,
- lldb::ThreadPlanSP thread_plan_sp, const StructuredDataImpl &args_sp) {
+ lldb::ThreadPlanSP thread_plan_sp) {
+ StructuredDataImpl args_sp(scripted_metadata.GetArgsSP());
return ScriptedPythonInterface::CreatePluginObject(scripted_metadata, nullptr,
thread_plan_sp, args_sp);
}
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPlanPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPlanPythonInterface.h
index 7efd894d9d53a..efb3225b36df7 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPlanPythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPlanPythonInterface.h
@@ -24,8 +24,7 @@ class ScriptedThreadPlanPythonInterface : public ScriptedThreadPlanInterface,
llvm::Expected<StructuredData::GenericSP>
CreatePluginObject(const ScriptedMetadata &scripted_metadata,
- lldb::ThreadPlanSP thread_plan_sp,
- const StructuredDataImpl &args_sp) override;
+ lldb::ThreadPlanSP thread_plan_sp) override;
llvm::SmallVector<AbstractMethodRequirement>
GetAbstractMethodRequirements() const override {
diff --git a/lldb/source/Target/ScriptedThreadPlan.cpp b/lldb/source/Target/ScriptedThreadPlan.cpp
index 757417ac649c7..e218299f0909d 100644
--- a/lldb/source/Target/ScriptedThreadPlan.cpp
+++ b/lldb/source/Target/ScriptedThreadPlan.cpp
@@ -24,11 +24,11 @@
using namespace lldb;
using namespace lldb_private;
-ScriptedThreadPlan::ScriptedThreadPlan(Thread &thread, const char *class_name,
- const StructuredDataImpl &args_data)
+ScriptedThreadPlan::ScriptedThreadPlan(
+ Thread &thread, const ScriptedMetadata &scripted_metadata)
: ThreadPlan(ThreadPlan::eKindPython, "Script based Thread Plan", thread,
eVoteNoOpinion, eVoteNoOpinion),
- m_class_name(class_name), m_args_data(args_data), m_did_push(false),
+ m_scripted_metadata(scripted_metadata), m_did_push(false),
m_stop_others(false) {
ScriptInterpreter *interpreter = GetScriptInterpreter();
if (!interpreter) {
@@ -74,14 +74,19 @@ ScriptInterpreter *ScriptedThreadPlan::GetScriptInterpreter() {
return m_process.GetTarget().GetDebugger().GetScriptInterpreter();
}
+llvm::StringRef ScriptedThreadPlan::GetScriptClassName() const {
+ if (m_interface && m_interface->GetScriptedMetadata())
+ return m_interface->GetScriptedMetadata()->GetClassName();
+ return "<unknown>";
+}
+
void ScriptedThreadPlan::DidPush() {
// We set up the script side in DidPush, so that it can push other plans in
// the constructor, and doesn't have to care about the details of DidPush.
m_did_push = true;
if (m_interface) {
- ScriptedMetadata scripted_metadata(m_class_name, {});
auto obj_or_err = m_interface->CreatePluginObject(
- scripted_metadata, this->shared_from_this(), m_args_data);
+ m_scripted_metadata, this->shared_from_this());
if (!obj_or_err) {
m_error_str = llvm::toString(obj_or_err.takeError());
SetPlanComplete(false);
@@ -92,8 +97,8 @@ void ScriptedThreadPlan::DidPush() {
bool ScriptedThreadPlan::ShouldStop(Event *event_ptr) {
Log *log = GetLog(LLDBLog::Thread);
- LLDB_LOGF(log, "%s called on Scripted Thread Plan: %s )",
- LLVM_PRETTY_FUNCTION, m_class_name.c_str());
+ LLDB_LOG(log, "{0} called on Scripted Thread Plan: {1} )",
+ LLVM_PRETTY_FUNCTION, GetScriptClassName());
bool should_stop = true;
if (m_implementation_sp) {
@@ -110,8 +115,8 @@ bool ScriptedThreadPlan::ShouldStop(Event *event_ptr) {
bool ScriptedThreadPlan::IsPlanStale() {
Log *log = GetLog(LLDBLog::Thread);
- LLDB_LOGF(log, "%s called on Scripted Thread Plan: %s )",
- LLVM_PRETTY_FUNCTION, m_class_name.c_str());
+ LLDB_LOG(log, "{0} called on Scripted Thread Plan: {1} )",
+ LLVM_PRETTY_FUNCTION, GetScriptClassName());
bool is_stale = true;
if (m_implementation_sp) {
@@ -128,8 +133,8 @@ bool ScriptedThreadPlan::IsPlanStale() {
bool ScriptedThreadPlan::DoPlanExplainsStop(Event *event_ptr) {
Log *log = GetLog(LLDBLog::Thread);
- LLDB_LOGF(log, "%s called on Scripted Thread Plan: %s )",
- LLVM_PRETTY_FUNCTION, m_class_name.c_str());
+ LLDB_LOG(log, "{0} called on Scripted Thread Plan: {1} )",
+ LLVM_PRETTY_FUNCTION, GetScriptClassName());
bool explains_stop = true;
if (m_implementation_sp) {
@@ -147,8 +152,8 @@ bool ScriptedThreadPlan::DoPlanExplainsStop(Event *event_ptr) {
bool ScriptedThreadPlan::MischiefManaged() {
Log *log = GetLog(LLDBLog::Thread);
- LLDB_LOGF(log, "%s called on Scripted Thread Plan: %s )",
- LLVM_PRETTY_FUNCTION, m_class_name.c_str());
+ LLDB_LOG(log, "{0} called on Scripted Thread Plan: {1} )",
+ LLVM_PRETTY_FUNCTION, GetScriptClassName());
bool mischief_managed = true;
if (m_implementation_sp) {
// I don't really need mischief_managed, since it's simpler to just call
@@ -165,8 +170,8 @@ bool ScriptedThreadPlan::MischiefManaged() {
lldb::StateType ScriptedThreadPlan::GetPlanRunState() {
Log *log = GetLog(LLDBLog::Thread);
- LLDB_LOGF(log, "%s called on Scripted Thread Plan: %s )",
- LLVM_PRETTY_FUNCTION, m_class_name.c_str());
+ LLDB_LOG(log, "{0} called on Scripted Thread Plan: {1} )",
+ LLVM_PRETTY_FUNCTION, GetScriptClassName());
lldb::StateType run_state = eStateRunning;
if (m_implementation_sp)
run_state = m_interface->GetRunState();
@@ -176,8 +181,8 @@ lldb::StateType ScriptedThreadPlan::GetPlanRunState() {
void ScriptedThreadPlan::GetDescription(Stream *s,
lldb::DescriptionLevel level) {
Log *log = GetLog(LLDBLog::Thread);
- LLDB_LOGF(log, "%s called on Scripted Thread Plan: %s )",
- LLVM_PRETTY_FUNCTION, m_class_name.c_str());
+ LLDB_LOG(log, "{0} called on Scripted Thread Plan: {1} )",
+ LLVM_PRETTY_FUNCTION, GetScriptClassName());
if (m_implementation_sp) {
ScriptInterpreter *script_interp = GetScriptInterpreter();
if (script_interp) {
@@ -188,7 +193,7 @@ void ScriptedThreadPlan::GetDescription(Stream *s,
GetLog(LLDBLog::Thread), std::move(err),
"Can't call ScriptedThreadPlan::GetStopDescription: {0}");
s->Printf("Scripted thread plan implemented by class %s.",
- m_class_name.c_str());
+ GetScriptClassName().data());
} else
s->PutCString(
reinterpret_cast<StreamString *>(stream.get())->GetData());
@@ -199,15 +204,15 @@ void ScriptedThreadPlan::GetDescription(Stream *s,
// add something.
if (m_stop_description.Empty())
s->Printf("Scripted thread plan implemented by class %s.",
- m_class_name.c_str());
+ GetScriptClassName().data());
s->PutCString(m_stop_description.GetData());
}
// The ones below are not currently exported to Python.
bool ScriptedThreadPlan::WillStop() {
Log *log = GetLog(LLDBLog::Thread);
- LLDB_LOGF(log, "%s called on Scripted Thread Plan: %s )",
- LLVM_PRETTY_FUNCTION, m_class_name.c_str());
+ LLDB_LOG(log, "{0} called on Scripted Thread Plan: {1} )",
+ LLVM_PRETTY_FUNCTION, GetScriptClassName());
return true;
}
diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp
index 9199721be9627..feaa5ba387324 100644
--- a/lldb/source/Target/Thread.cpp
+++ b/lldb/source/Target/Thread.cpp
@@ -1435,12 +1435,11 @@ ThreadPlanSP Thread::QueueThreadPlanForStepUntil(
}
lldb::ThreadPlanSP Thread::QueueThreadPlanForStepScripted(
- bool abort_other_plans, const char *class_name,
- StructuredData::ObjectSP extra_args_sp, bool stop_other_threads,
- Status &status) {
+ bool abort_other_plans, const ScriptedMetadata &scripted_metadata,
+ bool stop_other_threads, Status &status) {
- ThreadPlanSP thread_plan_sp(new ScriptedThreadPlan(
- *this, class_name, StructuredDataImpl(extra_args_sp)));
+ ThreadPlanSP thread_plan_sp(
+ new ScriptedThreadPlan(*this, scripted_metadata));
thread_plan_sp->SetStopOthers(stop_other_threads);
status = QueueThreadPlan(thread_plan_sp, abort_other_plans);
return thread_plan_sp;
More information about the lldb-commits
mailing list