[lldb] Fix ^C handling in IOHandlerProcessSTDIO
authorPavel Labath <pavel@labath.sk>
Thu, 17 Mar 2022 14:09:12 +0000 (15:09 +0100)
committerPavel Labath <pavel@labath.sk>
Fri, 18 Mar 2022 07:58:30 +0000 (08:58 +0100)
D120762 accidentally moved the interrupt check into the block which was
reading stdio. This meant that a ^C only took effect after a regular
character has been pressed.

This patch fixes that and adds a (pexpect) test.

Differential Revision: https://reviews.llvm.org/D121912

lldb/source/Target/Process.cpp
lldb/test/API/iohandler/sigint/Makefile [new file with mode: 0644]
lldb/test/API/iohandler/sigint/TestProcessIOHandlerInterrupt.py [new file with mode: 0644]
lldb/test/API/iohandler/sigint/cat.cpp [new file with mode: 0644]

index 122f20b..54a1983 100644 (file)
@@ -4361,18 +4361,18 @@ public:
             break;
         } else
           break;
+      }
 
-        if (select_helper.FDIsSetRead(pipe_read_fd)) {
-          size_t bytes_read;
-          // Consume the interrupt byte
-          Status error = m_pipe.Read(&ch, 1, bytes_read);
-          if (error.Success()) {
-            if (ch == 'q')
-              break;
-            if (ch == 'i')
-              if (StateIsRunningState(m_process->GetState()))
-                m_process->SendAsyncInterrupt();
-          }
+      if (select_helper.FDIsSetRead(pipe_read_fd)) {
+        size_t bytes_read;
+        // Consume the interrupt byte
+        Status error = m_pipe.Read(&ch, 1, bytes_read);
+        if (error.Success()) {
+          if (ch == 'q')
+            break;
+          if (ch == 'i')
+            if (StateIsRunningState(m_process->GetState()))
+              m_process->SendAsyncInterrupt();
         }
       }
     }
diff --git a/lldb/test/API/iohandler/sigint/Makefile b/lldb/test/API/iohandler/sigint/Makefile
new file mode 100644 (file)
index 0000000..22f1051
--- /dev/null
@@ -0,0 +1 @@
+include Makefile.rules
diff --git a/lldb/test/API/iohandler/sigint/TestProcessIOHandlerInterrupt.py b/lldb/test/API/iohandler/sigint/TestProcessIOHandlerInterrupt.py
new file mode 100644 (file)
index 0000000..f1bd76e
--- /dev/null
@@ -0,0 +1,42 @@
+"""
+Test sending SIGINT Process IOHandler
+"""
+
+import os
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.lldbpexpect import PExpectTest
+
+class TestCase(PExpectTest):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    def test(self):
+        self.build(dictionary={"CXX_SOURCES":"cat.cpp"})
+        self.launch(executable=self.getBuildArtifact(), timeout=5)
+
+        self.child.sendline("process launch")
+        self.child.expect("Process .* launched")
+
+        self.child.sendline("Hello cat")
+        self.child.expect_exact("read: Hello cat")
+
+        self.child.sendintr()
+        self.child.expect("Process .* stopped")
+        self.expect_prompt()
+
+        self.expect("bt", substrs=["input_copy_loop"])
+
+        self.child.sendline("continue")
+        self.child.expect("Process .* resuming")
+
+        self.child.sendline("Goodbye cat")
+        self.child.expect_exact("read: Goodbye cat")
+
+        self.child.sendeof()
+        self.child.expect("Process .* exited")
+        self.expect_prompt()
+
+        self.quit()
diff --git a/lldb/test/API/iohandler/sigint/cat.cpp b/lldb/test/API/iohandler/sigint/cat.cpp
new file mode 100644 (file)
index 0000000..5a3d938
--- /dev/null
@@ -0,0 +1,12 @@
+#include <iostream>
+
+void input_copy_loop() {
+  std::string str;
+  while (std::getline(std::cin, str))
+    std::cout << "read: " << str << std::endl;
+}
+
+int main() {
+  input_copy_loop();
+  return 0;
+}