我们有一段代码造成了死锁,如下(简化版本)
std::shared_timed_mutex read_file_mutex;
std::shared_lock<std::shared_timed_mutex> read_file_lock(read_file_mutex
, std::defer_lock);
if (read_file_lock.try_lock_for(std::chrono::milliseconds(200))) {
...
...
if (read_file_lock.try_lock_for(std::chrono::milliseconds(200))) {
第二个 try_lock 抛出异常,正如预期的那样,在验证期间来自 MSVC shared_mutex 的资源死锁:
void _Validate() const {
// check if the mutex can be locked
if (!_Pmtx)
_THROW(system_error(
_STD make_error_code(errc::operation_not_permitted)));
if (_Owns)
_THROW(system_error(
_STD make_error_code(errc::resource_deadlock_would_occur)));
}
问题是,当引发上述异常时,为什么当我们注册了自己的无效参数异常处理程序时,它会调用带有无效参数异常的 watson 处理程序?这导致程序终止而不生成故障转储。
我们为 UnhandledExceptionFilter、_set_invalid_parameter_handler、_set_purecall_handler、Abort Signal handler 等设置了异常处理程序,如here所述,所有其他类型的异常都很好地调用我们的处理程序,我们在其中向辅助进程发出信号以生成故障转储。 this示例中给出的无效参数异常也可以很好地调用我们的处理程序。
_invalid_parameter_handler old_handler, new_handler;
SetUnhandledExceptionFilter(&UnhandledExceptionHandler);
new_handler = HandleInvalidParameter;
old_handler = _set_invalid_parameter_handler(new_handler);
_set_purecall_handler(PureVirtualCallHandler);
void (*rv)(int) = signal(SIGABRT, HandleAbortSignal);
_set_abort_behavior(0, 0);
EnableCrashingOnCrashes();
PreventSetUnhandledExceptionFilter();
shared_timed_mutex 或 system_error 异常有什么特别之处?需要做什么才能正确注册处理程序?
软件是32位,在64位Windows 10上运行。使用的编译器是clang
事实证明,在某些应用程序(混合了 C/CPP 代码)上禁用 cpp 异常会导致包含的 cpp 库中使用异常的混合行为。这些库中的某些类型的异常会正确调用已注册的异常处理程序,但其他一些类型的异常(例如 system_error)不会调用已注册的处理程序,而是直接调用 watson