以下是LLVM的libcxxabi中的函数:
void *__cxa_current_primary_exception() throw() {
// get the current exception
__cxa_eh_globals* globals = __cxa_get_globals_fast();
if (NULL == globals)
return NULL; // If there are no globals, there is no exception
__cxa_exception* exception_header = globals->caughtExceptions;
if (NULL == exception_header)
return NULL; // No current exception
if (!isOurExceptionClass(&exception_header->unwindHeader))
return NULL; // Can't capture a foreign exception (no way to refcount it)
if (isDependentException(&exception_header->unwindHeader)) {
__cxa_dependent_exception* dep_exception_header =
reinterpret_cast<__cxa_dependent_exception*>(exception_header);
exception_header = cxa_exception_from_thrown_object(dep_exception_header->primaryException);
}
void* thrown_object = thrown_object_from_cxa_exception(exception_header);
__cxa_increment_exception_refcount(thrown_object);
return thrown_object;
}
globals是线程局部存储变量,因此thrown_object也特定于线程。我的理解是thrown_object是在线程中引发的异常-每个线程都可以引发自己的异常。
但是函数__cxa_increment_exception_refcount()自动执行增量操作-为什么?在什么情况下需要增量执行原子操作?
答案 0 :(得分:2)
您可以调用std::current_exception
并获得指向异常的智能指针:
std::exception_ptr
是一种可为空的指针式类型,用于管理已用std :: current_exception抛出并捕获的异常对象。std::exception_ptr
的实例可能会传递到另一个函数(可能在另一个线程上),在该线程中,异常可能会被重新抛出并通过catch子句进行处理。...
std::exception_ptr
是共享所有权智能指针。
由于std::exception_ptr
可以传递给另一个线程,因此引用计数器维护必须使用原子增量/减量。
参考计数器被嵌入到异常对象中,就像boost::intrusive_ptr
一样,与std::shared_ptr
不同。