I am currently using a script to call pkill to terminate my C++ program.
However i noticed that the destructors were not called from my traces when using pkill.
Is there another good way that i can exit the program gracefully?
pkill seems kind of untidy and some logs in the buffer do not get recorded. I'd like to be able to flush on my fstream and to close all resources programatically (instead of relying on the O/S to clean up my mess).
The application runs 24/7 without any problem, the only time i want to stop it is during maintenance. The application does not have any user interface for me to type exit.
You do it by defining a signal handler for SIGTERM along these lines:
Somewhere in your include block:
#include <signal.h>
#include <stdio.h>
Yes, we're doing i C style!
Somewhere in the initialization part of your code:
signal (SIGTERM, handler);
and then define the signal handlers code (flush everything, etc):
void handler(int num)
{
// we might use this handler for many signals
switch (num)
{
case SIGTERM:
// clean up code.
break;
}
}
Now when you run pkill <app>, where <app> is the name of the executable, the code for handler() will run.
Without switches, the default SIGTERM signal will be sent to the application. Should you choose to use a different signal you would have to make sure you send the same signal as you "catch" in the handler().
Relevant information can be found by man 7 signal and of course, man kill.
In addition to Zrvan's answer, be aware that only a restricted set of functions can be safely called from a signal handler. The signal(7) man page, and the Posix standards, require that only Async-signal-safe functions can be called directly or indirectly inside a signal handler. Note that printf or malloc are not safe inside a signal handler. Signal handler's code is tricky to write (and you cannot debug it easily, because signal sending is non-reproducible).
As the Glibc documentation suggests, your signal handler could just set a volatile sig_atomic_t variable, which your main loop[s] would test and handle.
You could also decide, if you application is event based, that some socket or named pipe is dedicated to control it. That event loop (perhaps using select(2) or poll(2), or even pselect or ppoll) could handle the control message on the pipe or socket.
You may be interested by event looping libraries like libevent. You might also use an HTTP server library like onion or Wt. You could also be interested by SNMP or D-bus.
A trick to overcome the limitation of signal handlers is to have them write on a pipe to the same process, as e.g. Qt's doc is suggesting. Then the event loop would handle reading on that pipe.
If your application is multi-threaded, signal handling is more tricky. Some signals are delivered to an individual thread.
Unless you modify the target application, I don't see a way.
Consider the following:
int main()
{
MyClass a;
while ( true )
{
}
}
You'd have to tell the program to exit the loop. But unless you have some signal handling mechanism on your app, that seems impossible.
You'd need something like:
int main()
{
MyClass a;
while ( !killSignalReceived() )
{
}
}
The best way is to handle a signal in the program, and then send that signal using kill. In the signal handler, mark a flag that will cause the main loop to end.
Related
I need to capture the event of a terminal resize, to do this I am capturing (although other methods are welcome) SIGWINCH with the following:
std::signal(SIGWINCH, &handle_sigwinch);
I was then hoping to have handle_sinwinch do something like:
display_type *dt; //inited elsewhere
void handle_sinwinch(int sig) {
dt->async_redraw();
}
Where async_redraw post the work to do onto an internal boost::asio::io_service and then returns. Thus there should be no race conditions; however, the doc for std::signal seems to imply that I can safely ONLY manipulate volatile std::sig_atomic_ts.
IE I can set a flag, then pick it up from the main thread as a part of an event loop.
The problem is that this is asynchronous so there is no while(true) loop or anything like that. The only way to loop over such a flag would be to create a deadline timer and check it periodically. Which seems like a real hack.
So my question is, is my understanding of signals correct? And any insight how to do this would be appreciated.
If you use boost::asio you can handle signals with async_wait() method of boost::asio::signal_set. Handler set with async_wait() can do what you want, it is not called in signal handler context.
What is a reasonable reaction time to posix signals intending to quit the application?
In other words, how long may my sigint, sigterm or sigtstp handling take before the system kills the application during shutdown, runlevel switching or other automated situations?
I'm writing a non graphical qt application that has to respond to signals in order to clean up before terminating. this is my current implementation:
#include "posixsignals.h"
#include <signal.h>
QAtomicInt posixSignals::sig(0);
posixSignals::posixSignals()
{
//connect to posix signals
signal(SIGINT, posixSignals::interrupt);
signal(SIGTSTP, posixSignals::interrupt);
signal(SIGTERM, posixSignals::interrupt);
//connect and start QTimer t
connect(&t, SIGNAL(timeout()), this, SLOT(check()));
t.start(500);
}
void posixSignals::interrupt(int signal)
{
sig.testAndSetOrdered(0,signal);
}
void posixSignals::check()
{
if(sig)
emit signalCought(sig);
}
In the actual implementation i connect something to the signalCought signal in order to trigger the cleanup and exit of the application. the "problem" here is if i set the timer too low the app maxes a core, but if i set it too high, it might be killed or slow down the shutdown process noticeably.
When using init(8), scripts in /etc/init.d/ are being used to stop processes. I believe the exact mechanism as well as timing constraints may vary from distribution to distribution. In my case, the time is set to 3 seconds (you can find it in /etc/rc.d/init.d/functions file inside a killproc() function. So 3 seconds is an upper limit in general.
This parameter can also be overridden by start/stop scripts of any particular daemon/application. There are also alternatives to init.d, systemd for instance. But I am not sure how that system works so cannot tell about timeouts.
I think 3 seconds is more than enough to stop any application — it is hard to imagine what can take longer than that. In the worse case scenario — just maintain some logs to see whether your application makes it on time or not.
Hope it helps.
Instead of a polling loop, you could use sockets with a QSocketNotifier to translate the posix signals into Qt events, as described here.
I just came across some code which used the kill system call to send a SIGSEGV signal to an app. The rationale behind this was that this would force the app to core dump and quit. This seems so wrong to me, is this normal practice?
SIGQUIT is the correct signal to send to a program if you wish to produce a core dump. kill is the correct command line program to send signals (it is of course poorly named, since not all signals will kill the program).
Note, you should not send random signals to the program, not all of them will produce a core dump. Many of them will be handled by the program itself, either consumed, ignored, or induce other processing. Thus sending a SIGSEGV is wrong.
GCC Says:
http://www.gnu.org/s/libc/manual/html_node/Termination-Signals.html
POSIX/Unix Says:
http://pubs.opengroup.org/onlinepubs/009695399/basedefs/signal.h.html
Yes. kill is somewhat misnamed -- it can send any signal. There are many uses for kill which don't result in the process being killed at all!
If you want to make an application dump it's core from another program, pretty much the only way to do it is via a signal. SEGV would be fine for this. Alternatively you can hook a debugger up to the program and freeze it and view it's registers and such without killing it.
If you want to dump a core from within an application there are nicer ways to do it, like via an assert().
So, no, it's not particularly wrong to send a SEGV to a program. You could also send things like SIGILL for illegal instruction, or a divide by zero signal. It's all fine.
The way to do it in Unix/Linux is to call abort() which will send SIGABORT to current process. The other option is raise() where you can specify what signal you want to send to current process.
Richard Stevens (_Advanced Programming in the UNIX Environment) wrote:
The generation of core is an implementation features of most Unix. It is not part of POSIX.1.
He lists 12 signals whose default action is to terminate with a core (ANSI: SIGABRT, SIGFPE, SIGILL, SIGSEGV, POSIX: SIGQUIT, Other: SIGBUS, SIGEMT, SIGIOT, SIGSYS, SIGTRAP, SIGXCPU, SIGXFSZ), all of them are overwritable (the two signals which aren't overwritable are SIGKILL and SIGSTOP).
I've never seen a way to generate a core which isn't the use of a default signal handler.
So if your goal is to generate a core and stop, the best is to choose a signal whose default handler does the job (SIGSEGV does the job), reset the default handler for the signal if you are using it and then use kill.
Sometimes when I am debugging I get message like this.
Program received signal SIG44, Real-time event 44.
What does it means?
Thank you.
EDIT :
Platform is linux
A signal is a message sent by the kernel to a process in order to notify the process that event of some kind has occurred in the system.
Usual signals on linux are for example SIGINT (value 2, interrupt from keyboard) or SIGKILL ( value 9, kill a program).
Signals are received either when the kernel detects a system event (like division by zero is SIGFPE, value 8) or when a process invokes the kill() function to explicitly tell the kernel to send a signal to a process (or to the process itself that called the kill() ).
A signal can often be caught by the process in order to do something.
So to answer to your question, the code is most likely calling the kill() function and sending it a signal with value 44 when something happens. Since you are getting that message, it means that the process has received the signal and is going to exit or do what is written in the code in case that signal comes.
Unlike standard signals, real-time
signals have no predefined meanings:
the entire set of real-time signals
can be used for application-defined
purposes. (Note, however, that the
LinuxThreads implementation uses the
first three real-time signals.)
Source for the quote here
The GNU C++ library uses SIG44 to awaken sleeping threads when signalling condition variables.
I'm importing a portion of existing code into my Qt app and noticed a sleep function in there. I see that this type of function has no place in event programming. What should I do instead?
UPDATE: After thought and feedback I would say the answer is: call sleep outside the GUI main thread only and if you need to wait in the GUI thread use processEvents() or an event loop, this will prevent the GUI from freezing.
It isn't pretty but I found this in the Qt mailing list archives:
The sleep method of QThread is protected, but you can expose it like so:
class SleeperThread : public QThread
{
public:
static void msleep(unsigned long msecs)
{
QThread::msleep(msecs);
}
};
Then just call:
SleeperThread::msleep(1000);
from any thread.
However, a more elegant solution would be to refactor your code to use a QTimer - this might require you saving the state so you know what to do when the timer goes off.
I don't recommend sleep in a event based system but if you want to ...
You can use a waitcondition, that way you can always interrupt the sleep if neccesary.
//...
QMutex dummy;
dummy.lock();
QWaitCondition waitCondition;
waitCondition.wait(&dummy, waitTime);
//...
The reason why sleep is a bad idea in event based programming is because event based programming is effectively a form on non-preemptive multitasking. By calling sleep, you prevent any other event becoming active and therefore blocking the processing of the thread.
In a request response scenario for udp packets, send the request and immediately wait for the response. Qt has good socket APIs which will ensure that the socket does not block while waiting for the event. The event will come when it comes. In your case the QSocket::readReady signal is your friend.
If you want to schedule an event for some point of time in the future, use QTimer. This will ensure that other events are not blocked.
It is not necessary to break down the events at all. All I needed to do was to call QApplication::processEvents() where sleep() was and this prevents the GUI from freezing.
I don't know how the QTs handle the events internally, but on most systems at the lowest level the application life goes like this: the main thread code is basically a loop (the message loop), in which, at each iteration, the application calls a function that gives to it a new message; usually that function is blocking, i.e. if there are no messages the function does not return and the application is stopped.
Each time the function returns, the application has a new message to process, that usually has some recipient (the window to which is sent), a meaning (the message code, e.g. the mouse pointer has been moved) and some additional data (e.g. the mouse has been moved to coords 24, 12).
Now, the application has to process the message; the OS or the GUI toolkit usually do this under the hood, so with some black magic the message is dispatched to its recipient and the correct event handler is executed. When the event handler returns, the internal function that called the event handler returns, so does the one that called it and so on, until the control comes back to the main loop, that now will call again the magic message-retrieving function to get another message. This cycle goes on until the application terminates.
Now, I wrote all this to make you understand why sleep is bad in an event driven GUI application: if you notice, while a message is processed no other messages can be processed, since the main thread is busy running your event handler, that, after all, is just a function called by the message loop. So, if you make your event handler sleep, also the message loop will sleep, which means that the application in the meantime won't receive and process any other messages, including the ones that make your window repaint, so your application will look "hang" from the user perspective.
Long story short: don't use sleep unless you have to sleep for very short times (few hundreds milliseconds at most), otherwise the GUI will become unresponsive. You have several options to replace the sleeps: you can use a timer (QTimer), but it may require you to do a lot of bookkeeping between a timer event and the other. A popular alternative is to start a separate worker thread: it would just handle the UDP communication, and, being separate from the main thread, it would not cause any problem sleeping when necessary. Obviously you must take care to protect the data shared between the threads with mutexes and be careful to avoid race conditions and all the other kind of problems that occur with multithreading.