Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can exit() from a library be replaced with throwing an exception? [duplicate]

Tags:

c++

c

exception

I'm working with a C/Fortran library from C++ and the library calls exit(). I would like it to throw an exception so that the destructors in my C++ program will be called. I have been able to create my one definition of exit that throws an exception, but then terminate is still called. Is there to prevent terminate from being called and allow the normal exception handling to happen?

UPDATE: In the comments it was pointed out that this works on x64 but fails on x86, so the main question is "is there is a way to make x86 work like x64?".

UPDATE2: See my response about why this wasn't working on x86 and how to fix it.

Here's my test code:

test_exception.c

#include <stdlib.h>

void call_c() { exit(1); }

test_exception.cpp

#include <iostream>
#include <stdexcept>

extern "C" void call_c();

extern "C" void exit(int value)
{
  throw std::runtime_error(std::string("Throwing an exception: ") + char('0' + value));
}

int main()
{
  try {
    call_c();
  } catch (const std::exception &e) {
    std::cerr << e.what() << std::endl;
    return 1;
  }

  return 0;
}

Built with the following commands:

gcc -c test_exception.c -o test_exception_c.o
g++ -c test_exception.cpp -o test_exception_cpp.o
g++ test_exception_c.o test_exception_cpp.o -o test_exception
like image 434
Dave Johansen Avatar asked May 13 '15 16:05

Dave Johansen


2 Answers

I understand you may not want to read this, but it's most likely a mistake to continue executing a program after any part of it has attempted to call exit() or similar.

If part of the program called exit(), you have no guarantees about the state of the program at that point. You don't know if the heap is in a consistent state. You don't know if the stack is any good. If you convert the exit() into a throw, the very least you're likely to encounter are memory leaks each time this happens. You don't know if the library that caused this error can be safely called again.

If you have inspected the library's source code, and you're certain that no corruption will result, then the cleanest solution would be to modify the library itself, so that it throws instead of exiting.

If changing the library is not permissible, the other clean and correct solution is to put all usage of the library into a separate process which you can monitor and restart.

like image 117
denis bider Avatar answered Sep 30 '22 03:09

denis bider


The above code works, but on x86 before gcc 4.6, -fexceptions or -funwind-tables needs to be added when building the C code so that the stack unwinding can happen. You can see the details here.

like image 41
Dave Johansen Avatar answered Sep 30 '22 03:09

Dave Johansen