【问题标题】:std::rethrow_exception fails with nested threadsstd::rethrow_exception 因嵌套线程而失败
【发布时间】:2013-02-19 06:17:25
【问题描述】:

我有一个程序需要将异常从任何未捕获的线程传播到主线程,以便它可以向用户提供有关它失败的原因并安全关闭的信息。我的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);
}

【问题讨论】:

  • 你的类在 GNU/Linux 上与 GCC 一起工作得很好(在将 count() 更改为 size() 并将调用更改为非标准 std::exception 构造函数并将 Semaphore 替换为 std::condition_variable 之后) 所以这听起来像是一个 MSVC 错误。线程是由main 线程还是由其他线程产生的,这无关紧要。
  • 在vs2013上能用吗?
  • 是否适用于VS2015或VS2017?

标签: c++ multithreading exception c++11 visual-studio-2012


【解决方案1】:

抱歉,这不是您问题的直接答案,但无论如何它可能会有所帮助。

如果我通过捕获异常、检查返回码等方式检测到线程中的运行时错误,我会让该线程冻结整个进程。我还将让它关闭 ftracing(dtrace 的 Linux 克隆),以便保留我可以获得的任何跟踪日志,以解决问题。恐怕我不知道 Windows 等价物是什么。然后我可以附加一个调试器并环顾四周看看发生了什么,甚至可以更正一个值并继续执行。

它在已部署的代码中不是很有用,但在开发过程中却非常有用。对问题的看法很好,因为一切都“按原样”存在,没有堆栈展开,其他线程没有太多机会到达任何地方,等等。这可以使故障识别更容易。对于已部署的代码,我可能会引发核心转储(我倾向于在 unixy 上运行)。显然,如果需要进行某种程度的清理,那就不好了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-24
    相关资源
    最近更新 更多