develooper Front page | perl.perl5.porters | Postings from September 2023

Re: Native stack traces?

Thread Previous | Thread Next
September 8, 2023 17:30
Re: Native stack traces?
Message ID:
On Fri, 8 Sept 2023 at 18:52, Dave Mitchell <> wrote:

> On Fri, Sep 08, 2023 at 04:52:16PM +0100, Paul "LeoNerd" Evans wrote:
> > At least for me, stacktraces fall below the criteria to bother spending
> > a lot of time on just at the moment, when there's so many other things
> > to be done. But of course that's not to stop anyone else who wishes to
> > have a go.
> On the other hand, the current 'package DB; @args = @DB::args' is a
> horrible hack. Perhaps once signatures have been properly implemented
> (with the original args kept on the stack rather than quietly being copied
> into @_ and accessed from there) it might be time to revisit the official
> API that perl provides to access the stack args, and come up up with
> something better? For example something that can extract the names of
> named parameters.
> But I think creating exception objects which can have stack trace info
> attached to them or similar, is a tad ambitious.
> PS:
> This quick-n-dirty sample code creates a full stack trace about 75,000
> times per second on my laptop. It sanitises the output by just listing the
> class or type of the arg, such as,
> It shows that such code can be small and fast.
> Here goes:
>     package Foo;
>     f(bless({}, 'Foo'), [], qw(here's some args for f));
>     sub f { my $self = shift; $self->g(qw(args for g)) }
>     sub g { my $self = shift; $self->h(qw(h's args))   }
>     sub h {
>         my $self = shift;
>         for my $i (1..100_000) {
>             dump_stack();
>         }
>     }
>     sub dump_stack {
>         my @c;
>         my $i = 0;
>         my @frames;
>         package DB;
>         while (@c = caller(++$i)) {
>             my @args = map ref ? ref : ref \$_, @DB::args;
>             push @frames, "$c[1]:$c[2] $c[3](" . join(', ', @args) .
> ")\n";
>         }
>     }

That stack isnt very deep and the args on the stack aren't complex, and as
you said what it does with those arguments isnt very fancy. Also there are
a lot of subtleties that code leaves out. A typical use case for a stack
trace dump is to be called from a $SIG{__DIE__} handler, and in that
context you probably want to be careful about dealing with eval frames.
Either because you specifically *don't* want to serialize the stack from a
specific eval frame, or because you *do* want to do so, or a mixture of
both, where you want to ignore some eval frames at the top of the stack but
not those at the bottom.  So $^S comes up as a factor, and within a
web-server there is a very good chance you actually want to let the
developer decide if a given eval should disable the stack-trace or not, so
you end up needing code that counts the number of eval frames in the stack,
and provide a way for users to control how many evals to ignore. So a
simple implementation probably acquires additional functionality over time.
Consider that a good stack trace dumper used in a corporate setting
probably shouldnt accidentally dump credit card numbers and other sensitive
data, and you end up needing a fair bit of logic.


perl -Mre=debug -e "/just|another|perl|hacker/"

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About