How to ensure popen()ed process runs destructors on exit? - c++

If I have a pipe to run some command, the piped command needs to do some cleanup, however, if the processes that started the pipe has an error, the piped command is not cleaning up. Is the piped command getting SIGPIPE in this case? How can I ensure cleanupPipe destructor is always run? When the errorOccurred exception is thrown, I am seeing that cleanupPipe destructor is not run. I have SIGPIPE handler set up to throw an exception, so if SIGPIPE is the result, I would expect my destructor to be run when the SIGPIPE results in thrown exception unwinding the stack.
void
testCase() {
class cleanup {
public:
cleanup(FILE *pipe)
: _pipe(pipe) {
}
~cleanup() {
::pclose(_pipe);
}
private:
FILE *_pipe;
};
string cmd("runMyCommandImplementationHere argsHere");
FILE *pipePtr = ::popen(cmd, "w");
cleanup cleanUpPipe(pipePtr);
// Normally, write data to pipe until process in pipe gets all the data it
// needs and exits gracefully.
for (;;) {
if (someErrorOccured()) {
// When this error occurs, we want to ensure cleanupPipe is run in piped
// process.
throw errorOccurred(status);
}
if (finishedWritingData()) {
break;
}
writeSomeDataToPipe(pipePtr);
}
}
void
myCommandImplementationHere() {
class cleaupPipe {
public:
cleanupPipe(const string &filename)
: _filename(filename) {
}
~cleanupPipe() {
::unlink(_filename.c_str());
}
private:
string _filename;
};
string file("/tmp/fileToCleanUp");
cleanupPipe cleanup(file);
doSomeWorkOnFileWhileReadingPipeTillDone(file);
}

Throwing an exception in a signal handler is a very bad idea. Signal handlers must be asynchronous-safe. To make matters worse, signal handlers run in which is essentially a different thread of execution than your mainline code. It is best to keep your signal handlers small and very primitive. For example, make the SIGPIPE handler set some volatile global variable that indicates that SIGPIPE occurred and test for that as an error condition in your mainline code.
A couple of other comments:
You should check the return status when dealing with C functions such as popen, pclose, and write. You aren't doing so on your call to popen or pclose, at least not in the sample code.
Why the asymmetry in class Cleanup? The constructor receives an already-constructed FILE pointer, but the destructor destroys it via pclose. IMO it would be better if the constructor calls popen, taking the command string as an argument to the constructor.
Addendum
Perhaps even better than creating a handler for SIGPIPE that sets some global variable is to set the handler for SIGPIPE to ignore, and then check for an EPIPE error from your writes to the pipe.

Related

Should we use exit or return in child process

Saying that I have used fork to create one child process. Here is an example:
pid_t pid=fork();
if (pid==0) /* child */
{
// do something
exit(0); // _exit, exit or return????
}
else /* parrent */
{
wait(nullptr);
return 0;
}
I've seen many examples of fork. Some of them used _exit to terminate the child process to avoid flush the I/O buffer, others used exit to terminate the child process. But non of them used return. As my understanding, _exit and exit won't call destructors automatically, so is it better to call return instead of exit in the child process? Or because all examples that I've ever seen are C, instead of C++, so they don't need to worry about destructors?
You can use either _exit or exit, but you shouldn't use return. When you fork a child, you retain the entire call stack as part of forking the child. So if you use return, you end up returning up all the way through your program, potentially continuing on and performing other tasks, which is almost certainly not what you want.
For example, if you have something like this snippet:
int get_value()
{
pid_t pid;
if (!(pid = fork())) {
int x = 0;
// do something with x.
exit(x);
}
else {
int status;
wait(&status);
return status;
}
}
int main()
{
int value = get_value();
switch (get_value()) {
case 0:
// call f
break;
case 255 << 8:
// call g
break;
}
}
you'll could end up calling f or g or doing other work with return, which is definitely not desired.
If you call _exit, functions that are registered with atexit are not called. This is the right thing to do in threaded environments. If you're not working in a threaded environment and you don't have any handlers registered with atexit, then they should be functionally equivalents.
If you want destructors in your child process to be called, put the child process code in its own function and let its variables be automatically destroyed when they go out of scope. exit will not destroy objects for you, which is good because usually you do not want to destroy objects created in the parent process in your child process.
You could use return if you are looking for an exit code of the child process, just to say the process ran and executed correctly/not. Same as you do with your main function in a program. Otherwise just use exit to stop the process from running any further.
fork will copy the whole process, its not equivalent to launching a thread with a new main function.
Returning will simply return from the current function and the execution of the child will continue in the enclosing function.
So in you snippet you have to terminate the child or it will "escape". You can do that by calling exit() or std::terminate(). No destructors are called in both cases. Don't mix two different languages.
If you really need to call the destructors in the child, throw an exception and catch it in main. That will unwind the stack correctly.
Exit command should be avoid to use in any case except from ending the execution of the programme. For anything else, I would use return.

