Boost logo

Boost Users :

Subject: [Boost-users] [fiber] Fiber context switching during stack unwinding...
From: Oliver Seiler (oseiler_at_[hidden])
Date: 2018-02-28 05:45:16


(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



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net