classification
Title: Spurious warning emitted during fork() can deadlock a multi-threaded process
Type: behavior Stage:
Components: Library (Lib) Versions: Python 3.7
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: bowiechen, ionelmc, rojer, vstinner
Priority: normal Keywords:

Created on 2020-04-29 20:46 by rojer, last changed 2020-04-30 17:30 by bowiechen.

Messages (1)
msg367701 - (view) Author: Deomid Ryabkov (rojer) Date: 2020-04-29 20:46
I know, I know - forking a multi-threaded process is bad. But it happens.

This is related  to https://bugs.python.org/issue40399 and https://bugs.python.org/issue6721 but is distinct because the problem is entirely self-inflicted.

What happens:

1) A multithreaded program forks using one of the functions, such as os.forkpty()
2) In the child process the Python interpreter, in its PyOS_AfterFork_Child function ([1]) tries to kill all the threads other than the one doing the forking.
3) Among the objects being destroyed may include file or socket objects that are now being destroyed too, without having been previosuly closed, which triggers a ResourceWarning in the finalizer [2], [3].
4) Default action for warnings is to write to sys.stderr
5) A mutex used in BufferedIO is held by some other (now deceased thread).
6) Deadlock in _enter_buffered_busy [4].

This is bad because there is absolutely no way to avoid it without disabling warnings.
Even if the program is super careful to not do anything after forking other than exec, it doesn't help because the resource warning and the resulting deadlock is triggered by activity of the interpreter: it is the interpreter that orphans and is forcibly destroying the files and sockets, not the program that lost track of them.

[1] https://github.com/python/cpython/blob/beba1a808000d5fc445cb28eab96bdb4cdb7c959/Modules/posixmodule.c#L451

[2] https://github.com/python/cpython/blob/beba1a808000d5fc445cb28eab96bdb4cdb7c959/Modules/_io/fileio.c#L95

[3] https://github.com/python/cpython/blob/beba1a808000d5fc445cb28eab96bdb4cdb7c959/Modules/socketmodule.c#L4800

[4] https://github.com/python/cpython/blob/beba1a808000d5fc445cb28eab96bdb4cdb7c959/Modules/_io/bufferedio.c#L282
History
Date User Action Args
2020-04-30 17:30:13bowiechensetnosy: + bowiechen
2020-04-30 07:18:52ionelmcsetnosy: + ionelmc
2020-04-29 21:47:01vstinnersetnosy: + vstinner
2020-04-29 20:46:27rojersettype: behavior
2020-04-29 20:46:13rojercreate