C++ Logo

std-proposals

Advanced search

Re: Stacktrace from exception

From: Ville Voutilainen <ville.voutilainen_at_[hidden]>
Date: Wed, 28 Apr 2021 14:15:10 +0300
On Wed, 28 Apr 2021 at 14:04, Andrey Semashev via Std-Proposals
<std-proposals_at_[hidden]> wrote:
>
> On 4/28/21 1:34 PM, Edward Catmur wrote:
> >
> >
> > On Wed, 28 Apr 2021 at 11:22, Andrey Semashev via Std-Proposals
> > <std-proposals_at_[hidden] <mailto:std-proposals_at_[hidden]>>
> > wrote:
> >
> > On 4/28/21 1:21 PM, Andrey Semashev wrote:
> > > Saving a single pointer is not enough to capture a stacktrace. A
> > > captured stacktrace is supposed to be stable and not rely on the
> > current
> > > state of frames on the stack, which means the whole snapshot of
> > > information related to frames need to be copied at the point of
> > capture.
> > > This is a dynamic amount of information, dependent on the number of
> > > frames and the max depth you want to save, and it is definitely
> > larger
> > > than a pointer.
> >
> >
> > It's only one pointer per frame, though; and as Antony says, you've
> > likely already determined that pointer while unwinding. So the only real
> > overhead is in allocating the array of pointers.
>
> You're only unwinding up to the exception handler. And the handler may
> save the stacktrace to extend its lifetime beyond its scope. This means,
> to make the stacktrace persistent and not limited to the exception
> handler stack frame, one has to unwind and save information beyond the
> exception handler.

Yep - and you and Antony both know this, but for other people,
consider the following use case:
1) you get a stack trace
2) you invoke a function that processes the stack trace.

I don't think you want the stacktrace to change just because you
called a function to process it, right? :)
Thus it's not just a simple matter of capturing frame pointer.

> > > I'm firmly of an opinion that the stacktrace capturing must be an
> > > explicit operation issued by the user at the throw site. It must
> > not be
> > > implicitly done on every throw. And no, making it an optional
> > opt-in is
> > > not acceptable either, as it will affect the existing code that
> > has no
> > > idea of this new feature.
> >
> > I meant "opt-out" in the sentence above. It should be an explicit
> > opt-in.
> >
> >
> > That makes it significantly less useful; where we've found exception
> > stack traces most useful is when an exception is being thrown from deep
> > inside third-party library code, that we either don't control or know
> > enough about to modify all throw sites.
>
> I realize that. But at the same time, I would not want all that overhead
> to capture the stacktrace in cases when I don't use or don't care about
> the stacktrace, and that is the absolute majority of cases today.

Indeed. While the ability to inject stacktrace capture and emission to
existing code is interesting, that's
really a separate matter and shouldn't be baked into all exceptions.

> In my view, this new feature has to be accompanied by the standard
> library additions, which would make attaching arbitrary data, including
> stacktraces, to exceptions easy. Something similar to Boost.Exception.
> As a result, this feature would be used where it truly matters.

Strongly agreed.

> > On the other hand, given 2-phase unwinding, it would be feasible to
> > opt-in at the *catch* site. This would work for everything except
> > third-party code that transports exceptions via std::exception_ptr. But
> > you'd need syntax for that.
>
> I don't think stacktraces should be inherently tied to exceptions. I
> mean, if there are optimizations possible wrt. stacktraces with
> exceptions, that is fine. But there are cases when one would like to
> obtain a stacktrace without an exception, and those should work as well.

Also agreed. I may have code that wishes to capture stacktraces even though that
code doesn't throw; code that handles errors without exceptions, code that just
wants to dump a stacktrace somewhere when it encounters a rare error situation,
etc. etc.

Received on 2021-04-28 06:15:25