如何使作业/线程与崩溃隔离

我正在建立一个图书馆,在那里我将各种任务培养到一些第三方图书馆,这些图书馆做了一些相对粗略或危险的平台特定工作。 (具体来说,我正在编写一个数学函数解析器,它调用JIT编译器,如LLVM或libjit,来构建机器代码。)实际上,这些第三方库有崩溃的倾向(部分原因是我的错当然,但我仍然需要一些保险)。 那么,我希望能够非常优雅地处理可怕的工作 - SIGSEGV,SIGILL等 - 而不会删除我的其余代码(或用户调用我的库函数的代码)。要明确的是,我不在乎这个特定的工作是否可以继续(我不打算尝试修复碰撞情况),也不关心碰撞后的物体状态(我会丢弃)如果发生碰撞,他们会马上出现。)我只是希望能够检测到发生了崩溃,阻止崩溃取出整个进程,停止调用崩溃的任何内容,然后继续执行。 (对于更多的上下文,目前的代码是for循环,测试每个可用的JIT编译器。这些编译器中的一些可能会崩溃。如果他们这样做,我只想执行
continue;
并继续测试另一个编译器。) 目前,我有一个基于
signal()
的实现失败了很多;当然,它是信号处理程序中的unde2ѭ的未定义行为,并且信号处理程序几乎可以以
exit()
terminate()
结束。只是将代码抛入另一个线程本身并没有帮助,至少我到目前为止测试它的方式。我也无法使用C ++异常来解决这个问题。 那么,什么是将特定指令/线程/作业与崩溃隔离的最佳方法是什么?     
已邀请:
产生一个新的过程。     
当工作成功时,您收集什么输出? 我问,因为如果输出带宽很低,我很想在自己的进程中运行每个作业。 您启动的这些崩溃工作中的每一个都很有可能破坏过程中其他地方使用的内存。 流程提供最佳保护。     
流程提供最好的保护,但您可能无法做到这一点。 如果您的线程的入口点是您编写的函数(例如,Windows世界中的
ThreadProc
),那么您可以将它们包装在
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;
  }
}
请注意,如果您采用这种方式,则在发生异常时可能会出现管理主机进程的风险。你说你不是想纠正这个问题,但是你怎么知道恶性线程没有吃掉你的堆栈呢?捕获和忽略是创建可怕的混杂错误的好方法。     
在Windows上,您可以在调用不受信任的代码时使用
VirtualProtect(YourMemory, PAGE_READONLY)
。任何修改此内存的尝试都会导致结构化异常。您可以安全地捕获并继续执行。但是,该库分配的内存当然会泄漏,其他资源也会泄漏。 Linux等价物是
mprotect(YorMemory, PROT_READ)
,导致SEGV。     

要回复问题请先登录注册