Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use exit() safely from any thread

According to the man page (2) the exit function is not thread safe : MT-Unsafe race:exit, this is because this function tries to clean up resources (flush data to the disk, close file descriptors, etc...) by calling callbacks registered using on_exit and atexit. And I want my program to do that ! (one of my thread keeps a fd open during the whole program's lifespan so _exit is not an option for me because I want all the data to be written to the output file)

My question is the following : if I'm being careful and I don't share any sensible data (like a fd) between my threads, is it "acceptable" to call exit in a multi-threaded program ? Note that I'm only calling exit if an unrecoverable error occurs. Yet, I can't afford having a segfault while the program tries to exit. The thing is, an unrecoverable error can happen from any thread...

I was thinking about using setjmp/longjmp to kill my threads "nicely" but this would be quite complex to do and would require many changes everywhere in my code.

Any suggestions would be greatly appreciated. Thanks ! :)

EDIT : Thanks to @Ctx enlightenment, I came up with the following idea :

#define EXIT(status) do { pthread_mutex_lock(&exit_mutex); exit(status); } while(0)

Of course the exit_mutex must be global (extern).

like image 564
ShellCode Avatar asked Jul 23 '19 10:07

ShellCode


2 Answers

The manpage states that

The exit() function uses a global variable that is not protected, so it is not thread-safe.

so it won't help, if you are being careful in any way.

But the problem documented is a race condition: MT-Unsafe race:exit

So if you make sure, that exit() can never be called concurrently from two threads, you should be on the safe side! You can make this sure by using a mutex for example.

like image 94
Ctx Avatar answered Oct 20 '22 12:10

Ctx


A modern cross-platform C++ solution could be:

#include <cstdlib>
#include <mutex>

std::mutex exit_mutex;

[[noreturn]] void exit_thread_safe(const int status)
{
    exit_mutex.lock();
    exit(status);
}

The mutex ensures that exit is never called by 2 (or more) different threads.

However, I still question the reason behind even caring about this. How likely is a multi-threaded call to exit() and which bad things can even realistically happen?

EDIT:
Using std::quick_exit avoids the clang diagnostic warning.

like image 41
BullyWiiPlaza Avatar answered Oct 20 '22 13:10

BullyWiiPlaza