Details
Description
When one thread locked environmentMutex and main thread fork() at the same time. Forked process will keep the environmentMutex locked state and request to release the environmentMutex. The program will deadlock, as follows:
root 19865 74.9 0.0 124884 10572 pts/1 Sl+ 06:57 23:24 ./ForkLockTest root 19869 0.0 0.0 0 0 ? Zs 06:57 0:00 [ForkLockTest] <defunct> root 19870 0.0 0.0 124884 928 ? S 06:57 0:00 ./ForkLockTest
Actually, this error is the "Fork-One Safety Problem". you can find more information here:
https://docs.oracle.com/cd/E19455-01/806-5257/gen-92888/index.html
Error flow:
1. A thread call qgetenv() or other functions that locked environmentMutex;
2. At the same time, the main thread call QProcess::startDetached();
3. Call fork() create child process and doublefork process;
4. The environmentMutex keep locked state in the doublefork process;
5. The doublefork process call QStandardPaths::findExecutable() get exeFilePath, call qgetenv() and try lock the environmentMutex;
6. But the environmentMutex has been locked, the doublefork process must wait for the environmentMutex unlock, which is a deadlock;
7. The main thread is waiting for the fork process info, but can never read the data.
The error is located here:
https://github.com/qt/qtbase/blob/29400a683f96867133b28299c0d0bd6bcf40df35/src/corelib/io/qprocess_unix.cpp#L991C15-L991C15
The forklocktest.zip is a simple example that reproduce the error. I verified it on version 5.11.3 and 5.15.10-lts-lgpl.