| """ |
| 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.") |