有没有任何方法可以在C++中导致整个堆栈框架展开?(使用异常除外)
Is there any method that causes whole stack frame unwinding in C++? (except using exception)
我一直在写一个延续-在特定的协同程序库中。它类似于std::thread(只是它是协作的)——每个执行上下文都在continuation对象中表示。
问题是关于连续对象销毁。如果在执行上下文没有正常退出的情况下调用了延续对象的dtor,则应该通过销毁对象的上下文来强制关闭它。
这样,堆栈框架中的每个C++对象都不会被正确地销毁。这可能对任何人来说都不是一个愉快的情况——所以我决定找到一个解决方案。
第一次,我想用异常来展开下面的堆栈框架。(请注意,下面只是有缺陷的psuedo代码。)
coroutine::~coroutine()
{
status = FORCED_EXIT;
switch_to(*this);
}
void coroutine::yield(coroutine& other_coroutine)
{
// switch to other context, halt until invocation by other context
switch_to(other_coroutine);
if (status_ != FORCED_EXIT) {
return; // resume
} else {
throw ContextClosingException;
}
}
void coroutine::entrypoint()
{
try {
entry_function_();
} catch(ContextClosingException& e) {
switch_to(caller_coroutine);
}
}
然而,我发现了一些关键的缺陷。任何如下"吞下异常"的用户代码都将完全打破协作调度的假设。
try {
...
} catch(...) { // ContextClosingException
// do nothing, just swallow exception.
}
所以我需要找到其他方法来调用堆栈展开(或者在延续中破坏堆栈对象的任何其他方法)。标准一致性方式会很好,但延续实现本身依赖于特定于平台的API,所以非可移植方式是可以接受的。(我使用的是win32)
在C++标准中,除了异常之外,没有任何东西允许展开堆栈。Coroutines(或对corountines的支持)可以在C++11之后提出(在Going Native会议期间讨论)。
您将不得不使用特定于操作系统的C调用(如果存在,我不这么认为),但很可能您只能使用ASM。您可以查看boost.context库中的示例解决方案。
相关文章:
- 处理多个异常集合的C++方法
- 我在c++代码中生成了一个运行时#3异常
- 孤立代码块在结构中引发异常
- C++中的赋值发生,尽管右侧出现异常
- 从构造函数抛出异常时如何克服内存泄漏
- 异常属于C++中的线程还是进程
- 当类定义不可见时捕获异常
- 在没有Xcode的情况下在Mac捆绑包中嵌入框架
- 引发异常:读取访问冲突**dynamicArray**为0x1118235.发生
- 为什么异常不退出程序?
- 为什么我应该在异常处理中使用std::cerr而不是std::cout
- catch框架有没有办法比较流或文件
- 如何修复链表类实现的未处理异常0xDDDDDDDD
- 关于:C++中异常对象的范围:为什么我没有得到副本?
- 是什么导致了Unity 3D中的"错误线程异常"?
- 如何将strftime中的格式错误作为异常捕获
- 有没有任何方法可以在C++中导致整个堆栈框架展开?(使用异常除外)
- c++禁止堆栈框架下的异常
- CppUTest单元测试框架多定义异常
- CLR 有胖或小的异常框架