Properly terminating program. Using exceptions

Question:
Is using exceptions the proper way to terminate my program if all I want is to display an error message and close (accounting that I may be deep in the program)? Or can I just explicitly call something like exit(EXIT_FAILURE) instead?
What I'm Currently Doing:
I'm working on a game project and am trying to figure out the best way to terminate the program in the case of an error that calls for such an action. For example, in the case the textures can't be loaded I display an error message and terminate the program.
I'm currently doing this with exceptions like so:
int main()
{
Game game;
try
{
game.run();
}
catch (BadResolutionException & e)
{
Notification::showErrorMessage(e.what(), "ERROR: Resolution");
return 1;
}
catch (BadAssetException & e)
{
Notification::showErrorMessage(e.what(), "ERROR: Assets");
return 1;
}
catch (std::bad_alloc & e)
{
Notification::showErrorMessage(e.what(), "ERROR: Memory");
return 1;
}
return 0;
}
All but bad_alloc are my own defined exceptions derived from runtime_error.
I don't need any manual resource cleanup and I'm using std::unique_ptr for any dynamic allocation. I just need to display the error message and close the program.
Research/Alternatives to Exceptions:
I've looked up a lot of posts on SO and other places and have seen others say anything from don't use exceptions, to use exceptions but your using them wrong. I've also looked up explicitly calling something like exit().
Using exit() sounds nice but I read it won't go back through the call stack up to main cleaning everything up (if I can find this again I'll post the link). Additionally, according to http://www.cplusplus.com/reference/cstdlib/exit/ this should not be used if multiple threads are active. I do expect to be creating a second thread for a short time at least once, and an error could occur in that thread.
Not using exceptions was mentioned in some replies here in relation to games https://gamedev.stackexchange.com/questions/103285/how-industy-games-handle-their-code-errors-and-exceptions
Use exceptions was discussed here: http://www.quora.com/Why-do-some-people-recommend-not-using-exception-handling-in-C++
There are a number of other sources I've read but those were the most recent I looked at.
Personal Conclusion:
Due to my limited experience of working with error handling and using exceptions, I'm not sure if I'm on the right track. I've chosen the route of using exceptions based on the code I posted above. If you agree that I should tackle those cases with exceptions, am I using it correctly?
It's generally considered good practice to let all exceptions propagate through to main. This is primarily because you can be sure the stack is properly unwound and all destructors are called (see this answer). I also think it's more organised to do things this way; you always known where your program will terminate (unless the program crashes). It's also facilitates more consistent error reporting (a point often neglected in exception handling; if you can't handle the exception, you should make sure your user knows exactly why). If you always start with this basic layout
int main(int argc, const char **argv)
{
try {
// do stuff
return EXIT_SUCCESS;
} catch (...) {
std::cerr << "Error: unknown exception" << std::endl;
return EXIT_FAILURE;
}
}
then you won't go far wrong. You can (and should) add specific catch statements for better error reporting.
Exceptions when multithreading
There are two basic ways of executing code asynchronously in C++11 using standard library features: std::async and std::thread.
First the simple one. std::async will return a std::future which will capture and store any uncaught exceptions thrown in the given function. Calling std::future::get on the future will cause any exceptions to propagate into the calling thread.
auto fut = std::async(std::launch::async, [] () { throw std::runtime_error {"oh dear"}; });
fut.get(); // fine, throws exception
On the other hand, if an exception in a std::thread object is uncaught then std::terminate will be called:
try {
std::thread t {[] () { throw std::runtime_error {"oh dear"};}};
t.join();
} catch(...) {
// only get here if std::thread constructor throws
}
One solution to this could be to pass a std::exception_ptr into the std::thread object which it can pass the exception to:
void foo(std::exception_ptr& eptr)
{
try {
throw std::runtime_error {"oh dear"};
} catch (...) {
eptr = std::current_exception();
}
}
void bar()
{
std::exception_ptr eptr {};
std::thread t {foo, std::ref(eptr)};
try {
// do stuff
} catch(...) {
t.join(); // t may also have thrown
throw;
}
t.join();
if (eptr) {
std::rethrow_exception(eptr);
}
}
Although a better way is to use std::package_task:
void foo()
{
throw std::runtime_error {"oh dear"};
}
void bar()
{
std::packaged_task<void()> task {foo};
auto fut = task.get_future();
std::thread t {std::move(task)};
t.join();
auto result = fut.get(); // throws here
}
But unless you have good reason to use std::thread, prefer std::async.
There's nothing wrong with catching unrecoverable errors and shutting down your program this way. In fact, it's how exceptions should be used. However, be careful not to cross the line of using exceptions to control the flow of your program in ordinary circumstances. They should always represent an error which cannot be gracefully handled at the level the error occurred.
Calling exit() would not unwind the stack from wherever you called it. If you want to exit cleanly, what you're already doing is ideal.
You have already accepted an answer, but I wanted to add something about this:
Can I just explicitly call something like exit() instead?
You can call exit, but (probably) shouldn't.
std::exit should be reserved for situations where you want to express "exit right now!", not simply "application has nothing left to do".
As an example, if you were to write a controller for a laser used in cancer treatments, your first priority in case something went wrong would be to shut down the laser and call std::exit - or possibly std::terminate (to ensure any side effects of a hanging, slow or crashing application do not kill a patient).
Similar to how exceptions should not be used for controlling application flow, exit should not be used to stop the application in normal conditions.
Is using exceptions the proper way to terminate my program if all I want is to display an error message and close (accounting that I may be deep in the program)?
Yes. This is the reason for using exceptions. An error occurred deep down in the code and something at a higher level will handle it. In your case, at the highest level.
There are arguments for/against exceptions vs. error codes, and this is a good read:
Exceptions or error codes
Can I just explicitly call something like exit() instead?
You can, but you may end up duplicating your logging code. Also, if in the future you decide that you want to handle an exception differently you will have to change all your exit calls. Imagine you wanted a different message, or to fall back on an alternative process.
Another similar question:
Correct usage of exit() in c++?
You also have a flaw in your approach as you don't handle all (C++) exceptions. You want something like this:
int main()
{
Game game;
try
{
game.run();
}
catch (BadResolutionException & e)
{
Notification::showErrorMessage(e.what(), "ERROR: Resolution");
return 1;
}
catch (BadAssetException & e)
{
Notification::showErrorMessage(e.what(), "ERROR: Assets");
return 1;
}
catch (std::bad_alloc & e)
{
Notification::showErrorMessage(e.what(), "ERROR: Memory");
return 1;
}
catch (...)
{
// overload?
Notification::showErrorMessage("ERROR: Unhandled");
return 1;
}
return 0;
}
If you don't handle all* exceptions you could have the game terminate without telling you anything useful.
You can't handle ALL exceptions. See this link:
C++ catching all exceptions
From the documentation:
[[noreturn]] void exit (int status);
Terminate calling process
Terminates the process normally, performing the regular cleanup for terminating programs.
Normal program termination performs the following (in the same order):
Objects associated with the current thread with thread storage duration are destroyed (C++11 only).
Objects with static storage duration are destroyed (C++) and functions registered with atexit are called.
All C streams (open with functions in ) are closed (and flushed, if buffered), and all files created with tmpfile are removed.
Control is returned to the host environment.
Note that objects with automatic storage are not destroyed by calling exit (C++).
If status is zero or EXIT_SUCCESS, a successful termination status is returned to the host environment.
If status is EXIT_FAILURE, an unsuccessful termination status is returned to the host environment.
Otherwise, the status returned depends on the system and library implementation.
For a similar function that does not perform the cleanup described above, see quick_exit.

