Boost logo

Boost :

Subject: Re: [boost] [Stacktrace] review
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2016-12-16 16:59:03


On Sat, Dec 17, 2016 at 12:11 AM, Emil Dotchevski
<emildotchevski_at_[hidden]> wrote:
> On Fri, Dec 16, 2016 at 12:24 PM, Andrey Semashev <andrey.semashev_at_[hidden]
>> wrote:
>>
>> The backtrace itself is not a lightweght object
>
> Yes it is. It's basically a list of pointers and we can cap it by default
> at, say, 10.
>
> Just to be clear, I'm talking about adding the equivalent of something like
> this to the boost::exception class:
>
> void (*stack_trace_[10])();

What happens when the backtrace exceeds this limit? Would it be
possible to attach backtraces larger than that?

Adding an array of pointers to the base class of exceptions is also
not free. Whether one uses stacktraces or not, all Boost exceptions
become 80 bytes larger regardless. For comparison, std::runtime_error
in gcc 6 takes 16 bytes (not counting the string, if it's dynamically
allocated and not stored in-place). Not that I have thousands
exceptions stored somewhere, but that doesn't look like a reasonable
tradeoff.

>> so the overhead of the generic Boost.Exception machinery is probably not
>> significant. And if that overhead is significant then maybe it could be
>> optimized instead. After all, why have it if we don't want to use it.
>
> The cost of using the generic Boost Exception machinery is not limited to
> speed and space but also coupling. The boost::throw_exception function
> template is not coupled with any Boost libraries, while Boost Exception
> itself uses e.g. shared_ptr and a few others. That said, even the runtime
> cost of the generic Boost Exception machinery is probably an order of
> magnitude bigger than storing 10 pointers.

Thing is, the 10 pointers affect everyone, including those not using
the backtraces. They also affect boost::exception interface making it
more like a swiss knife with a bunch of case-specific APIs. That means
everyone using boost::exception are coupled with whatever is present
with those APIs. You described the 10 pointers, but I don't think you
would expose that array as is from boost::exception - if only for type
safety, you would want to wrap it into a class or something. That
class will have some methods to work with the stacktrace, and so on.
That is beside the fact that given there is Boost.Stacktrace library,
that class doesn't really belong to Boost.Exception or
throw_exception.

>> How old? I mean, it only has to support the oldest compiler Boost
>> libraries support.
>
> Yes, which is very old. :) Anyway, the point is that boost::throw_exception
> must remain extremely lightweight in terms of dependencies AND it must be
> very conservative in terms of using C++ features. Specifically, I am
> hinting that std synchronization facilities are off-limits

Intrinsics are still available.

> Requiring to link the Windows kernel? That's a breaking change, too.

But you do have to link something to obtain the backtrace. You're not
planning to implement it inline in the header, for all platforms, do
you? :)

Anyway, if everything's off limits then the only thing I can suggest
is to leave throw_exception as is and create a separate macro/function
with support for backtraces.


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