Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2022-02-15 00:50:09


Gavin Lambert wrote:
> Not sure about gcc/clang/Linux, but with msvc/Windows it's possible to
> recover a stack trace from any thrown exception regardless of type, without
> any fanfare at the throw site (albeit only by relying on some fugly compiler
> internals).

Not sure that's true for Linux/macOS. Windows exception handling is
unique in that the stack is not touched (except for running the destructors)
during unwinding so the frames are still intact.

> Although also I thought one of the main selling points of Boost.StackTrace is
> that it's nearly free to capture a trace at time of exception; it's only formatting
> into human-readable that's potentially expensive, but that only happens at the
> other end on demand.
>
>
> Personally, I find passing around source-locations to be completely useless
> (and subject to binary bloat and undesirable disclosure, as Niall pointed out).
> Stack traces all the way.

Now that Stacktrace is in the C++23 standard, there's an interesting proposal
to make stacktrace captures automatic on throw:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2370r2.html

although I'm not sure it will fly, even for C++26.

It's nice to have stack traces, but we can't realistically make ThrowException
depend on Stacktrace, for several reasons. First and least, dependency cycles.
Second, Stacktrace is not header-only, so all header-only libraries that throw
exceptions will acquire a compiled dependency, which is a massive pain.

And third, even for compiled libraries, the way Stacktrace uses separate library
per backend makes it hard to express the dependency in b2 or CMake, because
you have no idea what target your library needs to link to.

All in all, that's currently impractical (for Boost libraries.)

But there's more to it. If you follow a straightforward style in which you
immediately throw on error, capturing stack traces on throw works well. But
if your library is written to use error codes internally, so that it can expose a
dual API to the user, that is, to be usable with either exceptions or error codes,
things are not so rosy. That's because failures are propagated upwards through
several layers using error codes, and only at the last layer is that turned into
an exception. So you get a stack trace from that point upwards, which is not
as helpful.

With source locations you don't get a stack trace at all, but you do get two
locations, one where the error code was originally produced, and one where
it got turned into an exception.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk