Index: include/lldb/Host/File.h =================================================================== --- include/lldb/Host/File.h +++ include/lldb/Host/File.h @@ -42,7 +42,8 @@ eOpenOptionNonBlocking = (1u << 4), // File reads eOpenOptionCanCreate = (1u << 5), // Create file if doesn't already exist eOpenOptionCanCreateNewOnly = (1u << 6), // Can create file only if it doesn't already exist - eOpenoptionDontFollowSymlinks = (1u << 7) + eOpenoptionDontFollowSymlinks = (1u << 7), + eOpenOptionCloseOnExec = (1u << 8) // Close the file when executing a new process }; static mode_t Index: source/Core/StreamFile.cpp =================================================================== --- source/Core/StreamFile.cpp +++ source/Core/StreamFile.cpp @@ -49,7 +49,8 @@ StreamFile::StreamFile (const char *path) : Stream (), - m_file (path, File::eOpenOptionWrite | File::eOpenOptionCanCreate, lldb::eFilePermissionsFileDefault) + m_file (path, File::eOpenOptionWrite | File::eOpenOptionCanCreate | File::eOpenOptionCloseOnExec, + lldb::eFilePermissionsFileDefault) { } Index: source/Host/common/File.cpp =================================================================== --- source/Host/common/File.cpp +++ source/Host/common/File.cpp @@ -288,6 +288,8 @@ #ifndef _WIN32 if (options & eOpenOptionNonBlocking) oflag |= O_NONBLOCK; + if (options & eOpenOptionCloseOnExec) + oflag |= O_CLOEXEC; #else oflag |= O_BINARY; #endif Index: test/functionalities/avoids-fd-leak/TestFdLeak.py =================================================================== --- test/functionalities/avoids-fd-leak/TestFdLeak.py +++ test/functionalities/avoids-fd-leak/TestFdLeak.py @@ -13,17 +13,29 @@ mydir = TestBase.compute_mydir(__file__) @expectedFailureWindows("The check for descriptor leakage needs to be implemented differently") - def test_fd_leak (self): + def test_fd_leak_basic (self): + self.do_test([]) + + @expectedFailureWindows("The check for descriptor leakage needs to be implemented differently") + def test_fd_leak_log (self): + self.do_test(["log enable -f '/dev/null' lldb commands"]) + + def do_test (self, commands): self.buildDefault() exe = os.path.join (os.getcwd(), "a.out") + for c in commands: + self.runCmd(c) + target = self.dbg.CreateTarget(exe) process = target.LaunchSimple (None, None, self.get_process_working_directory()) self.assertTrue(process, PROCESS_IS_VALID) - self.assertTrue(process.GetState() == lldb.eStateExited) - self.assertTrue(process.GetExitStatus() == 0) + self.assertTrue(process.GetState() == lldb.eStateExited, "Process should have exited.") + self.assertTrue(process.GetExitStatus() == 0, + "Process returned non-zero status. Were incorrect file descriptors passed?") + if __name__ == '__main__': import atexit