QProcess stuck in Starting state until waitForStarted returns from timeout
-
Hello!
Recently I am troubleshooting sddm, a Linux desktop manager. When I login via sddm, there's a high chance that there will be a 30 sec black screen before KDE starts loading. 60 seconds later another black screen would occur, and this one is unrecoverable.
After trying to read the code of sddm and add some debug messages to it, I found that when sddm tries to start the user session, sddm would start a helper via
QProcess
. After callingQProcess::start
, sddm would callwaitForStarted()
to confirm whether the helper started successfully or not.Normally the
QProcess
should finish starting and transit intoRunning
state soon, but under in our case it's stuck inStarting
state, untilwaitForStarted
returns because of timeout. Immediately after the return,QProcess
finally transit intoRunning
state, and the helper starts running.I have tried to modify the timeout length, and by doing that I can see if the
QProcess
stucks inStarting
state, it would only starts running only and immediately afterwaitForStarted
returns. That is, if the timeout is 30 sec, it starts 30 sec after theQProcess::start
call. If the timeout is 25 sec, it starts 25 sec after the call.Note that this problem doesn't always happen, but it has a high chance to happen. Also, this problem only happens to the sddm and the helper, I haven't seen other programs which utilizes
QProcess
suffer from similar issues. Nor have I seen other parts of sddm suffer from similar issues.Original GitHub issue: https://github.com/sddm/sddm/issues/1929
I'm willing to devote my spare time to troubleshoot it, e.g. running tests, modifying source code, read materials e.t.c..
Help is appreciated.Environment:
Arch Linux
KDE Plasma 6
Qt 6.7.0
sddm 0.21.0 -
I do not claim to understand what you are saying here or in your detailed github thread. But to test can you do whatever to alter the code so as not to call
waitForStarted()
? Just act onstarted()
signal. If you cannot figure how to change code so as not to block, try with your ownQEventLoop::exec()
. It removes the behaviour ofwaitForStarted()
from the equation.I started look at the source of the (Linux)
QProcess
to see if I could understand how it implements e.g. thestarted
/stateChanged
signals. I didn't pursue very far. It's something to do with "child pipes" an notifications, but I didn't get as far as figuring what they are checking for and how.Note that if this some sddm issue, like the complicated discussions you were having on the github thread, then that is a different matter.
-
@JonB
I tried to useQEventLoop
as you told me to avoid thewaitForStarted()
call, what I do isconnect
theQProcess::started()
signal and theQEventLoop::quit
function, and callloop.exec()
to wait for the signal.
Now it's going funny: theQProcess
is now just stuck in theStarting
state forever, and the sddm helper isn't started neither.As for it's whether sddm's issue or Qt's issue, I'm not sure about it. On one hand this issue never happens outside sddm (at least it's what I see), on the other hand it seems to be related to Qt's low-level code, as how could
QProcess
just stuck like that? -
@FishBoneEK
We could do with someone who has the Qt Linux code telling us whatwaitForStarted()
actually does/how it defines/detects "started". Like I said, I didn't follow it down on woboq. Then we might have a clue whether/what sddm might do which could apparently cause your "stuck" behaviour. -
@JonB said in QProcess stuck in Starting state until waitForStarted returns from timeout:
We could do with someone who has the Qt Linux code telling us what waitForStarted() actually does/how it defines/detects "started".
Alright, hope this "someone" will see this forum thread and give us clues.
By the way, I made a new comment in the GitHub issue, about something I have found.
To summarize, I thought it's the return ofwaitForStarted
that let theQProcess
start in the end, but this could be something sddm does in the later code logic.Sorry for the mess. I thought this might be more Qt related, so I submitted this forum post, but this might be more sddm related than I originally thought.
-
@FishBoneEK
Since (so far) we are not getting an answer. Why do you need to callwaitForStarted()
at all? It's an "unusual" one. And (not that understand how/why) you talk about "when the wait for started times out only then does it proceed, and proceeds OK"? What happens if you (a) reduce the timeout right down or (b) just comment it out? -
@JonB
Wow what a fast reply, sorry I thought you wouldn't have replied so fast so I edited the new GitHub comment just now because of some new findings.TL;DR
The parent process, which starts the child helper to start Xorg and KDE session,
exit
s almost immediately after the timeout. It's theexit
caused the child helper to unstuck and start, not the return ofwaitForStarted
. I have been mistaken.And (not that understand how/why) you talk about "when the wait for started times out only then does it proceed, and proceeds OK"?
Sorry for the frustration.
Normally, the parent process starts a child helper viaQProcess
, and wait for it viawaitForStarted()
. The child helper should start immediately (why not), thenwaitForStarted()
returns true, next the parent process continues on its work. ThewaitForStarted()
is sddm's decision, it's not added by me.AND now, there's a high chance that:
The child helper won't start, like the binary won't execute, andQProcess
'sstate
will beStarting
instead ofRunning
. ThewaitForStarted()
will timeout and return false. Then the parent processexit
s, next the child helper starts executing.I have tried to reduce the timeout from 30 sec to 25 sec, the child helper will start right after that. Though now according to my findings, the child helper will start at the moment the parent process
exit
s.
I will try comment it out later.So perhaps it's related to some pipe stuff? Since
exit
ing should close the pair of pipe the parent process and the child helper are sharing. -
So ehhh, if I comment it out, the helper will start, the systemd user session will start too, as I can see user slices and services starting in the journal. But KDE won't start, so the screen will keep being black. Also there seems to be some weird behavior of sddm.
I don't want to investigate this, as it seems not helping.