|
Boost : |
From: Gavin Lambert (boost_at_[hidden])
Date: 2022-02-15 01:39:03
On 15/02/2022 13:50, Peter Dimov wrote:
> 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.
Perhaps StackTrace could be split into a capture-only component that has
the properties you desire and a formatting component for the rest?
Although I suspect platform differences for stack capture would likely
make having it be header-only too impractical. Still, I usually regard
header-only as a misfeature anyway.
What's probably a more practical solution might be to have potential
throw sites declare a context object on their stack. Any Boost-aware
throw that occurs while these objects are on the stack would capture
whatever additional information is requested by the context objects that
are still in scope at the time. This might be a stack trace, a source
location, a plain string, or any other context info (e.g. method
parameters) that seems useful.
(This fixes the dependency problem because it could be StackTrace, or a
third library dependent on both, that provides the stack-tracing-capture
context class. And one instance of this could be declared at the top of
each thread to cause stack tracing on any Boost-aware exception thrown
on the thread.)
One possible downside is that this is unlikely to be zero-cost in the
successful path, unless you can avoid making copies of the data unless
an exception is actually thrown, which might limit what can be captured
(e.g. capturing calculated rvalues may be harder, though possibly a
lambda may help hide that).
> 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.
Sure, but there still has to be some mechanism to pass that additional
information along with the error code. (Such as Boost.LEAF.)
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk