[Lldb-commits] [lldb] r228130 - Avoid leakage of file descriptors in LLDB and LLGS
Pavel Labath
labath at google.com
Wed Feb 4 02:36:58 PST 2015
Author: labath
Date: Wed Feb 4 04:36:57 2015
New Revision: 228130
URL: http://llvm.org/viewvc/llvm-project?rev=228130&view=rev
Log:
Avoid leakage of file descriptors in LLDB and LLGS
Summary:
Both LLDB and LLGS are leaking file descriptors into the debugged process. This plugs the leak by
closing the unneeded descriptors. In one case I use O_CLOEXEC, which I hope is supported on
relevant platforms. I also added a regression test and plugged a fd leak in dosep.py.
Reviewers: vharron, clayborg
Subscribers: lldb-commits
Differential Revision: http://reviews.llvm.org/D7372
Added:
lldb/trunk/test/functionalities/avoids-fd-leak/
lldb/trunk/test/functionalities/avoids-fd-leak/Makefile
lldb/trunk/test/functionalities/avoids-fd-leak/TestFdLeak.py
lldb/trunk/test/functionalities/avoids-fd-leak/main.c
Modified:
lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp
lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp
lldb/trunk/source/Target/ProcessLaunchInfo.cpp
lldb/trunk/test/dosep.py
Modified: lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp?rev=228130&r1=228129&r2=228130&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp Wed Feb 4 04:36:57 2015
@@ -1545,6 +1545,11 @@ NativeProcessLinux::Launch(LaunchArgs *a
if (args->m_error.Fail())
exit(ePtraceFailed);
+ // terminal has already dupped the tty descriptors to stdin/out/err.
+ // This closes original fd from which they were copied (and avoids
+ // leaking descriptors to the debugged process.
+ terminal.CloseSlaveFileDescriptor();
+
// Do not inherit setgid powers.
if (setgid(getgid()) != 0)
exit(eSetGidFailed);
@@ -3532,7 +3537,10 @@ NativeProcessLinux::DupDescriptor(const
if (target_fd == -1)
return false;
- return (dup2(target_fd, fd) == -1) ? false : true;
+ if (dup2(target_fd, fd) == -1)
+ return false;
+
+ return (close(target_fd) == -1) ? false : true;
}
void
Modified: lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp?rev=228130&r1=228129&r2=228130&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp Wed Feb 4 04:36:57 2015
@@ -1356,6 +1356,11 @@ ProcessMonitor::Launch(LaunchArgs *args)
if (PTRACE(PTRACE_TRACEME, 0, NULL, NULL, 0) < 0)
exit(ePtraceFailed);
+ // terminal has already dupped the tty descriptors to stdin/out/err.
+ // This closes original fd from which they were copied (and avoids
+ // leaking descriptors to the debugged process.
+ terminal.CloseSlaveFileDescriptor();
+
// Do not inherit setgid powers.
if (setgid(getgid()) != 0)
exit(eSetGidFailed);
@@ -2319,7 +2324,10 @@ ProcessMonitor::DupDescriptor(const char
if (target_fd == -1)
return false;
- return (dup2(target_fd, fd) == -1) ? false : true;
+ if (dup2(target_fd, fd) == -1)
+ return false;
+
+ return (close(target_fd) == -1) ? false : true;
}
void
Modified: lldb/trunk/source/Target/ProcessLaunchInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ProcessLaunchInfo.cpp?rev=228130&r1=228129&r2=228130&view=diff
==============================================================================
--- lldb/trunk/source/Target/ProcessLaunchInfo.cpp (original)
+++ lldb/trunk/source/Target/ProcessLaunchInfo.cpp Wed Feb 4 04:36:57 2015
@@ -344,7 +344,7 @@ ProcessLaunchInfo::FinalizeFileActions (
log->Printf ("ProcessLaunchInfo::%s default_to_use_pty is set, and at least one stdin/stderr/stdout is unset, so generating a pty to use for it",
__FUNCTION__);
- if (m_pty->OpenFirstAvailableMaster(O_RDWR| O_NOCTTY, NULL, 0))
+ if (m_pty->OpenFirstAvailableMaster(O_RDWR | O_NOCTTY | O_CLOEXEC, NULL, 0))
{
const char *slave_path = m_pty->GetSlaveName(NULL, 0);
Modified: lldb/trunk/test/dosep.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dosep.py?rev=228130&r1=228129&r2=228130&view=diff
==============================================================================
--- lldb/trunk/test/dosep.py (original)
+++ lldb/trunk/test/dosep.py Wed Feb 4 04:36:57 2015
@@ -57,8 +57,8 @@ def call_with_timeout(command, timeout):
"""Run command with a timeout if possible."""
if timeout_command and timeout != "0":
return subprocess.call([timeout_command, timeout] + command,
- stdin=subprocess.PIPE)
- return (ePassed if subprocess.call(command, stdin=subprocess.PIPE) == 0
+ stdin=subprocess.PIPE, close_fds=True)
+ return (ePassed if subprocess.call(command, stdin=subprocess.PIPE, close_fds=True) == 0
else eFailed)
def process_dir(root, files, test_root, dotest_options):
Added: lldb/trunk/test/functionalities/avoids-fd-leak/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/avoids-fd-leak/Makefile?rev=228130&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/avoids-fd-leak/Makefile (added)
+++ lldb/trunk/test/functionalities/avoids-fd-leak/Makefile Wed Feb 4 04:36:57 2015
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
Added: lldb/trunk/test/functionalities/avoids-fd-leak/TestFdLeak.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/avoids-fd-leak/TestFdLeak.py?rev=228130&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/avoids-fd-leak/TestFdLeak.py (added)
+++ lldb/trunk/test/functionalities/avoids-fd-leak/TestFdLeak.py Wed Feb 4 04:36:57 2015
@@ -0,0 +1,32 @@
+"""
+Test whether a process started by lldb has no extra file descriptors open.
+"""
+
+import os
+import unittest2
+import lldb
+from lldbtest import *
+import lldbutil
+
+class AvoidsFdLeakTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureWindows("The check for descriptor leakage needs to be implemented differently")
+ def test_fd_leak (self):
+ self.buildDefault()
+ exe = os.path.join (os.getcwd(), "a.out")
+
+ 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)
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Added: lldb/trunk/test/functionalities/avoids-fd-leak/main.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/avoids-fd-leak/main.c?rev=228130&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/avoids-fd-leak/main.c (added)
+++ lldb/trunk/test/functionalities/avoids-fd-leak/main.c Wed Feb 4 04:36:57 2015
@@ -0,0 +1,28 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+
+int
+main (int argc, char const **argv)
+{
+ struct stat buf;
+ int i;
+
+ // Make sure stdin/stdout/stderr exist.
+ for (i = 0; i <= 2; ++i) {
+ if (fstat(i, &buf) != 0)
+ return 1;
+ }
+
+ // Make sure no other file descriptors are open.
+ for (i = 3; i <= 256; ++i) {
+ if (fstat(i, &buf) == 0 || errno != EBADF) {
+ fprintf(stderr, "File descriptor %d is open.\n", i);
+ return 2;
+ }
+ }
+
+ return 0;
+}
More information about the lldb-commits
mailing list