[Lldb-commits] [lldb] [lldb] Consolidate Target Hook/StopHook scripted state into ScriptedMetadata (PR #199088)

via lldb-commits lldb-commits at lists.llvm.org
Thu May 21 12:49:16 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: Med Ismail Bennani (medismailben)

<details>
<summary>Changes</summary>

This is a follow-up to 1b4a578a9f77.

Replace `Target::HookScripted`'s and `Target::StopHookScripted`'s separate `m_class_name` and `m_extra_args` members with a single `m_scripted_metadata`, and update `SetScriptCallback to take a `const ScriptedMetadata &` directly. Drop the now-redundant `args_sp` parameter from ScriptedHookInterface::CreatePluginObject and ScriptedStopHookInterface::CreatePluginObject; the Python overrides construct a StructuredDataImpl from the metadata's args dict for the dispatched call.

Each hook subclass keeps its own `m_scripted_metadata` member because the interface's metadata is only set when SetScriptCallback runs the Python override of CreatePluginObject; the hook needs to hold the metadata between construction and that callback. Read-side description printing goes through the new GetScriptClassName() helper which delegates to m_interface_sp->GetScriptedMetadata(). The two s.Printf("%s\n", class_name.data()) sites are also converted to s.Format("{0}\n", class_name).

---
Full diff: https://github.com/llvm/llvm-project/pull/199088.diff


9 Files Affected:

- (modified) lldb/include/lldb/Interpreter/Interfaces/ScriptedHookInterface.h (+1-2) 
- (modified) lldb/include/lldb/Interpreter/Interfaces/ScriptedStopHookInterface.h (+1-2) 
- (modified) lldb/include/lldb/Target/Target.h (+7-10) 
- (modified) lldb/source/Commands/CommandObjectTarget.cpp (+6-4) 
- (modified) lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedHookPythonInterface.cpp (+2-2) 
- (modified) lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedHookPythonInterface.h (+1-2) 
- (modified) lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedStopHookPythonInterface.cpp (+2-2) 
- (modified) lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedStopHookPythonInterface.h (+1-2) 
- (modified) lldb/source/Target/Target.cpp (+46-45) 


``````````diff
diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedHookInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedHookInterface.h
index 6658d0693bc54..54d335122300d 100644
--- a/lldb/include/lldb/Interpreter/Interfaces/ScriptedHookInterface.h
+++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedHookInterface.h
@@ -29,8 +29,7 @@ class ScriptedHookInterface : public ScriptedInterface {
 
   virtual llvm::Expected<StructuredData::GenericSP>
   CreatePluginObject(const ScriptedMetadata &scripted_metadata,
-                     lldb::TargetSP target_sp,
-                     const StructuredDataImpl &args_sp) = 0;
+                     lldb::TargetSP target_sp) = 0;
 
   /// Check which hook callback methods the Python class implements.
   /// Called after CreatePluginObject to determine the trigger mask.
diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedStopHookInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedStopHookInterface.h
index f36cce54c9f68..c68498cba1632 100644
--- a/lldb/include/lldb/Interpreter/Interfaces/ScriptedStopHookInterface.h
+++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedStopHookInterface.h
@@ -18,8 +18,7 @@ class ScriptedStopHookInterface : public ScriptedInterface {
 public:
   virtual llvm::Expected<StructuredData::GenericSP>
   CreatePluginObject(const ScriptedMetadata &scripted_metadata,
-                     lldb::TargetSP target_sp,
-                     const StructuredDataImpl &args_sp) = 0;
+                     lldb::TargetSP target_sp) = 0;
 
   /// "handle_stop" will return a bool with the meaning "should_stop"...
   /// If nothing is returned, we'll assume we are going to stop.
diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index 7a88184849d6e..32b80cdcb86af 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -38,6 +38,7 @@
 #include "lldb/Utility/Broadcaster.h"
 #include "lldb/Utility/LLDBAssert.h"
 #include "lldb/Utility/RealpathPrefixes.h"
+#include "lldb/Utility/ScriptedMetadata.h"
 #include "lldb/Utility/Stream.h"
 #include "lldb/Utility/StructuredData.h"
 #include "lldb/Utility/Timeout.h"
@@ -1680,17 +1681,14 @@ class Target : public std::enable_shared_from_this<Target>,
     StopHookResult HandleStop(ExecutionContext &exc_ctx,
                               lldb::StreamSP output) override;
 
-    Status SetScriptCallback(std::string class_name,
-                             StructuredData::ObjectSP extra_args_sp);
+    Status SetScriptCallback(const ScriptedMetadata &scripted_metadata);
 
     void GetSubclassDescription(Stream &s,
                                 lldb::DescriptionLevel level) const override;
 
   private:
-    std::string m_class_name;
-    /// This holds the dictionary of keys & values that can be used to
-    /// parametrize any given callback's behavior.
-    StructuredDataImpl m_extra_args;
+    llvm::StringRef GetScriptClassName() const;
+
     lldb::ScriptedStopHookInterfaceSP m_interface_sp;
 
     /// Use CreateStopHook to make a new empty stop hook. Use SetScriptCallback
@@ -1897,12 +1895,11 @@ class Target : public std::enable_shared_from_this<Target>,
     StopHook::StopHookResult HandleStop(ExecutionContext &exe_ctx,
                                         lldb::StreamSP output) override;
 
-    Status SetScriptCallback(std::string class_name,
-                             StructuredData::ObjectSP extra_args_sp);
+    Status SetScriptCallback(const ScriptedMetadata &scripted_metadata);
 
   private:
-    std::string m_class_name;
-    StructuredDataImpl m_extra_args;
+    llvm::StringRef GetScriptClassName() const;
+
     lldb::ScriptedHookInterfaceSP m_interface_sp;
 
     HookScripted(lldb::TargetSP target_sp, lldb::user_id_t uid)
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index d2bf9ef752014..471e8473e84c6 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -5073,9 +5073,10 @@ Filter Options:
       // This is a scripted stop hook:
       Target::StopHookScripted *hook_ptr =
           static_cast<Target::StopHookScripted *>(new_hook_sp.get());
-      Status error = hook_ptr->SetScriptCallback(
+      ScriptedMetadata scripted_metadata(
           m_python_class_options.GetName(),
           m_python_class_options.GetStructuredData());
+      Status error = hook_ptr->SetScriptCallback(scripted_metadata);
       if (error.Success())
         result.AppendMessageWithFormatv("Stop hook #{0} added.",
                                         new_hook_sp->GetID());
@@ -5707,9 +5708,10 @@ Filter options:
                                       new_hook_sp->GetID());
     } else if (!m_python_class_options.GetName().empty()) {
       auto *hook = static_cast<Target::HookScripted *>(new_hook_sp.get());
-      Status callback_error =
-          hook->SetScriptCallback(m_python_class_options.GetName(),
-                                  m_python_class_options.GetStructuredData());
+      ScriptedMetadata scripted_metadata(
+          m_python_class_options.GetName(),
+          m_python_class_options.GetStructuredData());
+      Status callback_error = hook->SetScriptCallback(scripted_metadata);
       if (callback_error.Fail()) {
         result.AppendErrorWithFormat("couldn't add hook: %s",
                                      callback_error.AsCString());
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedHookPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedHookPythonInterface.cpp
index 0f767f4357371..09f5d91796bb4 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedHookPythonInterface.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedHookPythonInterface.cpp
@@ -54,8 +54,8 @@ ScriptedHookPythonInterface::GetSupportedMethods() {
 
 llvm::Expected<StructuredData::GenericSP>
 ScriptedHookPythonInterface::CreatePluginObject(
-    const ScriptedMetadata &scripted_metadata, lldb::TargetSP target_sp,
-    const StructuredDataImpl &args_sp) {
+    const ScriptedMetadata &scripted_metadata, lldb::TargetSP target_sp) {
+  StructuredDataImpl args_sp(scripted_metadata.GetArgsSP());
   return ScriptedPythonInterface::CreatePluginObject(scripted_metadata, nullptr,
                                                      target_sp, args_sp);
 }
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedHookPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedHookPythonInterface.h
index 9874c7de97873..ea76e18218490 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedHookPythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedHookPythonInterface.h
@@ -22,8 +22,7 @@ class ScriptedHookPythonInterface : public ScriptedHookInterface,
 
   llvm::Expected<StructuredData::GenericSP>
   CreatePluginObject(const ScriptedMetadata &scripted_metadata,
-                     lldb::TargetSP target_sp,
-                     const StructuredDataImpl &args_sp) override;
+                     lldb::TargetSP target_sp) override;
 
   /// A hook class must implement at least one callback. All three are
   /// individually optional; hooks that implement none will be rejected
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedStopHookPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedStopHookPythonInterface.cpp
index 243b0ac51e555..ca02e9070c4c2 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedStopHookPythonInterface.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedStopHookPythonInterface.cpp
@@ -28,8 +28,8 @@ ScriptedStopHookPythonInterface::ScriptedStopHookPythonInterface(
 
 llvm::Expected<StructuredData::GenericSP>
 ScriptedStopHookPythonInterface::CreatePluginObject(
-    const ScriptedMetadata &scripted_metadata, lldb::TargetSP target_sp,
-    const StructuredDataImpl &args_sp) {
+    const ScriptedMetadata &scripted_metadata, lldb::TargetSP target_sp) {
+  StructuredDataImpl args_sp(scripted_metadata.GetArgsSP());
   return ScriptedPythonInterface::CreatePluginObject(scripted_metadata, nullptr,
                                                      target_sp, args_sp);
 }
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedStopHookPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedStopHookPythonInterface.h
index fd4805f66f028..1e3a2280722cb 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedStopHookPythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedStopHookPythonInterface.h
@@ -22,8 +22,7 @@ class ScriptedStopHookPythonInterface : public ScriptedStopHookInterface,
 
   llvm::Expected<StructuredData::GenericSP>
   CreatePluginObject(const ScriptedMetadata &scripted_metadata,
-                     lldb::TargetSP target_sp,
-                     const StructuredDataImpl &args_sp) override;
+                     lldb::TargetSP target_sp) override;
 
   llvm::SmallVector<AbstractMethodRequirement>
   GetAbstractMethodRequirements() const override {
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 08127e2c8b79c..3076cbd1b3781 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -4281,7 +4281,7 @@ Target::StopHookCommandLine::HandleStop(ExecutionContext &exc_ctx,
 
 // Target::StopHookScripted
 Status Target::StopHookScripted::SetScriptCallback(
-    std::string class_name, StructuredData::ObjectSP extra_args_sp) {
+    const ScriptedMetadata &scripted_metadata) {
   Status error;
 
   ScriptInterpreter *script_interp =
@@ -4299,12 +4299,8 @@ Status Target::StopHookScripted::SetScriptCallback(
     return error;
   }
 
-  m_class_name = class_name;
-  m_extra_args.SetObjectSP(extra_args_sp);
-
-  ScriptedMetadata scripted_metadata(m_class_name, {});
-  auto obj_or_err = m_interface_sp->CreatePluginObject(
-      scripted_metadata, GetTarget(), m_extra_args);
+  auto obj_or_err =
+      m_interface_sp->CreatePluginObject(scripted_metadata, GetTarget());
   if (!obj_or_err) {
     return Status::FromError(obj_or_err.takeError());
   }
@@ -4343,25 +4339,29 @@ Target::StopHookScripted::HandleStop(ExecutionContext &exc_ctx,
                              : StopHookResult::RequestContinue;
 }
 
+llvm::StringRef Target::StopHookScripted::GetScriptClassName() const {
+  if (m_interface_sp && m_interface_sp->GetScriptedMetadata())
+    return m_interface_sp->GetScriptedMetadata()->GetClassName();
+  return "<unknown>";
+}
+
 void Target::StopHookScripted::GetSubclassDescription(
     Stream &s, lldb::DescriptionLevel level) const {
+  llvm::StringRef class_name = GetScriptClassName();
   if (level == eDescriptionLevelBrief) {
-    s.PutCString(m_class_name);
+    s.PutCString(class_name);
     return;
   }
   s.Indent("Class:");
-  s.Printf("%s\n", m_class_name.c_str());
+  s.Format("{0}\n", class_name);
 
   // Now print the extra args:
-  // FIXME: We should use StructuredData.GetDescription on the m_extra_args
+  // FIXME: We should use StructuredData.GetDescription on the args dict
   // but that seems to rely on some printing plugin that doesn't exist.
-  if (!m_extra_args.IsValid())
-    return;
-  StructuredData::ObjectSP object_sp = m_extra_args.GetObjectSP();
-  if (!object_sp || !object_sp->IsValid())
-    return;
-
-  StructuredData::Dictionary *as_dict = object_sp->GetAsDictionary();
+  StructuredData::DictionarySP as_dict =
+      (m_interface_sp && m_interface_sp->GetScriptedMetadata())
+          ? m_interface_sp->GetScriptedMetadata()->GetArgsSP()
+          : nullptr;
   if (!as_dict || !as_dict->IsValid())
     return;
 
@@ -4595,7 +4595,7 @@ Target::HookCommandLine::HandleStop(ExecutionContext &exc_ctx,
 // HookScripted
 
 Status Target::HookScripted::SetScriptCallback(
-    std::string class_name, StructuredData::ObjectSP extra_args_sp) {
+    const ScriptedMetadata &scripted_metadata) {
   ScriptInterpreter *script_interp =
       GetTarget()->GetDebugger().GetScriptInterpreter();
   if (!script_interp)
@@ -4607,12 +4607,8 @@ Status Target::HookScripted::SetScriptCallback(
         "ScriptedHook::%s () - ERROR: %s", __FUNCTION__,
         "Script interpreter couldn't create Scripted Hook Interface");
 
-  m_class_name = std::move(class_name);
-  m_extra_args.SetObjectSP(extra_args_sp);
-
-  ScriptedMetadata scripted_metadata(m_class_name, {});
-  auto obj_or_err = m_interface_sp->CreatePluginObject(
-      scripted_metadata, GetTarget(), m_extra_args);
+  auto obj_or_err =
+      m_interface_sp->CreatePluginObject(scripted_metadata, GetTarget());
   if (!obj_or_err)
     return Status::FromError(obj_or_err.takeError());
 
@@ -4677,11 +4673,18 @@ Target::HookScripted::HandleStop(ExecutionContext &exc_ctx,
                              : StopHook::StopHookResult::RequestContinue;
 }
 
+llvm::StringRef Target::HookScripted::GetScriptClassName() const {
+  if (m_interface_sp && m_interface_sp->GetScriptedMetadata())
+    return m_interface_sp->GetScriptedMetadata()->GetClassName();
+  return "<unknown>";
+}
+
 void Target::HookScripted::GetDescription(Stream &s,
                                           lldb::DescriptionLevel level) const {
   Hook::GetDescription(s, level);
+  llvm::StringRef class_name = GetScriptClassName();
   if (level == eDescriptionLevelBrief) {
-    s.PutCString(m_class_name);
+    s.PutCString(class_name);
     return;
   }
 
@@ -4689,27 +4692,25 @@ void Target::HookScripted::GetDescription(Stream &s,
   // filters.
   s.IndentMore();
   s.Indent("Class: ");
-  s.Printf("%s\n", m_class_name.c_str());
-
-  if (m_extra_args.IsValid()) {
-    StructuredData::ObjectSP object_sp = m_extra_args.GetObjectSP();
-    if (object_sp && object_sp->IsValid()) {
-      StructuredData::Dictionary *as_dict = object_sp->GetAsDictionary();
-      if (as_dict && as_dict->IsValid() && as_dict->GetSize() > 0) {
-        s.Indent("Args:\n");
-        s.IndentMore();
-
-        auto print_one_element = [&s](llvm::StringRef key,
-                                      StructuredData::Object *object) {
-          s.Indent();
-          s.Format("{0} : {1}\n", key, object->GetStringValue());
-          return true;
-        };
+  s.Format("{0}\n", class_name);
+
+  StructuredData::DictionarySP as_dict =
+      (m_interface_sp && m_interface_sp->GetScriptedMetadata())
+          ? m_interface_sp->GetScriptedMetadata()->GetArgsSP()
+          : nullptr;
+  if (as_dict && as_dict->IsValid() && as_dict->GetSize() > 0) {
+    s.Indent("Args:\n");
+    s.IndentMore();
 
-        as_dict->ForEach(print_one_element);
-        s.IndentLess();
-      }
-    }
+    auto print_one_element = [&s](llvm::StringRef key,
+                                  StructuredData::Object *object) {
+      s.Indent();
+      s.Format("{0} : {1}\n", key, object->GetStringValue());
+      return true;
+    };
+
+    as_dict->ForEach(print_one_element);
+    s.IndentLess();
   }
   s.IndentLess();
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/199088


More information about the lldb-commits mailing list