Skip to content

gh-159485: Fix warnings lock deadlock during interpreter shutdown - #159488

Open
ngoldbaum wants to merge 1 commit into
python:mainfrom
ngoldbaum:gh-158974-warnings-shutdown
Open

ngoldbaum wants to merge 1 commit into
python:mainfrom
ngoldbaum:gh-158974-warnings-shutdown

Conversation

@ngoldbaum

@ngoldbaum ngoldbaum commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Closes #159485

It looks like the 3.14 backport will need to happen manually but I think the same fix applies there as well if I adjust where the shutdown hook goes.

@ngoldbaum
ngoldbaum requested a review from nascheme October 15, 2026 20:53
@ngoldbaum ngoldbaum added the type-bug An unexpected behavior, bug, or error label Oct 15, 2026
@ngoldbaum ngoldbaum added the interpreter-core (Objects, Python, Grammar, and Parser dirs) label Oct 15, 2026
@ngoldbaum ngoldbaum added needs backport to 3.14 bugs and security fixes needs backport to 3.15 bugs and security fixes labels Oct 15, 2026

@ZeroIntensity ZeroIntensity left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An alternative (and simpler) approach would be to hold an interpreter guard while holding the warnings lock.

@ngoldbaum

Copy link
Copy Markdown
Contributor Author

I don’t see a way to do that without a larger refactor. warnings.warn() holds the warnings lock while calling user-defined showwarning(), and the issue’s reproducer blocks forever in that callback.

If the guard lasts as long as the lock, shutdown waits forever for the guard. Releasing the guard before the callback doesn’t help if the lock remains held: the callback never returns, so the daemon never releases the lock, and the finalizing thread later blocks on it.

Did you have a different guard placement in mind, or were you suggesting a refactor that releases the lock before calling user code?

@ZeroIntensity

Copy link
Copy Markdown
Member

I was thinking we could acquire a guard before acquiring the lock, and then release it after the lock is acquired. It's fine to call into Python code while a guard is held (and if it isn't, we need to fix that). A thread entering finalization must wait until all daemon threads have released their guards, ensuring that no one holds the lock.

FTR, this kind of issue is one of the reasons PyInterpreterGuard was created in the first place.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting core review interpreter-core (Objects, Python, Grammar, and Parser dirs) needs backport to 3.14 bugs and security fixes needs backport to 3.15 bugs and security fixes type-bug An unexpected behavior, bug, or error

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Interpreter shutdown can deadlock when a daemon thread holds the warnings lock

2 participants