[Lldb-commits] [lldb] f775fe5 - Revert "Add the ability to write target stop-hooks using the ScriptInterpreter."

Jonas Devlieghere via lldb-commits lldb-commits at lists.llvm.org
Mon Sep 28 09:05:12 PDT 2020


Author: Jonas Devlieghere
Date: 2020-09-28T09:04:32-07:00
New Revision: f775fe59640a2e837ad059a8f40e26989d4f9831

URL: https://github.com/llvm/llvm-project/commit/f775fe59640a2e837ad059a8f40e26989d4f9831
DIFF: https://github.com/llvm/llvm-project/commit/f775fe59640a2e837ad059a8f40e26989d4f9831.diff

LOG: Revert "Add the ability to write target stop-hooks using the ScriptInterpreter."

This temporarily reverts commit b65966cff65bfb66de59621347ffd97238d3f645
while Jim figures out why the test is failing on the bots.

Added: 
    

Modified: 
    lldb/bindings/python/python-swigsafecast.swig
    lldb/bindings/python/python-wrapper.swig
    lldb/docs/use/python-reference.rst
    lldb/include/lldb/Interpreter/ScriptInterpreter.h
    lldb/include/lldb/Symbol/SymbolContext.h
    lldb/include/lldb/Target/Target.h
    lldb/source/Commands/CommandObjectTarget.cpp
    lldb/source/Commands/Options.td
    lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
    lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
    lldb/source/Symbol/SymbolContext.cpp
    lldb/source/Target/Target.cpp
    lldb/test/API/commands/target/stop-hooks/TestStopHooks.py
    lldb/test/API/commands/target/stop-hooks/main.c
    lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp

Removed: 
    lldb/test/API/commands/target/stop-hooks/TestStopHookScripted.py
    lldb/test/API/commands/target/stop-hooks/stop_hook.py
    lldb/test/Shell/Commands/Inputs/stop_hook.py
    lldb/test/Shell/Commands/command-stop-hook-output.test


################################################################################
diff  --git a/lldb/bindings/python/python-swigsafecast.swig b/lldb/bindings/python/python-swigsafecast.swig
index 091fc29b1057..d5cafbfa67cb 100644
--- a/lldb/bindings/python/python-swigsafecast.swig
+++ b/lldb/bindings/python/python-swigsafecast.swig
@@ -152,10 +152,3 @@ SBTypeToSWIGWrapper (lldb::SBSymbolContext* sym_ctx_sb)
 {
     return SWIG_NewPointerObj((void *) sym_ctx_sb, SWIGTYPE_p_lldb__SBSymbolContext, 0);
 }
-
-template <>
-PyObject*
-SBTypeToSWIGWrapper (lldb::SBStream* stream_sb)
-{
-    return SWIG_NewPointerObj((void *) stream_sb, SWIGTYPE_p_lldb__SBStream, 0);
-}

diff  --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig
index cd326046b421..516590ed5771 100644
--- a/lldb/bindings/python/python-wrapper.swig
+++ b/lldb/bindings/python/python-wrapper.swig
@@ -468,124 +468,6 @@ LLDBSwigPythonCallBreakpointResolver
     return ret_val;
 }
 
-SWIGEXPORT void *
-LLDBSwigPythonCreateScriptedStopHook
-(
-    lldb::TargetSP target_sp,
-    const char *python_class_name,
-    const char *session_dictionary_name,
-    lldb_private::StructuredDataImpl *args_impl,
-    Status &error
-)
-{
-    if (python_class_name == NULL || python_class_name[0] == '\0') {
-        error.SetErrorString("Empty class name.");
-        Py_RETURN_NONE;
-    }
-    if (!session_dictionary_name) {
-      error.SetErrorString("No session dictionary");
-      Py_RETURN_NONE;
-    }
-    
-    PyErr_Cleaner py_err_cleaner(true);
-
-    auto dict = 
-        PythonModule::MainModule().ResolveName<PythonDictionary>(
-            session_dictionary_name);
-    auto pfunc = 
-        PythonObject::ResolveNameWithDictionary<PythonCallable>(
-            python_class_name, dict);
-
-    if (!pfunc.IsAllocated()) {
-        error.SetErrorStringWithFormat("Could not find class: %s.", 
-                                       python_class_name);
-        return nullptr;
-    }
-
-    lldb::SBTarget *target_val 
-        = new lldb::SBTarget(target_sp);
-
-    PythonObject target_arg(PyRefType::Owned, SBTypeToSWIGWrapper(target_val));
-
-    lldb::SBStructuredData *args_value = new lldb::SBStructuredData(args_impl);
-    PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(args_value));
-
-    PythonObject result = pfunc(target_arg, args_arg, dict);
-
-    if (result.IsAllocated())
-    {
-        // Check that the handle_stop callback is defined:
-        auto callback_func = result.ResolveName<PythonCallable>("handle_stop");
-        if (callback_func.IsAllocated()) {
-          if (auto args_info = callback_func.GetArgInfo()) {
-            if ((*args_info).max_positional_args < 2) {
-              error.SetErrorStringWithFormat("Wrong number of args for "
-              "handle_stop callback, should be 2 (excluding self), got: %d", 
-              (*args_info).max_positional_args);
-            } else
-              return result.release();
-          } else {
-            error.SetErrorString("Couldn't get num arguments for handle_stop "
-                                 "callback.");
-          }
-          return result.release();
-        }
-        else {
-          error.SetErrorStringWithFormat("Class \"%s\" is missing the required "
-                                         "handle_stop callback.",
-                                         python_class_name);
-          result.release();
-        }
-    }
-    Py_RETURN_NONE;
-}
-
-SWIGEXPORT bool
-LLDBSwigPythonStopHookCallHandleStop
-(
-    void *implementor,
-    lldb::ExecutionContextRefSP exc_ctx_sp,
-    lldb::StreamSP stream
-)
-{
-    // handle_stop will return a bool with the meaning "should_stop"...
-    // If you return nothing we'll assume we are going to stop.
-    // Also any errors should return true, since we should stop on error.
-
-    PyErr_Cleaner py_err_cleaner(false);
-    PythonObject self(PyRefType::Borrowed, static_cast<PyObject*>(implementor));
-    auto pfunc = self.ResolveName<PythonCallable>("handle_stop");
-
-    if (!pfunc.IsAllocated())
-        return true;
-
-    PythonObject result;
-    lldb::SBExecutionContext sb_exc_ctx(exc_ctx_sp);
-    PythonObject exc_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_exc_ctx));
-    lldb::SBStream sb_stream;
-    PythonObject sb_stream_arg(PyRefType::Owned, 
-                               SBTypeToSWIGWrapper(sb_stream));
-    result = pfunc(exc_ctx_arg, sb_stream_arg);
-
-    if (PyErr_Occurred())
-    {
-        stream->PutCString("Python error occurred handling stop-hook.");
-        PyErr_Print();
-        PyErr_Clear();
-        return true;
-    }
-    
-    // Now add the result to the output stream.  SBStream only
-    // makes an internally help StreamString which I can't interpose, so I 
-    // have to copy it over here.
-    stream->PutCString(sb_stream.GetData());
-    
-    if (result.get() == Py_False)
-      return false;
-    else
-      return true;
-}
-
 // wrapper that calls an optional instance member of an object taking no arguments
 static PyObject*
 LLDBSwigPython_CallOptionalMember

diff  --git a/lldb/docs/use/python-reference.rst b/lldb/docs/use/python-reference.rst
index 60474c94f185..8c76ef1a0830 100644
--- a/lldb/docs/use/python-reference.rst
+++ b/lldb/docs/use/python-reference.rst
@@ -819,49 +819,3 @@ When the program is stopped at the beginning of the 'read' function in libc, we
       frame #0: 0x00007fff06013ca0 libsystem_kernel.dylib`read
   (lldb) frame variable
   (int) fd = 3
