Std::rethrow_exception在嵌套线程中失败
std::rethrow_exception fails with nested threads
我有一个程序,它需要从任何未捕获的线程传播异常到主线程,以便它可以向用户提供有关它失败的原因并安全关闭的信息。我的InterThreadException
处理程序似乎工作,但只有当抛出异常的线程由主线程直接生成时。
InterTheadException
处理程序在所有情况下都被正确调用,通过将异常指针传递给它来传播异常,并且主线程接收到它已收到新异常的通知,但是对异常指针上的std::rethrow_exception
的调用简单地失败并且似乎什么都不做。我已经测试了从这两个不同的线程抛出完全相同的异常,无论我抛出什么,问题似乎都持续存在。
我怀疑我对如何使用异常指针有一个根本性的误解,但我不确定。
这是我对InterThreadExceptionHandler
的实现。
class InterThreadExceptionHandler : NonCopyable
{
public:
InterThreadExceptionHandler();
~InterThreadExceptionHandler();
//
// Sends an exception into this handler, informing it that
//this exception has been caught
// and may be propagated to another thread
//
void sendException(std::exception_ptr exception);
//
// Freezes the calling thread until an exception has been sent,
//then rethrows said exception
//
void waitForException();
private:
std::vector<std::exception_ptr> sentExceptions;
std::mutex sentExceptionsMutex;
Semaphore sentExceptionsCounter;
};
InterThreadExceptionHandler::InterThreadExceptionHandler()
{
}
InterThreadExceptionHandler::~InterThreadExceptionHandler()
{
}
void InterThreadExceptionHandler::sendException(std::exception_ptr exception)
{
ScopedLock lock(this->sentExceptionsMutex);
this->sentExceptions.push_back(exception);
this->sentExceptionsCounter.give();
}
void InterThreadExceptionHandler::waitForException()
{
this->sentExceptionsCounter.take();
ScopedLock lock(this->sentExceptionsMutex);
assert( this->sentExceptions.size() > 0 );
std::exception_ptr e = this->sentExceptions[0];
this->sentExceptions.erase(this->sentExceptions.begin());
if (e == std::exception_ptr())
{
throw std::exception("Invalid exception propagated!");
}
std::rethrow_exception(e);
}
很抱歉这不是对你问题的直接回答,但它可能会有所帮助。
如果我通过捕获异常、检查返回代码等检测到线程中的运行时错误,我让该线程冻结整个进程。我还将关闭ftracing (dtrace的一个Linux克隆),以便保留我可以获得的任何跟踪日志,以查找导致问题的原因。恐怕我不知道Windows对应的是什么。然后我可以附加一个调试器,看看发生了什么,甚至可能纠正一个值并继续执行。
它在已部署的代码中不是很有用,但在开发过程中很有用。这个问题的观点是好的,因为一切都是"原样",没有堆栈展开,其他线程没有太多的机会去任何地方,等等。这可以使故障识别更容易。对于已部署的代码,我可能会触发一个核心转储(我倾向于在unix上运行)。显然,如果某种程度的清理是必要的,这是不好的。
相关文章:
- 非静态成员失败的线程调用函数
- MS 本机单元测试 - 断言::线程失败不起作用
- 两个线程一个使用流 Api,另一个线程创建文件失败并出现错误ERROR_SHARING_VIOLATION
- 使用提升线程时编译失败
- librdkafka 线程在失败时不清理
- 错误:静态断言失败:std ::线程参数必须在转换为rvalues后不可行
- 什么时候标准::线程::连接会因no_such_process而失败
- 更改线程实时调度策略失败:config_rt_group_sched = y
- C++ 提升 UDP 接收器在放入线程时失败
- 为线程构造函数传递引用以将其绑定到函数失败
- glewInit 从后台线程调用时失败
- 链接到boost ::线程失败
- 将函子传递给boost ::线程在Visual Studio 2010中失败
- Qt 窗口包含提升线程标头失败
- 在多个线程中使用libcurl失败
- pthread_create()在Xeon Phi上每60个线程失败一次(参数无效)
- Boost线程失败Boost_ASSERT(px!=0);
- 当一个工作线程失败时,如何中止剩余的工作线程
- 一段时间后使线程失败
- Pthread_create创建多个线程失败