How to isolate work / flow from failures

I am working on a library where I do various tasks in some third-party libraries that do some relatively sketchy or dangerous work on the platform. (In particular, I write a mathematical function analyzer that calls JIT compilers, such as LLVM or libjit, to generate machine code.) In practice, these third-party libraries tend to crash (some of this is my mistake, of course, but I'm all I also want some insurance).

Then I would very competently cope with the terrible work - SIGSEGV, SIGILL, etc. - without reducing the rest of my code (or the code of users calling my function library). To be clear, I don't care if this particular job can continue (I'm not going to try to restore the state of failure), and I'm not really interested in the state of objects after such a failure (I will drop them immediately if the failure occurs). I just want to detect that a failure has occurred, stop the crash in order to pull out the whole process, stop calling any failure and resume execution.

(For a slightly larger context, the code is currently a for loop, checking each of the available JIT compilers. Some of these compilers may fail. If so, I just want to execute continue;and get another compiler to test.)

Currently, I have an implementation based on signal()which is not very successful; of course, this behavior is undefined for longjmp()from a signal handler, and signal handlers are pretty much expected at the end with exit()or terminate(). Just throwing code into another thread does not help on its own, at least as I have tested it so far. I also can't hack a way to make this work using C ++ exceptions.

So what is the best way to isolate a specific instruction set / thread / job from failures?

+5
4

.

+10

?

, , , .

, , , .

.

+5

, , , .

- , (, ThreadProc Windows), try{...}catch(...). , , - . , , , . :

int my_tempermental_thread()
{
  try
  {
    // ... magic happens ...
    return 0;
  }
  catch( const std::exception& ex )
  {
    // ... or maybe it doesn't ...
    string reason = ex.what();
    tell_main_thread_what_went_wong(reason);
    return 1;
  }
  catch( ... )
  {
    // ... definitely not magical happenings here ...
    tell_main_thread_what_went_wrong("uh, something bad and undefined");
    return 2;
  }
}

, , -, . , , , ? Catch-and-ignore - .

+1
source

On Windows, you can use VirtualProtect(YourMemory, PAGE_READONLY)when calling untrusted code. Any attempt to modify this memory will raise a Structured Exception. You can safely catch it and continue execution. However, the memory allocated by this library will leak like other resources. Equivalent to Linux mprotect(YorMemory, PROT_READ)that calls SEGV.

0
source

All Articles