This revision was automatically updated to reflect the committed changes.
Closed by commit rG04de24e690d3: [lldb/IOHandler] Improve synchronization 
between IO handlers. (authored by JDevlieghere).

Changed prior to commit:
  https://reviews.llvm.org/D72748?vs=238886&id=239178#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72748/new/

https://reviews.llvm.org/D72748

Files:
  lldb/include/lldb/Core/Debugger.h
  
lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_callback_command_source/Makefile
  
lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_callback_command_source/TestBreakpointCallbackCommandSource.py
  
lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_callback_command_source/main.c
  
lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_callback_command_source/source.lldb
  lldb/source/Core/Debugger.cpp

Index: lldb/source/Core/Debugger.cpp
===================================================================
--- lldb/source/Core/Debugger.cpp
+++ lldb/source/Core/Debugger.cpp
@@ -895,23 +895,62 @@
 }
 
 void Debugger::RunIOHandlers() {
+  IOHandlerSP reader_sp = m_io_handler_stack.Top();
   while (true) {
-    IOHandlerSP reader_sp(m_io_handler_stack.Top());
     if (!reader_sp)
       break;
 
     reader_sp->Run();
+    {
+      std::lock_guard<std::recursive_mutex> guard(
+          m_io_handler_synchronous_mutex);
+
+      // Remove all input readers that are done from the top of the stack
+      while (true) {
+        IOHandlerSP top_reader_sp = m_io_handler_stack.Top();
+        if (top_reader_sp && top_reader_sp->GetIsDone())
+          PopIOHandler(top_reader_sp);
+        else
+          break;
+      }
+      reader_sp = m_io_handler_stack.Top();
+    }
+  }
+  ClearIOHandlers();
+}
+
+void Debugger::RunIOHandlerSync(const IOHandlerSP &reader_sp) {
+  std::lock_guard<std::recursive_mutex> guard(m_io_handler_synchronous_mutex);
+
+  PushIOHandler(reader_sp);
+  IOHandlerSP top_reader_sp = reader_sp;
 
-    // Remove all input readers that are done from the top of the stack
+  while (top_reader_sp) {
+    if (!top_reader_sp)
+      break;
+
+    top_reader_sp->Run();
+
+    // Don't unwind past the starting point.
+    if (top_reader_sp.get() == reader_sp.get()) {
+      if (PopIOHandler(reader_sp))
+        break;
+    }
+
+    // If we pushed new IO handlers, pop them if they're done or restart the
+    // loop to run them if they're not.
     while (true) {
-      IOHandlerSP top_reader_sp = m_io_handler_stack.Top();
-      if (top_reader_sp && top_reader_sp->GetIsDone())
+      top_reader_sp = m_io_handler_stack.Top();
+      if (top_reader_sp && top_reader_sp->GetIsDone()) {
         PopIOHandler(top_reader_sp);
-      else
+        // Don't unwind past the starting point.
+        if (top_reader_sp.get() == reader_sp.get())
+          return;
+      } else {
         break;
+      }
     }
   }
-  ClearIOHandlers();
 }
 
 bool Debugger::IsTopIOHandler(const lldb::IOHandlerSP &reader_sp) {
@@ -950,28 +989,6 @@
   PushIOHandler(reader_sp, cancel_top_handler);
 }
 
-void Debugger::RunIOHandlerSync(const IOHandlerSP &reader_sp) {
-  PushIOHandler(reader_sp);
-
-  IOHandlerSP top_reader_sp = reader_sp;
-  while (top_reader_sp) {
-    top_reader_sp->Run();
-
-    if (top_reader_sp.get() == reader_sp.get()) {
-      if (PopIOHandler(reader_sp))
-        break;
-    }
-
-    while (true) {
-      top_reader_sp = m_io_handler_stack.Top();
-      if (top_reader_sp && top_reader_sp->GetIsDone())
-        PopIOHandler(top_reader_sp);
-      else
-        break;
-    }
-  }
-}
-
 void Debugger::AdoptTopIOHandlerFilesIfInvalid(FileSP &in, StreamFileSP &out,
                                                StreamFileSP &err) {
   // Before an IOHandler runs, it must have in/out/err streams. This function
Index: lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_callback_command_source/source.lldb
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_callback_command_source/source.lldb
@@ -0,0 +1 @@
+script foo = 95126
Index: lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_callback_command_source/main.c
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_callback_command_source/main.c
@@ -0,0 +1,4 @@
+int main (int argc, char const *argv[])
+{
+  return 0;
+}
Index: lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_callback_command_source/TestBreakpointCallbackCommandSource.py
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_callback_command_source/TestBreakpointCallbackCommandSource.py
@@ -0,0 +1,35 @@
+"""
+Test completion in our IOHandlers.
+"""
+
+import os
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.lldbpexpect import PExpectTest
+
+
+class BreakpointCallbackCommandSource(PExpectTest):
+
+    mydir = TestBase.compute_mydir(__file__)
+    file_to_source = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'source.lldb')
+
+    # PExpect uses many timeouts internally and doesn't play well
+    # under ASAN on a loaded machine..
+    @skipIfAsan
+    @skipIfEditlineSupportMissing
+    def test_breakpoint_callback_command_source(self):
+        self.build()
+        exe = self.getBuildArtifact("a.out")
+
+        self.launch(exe)
+        self.expect("b main", substrs=["Breakpoint 1"])
+        self.child.send("breakpoint command add -s python\n")
+        self.child.send(
+            "frame.GetThread().GetProcess().GetTarget().GetDebugger().HandleCommand('command source -s true {}')\n"
+            .format(self.file_to_source))
+        self.child.send("DONE\n")
+        self.expect_prompt()
+        self.expect("run", substrs=["Process", "stopped"])
+        self.expect("script print(foo)", substrs=["95126"])
Index: lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_callback_command_source/Makefile
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_callback_command_source/Makefile
@@ -0,0 +1,3 @@
+C_SOURCES := main.c
+
+include Makefile.rules
Index: lldb/include/lldb/Core/Debugger.h
===================================================================
--- lldb/include/lldb/Core/Debugger.h
+++ lldb/include/lldb/Core/Debugger.h
@@ -410,6 +410,8 @@
       m_script_interpreters;
 
   IOHandlerStack m_io_handler_stack;
+  std::recursive_mutex m_io_handler_synchronous_mutex;
+
   llvm::StringMap<std::weak_ptr<llvm::raw_ostream>> m_log_streams;
   std::shared_ptr<llvm::raw_ostream> m_log_callback_stream_sp;
   ConstString m_instance_name;
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to