Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to override exit(), perhaps by throwing exception

Tags:

c++

c

We have a third-party library that was written without multithreading or exception handling in mind. Our main executable is multithreaded and uses exceptions.

The third-party library uses exit() to abort the program for serious problems (like "driver not initialized" or "file not found"). Calling exit() in a multithreaded application is not allowed, as it does not shut down threads correctly. In addition, I really don't want to ever exit the main application, as it is a server application, and in many cases, there are proactive things that the main program can do to recover from the error.

I would like to essentially replace the system provided exit(int status) function with my own function, ie

class exit_exception : public runtime_error 
{
    public: exit_exception(int status) 
      : runtime_error("exit called with status " + to_string(status)) {}      
};

extern "C" void exit(int status) {
    throw  exit_exception(status);
}

and catch the exception in my code. It seems to work, but this is obviously a hack and not the way nature intended exit() to be used. What am I doing wrong without knowing?

edit

Many have suggested I put this in a separate process, but that would defeat many things. The third-party library does very high speed data transfer that needs to be in the main application process because it lives in the same virtual memory space and does not use malloc to allocate memory from the FPGA coprocessor that is controller. This code is close to the "iron" and is squeezing every bit of bandwidth out of the memory and PCIe busses.

edit 2

My program can still return status codes to the OS with the return value from int main(), which does not ultimately call exit(). Otherwise I would be in real trouble.

like image 522
Mark Lakata Avatar asked Jul 31 '14 21:07

Mark Lakata


2 Answers

This is just an idea, but you could use a similar approach as i did when i needed to wrap memcpy to use some different version, take a look at my answer here.

So you could build a replacement for the exit() function that does nothing, or do some cleanup. It's just an idea and i have not tried it, but it could help you to solve your problem.

like image 171
Ortwin Angermeier Avatar answered Sep 18 '22 13:09

Ortwin Angermeier


The biggest and most obvious risk is resource leakage. If the library thinks its error handling strategy is to dive out of the nearest window there's alway a risk that throwing that exception isn't going to result in well organised release of memory and system resources.

However I notice you mention it doesn't allocate memory with malloc() if that means you have to provide it with all its resources as buffers and the like then maybe by some miraculous accident it is safely unwindable!

If that fails all I can suggest is contact the supplier and persuade them that they should join the rest of us in 21st programming paradigms.

PS: Throwing an exception out of an atexit() handler causes termination of C++ programs. So adding a throwing handler is not an option. It's also not an option if some other library inserts an 'atexit()' handler after yours.

like image 28
Persixty Avatar answered Sep 22 '22 13:09

Persixty