Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-10734

The child process created by QProcess::startDetached() inherits the parent process's file descriptors

    XMLWordPrintable

Details

    • Bug
    • Resolution: Invalid
    • P2: Important
    • None
    • 4.7.0, 5.1.0
    • Core: I/O
    • Unix

    Description

      Note: this bug is related to QTBUG-9350, but is not quite the same. (In particular, QTBUG-9350 is about QProcess::start(), and this bug is about QProcess::startDetached()).

      The bug is: Under MacOS/X (and I suspect under Linux as well, although I haven't tested there), the child process created by QProcess::startDetached() inherits all the file descriptors of the parent process. Since the child process is (usually) an unrelated executable with no knowledge of the parent process's file descriptors, the child process does not know to close its inherited copies of the file descriptors, and thus the parent's TCP connections (and open files, open devices, etc) are held open for as long as the child process is still running (i.e. potentially forever), even if the parent process closes them.

      This behavior is unexpected and leads to hard-to-diagnose problems (e.g. TCP connections between the parent process and any servers it is talking to mysteriously not going away, even though the parent process has properly closed the its socket file descriptors).

      I've attached a simple example program that demonstrates the problem by creating a socket-pair, launching a child process ("/bin/sleep 30") via QProcess::startDetached(), and then immediately closing one end of the socket-pair and seeing how long it takes for a QSocketNotifier for the other socket to signal that the TCP connection has been closed. To reproduce the problem:

      1) Compile and run the attached example program under MacOS/X
      2) Note that the window that appears says "Socket connection is still open..." for 30 seconds, then switches to "Socket connection closed!". The 30 second delay is the unexpected/incorrect behavior.
      3) Now comment out the call to startDetached() in the ProcessWindow ctor (line 16 of qprocess_problem.cpp) and compile/run the program again.
      4) Note that this time, the window switches to "Socket connection closed!" immediately on startup This is the correct/expected behavior, and this is what should happen even if there is a child process that was launched with startDetached().

      An easy way to fix this problem might be to put something like the following code in the child-process's part of QProcessPrivate::startDetached(), just before the second call to qt_fork():

               int fdlimit = sysconf(_SC_OPEN_MAX);
               for (int i=STDERR_FILENO+1; i<fdlimit; i++) close(i);
      

      That way all of the parent's file descriptors would be immediately closed inside the child process, and so they would not be inherited by the grandchild process and thus they would not be held open indefinitely.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            thiago Thiago Macieira
            jfriesne Jeremy Friesner
            Votes:
            28 Vote for this issue
            Watchers:
            15 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes