互斥锁定期间未针对异常调用 CPP 异常处理程序

问题描述 投票:0回答:1

我们有一段代码造成了死锁,如下(简化版本)

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++ windows winapi crash-dumps msvcrt
1个回答
0
投票

事实证明,在某些应用程序(混合了 C/CPP 代码)上禁用 cpp 异常会导致包含的 cpp 库中使用异常的混合行为。这些库中的某些类型的异常会正确调用已注册的异常处理程序,但其他一些类型的异常(例如 system_error)不会调用已注册的处理程序,而是直接调用 watson

© www.soinside.com 2019 - 2024. All rights reserved.