How can I programmatically get the default behavior of sigterm inside a custom signal handler?

Based on man -S 7 signal, when a program which has not defined a signal handler receives SIGTERM, the default action is to Term.
I am registering a custom signal handler for SIGTERM, but I want the final statement (after specific cleanup is done) in my custom handler to be a function call that achieves the exact same effect as Term.
What is the correct function to call here?
I have tried exit(0), but that causes the destructors of statically initialized objects to be called, which does not match the behavior of Term. I have also tried abort(), and that causes a core dump.
In the following example, I am using the lifetime of statically allocated objects as an illustrative example, but my question is more broad than just the lifetime of statically allocated objects.
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
struct Foo{
~Foo() {
fprintf(stderr, "Dying!\n");
}
Foo() {
fprintf(stderr, "Constructing!\n");
}
};
Foo foo;
void sig_handler(int signo) {
// exit(0);
// abort();
}
int main(){
// signal(SIGTERM, sig_handler);
while(1);
}
Here are various behaviors:
The code as-is will print Constructing! but not Dying! if SIGTERM is received.
When the //signal line is commented back in, and exit(0) is commented back in, the code will print both Constructing! and Dying!
When exit(0) is commented out, and abort() is commented in, the program will output Constructing! followed by Aborted (core dumped).
To ask my question in another way, I want to know what I need to put in the body of signal_handler in order to mimic behavior 1 in every way (not just the output I have shown).
signal(SIGTERM, SIG_DFL);
kill(getpid(), SIGTERM);
There is no function call, as termination upon signals is handled by the kernel, not the user process, but this will restore the default handler, then send a signal to yourself, which kills the process just like the signal had never been caught.
You can call _exit instead of exit , which should exit the process without running global destructors.

