| """ | |
| Test that if you exec lldb with the stdio file handles | |
| closed, it is able to exit without hanging. | |
| """ | |
| import lldb | |
| import os | |
| import sys | |
| import socket | |
| if os.name != "nt": | |
| import fcntl | |
| import lldbsuite.test.lldbutil as lldbutil | |
| from lldbsuite.test.lldbtest import * | |
| from lldbsuite.test.decorators import * | |
| class TestDriverWithClosedSTDIO(TestBase): | |
| # If your test case doesn't stress debug info, then | |
| # set this to true. That way it won't be run once for | |
| # each debug info format. | |
| NO_DEBUG_INFO_TESTCASE = True | |
| # Windows doesn't have the fcntl module, so we can't run this | |
| # test there. | |
| @skipIf(hostoslist=["windows"]) | |
| def test_run_lldb_and_wait(self): | |
| """This test forks, closes the stdio channels and exec's lldb. | |
| Then it waits for it to exit and asserts it did that successfully""" | |
| pid = os.fork() | |
| if pid == 0: | |
| fcntl.fcntl(sys.stdin, fcntl.F_SETFD, fcntl.FD_CLOEXEC) | |
| fcntl.fcntl(sys.stdout, fcntl.F_SETFD, fcntl.FD_CLOEXEC) | |
| fcntl.fcntl(sys.stderr, fcntl.F_SETFD, fcntl.FD_CLOEXEC) | |
| lldb = lldbtest_config.lldbExec | |
| print(f"About to run: {lldb}") | |
| os.execlp( | |
| lldb, | |
| lldb, | |
| "-x", | |
| "-o", | |
| "script print(lldb.debugger.GetNumTargets())", | |
| "--batch", | |
| ) | |
| else: | |
| if pid == -1: | |
| print("Couldn't fork a process.") | |
| return | |
| ret_pid, status = os.waitpid(pid, 0) | |
| # We're really just checking that lldb doesn't stall. | |
| # At the time this test was written, if you close stdin | |
| # in an asserts build, lldb aborts. So handle both | |
| # of those cases. The failure will just be that the | |
| # waitpid doesn't return, and the test times out. | |
| self.assertFalse(os.WIFSTOPPED(status), "We either exited or crashed.") |