-
- Writing Target Stop-Hooks in Python:
- ------------------------------------
-
- Stop hooks fire whenever the process stops just before control is returned to the
- user.  Stop hooks can either be a set of lldb command-line commands, or can
- be implemented by a suitably defined Python class.  The Python based stop-hooks
- can also be passed as set of -key -value pairs when they are added, and those
- will get packaged up into a SBStructuredData Dictionary and passed to the
- constructor of the Python object managing the stop hook.  This allows for
- parametrization of the stop hooks.
-
- To add a Python-based stop hook, first define a class with the following methods:
-
-+--------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------+
-| Name               | Arguments                             | Description                                                                                                      |
-+--------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------+
-| **__init__**       | **target: lldb.SBTarget**             | This is the constructor for the new stop-hook.                                                                   |
-|                    | **extra_args: lldb.SBStructuredData** |                                                                                                                  |
-|                    |                                       |                                                                                                                  |
-|                    |                                       | **target** is the SBTarget to which the stop hook is added.                                                      |
-|                    |                                       |                                                                                                                  |
-|                    |                                       | **extra_args** is an SBStructuredData object that the user can pass in when creating instances of this           |
-|                    |                                       | breakpoint.  It is not required, but allows for reuse of stop-hook classes.                                      |
-+--------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------+
-| **handle_stop**    | **exe_ctx: lldb.SBExecutionContext**  | This is the called when the target stops.                                                                        |
-|                    | **stream: lldb.SBStream**             |                                                                                                                  |
-|                    |                                       | **exe_ctx** argument will be filled with the current stop point for which the stop hook is                       |
-|                    |                                       | being evaluated.                                                                                                 |
-|                    |                                       |                                                                                                                  |
-|                    |                                       | **stream** an lldb.SBStream, anything written to this stream will be written to the debugger console.            |
-|                    |                                       |                                                                                                                  |
-|                    |                                       | The return value is a "Should Stop" vote from this thread.  If the method returns either True or no return       |
-|                    |                                       | this thread votes to stop.  If it returns False, then the thread votes to continue after all the stop-hooks      |
-|                    |                                       | are evaluated.                                                                                                   |
-|                    |                                       | Note, the --auto-continue flag to 'target stop-hook add' overrides a True return value from the method.          |
-+--------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------+
-
-To use this class in lldb, run the command:
-
-::
-
-   (lldb) command script import MyModule.py
-   (lldb) target stop-hook add -P MyModule.MyStopHook -k first -v 1 -k second -v 2
-
-where MyModule.py is the file containing the class definition MyStopHook.

diff  --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h
index c38786fd50d4..491923e6a6c4 100644
--- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h
+++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h
@@ -298,23 +298,6 @@ class ScriptInterpreter : public PluginInterface {
     return lldb::eSearchDepthModule;
   }
 
-  virtual StructuredData::GenericSP
-  CreateScriptedStopHook(lldb::TargetSP target_sp, const char *class_name,
-                         StructuredDataImpl *args_data, Status &error) {
-    error.SetErrorString("Creating scripted stop-hooks with the current "
-                         "script interpreter is not supported.");
-    return StructuredData::GenericSP();
-  }
-
-  // This dispatches to the handle_stop method of the stop-hook class.  It
-  // returns a "should_stop" bool.
-  virtual bool
-  ScriptedStopHookHandleStop(StructuredData::GenericSP implementor_sp,
-                             ExecutionContext &exc_ctx,
-                             lldb::StreamSP stream_sp) {
-    return true;
-  }
-
   virtual StructuredData::ObjectSP
   LoadPluginModule(const FileSpec &file_spec, lldb_private::Status &error) {
     return StructuredData::ObjectSP();

diff  --git a/lldb/include/lldb/Symbol/SymbolContext.h b/lldb/include/lldb/Symbol/SymbolContext.h
index 0f99364596c2..cc49ce51c713 100644
--- a/lldb/include/lldb/Symbol/SymbolContext.h
+++ b/lldb/include/lldb/Symbol/SymbolContext.h
@@ -340,7 +340,7 @@ class SymbolContextSpecifier {
 
   void Clear();
 
-  bool SymbolContextMatches(const SymbolContext &sc);
+  bool SymbolContextMatches(SymbolContext &sc);
 
   bool AddressMatches(lldb::addr_t addr);
 

diff  --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index 94c6ebeac10d..92904682ffb6 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -28,7 +28,6 @@
 #include "lldb/Target/ExecutionContextScope.h"
 #include "lldb/Target/PathMappingList.h"
 #include "lldb/Target/SectionLoadHistory.h"
-#include "lldb/Target/ThreadSpec.h"
 #include "lldb/Utility/ArchSpec.h"
 #include "lldb/Utility/Broadcaster.h"
 #include "lldb/Utility/LLDBAssert.h"
@@ -509,8 +508,6 @@ class Target : public std::enable_shared_from_this<Target>,
 
   static void SetDefaultArchitecture(const ArchSpec &arch);
 
-  bool IsDummyTarget() const { return m_is_dummy_target; }
-
   /// Find a binary on the system and return its Module,
   /// or return an existing Module that is already in the Target.
   ///
@@ -1142,27 +1139,23 @@ class Target : public std::enable_shared_from_this<Target>,
   class StopHook : public UserID {
   public:
     StopHook(const StopHook &rhs);
-    virtual ~StopHook() = default;
 
-    enum class StopHookKind  : uint32_t { CommandBased = 0, ScriptBased };
+    ~StopHook();
+
+    StringList *GetCommandPointer() { return &m_commands; }
+
+    const StringList &GetCommands() { return m_commands; }
 
     lldb::TargetSP &GetTarget() { return m_target_sp; }
 
+    void SetCommands(StringList &in_commands) { m_commands = in_commands; }
+
     // Set the specifier.  The stop hook will own the specifier, and is
     // responsible for deleting it when we're done.
     void SetSpecifier(SymbolContextSpecifier *specifier);
 
     SymbolContextSpecifier *GetSpecifier() { return m_specifier_sp.get(); }
 
-    bool ExecutionContextPasses(const ExecutionContext &exe_ctx);
-
-    // Called on stop, this gets passed the ExecutionContext for each "stop
-    // with a reason" thread.  It should add to the stream whatever text it
-    // wants to show the user, and return False to indicate it wants the target
-    // not to stop.
-    virtual bool HandleStop(ExecutionContext &exe_ctx,
-                            lldb::StreamSP output) = 0;
-
     // Set the Thread Specifier.  The stop hook will own the thread specifier,
     // and is responsible for deleting it when we're done.
     void SetThreadSpecifier(ThreadSpec *specifier);
@@ -1180,79 +1173,26 @@ class Target : public std::enable_shared_from_this<Target>,
     bool GetAutoContinue() const { return m_auto_continue; }
 
     void GetDescription(Stream *s, lldb::DescriptionLevel level) const;
-    virtual void GetSubclassDescription(Stream *s,
-                                        lldb::DescriptionLevel level) const = 0;
 
-  protected:
+  private:
     lldb::TargetSP m_target_sp;
+    StringList m_commands;
     lldb::SymbolContextSpecifierSP m_specifier_sp;
     std::unique_ptr<ThreadSpec> m_thread_spec_up;
     bool m_active = true;
     bool m_auto_continue = false;
 
-    StopHook(lldb::TargetSP target_sp, lldb::user_id_t uid);
-  };
-
-  class StopHookCommandLine : public StopHook {
-  public:
-    virtual ~StopHookCommandLine() = default;
-
-    StringList &GetCommands() { return m_commands; }
-    void SetActionFromString(const std::string &strings);
-    void SetActionFromStrings(const std::vector<std::string> &strings);
-
-    bool HandleStop(ExecutionContext &exc_ctx,
-                    lldb::StreamSP output_sp) override;
-    void GetSubclassDescription(Stream *s,
-                                lldb::DescriptionLevel level) const override;
-
-  private:
-    StringList m_commands;
     // Use CreateStopHook to make a new empty stop hook. The GetCommandPointer
     // and fill it with commands, and SetSpecifier to set the specifier shared
     // pointer (can be null, that will match anything.)
-    StopHookCommandLine(lldb::TargetSP target_sp, lldb::user_id_t uid)
-        : StopHook(target_sp, uid) {}
-    friend class Target;
-  };
-
-  class StopHookScripted : public StopHook {
-  public:
-    virtual ~StopHookScripted() = default;
-    bool HandleStop(ExecutionContext &exc_ctx, lldb::StreamSP output) override;
-
-    Status SetScriptCallback(std::string class_name,
-                             StructuredData::ObjectSP extra_args_sp);
-
-    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; // We own this structured data,
-                                      // but the SD itself manages the UP.
-    /// This holds the python callback object.
-    StructuredData::GenericSP m_implementation_sp; 
-
-    /// Use CreateStopHook to make a new empty stop hook. The GetCommandPointer
-    /// and fill it with commands, and SetSpecifier to set the specifier shared
-    /// pointer (can be null, that will match anything.)
-    StopHookScripted(lldb::TargetSP target_sp, lldb::user_id_t uid)
-        : StopHook(target_sp, uid) {}
+    StopHook(lldb::TargetSP target_sp, lldb::user_id_t uid);
     friend class Target;
   };
-
   typedef std::shared_ptr<StopHook> StopHookSP;
 
-  /// Add an empty stop hook to the Target's stop hook list, and returns a
-  /// shared pointer to it in new_hook. Returns the id of the new hook.
-  StopHookSP CreateStopHook(StopHook::StopHookKind kind);
-
-  /// If you tried to create a stop hook, and that failed, call this to
-  /// remove the stop hook, as it will also reset the stop hook counter.
-  void UndoCreateStopHook(lldb::user_id_t uid);
+  // Add an empty stop hook to the Target's stop hook list, and returns a
+  // shared pointer to it in new_hook. Returns the id of the new hook.
+  StopHookSP CreateStopHook();
 
   void RunStopHooks();
 

diff  --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index 98285289e3a9..431c2f3a19f0 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -24,7 +24,6 @@
 #include "lldb/Interpreter/OptionGroupFile.h"
 #include "lldb/Interpreter/OptionGroupFormat.h"
 #include "lldb/Interpreter/OptionGroupPlatform.h"
-#include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
 #include "lldb/Interpreter/OptionGroupString.h"
 #include "lldb/Interpreter/OptionGroupUInt64.h"
 #include "lldb/Interpreter/OptionGroupUUID.h"
@@ -4443,10 +4442,10 @@ class CommandObjectTargetSymbols : public CommandObjectMultiword {
 class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
                                        public IOHandlerDelegateMultiline {
 public:
-  class CommandOptions : public OptionGroup {
+  class CommandOptions : public Options {
   public:
     CommandOptions()
-        : OptionGroup(), m_line_start(0), m_line_end(UINT_MAX),
+        : Options(), m_line_start(0), m_line_end(UINT_MAX),
           m_func_name_type_mask(eFunctionNameTypeAuto),
           m_sym_ctx_specified(false), m_thread_specified(false),
           m_use_one_liner(false), m_one_liner() {}
@@ -4460,8 +4459,7 @@ class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
                           ExecutionContext *execution_context) override {
       Status error;
-      const int short_option =
-          g_target_stop_hook_add_options[option_idx].short_option;
+      const int short_option = m_getopt_table[option_idx].val;
 
       switch (short_option) {
       case 'c':
@@ -4591,75 +4589,20 @@ class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
     // Instance variables to hold the values for one_liner options.
     bool m_use_one_liner;
     std::vector<std::string> m_one_liner;
-
     bool m_auto_continue;
   };
 
   CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
       : CommandObjectParsed(interpreter, "target stop-hook add",
-                            "Add a hook to be executed when the target stops."
-                            "The hook can either be a list of commands or an "
-                            "appropriately defined Python class.  You can also "
-                            "add filters so the hook only runs a certain stop "
-                            "points.",
+                            "Add a hook to be executed when the target stops.",
                             "target stop-hook add"),
         IOHandlerDelegateMultiline("DONE",
                                    IOHandlerDelegate::Completion::LLDBCommand),
-        m_options(), m_python_class_options("scripted stop-hook", true, 'P') {
-    SetHelpLong(
-        R"(
-Command Based stop-hooks:
--------------------------
-  Stop hooks can run a list of lldb commands by providing one or more
-  --one-line-command options.  The commands will get run in the order they are 
-  added.  Or you can provide no commands, in which case you will enter a
-  command editor where you can enter the commands to be run.
-  
-Python Based Stop Hooks:
-------------------------
-  Stop hooks can be implemented with a suitably defined Python class, whose name
-  is passed in the --python-class option.
-  
-  When the stop hook is added, the class is initialized by calling:
-  
-    def __init__(self, target, extra_args, dict):
-    
-    target: The target that the stop hook is being added to.
-    extra_args: An SBStructuredData Dictionary filled with the -key -value 
-                option pairs passed to the command.     
-    dict: An implementation detail provided by lldb.
-
-  Then when the stop-hook triggers, lldb will run the 'handle_stop' method. 
-  The method has the signature:
-  
-    def handle_stop(self, exe_ctx, stream):
-    
-    exe_ctx: An SBExecutionContext for the thread that has stopped.
-    stream: An SBStream, anything written to this stream will be printed in the
-            the stop message when the process stops.
-
-    Return Value: The method returns "should_stop".  If should_stop is false
-                  from all the stop hook executions on threads that stopped
-                  with a reason, then the process will continue.  Note that this
-                  will happen only after all the stop hooks are run.
-    
-Filter Options:
----------------
-  Stop hooks can be set to always run, or to only run when the stopped thread
-  matches the filter options passed on the command line.  The available filter
-  options include a shared library or a thread or queue specification, 
-  a line range in a source file, a function name or a class name.
-            )");
-    m_all_options.Append(&m_python_class_options,
-                         LLDB_OPT_SET_1 | LLDB_OPT_SET_2,
-                         LLDB_OPT_SET_FROM_TO(4, 6));
-    m_all_options.Append(&m_options);
-    m_all_options.Finalize();
-  }
+        m_options() {}
 
   ~CommandObjectTargetStopHookAdd() override = default;
 
-  Options *GetOptions() override { return &m_all_options; }
+  Options *GetOptions() override { return &m_options; }
 
 protected:
   void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
@@ -4683,15 +4626,10 @@ Filter Options:
           error_sp->Flush();
         }
         Target *target = GetDebugger().GetSelectedTarget().get();
-        if (target) {
-          target->UndoCreateStopHook(m_stop_hook_sp->GetID());
-        }
+        if (target)
+          target->RemoveStopHookByID(m_stop_hook_sp->GetID());
       } else {
-        // The IOHandler editor is only for command lines stop hooks:
-        Target::StopHookCommandLine *hook_ptr =
-            static_cast<Target::StopHookCommandLine *>(m_stop_hook_sp.get());
-
-        hook_ptr->SetActionFromString(line);
+        m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
         StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
         if (output_sp) {
           output_sp->Printf("Stop hook #%" PRIu64 " added.\n",
@@ -4708,10 +4646,7 @@ Filter Options:
     m_stop_hook_sp.reset();
 
     Target &target = GetSelectedOrDummyTarget();
-    Target::StopHookSP new_hook_sp =
-        target.CreateStopHook(m_python_class_options.GetName().empty() ?
-                               Target::StopHook::StopHookKind::CommandBased
-                               : Target::StopHook::StopHookKind::ScriptBased);
+    Target::StopHookSP new_hook_sp = target.CreateStopHook();
 
     //  First step, make the specifier.
     std::unique_ptr<SymbolContextSpecifier> specifier_up;
@@ -4780,30 +4715,11 @@ Filter Options:
 
     new_hook_sp->SetAutoContinue(m_options.m_auto_continue);
     if (m_options.m_use_one_liner) {
-      // This is a command line stop hook:
-      Target::StopHookCommandLine *hook_ptr =
-          static_cast<Target::StopHookCommandLine *>(new_hook_sp.get());
-      hook_ptr->SetActionFromStrings(m_options.m_one_liner);
+      // Use one-liners.
+      for (auto cmd : m_options.m_one_liner)
+        new_hook_sp->GetCommandPointer()->AppendString(cmd.c_str());
       result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
                                      new_hook_sp->GetID());
-    } else if (!m_python_class_options.GetName().empty()) {
-      // This is a scripted stop hook:
-      Target::StopHookScripted *hook_ptr =
-          static_cast<Target::StopHookScripted *>(new_hook_sp.get());
-      Status error = hook_ptr->SetScriptCallback(
-          m_python_class_options.GetName(),
-          m_python_class_options.GetStructuredData());
-      if (error.Success())
-        result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
-                                       new_hook_sp->GetID());
-      else {
-        // FIXME: Set the stop hook ID counter back.
-        result.AppendErrorWithFormat("Couldn't add stop hook: %s",
-                                     error.AsCString());
-        result.SetStatus(eReturnStatusFailed);
-        target.UndoCreateStopHook(new_hook_sp->GetID());
-        return false;
-      }
     } else {
       m_stop_hook_sp = new_hook_sp;
       m_interpreter.GetLLDBCommandsFromIOHandler("> ",   // Prompt
@@ -4816,9 +4732,6 @@ Filter Options:
 
 private:
   CommandOptions m_options;
-  OptionGroupPythonClassWithDict m_python_class_options;
-  OptionGroupOptions m_all_options;
-
   Target::StopHookSP m_stop_hook_sp;
 };
 

diff  --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index ad2f5fdae8e7..8c83fd20a366 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -879,7 +879,7 @@ let Command = "target modules lookup" in {
 }
 
 let Command = "target stop hook add" in {
-  def target_stop_hook_add_one_liner : Option<"one-liner", "o">, GroupRange<1,3>,
+  def target_stop_hook_add_one_liner : Option<"one-liner", "o">,
     Arg<"OneLiner">, Desc<"Add a command for the stop hook.  Can be specified "
     "more than once, and commands will be run in the order they appear.">;
   def target_stop_hook_add_shlib : Option<"shlib", "s">, Arg<"ShlibName">,
@@ -897,19 +897,19 @@ let Command = "target stop hook add" in {
   def target_stop_hook_add_queue_name : Option<"queue-name", "q">,
     Arg<"QueueName">, Desc<"The stop hook is run only for threads in the queue "
     "whose name is given by this argument.">;
-  def target_stop_hook_add_file : Option<"file", "f">, Groups<[1,4]>,
+  def target_stop_hook_add_file : Option<"file", "f">, Group<1>,
     Arg<"Filename">, Desc<"Specify the source file within which the stop-hook "
     "is to be run.">, Completion<"SourceFile">;
-  def target_stop_hook_add_start_line : Option<"start-line", "l">, Groups<[1,4]>,
+  def target_stop_hook_add_start_line : Option<"start-line", "l">, Group<1>,
     Arg<"LineNum">, Desc<"Set the start of the line range for which the "
     "stop-hook is to be run.">;
-  def target_stop_hook_add_end_line : Option<"end-line", "e">, Groups<[1,4]>,
+  def target_stop_hook_add_end_line : Option<"end-line", "e">, Group<1>,
     Arg<"LineNum">, Desc<"Set the end of the line range for which the stop-hook"
     " is to be run.">;
-  def target_stop_hook_add_classname : Option<"classname", "c">, Groups<[2,5]>,
+  def target_stop_hook_add_classname : Option<"classname", "c">, Group<2>,
     Arg<"ClassName">,
     Desc<"Specify the class within which the stop-hook is to be run.">;
-  def target_stop_hook_add_name : Option<"name", "n">, Groups<[3,6]>,
+  def target_stop_hook_add_name : Option<"name", "n">, Group<3>,
     Arg<"FunctionName">, Desc<"Set the function name within which the stop hook"
     " will be run.">, Completion<"Symbol">;
   def target_stop_hook_add_auto_continue : Option<"auto-continue", "G">,

diff  --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index 34f311892775..9f56b4fa60a5 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -127,16 +127,6 @@ extern "C" unsigned int
 LLDBSwigPythonCallBreakpointResolver(void *implementor, const char *method_name,
                                      lldb_private::SymbolContext *sym_ctx);
 
-extern "C" void *LLDBSwigPythonCreateScriptedStopHook(
-    TargetSP target_sp, const char *python_class_name,
-    const char *session_dictionary_name, lldb_private::StructuredDataImpl *args,
-    lldb_private::Status &error);
-
-extern "C" unsigned int
-LLDBSwigPythonStopHookCallHandleStop(void *implementor,
-                                     lldb::ExecutionContextRefSP exc_ctx,
-                                     lldb::StreamSP stream);
-
 extern "C" size_t LLDBSwigPython_CalculateNumChildren(void *implementor,
                                                       uint32_t max);
 
@@ -1989,60 +1979,6 @@ ScriptInterpreterPythonImpl::ScriptedBreakpointResolverSearchDepth(
   return lldb::eSearchDepthModule;
 }
 
-StructuredData::GenericSP ScriptInterpreterPythonImpl::CreateScriptedStopHook(
-    TargetSP target_sp, const char *class_name, StructuredDataImpl *args_data,
-    Status &error) {
-
-  if (!target_sp) {
-    error.SetErrorString("No target for scripted stop-hook.");
-    return StructuredData::GenericSP();
-  }
-
-  if (class_name == nullptr || class_name[0] == '\0') {
-    error.SetErrorString("No class name for scripted stop-hook.");
-    return StructuredData::GenericSP();
-  }
-
-  ScriptInterpreter *script_interpreter = m_debugger.GetScriptInterpreter();
-  ScriptInterpreterPythonImpl *python_interpreter =
-      static_cast<ScriptInterpreterPythonImpl *>(script_interpreter);
-
-  if (!script_interpreter) {
-    error.SetErrorString("No script interpreter for scripted stop-hook.");
-    return StructuredData::GenericSP();
-  }
-
-  void *ret_val;
-
-  {
-    Locker py_lock(this,
-                   Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
-
-    ret_val = LLDBSwigPythonCreateScriptedStopHook(
-        target_sp, class_name, python_interpreter->m_dictionary_name.c_str(),
-        args_data, error);
-  }
-
-  return StructuredData::GenericSP(new StructuredPythonObject(ret_val));
-}
-
-bool ScriptInterpreterPythonImpl::ScriptedStopHookHandleStop(
-    StructuredData::GenericSP implementor_sp, ExecutionContext &exc_ctx,
-    lldb::StreamSP stream_sp) {
-  assert(implementor_sp &&
-         "can't call a stop hook with an invalid implementor");
-  assert(stream_sp && "can't call a stop hook with an invalid stream");
-
-  Locker py_lock(this,
-                 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
-
-  lldb::ExecutionContextRefSP exc_ctx_ref_sp(new ExecutionContextRef(exc_ctx));
-
-  bool ret_val = LLDBSwigPythonStopHookCallHandleStop(
-      implementor_sp->GetValue(), exc_ctx_ref_sp, stream_sp);
-  return ret_val;
-}
-
 StructuredData::ObjectSP
 ScriptInterpreterPythonImpl::LoadPluginModule(const FileSpec &file_spec,
                                               lldb_private::Status &error) {

diff  --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
index f89c3d461f7f..22b2c8152eac 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
@@ -105,14 +105,6 @@ class ScriptInterpreterPythonImpl : public ScriptInterpreterPython {
   lldb::SearchDepth ScriptedBreakpointResolverSearchDepth(
       StructuredData::GenericSP implementor_sp) override;
 
-  StructuredData::GenericSP
-  CreateScriptedStopHook(lldb::TargetSP target_sp, const char *class_name,
-                         StructuredDataImpl *args_data, Status &error) override;
-
-  bool ScriptedStopHookHandleStop(StructuredData::GenericSP implementor_sp,
-                                  ExecutionContext &exc_ctx,
-                                  lldb::StreamSP stream_sp) override;
-
   StructuredData::GenericSP
   CreateFrameRecognizer(const char *class_name) override;
 

diff  --git a/lldb/source/Symbol/SymbolContext.cpp b/lldb/source/Symbol/SymbolContext.cpp
index f20dc61996e0..51f56704cca6 100644
--- a/lldb/source/Symbol/SymbolContext.cpp
+++ b/lldb/source/Symbol/SymbolContext.cpp
@@ -1010,15 +1010,11 @@ void SymbolContextSpecifier::Clear() {
   m_type = eNothingSpecified;
 }
 
-bool SymbolContextSpecifier::SymbolContextMatches(const SymbolContext &sc) {
+bool SymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc) {
   if (m_type == eNothingSpecified)
     return true;
 
-  // Only compare targets if this specifier has one and it's not the Dummy
-  // target.  Otherwise if a specifier gets made in the dummy target and
-  // copied over we'll artificially fail the comparision.
-  if (m_target_sp && !m_target_sp->IsDummyTarget() &&
-      m_target_sp != sc.target_sp)
+  if (m_target_sp.get() != sc.target_sp.get())
     return false;
 
   if (m_type & eModuleSpecified) {

diff  --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index a5250ddcef74..a529df998ba7 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -2484,28 +2484,13 @@ ClangModulesDeclVendor *Target::GetClangModulesDeclVendor() {
   return m_clang_modules_decl_vendor_up.get();
 }
 
-Target::StopHookSP Target::CreateStopHook(StopHook::StopHookKind kind) {
+Target::StopHookSP Target::CreateStopHook() {
   lldb::user_id_t new_uid = ++m_stop_hook_next_id;
-  Target::StopHookSP stop_hook_sp;
-  switch (kind) {
-  case StopHook::StopHookKind::CommandBased:
-    stop_hook_sp.reset(new StopHookCommandLine(shared_from_this(), new_uid));
-    break;
-  case StopHook::StopHookKind::ScriptBased:
-    stop_hook_sp.reset(new StopHookScripted(shared_from_this(), new_uid));
-    break;
-  }
+  Target::StopHookSP stop_hook_sp(new StopHook(shared_from_this(), new_uid));
   m_stop_hooks[new_uid] = stop_hook_sp;
   return stop_hook_sp;
 }
 
-void Target::UndoCreateStopHook(lldb::user_id_t user_id) {
-  if (!RemoveStopHookByID(user_id))
-    return;
-  if (user_id == m_stop_hook_next_id)
-    m_stop_hook_next_id--;
-}
-
 bool Target::RemoveStopHookByID(lldb::user_id_t user_id) {
   size_t num_removed = m_stop_hooks.erase(user_id);
   return (num_removed != 0);
@@ -2561,18 +2546,25 @@ void Target::RunStopHooks() {
   if (m_stop_hooks.empty())
     return;
 
+  StopHookCollection::iterator pos, end = m_stop_hooks.end();
+
   // If there aren't any active stop hooks, don't bother either.
+  // Also see if any of the active hooks want to auto-continue.
   bool any_active_hooks = false;
+  bool auto_continue = false;
   for (auto hook : m_stop_hooks) {
     if (hook.second->IsActive()) {
       any_active_hooks = true;
-      break;
+      auto_continue |= hook.second->GetAutoContinue();
     }
   }
   if (!any_active_hooks)
     return;
 
+  CommandReturnObject result(m_debugger.GetUseColor());
+
   std::vector<ExecutionContext> exc_ctx_with_reasons;
+  std::vector<SymbolContext> sym_ctx_with_reasons;
 
   ThreadList &cur_threadlist = m_process_sp->GetThreadList();
   size_t num_threads = cur_threadlist.GetSize();
@@ -2580,8 +2572,10 @@ void Target::RunStopHooks() {
     lldb::ThreadSP cur_thread_sp = cur_threadlist.GetThreadAtIndex(i);
     if (cur_thread_sp->ThreadStoppedForAReason()) {
       lldb::StackFrameSP cur_frame_sp = cur_thread_sp->GetStackFrameAtIndex(0);
-      exc_ctx_with_reasons.emplace_back(m_process_sp.get(), cur_thread_sp.get(),
-                                        cur_frame_sp.get());
+      exc_ctx_with_reasons.push_back(ExecutionContext(
+          m_process_sp.get(), cur_thread_sp.get(), cur_frame_sp.get()));
+      sym_ctx_with_reasons.push_back(
+          cur_frame_sp->GetSymbolContext(eSymbolContextEverything));
     }
   }
 
@@ -2590,86 +2584,91 @@ void Target::RunStopHooks() {
   if (num_exe_ctx == 0)
     return;
 
-  StreamSP output_sp = m_debugger.GetAsyncOutputStream();
+  result.SetImmediateOutputStream(m_debugger.GetAsyncOutputStream());
+  result.SetImmediateErrorStream(m_debugger.GetAsyncErrorStream());
 
-  bool auto_continue = false;
+  bool keep_going = true;
   bool hooks_ran = false;
   bool print_hook_header = (m_stop_hooks.size() != 1);
   bool print_thread_header = (num_exe_ctx != 1);
-  bool should_stop = false;
-  bool somebody_restarted = false;
+  bool did_restart = false;
 
-  for (auto stop_entry : m_stop_hooks) {
-    StopHookSP cur_hook_sp = stop_entry.second;
+  for (pos = m_stop_hooks.begin(); keep_going && pos != end; pos++) {
+    // result.Clear();
+    StopHookSP cur_hook_sp = (*pos).second;
     if (!cur_hook_sp->IsActive())
       continue;
 
     bool any_thread_matched = false;
-    for (auto exc_ctx : exc_ctx_with_reasons) {
-      // We detect somebody restarted in the stop-hook loop, and broke out of
-      // that loop back to here.  So break out of here too.
-      if (somebody_restarted)
-        break;
-
-      if (!cur_hook_sp->ExecutionContextPasses(exc_ctx))
-        continue;
-
-      // We only consult the auto-continue for a stop hook if it matched the
-      // specifier.
-      auto_continue |= cur_hook_sp->GetAutoContinue();
-
-      if (!hooks_ran)
-        hooks_ran = true;
-
-      if (print_hook_header && !any_thread_matched) {
-        StreamString s;
-        cur_hook_sp->GetDescription(&s, eDescriptionLevelBrief);
-        if (s.GetSize() != 0)
-          output_sp->Printf("\n- Hook %" PRIu64 " (%s)\n", cur_hook_sp->GetID(),
-                            s.GetData());
-        else
-          output_sp->Printf("\n- Hook %" PRIu64 "\n", cur_hook_sp->GetID());
-        any_thread_matched = true;
-      }
+    for (size_t i = 0; keep_going && i < num_exe_ctx; i++) {
+      if ((cur_hook_sp->GetSpecifier() == nullptr ||
+           cur_hook_sp->GetSpecifier()->SymbolContextMatches(
+               sym_ctx_with_reasons[i])) &&
+          (cur_hook_sp->GetThreadSpecifier() == nullptr ||
+           cur_hook_sp->GetThreadSpecifier()->ThreadPassesBasicTests(
+               exc_ctx_with_reasons[i].GetThreadRef()))) {
+        if (!hooks_ran) {
+          hooks_ran = true;
+        }
+        if (print_hook_header && !any_thread_matched) {
+          const char *cmd =
+              (cur_hook_sp->GetCommands().GetSize() == 1
+                   ? cur_hook_sp->GetCommands().GetStringAtIndex(0)
+                   : nullptr);
+          if (cmd)
+            result.AppendMessageWithFormat("\n- Hook %" PRIu64 " (%s)\n",
+                                           cur_hook_sp->GetID(), cmd);
+          else
+            result.AppendMessageWithFormat("\n- Hook %" PRIu64 "\n",
+                                           cur_hook_sp->GetID());
+          any_thread_matched = true;
+        }
 
-      if (print_thread_header)
-        output_sp->Printf("-- Thread %d\n",
-                          exc_ctx.GetThreadPtr()->GetIndexID());
-
-      bool this_should_stop = cur_hook_sp->HandleStop(exc_ctx, output_sp);
-      // If this hook is set to auto-continue that should override the
-      // HandleStop result...
-      if (cur_hook_sp->GetAutoContinue())
-        this_should_stop = false;
-
-      // If anybody wanted to stop, we should all stop.
-      if (!should_stop)
-        should_stop = this_should_stop;
-
-      // We don't have a good way to prohibit people from restarting the target
-      // willy nilly in a stop hook.  So see if the private state is running
-      // here and bag out if it is.
-      // FIXME: when we are doing non-stop mode for realz we'll have to instead
-      // track each thread, and only bag out if a thread is set running.
-      if (m_process_sp->GetPrivateState() != eStateStopped) {
-        output_sp->Printf("\nAborting stop hooks, hook %" PRIu64
-                          " set the program running.\n"
-                          "  Consider using '-G true' to make "
-                          "stop hooks auto-continue.\n",
-                          cur_hook_sp->GetID());
-        somebody_restarted = true;
-        break;
+        if (print_thread_header)
+          result.AppendMessageWithFormat(
+              "-- Thread %d\n",
+              exc_ctx_with_reasons[i].GetThreadPtr()->GetIndexID());
+
+        CommandInterpreterRunOptions options;
+        options.SetStopOnContinue(true);
+        options.SetStopOnError(true);
+        options.SetEchoCommands(false);
+        options.SetPrintResults(true);
+        options.SetPrintErrors(true);
+        options.SetAddToHistory(false);
+
+        // Force Async:
+        bool old_async = GetDebugger().GetAsyncExecution();
+        GetDebugger().SetAsyncExecution(true);
+        GetDebugger().GetCommandInterpreter().HandleCommands(
+            cur_hook_sp->GetCommands(), &exc_ctx_with_reasons[i], options,
+            result);
+        GetDebugger().SetAsyncExecution(old_async);
+        // If the command started the target going again, we should bag out of
+        // running the stop hooks.
+        if ((result.GetStatus() == eReturnStatusSuccessContinuingNoResult) ||
+            (result.GetStatus() == eReturnStatusSuccessContinuingResult)) {
+          // But only complain if there were more stop hooks to do:
+          StopHookCollection::iterator tmp = pos;
+          if (++tmp != end)
+            result.AppendMessageWithFormat(
+                "\nAborting stop hooks, hook %" PRIu64
+                " set the program running.\n"
+                "  Consider using '-G true' to make "
+                "stop hooks auto-continue.\n",
+                cur_hook_sp->GetID());
+          keep_going = false;
+          did_restart = true;
+        }
       }
     }
   }
-
-  output_sp->Flush();
-
   // Finally, if auto-continue was requested, do it now:
-  // We only compute should_stop against the hook results if a hook got to run
-  // which is why we have to do this conjoint test.
-  if (!somebody_restarted && ((hooks_ran && !should_stop) || auto_continue))
+  if (!did_restart && auto_continue)
     m_process_sp->PrivateResume();
+
+  result.GetImmediateOutputStream()->Flush();
+  result.GetImmediateErrorStream()->Flush();
 }
 
 const TargetPropertiesSP &Target::GetGlobalProperties() {
@@ -3129,17 +3128,20 @@ void Target::FinalizeFileActions(ProcessLaunchInfo &info) {
 
 // Target::StopHook
 Target::StopHook::StopHook(lldb::TargetSP target_sp, lldb::user_id_t uid)
-    : UserID(uid), m_target_sp(target_sp), m_specifier_sp(),
+    : UserID(uid), m_target_sp(target_sp), m_commands(), m_specifier_sp(),
       m_thread_spec_up() {}
 
 Target::StopHook::StopHook(const StopHook &rhs)
     : UserID(rhs.GetID()), m_target_sp(rhs.m_target_sp),
-      m_specifier_sp(rhs.m_specifier_sp), m_thread_spec_up(),
-      m_active(rhs.m_active), m_auto_continue(rhs.m_auto_continue) {
+      m_commands(rhs.m_commands), m_specifier_sp(rhs.m_specifier_sp),
+      m_thread_spec_up(), m_active(rhs.m_active),
+      m_auto_continue(rhs.m_auto_continue) {
   if (rhs.m_thread_spec_up)
     m_thread_spec_up = std::make_unique<ThreadSpec>(*rhs.m_thread_spec_up);
 }
 
+Target::StopHook::~StopHook() = default;
+
 void Target::StopHook::SetSpecifier(SymbolContextSpecifier *specifier) {
   m_specifier_sp.reset(specifier);
 }
@@ -3148,31 +3150,8 @@ void Target::StopHook::SetThreadSpecifier(ThreadSpec *specifier) {
   m_thread_spec_up.reset(specifier);
 }
 
-bool Target::StopHook::ExecutionContextPasses(const ExecutionContext &exc_ctx) {
-  SymbolContextSpecifier *specifier = GetSpecifier();
-  if (!specifier)
-    return true;
-
-  bool will_run = true;
-  if (exc_ctx.GetFramePtr())
-    will_run = GetSpecifier()->SymbolContextMatches(
-        exc_ctx.GetFramePtr()->GetSymbolContext(eSymbolContextEverything));
-  if (will_run && GetThreadSpecifier() != nullptr)
-    will_run =
-        GetThreadSpecifier()->ThreadPassesBasicTests(exc_ctx.GetThreadRef());
-
-  return will_run;
-}
-
 void Target::StopHook::GetDescription(Stream *s,
                                       lldb::DescriptionLevel level) const {
-
-  // For brief descriptions, only print the subclass description:
-  if (level == eDescriptionLevelBrief) {
-    GetSubclassDescription(s, level);
-    return;
-  }
-
   unsigned indent_level = s->GetIndentLevel();
 
   s->SetIndentLevel(indent_level + 2);
@@ -3203,148 +3182,15 @@ void Target::StopHook::GetDescription(Stream *s,
     s->PutCString("\n");
     s->SetIndentLevel(indent_level + 2);
   }
-  GetSubclassDescription(s, level);
-}
 
-void Target::StopHookCommandLine::GetSubclassDescription(
-    Stream *s, lldb::DescriptionLevel level) const {
-  // The brief description just prints the first command.
-  if (level == eDescriptionLevelBrief) {
-    if (m_commands.GetSize() == 1)
-      s->PutCString(m_commands.GetStringAtIndex(0));
-    return;
-  }
   s->Indent("Commands: \n");
-  s->SetIndentLevel(s->GetIndentLevel() + 4);
+  s->SetIndentLevel(indent_level + 4);
   uint32_t num_commands = m_commands.GetSize();
   for (uint32_t i = 0; i < num_commands; i++) {
     s->Indent(m_commands.GetStringAtIndex(i));
     s->PutCString("\n");
   }
-  s->SetIndentLevel(s->GetIndentLevel() - 4);
-}
-
-// Target::StopHookCommandLine
-void Target::StopHookCommandLine::SetActionFromString(const std::string &string) {
-  GetCommands().SplitIntoLines(string);
-}
-
-void Target::StopHookCommandLine::SetActionFromStrings(
-    const std::vector<std::string> &strings) {
-  for (auto string : strings)
-    GetCommands().AppendString(string.c_str());
-}
-
-bool Target::StopHookCommandLine::HandleStop(ExecutionContext &exc_ctx,
-                                             StreamSP output_sp) {
-  assert(exc_ctx.GetTargetPtr() && "Can't call PerformAction on a context "
-                                   "with no target");
-
-  if (!m_commands.GetSize())
-    return true;
-
-  CommandReturnObject result(false);
-  result.SetImmediateOutputStream(output_sp);
-  Debugger &debugger = exc_ctx.GetTargetPtr()->GetDebugger();
-  CommandInterpreterRunOptions options;
-  options.SetStopOnContinue(true);
-  options.SetStopOnError(true);
-  options.SetEchoCommands(false);
-  options.SetPrintResults(true);
-  options.SetPrintErrors(true);
-  options.SetAddToHistory(false);
-
-  // Force Async:
-  bool old_async = debugger.GetAsyncExecution();
-  debugger.SetAsyncExecution(true);
-  debugger.GetCommandInterpreter().HandleCommands(GetCommands(), &exc_ctx,
-                                                  options, result);
-  debugger.SetAsyncExecution(old_async);
-
-  return true;
-}
-
-// Target::StopHookScripted
-Status Target::StopHookScripted::SetScriptCallback(
-    std::string class_name, StructuredData::ObjectSP extra_args_sp) {
-  Status error;
-
-  ScriptInterpreter *script_interp =
-      GetTarget()->GetDebugger().GetScriptInterpreter();
-  if (!script_interp) {
-    error.SetErrorString("No script interpreter installed.");
-    return error;
-  }
-
-  m_class_name = class_name;
-
-  m_extra_args = new StructuredDataImpl();
-
-  if (extra_args_sp)
-    m_extra_args->SetObjectSP(extra_args_sp);
-
-  m_implementation_sp = script_interp->CreateScriptedStopHook(
-      GetTarget(), m_class_name.c_str(), m_extra_args, error);
-
-  return error;
-}
-
-bool Target::StopHookScripted::HandleStop(ExecutionContext &exc_ctx,
-                                          StreamSP output_sp) {
-  assert(exc_ctx.GetTargetPtr() && "Can't call HandleStop on a context "
-                                   "with no target");
-
-  ScriptInterpreter *script_interp =
-      GetTarget()->GetDebugger().GetScriptInterpreter();
-  if (!script_interp)
-    return true;
-
-  bool should_stop = script_interp->ScriptedStopHookHandleStop(
-      m_implementation_sp, exc_ctx, output_sp);
-
-  return should_stop;
-}
-
-void Target::StopHookScripted::GetSubclassDescription(
-    Stream *s, lldb::DescriptionLevel level) const {
-  if (level == eDescriptionLevelBrief) {
-    s->PutCString(m_class_name);
-    return;
-  }
-  s->Indent("Class:");
-  s->Printf("%s\n", m_class_name.c_str());
-
-  // Now print the extra args:
-  // FIXME: We should use StructuredData.GetDescription on the m_extra_args
-  // 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();
-  if (!as_dict || !as_dict->IsValid())
-    return;
-
-  uint32_t num_keys = as_dict->GetSize();
-  if (num_keys == 0)
-    return;
-
-  s->Indent("Args:\n");
-  s->SetIndentLevel(s->GetIndentLevel() + 4);
-
-  auto print_one_element = [&s](ConstString key,
-                                StructuredData::Object *object) {
-    s->Indent();
-    s->Printf("%s : %s\n", key.GetCString(),
-              object->GetStringValue().str().c_str());
-    return true;
-  };
-
-  as_dict->ForEach(print_one_element);
-
-  s->SetIndentLevel(s->GetIndentLevel() - 4);
+  s->SetIndentLevel(indent_level);
 }
 
 static constexpr OptionEnumValueElement g_dynamic_value_types[] = {

diff  --git a/lldb/test/API/commands/target/stop-hooks/TestStopHookScripted.py b/lldb/test/API/commands/target/stop-hooks/TestStopHookScripted.py
deleted file mode 100644
index b3b65b82965f..000000000000
--- a/lldb/test/API/commands/target/stop-hooks/TestStopHookScripted.py
+++ /dev/null
@@ -1,131 +0,0 @@
-"""
-Test stop hook functionality
-"""
-
-
-
-import lldb
-import lldbsuite.test.lldbutil as lldbutil
-from lldbsuite.test.lldbtest import *
-
-
-class TestStopHooks(TestBase):
-
-    mydir = TestBase.compute_mydir(__file__)
-
-    # If your test case doesn't stress debug info, the
-    # set this to true.  That way it won't be run once for
-    # each debug info format.
-    NO_DEBUG_INFO_TESTCASE = True
-
-    def setUp(self):
-        TestBase.setUp(self)
-        self.build()
-        self.main_source_file = lldb.SBFileSpec("main.c")
-        full_path = os.path.join(self.getSourceDir(), "main.c")
-        self.main_start_line = line_number(full_path, "main()")
-        
-    def not_test_stop_hooks_scripted(self):
-        """Test that a scripted stop hook works with no specifiers"""
-        self.stop_hooks_scripted(5)
-
-    def not_test_stop_hooks_scripted_right_func(self):
-        """Test that a scripted stop hook fires when there is a function match"""
-        self.stop_hooks_scripted(5, "-n step_out_of_me")
-    
-    def not_test_stop_hooks_scripted_wrong_func(self):
-        """Test that a scripted stop hook doesn't fire when the function does not match"""
-        self.stop_hooks_scripted(0, "-n main")
-    
-    def not_test_stop_hooks_scripted_right_lines(self):
-        """Test that a scripted stop hook fires when there is a function match"""
-        self.stop_hooks_scripted(5, "-f main.c -l 1 -e %d"%(self.main_start_line))
-    
-    def not_test_stop_hooks_scripted_wrong_lines(self):
-        """Test that a scripted stop hook doesn't fire when the function does not match"""
-        self.stop_hooks_scripted(0, "-f main.c -l %d -e 100"%(self.main_start_line))
-
-    def not_test_stop_hooks_scripted_auto_continue(self):
-        """Test that the --auto-continue flag works"""
-        self.do_test_auto_continue(False)
-
-    def test_stop_hooks_scripted_return_false(self):
-        """Test that the returning False from a stop hook works"""
-        self.do_test_auto_continue(True)
-
-    def do_test_auto_continue(self, return_true):
-        """Test that auto-continue works."""
-        # We set auto-continue to 1 but the stop hook only applies to step_out_of_me,
-        # so we should end up stopped in main, having run the expression only once.
-        self.script_setup()
-        
-        result = lldb.SBCommandReturnObject()
-
-        if return_true:
-          command = "target stop-hook add -P stop_hook.stop_handler -k increment -v 5 -k return_false -v 1 -n step_out_of_me"
-        else:
-          command = "target stop-hook add -G 1 -P stop_hook.stop_handler -k increment -v 5 -n step_out_of_me"
-            
-        print("Running command: %s"%(command))
-        
-        self.interp.HandleCommand(command, result)
-        self.assertTrue(result.Succeeded, "Set the target stop hook")
-
-        # First run to main.  If we go straight to the first stop hook hit,
-        # run_to_source_breakpoint will fail because we aren't at original breakpoint
-
-        (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self,
-                                   "Stop here first", self.main_source_file)
-
-        # Now set the breakpoint on step_out_of_me, and make sure we run the
-        # expression, then continue back to main.
-        bkpt = target.BreakpointCreateBySourceRegex("Set a breakpoint here and step out", self.main_source_file)
-        self.assertTrue(bkpt.GetNumLocations() > 0, "Got breakpoints in step_out_of_me")
-        process.Continue()
-
-        var = target.FindFirstGlobalVariable("g_var")
-        self.assertTrue(var.IsValid())
-        self.assertEqual(var.GetValueAsUnsigned(), 5, "Updated g_var")
-        
-        func_name = process.GetSelectedThread().frames[0].GetFunctionName()
-        self.assertEqual("main", func_name, "Didn't stop at the expected function.")
-
-    def script_setup(self):
-        self.interp = self.dbg.GetCommandInterpreter()
-        result = lldb.SBCommandReturnObject()
-
-        # Bring in our script file:
-        script_name = os.path.join(self.getSourceDir(), "stop_hook.py")
-        command = "command script import " + script_name
-        self.interp.HandleCommand(command, result)
-        self.assertTrue(result.Succeeded(), "com scr imp failed: %s"%(result.GetError()))
-
-        # set a breakpoint at the end of main to catch our auto-continue tests.
-        # Do it in the dummy target so it will get copied to our target even when
-        # we don't have a chance to stop.
-        dummy_target = self.dbg.GetDummyTarget()
-        dummy_target.BreakpointCreateBySourceRegex("return result", self.main_source_file)
-
-        
-    def stop_hooks_scripted(self, g_var_value, specifier = None):
-        self.script_setup()
-        
-        result = lldb.SBCommandReturnObject()
-
-        command = "target stop-hook add -P stop_hook.stop_handler -k increment -v 5 "
-        if specifier:
-            command += specifier
-        print("Running command: %s"%(command))
-        
-        self.interp.HandleCommand(command, result)
-        self.assertTrue(result.Succeeded, "Set the target stop hook")
-        (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self,
-                                   "Set a breakpoint here", self.main_source_file)
-        # At this point we've hit our stop hook so we should have run our expression,
-        # which increments g_var by the amount specified by the increment key's value.
-        while process.GetState() == lldb.eStateRunning:
-            continue
-
-        var = target.FindFirstGlobalVariable("g_var")
-        self.assertTrue(var.IsValid())
-        self.assertEqual(var.GetValueAsUnsigned(), g_var_value, "Updated g_var")

diff  --git a/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py b/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py
index 43447a845156..64686afe627d 100644
--- a/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py
+++ b/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py
@@ -1,5 +1,5 @@
 """
-Test stop hook functionality
+Test that stop hooks trigger on "step-out"
 """
 
 
@@ -18,15 +18,10 @@ class TestStopHooks(TestBase):
     # each debug info format.
     NO_DEBUG_INFO_TESTCASE = True
 
-    def setUp(self):
-        TestBase.setUp(self)
-        self.build()
-        self.main_source_file = lldb.SBFileSpec("main.c")
-        full_path = os.path.join(self.getSourceDir(), "main.c")
-        self.main_start_line = line_number(full_path, "main()")
-        
     def test_stop_hooks_step_out(self):
         """Test that stop hooks fire on step-out."""
+        self.build()
+        self.main_source_file = lldb.SBFileSpec("main.c")
         self.step_out_test()
 
     def step_out_test(self):
@@ -42,3 +37,4 @@ def step_out_test(self):
         self.assertTrue(var.IsValid())
         self.assertEqual(var.GetValueAsUnsigned(), 1, "Updated g_var")
 
+

diff  --git a/lldb/test/API/commands/target/stop-hooks/main.c b/lldb/test/API/commands/target/stop-hooks/main.c
index 16bfc0ce5db6..d08ad14776b5 100644
--- a/lldb/test/API/commands/target/stop-hooks/main.c
+++ b/lldb/test/API/commands/target/stop-hooks/main.c
@@ -10,6 +10,5 @@ int step_out_of_me()
 int
 main()
 {
-  int result = step_out_of_me(); // Stop here first
-  return result;
+  return step_out_of_me();
 }

diff  --git a/lldb/test/API/commands/target/stop-hooks/stop_hook.py b/lldb/test/API/commands/target/stop-hooks/stop_hook.py
deleted file mode 100644
index 412c81acf737..000000000000
--- a/lldb/test/API/commands/target/stop-hooks/stop_hook.py
+++ /dev/null
@@ -1,34 +0,0 @@
-import lldb
-
-class stop_handler:
-    def __init__(self, target, extra_args, dict):
-        self.extra_args = extra_args
-        self.target = target
-        self.counter = 0
-        ret_val = self.extra_args.GetValueForKey("return_false")
-        if ret_val:
-            self.ret_val = False
-        else:
-            self.ret_val = True
-
-    def handle_stop(self, exe_ctx, stream):
-        self.counter += 1
-        stream.Print("I have stopped %d times.\n"%(self.counter))
-        increment = 1
-        value = self.extra_args.GetValueForKey("increment")
-        if value:
-            incr_as_str = value.GetStringValue(100)
-            increment = int(incr_as_str)
-        else:
-            stream.Print("Could not find increment in extra_args\n")
-        frame = exe_ctx.GetFrame()
-        expression = "g_var += %d"%(increment)
-        expr_result = frame.EvaluateExpression(expression)
-        if not expr_result.GetError().Success():
-            stream.Print("Error running expression: %s"%(expr_result.GetError().GetCString()))
-        value = exe_ctx.target.FindFirstGlobalVariable("g_var")
-        if not value.IsValid():
-            stream.Print("Didn't get a valid value for g_var.")
-        else:
-            int_val = value.GetValueAsUnsigned()
-        return self.ret_val

diff  --git a/lldb/test/Shell/Commands/Inputs/stop_hook.py b/lldb/test/Shell/Commands/Inputs/stop_hook.py
deleted file mode 100644
index e319ca9ec5bc..000000000000
--- a/lldb/test/Shell/Commands/Inputs/stop_hook.py
+++ /dev/null
@@ -1,10 +0,0 @@
-import lldb
-
-class stop_handler:
-    def __init__(self, target, extra_args, dict):
-        self.extra_args = extra_args
-        self.target = target
-
-    def handle_stop(self, exe_ctx, stream):
-        stream.Print("I did indeed run\n")
-        return True

diff  --git a/lldb/test/Shell/Commands/command-stop-hook-output.test b/lldb/test/Shell/Commands/command-stop-hook-output.test
deleted file mode 100644
index e7270c8f6631..000000000000
--- a/lldb/test/Shell/Commands/command-stop-hook-output.test
+++ /dev/null
@@ -1,18 +0,0 @@
-# RUN: %clang_host -g %S/Inputs/main.c -o %t
-# RUN: %lldb %t -O 'command script import %S/Inputs/stop_hook.py' -s %s -o exit | FileCheck %s
-
-b main
-# CHECK-LABEL: b main
-# CHECK: Breakpoint 1: where = {{.*}}`main
-
-target stop-hook add -P stop_hook.stop_handler
-# CHECK-LABEL: target stop-hook add -P stop_hook.stop_handler
-# CHECK: Stop hook #1 added.
-
-run
-# CHECK-LABEL: run
-# CHECK: I did indeed run
-# CHECK: Process {{.*}} stopped
-# CHECK: stop reason = breakpoint 1
-# CHECK:   frame #0: {{.*}}`main at main.c
-

diff  --git a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
index 58ddf0c40a26..f661835d191b 100644
--- a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
+++ b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
@@ -254,17 +254,3 @@ LLDBSWIGPython_GetDynamicSetting(void *module, const char *setting,
                                  const lldb::TargetSP &target_sp) {
   return nullptr;
 }
-
-extern "C" void *LLDBSwigPythonCreateScriptedStopHook(
-    lldb::TargetSP target_sp, const char *python_class_name,
-    const char *session_dictionary_name,
-    lldb_private::StructuredDataImpl *args_impl, Status &error) {
-  return nullptr;
-}
-
-extern "C" bool
-LLDBSwigPythonStopHookCallHandleStop(void *implementor,
-                                     lldb::ExecutionContextRefSP exc_ctx_sp,
-                                     lldb::StreamSP stream) {
-  return false;
-}


        


More information about the lldb-commits mailing list