How to write signal handler for sigabrt signal?

I am trying to delete an already deleted object and I am getting a SIGABRT signal.
I know this signal aborts my program, but I want to catch this signal in a signal handler and display the message that I am deleting an already deleted object...
Here is the code I have tried, but it doesn't seem to work.
Please help me figure out what's wrong in it?
using namespace std;
class myclass
{
public:
myclass() { cout <<"myclass constructed\n"; }
~myclass() { cout <<"myclass destroyed\n"; }
};
void func(int);
int main (void)
{
signal(SIGABRT,func);
myclass * pt;
pt = new myclass[3];
delete[] pt;
delete[] pt;
return 0;
}
void func(int)
{
signal(SIGABRT,func);
cout << "trying to delete unallocated memory, exiting....\n";
exit(0);
}
The C standard says (section 7.14, paragraph 4 of both C99 and C11):
An implementation need not generate any of these signals, except as a result of explicit
calls to the raise function.
The C++ standard doesn't give any additional additional guarantees.
POSIX says:
The abort() function shall cause abnormal process termination to occur, unless the signal SIGABRT is being caught and the signal handler does not return.
The abnormal termination processing shall include the default actions defined for SIGABRT and may include an attempt to effect fclose() on all open streams.
The SIGABRT signal shall be sent to the calling process as if by means of raise() with the argument SIGABRT.
The status made available to wait() or waitpid() by abort() shall be that of a process terminated by the SIGABRT signal. The abort() function shall override blocking or ignoring the SIGABRT signal.
So, yeah, you have no basis for expecting to see a SIGABRT at all; you're lucky you aren't encountering nasal demons!

C++ synchronization and exception handling in cross threads

I am using boost library for threading and synchronization in my application.
First of all I must say exceptions within threads on synchronization is compilitey new thing for me.
In any case below is the pseudo code what I want to achieve. I want synchronized threads to throw same exception that MAY have been thrown from the thread doing notify. How can I achieve this?
Could not find any topics from Stack Overflow regarding exception throwing with cross thread interaction using boost threading model
Many thanks in advance!
// mutex and scondition variable for the problem
mutable boost::mutex conditionMutex;
mutable boost::condition_variable condition;
inline void doTheThing() const {
if (noone doing the thing) {
try {
doIt()
// I succeeded
failed = false;
condition.notify_all();
}
catch (...) {
// I failed to do it
failed = true;
condition.notify_all();
throw
}
else {
boost::mutex::scoped_lock lock(conditionMutex);
condition.wait(lock);
if (failed) {
// throw the same exception that was thrown from
// thread doing notify_all
}
}
}
So you want the first thread that hits doTheThing() to call doIt(), and all subsequent threads that hit doTheThing() to wait for the first thread to finish calling doIt() before they proceed.
I think this should do the trick:
boost::mutex conditionMutex; // mutable qualifier not needed
bool failed = false;
bool done = false;
inline void doTheThing() const {
boost::unique_lock uql(conditionMutex);
if (!done) {
done = true;
try {
doIt();
failed = false;
}
catch (...) {
failed = true;
throw
}
}
else if (failed)
{
uql.unlock();
// now this thread knows that another thread called doIt() and an exception
// was thrown in that thread.
}
}
Important notes:
Every thread that calls doTheThing() must take a lock. There is no way around this. You are synchronizing threads, and for a thread to know anything about what's happening in another thread, it must take a lock. (Or it can use atomic memory operations, but that's a more advanced technique.) The variables failed and done are protected by the conditionMutex.
C++ will call destructor of uql when the function exits normally or by throwing exception.
EDIT Oh, and as for throwing the exception to all the other threads, forget about that, it's almost impossible, and it isn't the way things are done in C++. Instead, each thread can check to see if the first thread successfully called doIt() in the place I've indicated above.
EDIT There is no language support for propagating an exception to another thread. You can generalize the problem of propagating exceptions to another thread to passing messages to another thread. There are lots of library solutions to the problem of passing messages between threads ( boost::asio::io_service::post() ), and you could pass a message that contains the exception, with instructions to throw that exception on receipt of message. It's a bad idea, though. Only throw exceptions when you have an error that prevents you from unwinding the call stack by ordinary function return. That's what an exception is--an alternative way to return from a function when returning the usual way doesn't make sense.