GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-87474: Fix file descriptor leaks in subprocess.Popen by cptpcrd · Pull Request #96351 · python/cpython

Conversation

@cptpcrd

@cptpcrd cptpcrd commented Aug 28, 2022 •
edited by gpshead
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

Rationale in #87474. Didn't PR until now because there were no further comments on that issue, and the immediate problem I was seeing was resolved.

Fixes #87474.

  • Issue: subprocess.Popen leaks file descriptors opened for DEVNULL or PIPE stdin/stdout/stderr arguments #87474

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@cptpcrd
cptpcrd requested a review from gpshead as a code owner August 28, 2022 01:48
@bedevere-bot bedevere-bot added the awaiting review label Aug 28, 2022
@gpshead

gpshead commented Oct 1, 2022 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

Rather than logic that individually keeps track of which things need closing and duplicates decision logic as to which were opened within the exception handler, a cleaner less difficult to mess up tactic could be to use a fd closing context manager that allows registration of fds, and closes them all when the context manager __exit__ is called with an exception rather than a clean exit.

A method something like this perhaps?

@contextlib.contextmanager
def _on_error_fd_closer(self):
    to_close = []
    try:
        yield o_close
    except:
        if hasattr(self, '_devnull):
            fds_to_close.append(self._devnull)
            del self._devnull
        for fd in set(to_close):
            if windows_handle_close := getattr(fd, 'Close'):
                windows_handle_close()
            else:
                os.close(fd)   # wrap this in its own try: ... except: pass for good measure?
        raise
with self._on_error_fd_closer() as fds:
    x, y = os.pipe()
    fds.extend((x, y))
    ...
    # stuff happens
    ...

If an exception occurs, the file descriptors registered by adding them to the context's list of things to cleanup will be closed.

This way it becomes an RAII pattern, the code maintenance mistake that could be made is forgetting to add a fd or handle to the list of things to close. Which should be much more obvious in the code as that would usually happen immediately after its creation instead of duplicate logic in an error handler not within visual range.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@gpshead gpshead self-assigned this Oct 1, 2022
@gpshead gpshead added awaiting changes needs backport to 3.10 needs backport to 3.11 only security fixes and removed awaiting review labels Oct 1, 2022
@cptpcrd

cptpcrd commented Oct 2, 2022

Copy link
Copy Markdown
Contributor Author

@gpshead That's definitely much cleaner. I've incorporated a slightly modified version of that context manager (written to more closely mirror the cleanup code at the end of __init__).

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@AlexWaygood AlexWaygood added awaiting change review and removed awaiting changes labels Oct 2, 2022
akulakov
akulakov reviewed Oct 7, 2022
View reviewed changes
Comment thread Lib/subprocess.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

@cptpcrd

cptpcrd commented Oct 14, 2022

Copy link
Copy Markdown
Contributor Author

@gpshead any other changes you wanted to see/make to this PR before merging?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@cptpcrd

cptpcrd commented Nov 13, 2022

Copy link
Copy Markdown
Contributor Author

@gpshead pinging again, I don't want this to fall through the cracks.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@cptpcrd
cptpcrd force-pushed the subprocess-fd-leak branch from 4345a1a to 1f88111 Compare March 12, 2023 19:12
@bedevere-bot bedevere-bot mentioned this pull request Mar 12, 2023
subprocess.Popen leaks file descriptors opened for DEVNULL or PIPE stdin/stdout/stderr arguments #87474
Closed
cptpcrd and others added 3 commits March 12, 2023 15:14
@cptpcrd
Fix file descriptor leaks in subprocess.Popen
6270ccd
@cptpcrd @gpshead
Refactor to use context manager
783e6f8
Simplifies the logic and should help avoid mistakes in the future.

Co-authored-by: Gregory P. Smith <[email protected]>
@gpshead @cptpcrd
Move err_close_fds adds next to pipe creation.
0d4efba
@cptpcrd
cptpcrd force-pushed the subprocess-fd-leak branch from 1f88111 to 0d4efba Compare March 12, 2023 19:14
@cptpcrd

cptpcrd commented Mar 12, 2023

Copy link
Copy Markdown
Contributor Author

@gpshead it's been a while and I think I've addressed all your concerns; any way to get this merged soon?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@hugovk hugovk removed the needs backport to 3.10 label Apr 7, 2023
gpshead added 2 commits May 16, 2023 12:51
@gpshead
add ReST formatting to NEWS.
0265ce7
@gpshead
Merge branch 'main' into subprocess-fd-leak
1b7b0f4
gpshead
gpshead approved these changes May 16, 2023
View reviewed changes
@bedevere-bot bedevere-bot added awaiting merge and removed awaiting change review labels May 16, 2023
@gpshead
gpshead enabled auto-merge (squash) May 16, 2023 19:55
@gpshead
gpshead merged commit 3a4c44b into python:main May 16, 2023
@miss-islington

miss-islington commented May 16, 2023

Copy link
Copy Markdown
Contributor

Thanks @cptpcrd for the PR, and @gpshead for merging it 🌮🎉.. I'm working now to backport this PR to: 3.11.
🐍🍒⛏🤖

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-bot bedevere-bot removed the awaiting merge label May 16, 2023
@bedevere-bot

bedevere-bot commented May 16, 2023

Copy link
Copy Markdown

GH-104563 is a backport of this pull request to the 3.11 branch.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-bot bedevere-bot removed the needs backport to 3.11 only security fixes label May 16, 2023
miss-islington pushed a commit to miss-islington/cpython that referenced this pull request May 16, 2023
@cptpcrd @gpshead @miss-islington
pythongh-87474: Fix file descriptor leaks in subprocess.Popen (python…
96ca688
…GH-96351)

This fixes several ways file descriptors could be leaked from `subprocess.Popen` constructor during error conditions by opening them later and using a context manager "fds to close" registration scheme to ensure they get closed before returning.

---------

(cherry picked from commit 3a4c44b)

Co-authored-by: cptpcrd <[email protected]>
Co-authored-by: Gregory P. Smith [Google] <[email protected]>
gpshead added a commit that referenced this pull request May 17, 2023
@miss-islington @cptpcrd @gpshead
[3.11] gh-87474: Fix file descriptor leaks in subprocess.Popen (GH-96351
3ce7d57
) (#104563)

gh-87474: Fix file descriptor leaks in subprocess.Popen (GH-96351)

This fixes several ways file descriptors could be leaked from `subprocess.Popen` constructor during error conditions by opening them later and using a context manager "fds to close" registration scheme to ensure they get closed before returning.

---------

(cherry picked from commit 3a4c44b)

Co-authored-by: cptpcrd <[email protected]>
Co-authored-by: Gregory P. Smith [Google] <[email protected]>
carljm added a commit to carljm/cpython that referenced this pull request May 17, 2023
@carljm
Merge branch 'main' into 709funconly
b1bb3a7
* main: (26 commits)
  pythonGH-101520: Move tracemalloc functionality into core, leaving interface in Modules. (python#104508)
  typing: Add more tests for TypeVar (python#104571)
  pythongh-104572: Improve error messages for invalid constructs in PEP 695 contexts (python#104573)
  typing: Use PEP 695 syntax in typing.py (python#104553)
  pythongh-102153: Start stripping C0 control and space chars in `urlsplit` (python#102508)
  pythongh-104469: Update README.txt for _testcapi (pythongh-104529)
  pythonGH-103092: isolate `_elementtree` (python#104561)
  pythongh-104050: Add typing to Argument Clinic converters (python#104547)
  pythonGH-103906: Remove immortal refcounting in the interpreter (pythonGH-103909)
  pythongh-87474: Fix file descriptor leaks in subprocess.Popen (python#96351)
  pythonGH-103092: isolate `pyexpat`  (python#104506)
  pythongh-75367: Fix data descriptor detection in inspect.getattr_static (python#104517)
  pythongh-104050: Add more annotations to `Tools/clinic.py` (python#104544)
  pythongh-104555: Fix isinstance() and issubclass() for runtime-checkable protocols that use PEP 695 (python#104556)
  pythongh-103865: add monitoring support to LOAD_SUPER_ATTR (python#103866)
  CODEOWNERS: Assign new PEP 695 files to myself (python#104551)
  pythonGH-104510: Fix refleaks in `_io` base types (python#104516)
  pythongh-104539: Fix indentation error in logging.config.rst (python#104545)
  pythongh-104050: Don't star-import 'types' in Argument Clinic (python#104543)
  pythongh-104050: Add basic typing to CConverter in clinic.py (python#104538)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@akulakov akulakov akulakov left review comments
@gpshead gpshead gpshead approved these changes

Uh oh!

There was an error while loading. Please reload this page.

Assignees

@gpshead gpshead

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

subprocess.Popen leaks file descriptors opened for DEVNULL or PIPE stdin/stdout/stderr arguments

Uh oh!

There was an error while loading. Please reload this page.

7 participants

@cptpcrd @gpshead @miss-islington @bedevere-bot @akulakov @hugovk @AlexWaygood
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.