Qt application unable to catch sudo reboot / sudo poweroff from terminal
-
wrote on 13 Nov 2017, 08:47 last edited by
Hello,
I have an Qt (5.8) application running in Ubuntu 14.04. As part of my application I have portion of code which should take care of shutting down gracefully when system is power down or rebooted.
I have implemented code to catch signals like SIGTERM, SIGQUIT, SIGINT and then perform a graceful shutdown.
My implementation works as expected when i simulate poweroff / reboot through terminal by executing kill -15 pid. ( pid of my application) However my implementation doesn't work as expected when I execute sudo reboot / sudo poweroff in a terminal, though internally SIGTERM signal is getting emitted. Have checked this in syslog.
I have also modified my application based on the direction given in http://doc.qt.io/qt-4.8/unix-signals.html yet my application doesn't hit my signal handler when sudo poweroff / sudo reboot is executed through terminal. But when I execute kill -15 pid ( pid of my application ) signal handler gets executed.
It would be great is someone could direct me as to what I am missing here ? or some direction as to what I should be doing to gracefully close my application when sudo reboot/ sudo poweroff is executed in the terminal
Thanks for your time.
-
Hello,
I have an Qt (5.8) application running in Ubuntu 14.04. As part of my application I have portion of code which should take care of shutting down gracefully when system is power down or rebooted.
I have implemented code to catch signals like SIGTERM, SIGQUIT, SIGINT and then perform a graceful shutdown.
My implementation works as expected when i simulate poweroff / reboot through terminal by executing kill -15 pid. ( pid of my application) However my implementation doesn't work as expected when I execute sudo reboot / sudo poweroff in a terminal, though internally SIGTERM signal is getting emitted. Have checked this in syslog.
I have also modified my application based on the direction given in http://doc.qt.io/qt-4.8/unix-signals.html yet my application doesn't hit my signal handler when sudo poweroff / sudo reboot is executed through terminal. But when I execute kill -15 pid ( pid of my application ) signal handler gets executed.
It would be great is someone could direct me as to what I am missing here ? or some direction as to what I should be doing to gracefully close my application when sudo reboot/ sudo poweroff is executed in the terminal
Thanks for your time.
wrote on 13 Nov 2017, 09:26 last edited by JonB@NarutoKun
What happens if you gosudo kill -15 <pid>
?- If you cannot catch that, there must be something different about doing it as
sudo
(which actually I doubt). - If you can catch that, then there is more to
reboot
/poweroff
than just a SIGTERM.
Also, how precisely do you judge that "my implementation doesn't work as expected when I execute sudo reboot / sudo poweroff"? I understand that you say syslog shows SIGTERM delivered, but since I presume you cannot debug your program during shutdown it must be difficult to be sure what it's up to if the signal is received. Perhaps something very simple like "create a filename [not in
/tmp
! :) ] on very first action in signal received" would be a good idea to verify for sure that you get the signal? - If you cannot catch that, there must be something different about doing it as
-
@NarutoKun
What happens if you gosudo kill -15 <pid>
?- If you cannot catch that, there must be something different about doing it as
sudo
(which actually I doubt). - If you can catch that, then there is more to
reboot
/poweroff
than just a SIGTERM.
Also, how precisely do you judge that "my implementation doesn't work as expected when I execute sudo reboot / sudo poweroff"? I understand that you say syslog shows SIGTERM delivered, but since I presume you cannot debug your program during shutdown it must be difficult to be sure what it's up to if the signal is received. Perhaps something very simple like "create a filename [not in
/tmp
! :) ] on very first action in signal received" would be a good idea to verify for sure that you get the signal?wrote on 13 Nov 2017, 10:12 last edited byHI,
@JNBarchan
application is able to catch sudo kill -15 pid, to confirm the reception of signal I am writing to syslog directly as LOG_ALERT and also to a file. ( just writing short phrases in both instances ) - If you cannot catch that, there must be something different about doing it as
-
HI,
@JNBarchan
application is able to catch sudo kill -15 pid, to confirm the reception of signal I am writing to syslog directly as LOG_ALERT and also to a file. ( just writing short phrases in both instances )wrote on 13 Nov 2017, 10:26 last edited by@NarutoKun
So then the conclusion must be it's not to do withsudo
, it's to do with what actually happens duringpoweroff
/reboot
, which you need to discover.... -
wrote on 15 Nov 2017, 15:57 last edited by
@NarutoKun jsut in case, have you already taken a look at this: Turn Unix signals into Qt signals?
Here there's also another approach, which code seems more low-level but has a good explanation about signals.
Happy signal catching!
-
@NarutoKun jsut in case, have you already taken a look at this: Turn Unix signals into Qt signals?
Here there's also another approach, which code seems more low-level but has a good explanation about signals.
Happy signal catching!
wrote on 15 Nov 2017, 17:08 last edited by@Pablo-J.-Rogina
I think the problem is that the OP already knows how to do this --- e.g. he can catch SIGTERM --- the problem is that it "doesn't work" (or something else is going on) whenreboot
/poweroff
. -
wrote on 15 Nov 2017, 17:13 last edited by
@JNBarchan I suggested trying with a different implementation as his code might have some subtle issue and he could move along.
-
Hi,
shutdown send first the SIGTERM signal and, after a given time, SIGKILL thus is you tell your system to
shutdown now
, you'll likely going to get both SIGTERM and SIGKILL one after the other pretty fast hence, your application terminates. -
Hi,
shutdown send first the SIGTERM signal and, after a given time, SIGKILL thus is you tell your system to
shutdown now
, you'll likely going to get both SIGTERM and SIGKILL one after the other pretty fast hence, your application terminates.wrote on 16 Nov 2017, 17:26 last edited by@SGaist I believe that may be the case here.
Currently I have the following theories for it not working- Have implemented a wrong logic -- ( But I did try couple of implementations even the one @Pablo-J-Rogina mentioned. Thanks @Pablo-J-Rogina for your suggestion ). Also would like to point out that I am able to catch all ctrl c, ctrl z, kill -15 pid etc
- It could be something to do with Qt or the version of Qt I am using.
- May be my application goes to halt state as soon as sudo reboot / sudo poweroff is executed. Thus leading it not to catch the signals.
- When sudo reboot / sudo poweroff is executed my Qt application is not notified with the signal. I am guessing this because when I execute kill -15 pid it works as the signal is directed to my application by mentioning the pid.
So I would like to know if someone in the forum has tested their signal handler code with sudo reboot / sudo poweroff ? Meanwhile I shall keep trying to get through this or atleast try to learn why I am unable to catch the signal.
-
@SGaist I believe that may be the case here.
Currently I have the following theories for it not working- Have implemented a wrong logic -- ( But I did try couple of implementations even the one @Pablo-J-Rogina mentioned. Thanks @Pablo-J-Rogina for your suggestion ). Also would like to point out that I am able to catch all ctrl c, ctrl z, kill -15 pid etc
- It could be something to do with Qt or the version of Qt I am using.
- May be my application goes to halt state as soon as sudo reboot / sudo poweroff is executed. Thus leading it not to catch the signals.
- When sudo reboot / sudo poweroff is executed my Qt application is not notified with the signal. I am guessing this because when I execute kill -15 pid it works as the signal is directed to my application by mentioning the pid.
So I would like to know if someone in the forum has tested their signal handler code with sudo reboot / sudo poweroff ? Meanwhile I shall keep trying to get through this or atleast try to learn why I am unable to catch the signal.
wrote on 16 Nov 2017, 18:32 last edited by JonB@NarutoKun
Assuming you know how to do this, if it were me I'd write a small non-Qt C/C++ program (e.g. I'm thinking justsleep()
and do your signal handling), verify you can catch your SIGTERM like now, and then see how it behaves under shutdown. You need to know how/whether it works completely outside of Qt first. It may be this is purely a Linux (or code) issue, nothing to do with Qt. -
@NarutoKun
Assuming you know how to do this, if it were me I'd write a small non-Qt C/C++ program (e.g. I'm thinking justsleep()
and do your signal handling), verify you can catch your SIGTERM like now, and then see how it behaves under shutdown. You need to know how/whether it works completely outside of Qt first. It may be this is purely a Linux (or code) issue, nothing to do with Qt.wrote on 16 Nov 2017, 18:48 last edited by@JNBarchan
Good thought.. May be I shall give it a try. Non Qt code to handle Signals.
Thanks
-
@JNBarchan
Good thought.. May be I shall give it a try. Non Qt code to handle Signals.
Thanks
How do you judge that you haven't received/handled the SIGTERM at shutdown?
-
wrote on 17 Nov 2017, 07:59 last edited by JonB
@kshegunov
I already asked him this question above:Also, how precisely do you judge that "my implementation doesn't work as expected when I execute sudo reboot / sudo poweroff"?
He replied:
@JNBarchan
application is able to catch sudo kill -15 pid, to confirm the reception of signal I am writing to syslog directly as LOG_ALERT and also to a file. ( just writing short phrases in both instances )I take him at his word, that he sees these from
kill
but not fromshutdown
...! -
There seems to be an assumption that when calling
sudo shutdown
orsudo reboot
the system will let the time to all application do stop properly at their own pace. That's wrong. Like explained in the command documentation, theSIGTERM
andSIGKILL
signals are sent one after the other with a possible period between the two if provided. Since this period is not provided in this case and the default value is unspecified, the processes are likely going to get killed "en masse" pretty quickly to allow the system to shutdown/reboot. -
There seems to be an assumption that when calling
sudo shutdown
orsudo reboot
the system will let the time to all application do stop properly at their own pace. That's wrong. Like explained in the command documentation, theSIGTERM
andSIGKILL
signals are sent one after the other with a possible period between the two if provided. Since this period is not provided in this case and the default value is unspecified, the processes are likely going to get killed "en masse" pretty quickly to allow the system to shutdown/reboot.wrote on 17 Nov 2017, 09:13 last edited by@SGaist
I wondered about this too. One presumes processes would receive SIGTERM at least a touch before SIGKILL, and I advised the OP to put it something very quick & simple for SIGTERM handler. I believe he claims that syslog shows the SIGTERM signal being delivered to the process viakill -15
but not during shutdown (but not sure). In any case, that is why I advised him that he needs to discover the shutdown actual behaviour, preferably outside of Qt. He should also read around general Linux stuff to discover how you are supposed to gracefully handle shutdown, as again I assume (based on nothing) that it allows programs a quick "grace period" to clean up & exit. -
@kshegunov
I already asked him this question above:Also, how precisely do you judge that "my implementation doesn't work as expected when I execute sudo reboot / sudo poweroff"?
He replied:
@JNBarchan
application is able to catch sudo kill -15 pid, to confirm the reception of signal I am writing to syslog directly as LOG_ALERT and also to a file. ( just writing short phrases in both instances )I take him at his word, that he sees these from
kill
but not fromshutdown
...!@JNBarchan said in Qt application unable to catch sudo reboot / sudo poweroff from terminal:
I already asked him this question above
Missed that, sorry. Your suggestion is good, but as @SGaist pointed out there may be no time to really respond to the sequence of signals, and
SIGKILL
isn't something you can catch. -
@JNBarchan said in Qt application unable to catch sudo reboot / sudo poweroff from terminal:
I already asked him this question above
Missed that, sorry. Your suggestion is good, but as @SGaist pointed out there may be no time to really respond to the sequence of signals, and
SIGKILL
isn't something you can catch.wrote on 17 Nov 2017, 10:45 last edited by JonB@kshegunov
I do not know about this area, but I believed the OP was saying that the system logged in syslog the sent/delivered signals to processes and he was looking through that. I may have misunderstood, and he only means his application does the logging when signal received, and then indeed we could have race conditions or no such signal actually sent.This indicates even more that OP needs to read up elsewhere how others handle "graceful shutdown" --- assuming it is designed to allow brief code execution in response to SIGTERM before delievery of something like SIGKILL.... e.g. perhaps start from https://stackoverflow.com/questions/22009705/how-to-detect-linux-shutdown-reboot, which might be indicating the same issue as OP is reporting?
-
@kshegunov
I do not know about this area, but I believed the OP was saying that the system logged in syslog the sent/delivered signals to processes and he was looking through that. I may have misunderstood, and he only means his application does the logging when signal received, and then indeed we could have race conditions or no such signal actually sent.This indicates even more that OP needs to read up elsewhere how others handle "graceful shutdown" --- assuming it is designed to allow brief code execution in response to SIGTERM before delievery of something like SIGKILL.... e.g. perhaps start from https://stackoverflow.com/questions/22009705/how-to-detect-linux-shutdown-reboot, which might be indicating the same issue as OP is reporting?
I think the problem here is there's a very few functions that can be called from a signal handler. It may be that the process is actually segfaulting, or if the exact example from the Qt docs is used then the acceptance of the
SIGTERM
would mean the continuation of the shutdown sequence (and subsequently killing the process as it hasn't quit). I'd try the following (use only the allowed POSIX functions for the signal handler):- Create a semaphore on startup and acquire it
- When you get the
SIGTERM
write to the socket pair and acquire the semaphore again to prevent returning from the handler - Do the clean up from the Qt handler
- Subscribe to the
aboutToQuit
signal and release the semaphore from the slot - Only then return from the signal handler
The above you could also accomplish by
select
ing on the socket you opened and writing back a byte after your Qt handler has been called and the cleanup code has run. -
I think the problem here is there's a very few functions that can be called from a signal handler. It may be that the process is actually segfaulting, or if the exact example from the Qt docs is used then the acceptance of the
SIGTERM
would mean the continuation of the shutdown sequence (and subsequently killing the process as it hasn't quit). I'd try the following (use only the allowed POSIX functions for the signal handler):- Create a semaphore on startup and acquire it
- When you get the
SIGTERM
write to the socket pair and acquire the semaphore again to prevent returning from the handler - Do the clean up from the Qt handler
- Subscribe to the
aboutToQuit
signal and release the semaphore from the slot - Only then return from the signal handler
The above you could also accomplish by
select
ing on the socket you opened and writing back a byte after your Qt handler has been called and the cleanup code has run.wrote on 17 Nov 2017, 23:33 last edited by JonB@kshegunov
OP says of what happens when signal delivered:my implementation doesn't work as expected when I execute sudo reboot / sudo poweroff in a terminal, though internally SIGTERM signal is getting emitted. Have checked this in syslog.
I'm still unclear whether he means he writes to syslog from his handler, or that the OS automatically logs signal delivery itself. I'm thinking the latter, as he's saying:
yet my application doesn't hit my signal handler when sudo poweroff / sudo reboot is executed through terminal. But when I execute kill -15 pid ( pid of my application ) signal handler gets executed
It depends on whether during shutdown he is truly not receiving the initial SIGTERM which would initiate his clean up code, or whether actually he is receiving it but very soon afterwards he's getting a SIGKILL or similar, so that his clean up code doesn't get to do much. Even if he hasn't yet returned from the SIGTERM handler, I thought nothing would block the SIGKILL from immediate delivery and termination, surely it doesn't care that you are presently in a signal handler?
-
@kshegunov
OP says of what happens when signal delivered:my implementation doesn't work as expected when I execute sudo reboot / sudo poweroff in a terminal, though internally SIGTERM signal is getting emitted. Have checked this in syslog.
I'm still unclear whether he means he writes to syslog from his handler, or that the OS automatically logs signal delivery itself. I'm thinking the latter, as he's saying:
yet my application doesn't hit my signal handler when sudo poweroff / sudo reboot is executed through terminal. But when I execute kill -15 pid ( pid of my application ) signal handler gets executed
It depends on whether during shutdown he is truly not receiving the initial SIGTERM which would initiate his clean up code, or whether actually he is receiving it but very soon afterwards he's getting a SIGKILL or similar, so that his clean up code doesn't get to do much. Even if he hasn't yet returned from the SIGTERM handler, I thought nothing would block the SIGKILL from immediate delivery and termination, surely it doesn't care that you are presently in a signal handler?
I'd really like to see some code, though.
For one not everything can be done from a signal handler (as Qt's docs correctly note), and for two you need to register the handlers in such a way so you don't get interleaved signal handlers called, otherwise it's a big mess. A signal sent to the process is much like an interrupt, so it can get quite complicated if you're not requesting them to be queued.
1/25