This revision was automatically updated to reflect the committed changes.
Closed by commit rG4bcadd66864b: [lldb/driver] Fix SIGTSTP handling (authored
by labath).
Changed prior to commit:
https://reviews.llvm.org/D120320?vs=412643&id=414078#toc
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D120320/new/
https://reviews.llvm.org/D120320
Files:
lldb/packages/Python/lldbsuite/test/lldbpexpect.py
lldb/test/API/driver/job_control/TestJobControl.py
lldb/test/API/driver/job_control/shell.py
lldb/tools/driver/Driver.cpp
Index: lldb/tools/driver/Driver.cpp
===================================================================
--- lldb/tools/driver/Driver.cpp
+++ lldb/tools/driver/Driver.cpp
@@ -671,23 +671,30 @@
_exit(signo);
}
-void sigtstp_handler(int signo) {
+#ifndef _WIN32
+static void sigtstp_handler(int signo) {
if (g_driver != nullptr)
g_driver->GetDebugger().SaveInputTerminalState();
+ // Unblock the signal and remove our handler.
+ sigset_t set;
+ sigemptyset(&set);
+ sigaddset(&set, signo);
+ pthread_sigmask(SIG_UNBLOCK, &set, nullptr);
signal(signo, SIG_DFL);
- kill(getpid(), signo);
+
+ // Now re-raise the signal. We will immediately suspend...
+ raise(signo);
+ // ... and resume after a SIGCONT.
+
+ // Now undo the modifications.
+ pthread_sigmask(SIG_BLOCK, &set, nullptr);
signal(signo, sigtstp_handler);
-}
-void sigcont_handler(int signo) {
if (g_driver != nullptr)
g_driver->GetDebugger().RestoreInputTerminalState();
-
- signal(signo, SIG_DFL);
- kill(getpid(), signo);
- signal(signo, sigcont_handler);
}
+#endif
static void printHelp(LLDBOptTable &table, llvm::StringRef tool_name) {
std::string usage_str = tool_name.str() + " [options]";
@@ -826,7 +833,6 @@
signal(SIGPIPE, SIG_IGN);
signal(SIGWINCH, sigwinch_handler);
signal(SIGTSTP, sigtstp_handler);
- signal(SIGCONT, sigcont_handler);
#endif
int exit_code = 0;
Index: lldb/test/API/driver/job_control/shell.py
===================================================================
--- /dev/null
+++ lldb/test/API/driver/job_control/shell.py
@@ -0,0 +1,34 @@
+"""
+Launch a process (given through argv) similar to how a shell would do it.
+"""
+
+import signal
+import subprocess
+import sys
+import os
+
+
+def preexec_fn():
+ # Block SIGTTOU generated by the tcsetpgrp call
+ orig_mask = signal.pthread_sigmask(signal.SIG_BLOCK, [signal.SIGTTOU])
+
+ # Put us in a new process group.
+ os.setpgid(0, 0)
+
+ # And put it in the foreground.
+ fd = os.open("/dev/tty", os.O_RDONLY)
+ os.tcsetpgrp(fd, os.getpgid(0))
+ os.close(fd)
+
+ signal.pthread_sigmask(signal.SIG_SETMASK, orig_mask)
+
+
+if __name__ == "__main__":
+ child = subprocess.Popen(sys.argv[1:], preexec_fn=preexec_fn)
+ print("PID=%d" % child.pid)
+
+ _, status = os.waitpid(child.pid, os.WUNTRACED)
+ print("STATUS=%d" % status)
+
+ returncode = child.wait()
+ print("RETURNCODE=%d" % returncode)
Index: lldb/test/API/driver/job_control/TestJobControl.py
===================================================================
--- /dev/null
+++ lldb/test/API/driver/job_control/TestJobControl.py
@@ -0,0 +1,32 @@
+"""
+Test lldb's handling of job control signals (SIGTSTP, SIGCONT).
+"""
+
+
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.lldbpexpect import PExpectTest
+
+
+class JobControlTest(PExpectTest):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test_job_control(self):
+ def post_spawn():
+ self.child.expect("PID=([0-9]+)")
+ self.lldb_pid = int(self.child.match[1])
+
+ run_under = [sys.executable, self.getSourcePath('shell.py')]
+ self.launch(run_under=run_under, post_spawn=post_spawn)
+
+ os.kill(self.lldb_pid, signal.SIGTSTP)
+ self.child.expect("STATUS=([0-9]+)")
+ status = int(self.child.match[1])
+
+ self.assertTrue(os.WIFSTOPPED(status))
+ self.assertEquals(os.WSTOPSIG(status), signal.SIGTSTP)
+
+ os.kill(self.lldb_pid, signal.SIGCONT)
+
+ self.child.sendline("quit")
+ self.child.expect("RETURNCODE=0")
Index: lldb/packages/Python/lldbsuite/test/lldbpexpect.py
===================================================================
--- lldb/packages/Python/lldbsuite/test/lldbpexpect.py
+++ lldb/packages/Python/lldbsuite/test/lldbpexpect.py
@@ -23,11 +23,15 @@
def expect_prompt(self):
self.child.expect_exact(self.PROMPT)
- def launch(self, executable=None, extra_args=None, timeout=60, dimensions=None):
+ def launch(self, executable=None, extra_args=None, timeout=60,
+ dimensions=None, run_under=None, post_spawn=None):
logfile = getattr(sys.stdout, 'buffer',
sys.stdout) if self.TraceOn() else None
- args = ['--no-lldbinit', '--no-use-colors']
+ args = []
+ if run_under is not None:
+ args += run_under
+ args += [lldbtest_config.lldbExec, '--no-lldbinit', '--no-use-colors']
for cmd in self.setUpCommands():
args += ['-O', cmd]
if executable is not None:
@@ -41,8 +45,11 @@
import pexpect
self.child = pexpect.spawn(
- lldbtest_config.lldbExec, args=args, logfile=logfile,
+ args[0], args=args[1:], logfile=logfile,
timeout=timeout, dimensions=dimensions, env=env)
+
+ if post_spawn is not None:
+ post_spawn()
self.expect_prompt()
for cmd in self.setUpCommands():
self.child.expect_exact(cmd)
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits