如何覆盖exit(),可能是通过抛出exception
我们有一个第三方库,编写时没有考虑multithreading或exception处理。 我们的主要可执行文件是multithreading的并使用exception。
第三方库使用exit()
中止程序以解决严重问题(例如“未初始化驱动程序”或“未找到文件”)。 不允许在multithreading应用程序中调用exit()
,因为它不能正确关闭线程。 另外,我真的不想退出主应用程序,因为它是一个服务器应用程序,并且在许多情况下,主程序可以采取主动的事情来从错误中恢复。
我想基本上用我自己的函数替换系统提供的exit(int status)
函数,即
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); }
并在我的代码中捕获exception。 它似乎工作,但这显然是一个黑客,而不是自然意图exit()
使用的方式。 不知道我做错了什么?
编辑
许多人建议我把它放在一个单独的过程中,但这会打败很多东西。 第三方库执行非常高速的数据传输,需要在主应用程序进程中,因为它位于相同的虚拟内存空间中,并且不使用malloc
从作为控制器的FPGA协处理器分配内存。 这段代码接近“铁”,并且正在挤压内存和PCIe总线的每一点带宽。
编辑2
我的程序仍然可以使用int main()
的返回值将状态代码返回给OS,最终不会调用exit()
。 否则我会遇到麻烦。
这只是一个想法,但你可以使用类似的方法,因为我需要包装memcpy
使用一些不同的版本,看看我的答案在这里 。
所以你可以为exit()
函数构建一个什么都不做的替换,或者做一些清理。 这只是一个想法,我没有尝试过,但它可以帮助您解决您的问题。
最大和最明显的风险是资源泄漏。 如果库认为其error handling策略是从最近的窗口中跳出,则总是存在一种风险,即抛出该exception不会导致组织良好的内存和系统资源释放。
但是我注意到你提到它没有用malloc()
分配内存,如果这意味着你必须提供它作为缓冲区之类的所有资源然后可能通过一些奇迹般的事故安全地放松!
如果失败了我可以建议联系供应商并说服他们应该加入我们其他人的第21个编程范例。
PS:从atexit()
处理程序中抛出exception会导致C ++程序终止。 因此添加投掷处理程序不是一种选择。 如果其他库在您的后面插入’atexit()’处理程序,它也不是一个选项。
您可以尝试使用longjmp
保留atexit()
处理程序。 虽然行为是未定义的:)另一种方法是在一个单独的进程中运行lib,与任何IPC桥接。 更难,更乏味,但更安全。 或者,您可以尝试扫描二进制图像并挂钩任何exit()
调用。 我知道MS绕道而行,并在窗户上玩。 不幸的是,虽然我在linux上都不知道。