Hi,
The documentation for boost context contains the following warning: "Do not jump from inside a catch block and then re-throw the exception in another continuation. "
It's on this page: http://www.boost.org/doc/libs/1_66_0/libs/context/doc/html/context/cc.html
Context switching with call/cc - 1.66.0 - boost.orghttp://www.boost.org/doc/libs/1_66_0/libs/context/doc/html/context/cc.html
www.boost.org
call/cc (call with current continuation) is a universal control operator (well-known from the programming language Scheme) that captures the current continuation as a ...
________________________________
From: Boost-users on behalf of Oliver Seiler via Boost-users
Sent: Wednesday, February 28, 2018 6:45:16 AM
To: boost-users@lists.boost.org
Cc: Oliver Seiler
Subject: [Boost-users] [fiber] Fiber context switching during stack unwinding...
(Hopefully I'm not writing an essay for something that is a gcc/libstdc++/Linux bug)
I've been using Boost.Context for a number of years now, to do something similar to what Boost.Fiber does. We recently upgraded our development target environment to Debian 9 (gcc 6.3), and moved up to Boost 1.62.0, so I've been looking at Boost.Fiber to replace how we're using Boost.Context (because it looks like it could greatly simplify our code, among other things).
One thing I ran into with Boost.Context was that it interacted in some interesting ways with exception handling, and I haven't really seen any discussion about it. Specifically, switching contexts with an active exception (so during stack unwinding, or in a catch block) would result in weird behaviour in the other context (std::uncaught_exception() returning true, std::current_exception() returning the exception from the other context, try/catches in the new context causing new problems when switching back to the original context which is in the middle of stack unwinding, etc).
I chalked that up to limitations of the context switching, though I haven't seen any mention of avoiding context switches with active exceptions; presumably this is some interaction with gcc's exception implementation, and would maybe need support from libunwind to save/restore the exception state (I don't recall if I checked if clang produced similar results, though I'll probably give it a go when I have the chance). So I wasn't surprised when I ran into similar problems with Boost.Fiber.
I am wondering why this aspect of usage isn't discussed in any of the documentation; it would be nice if these libraries could work well with language features like exceptions, but I understand that the language spec doesn't really speak to the stack switching happening under-the-hood. It actually wouldn't surprise me that this wasn't even a problem in all environments, and just happens to be an artifact of the Linux implementation, but then we're either talking about unspecified or undefined behaviour, but would be nice to know. Even in the documents going through the C++ standards committee I don't see much mention of how things like coroutines should interact with something like std::current_exception() (perhaps because it is assumed to "just work" and doesn't need additional comment?)
Anyone else ever run into issues related to this? Seems like any use of RAII for exception handling would easily run into problems. Mostly I've just found ways to work around it (e.g., not allowing the context switch if std::uncaught_exception() or std::current_exception() indicate it would be unsafe to do so, typically by throwing another exception) but this tends to make libraries harder to use correctly (e.g., can't really allow context switching in a destructor, or in a function called from a destructor, etc).
Cheers
Oliver