houseabsolute / devel-stacktrace Goto Github PK
View Code? Open in Web Editor NEWAn object representing a stack trace
Home Page: https://metacpan.org/release/Devel-StackTrace/
License: Other
An object representing a stack trace
Home Page: https://metacpan.org/release/Devel-StackTrace/
License: Other
Migrated from rt.cpan.org #99095 (status was 'open')
Requestors:
From [email protected] (@karenetheridge) on 2014-09-23 23:20:27:
I'm afraid I don't have a reproduction case to give you, but I'm seeing this (reliably) on one of my test systems:
Can't call method "as_string" on an undefined value at /var/local/CE/extlib/lib/perl5/Devel/StackTrace.pm line 243 during global destruction.
line 243 is $st .= $f->as_string( $first, $p ) . "\n";
Is it possible that some of the frames are being destroyed prematurely? Or simply that an error condition during global destruction should be treated differently?
I have an Exception
class that consumes the Throwable
role. Furthermore I have an XMLException
class that extends the Exception
class. In the
sub BUILD { print STDERR Devel::StackTrace->new->as_string }
method of the Exception
class I am using Devel::Stacktrace
to dump a trace like this
Trace begun at lib/Exception.pm line 21
Exception::BUILD('XMLException=HASH(0x1109928e8)', 'HASH(0x1109928b8)') called at (eval 110) line 78
XMLException::new(undef, 'message', 'cannot read line') called at (eval 109) line 26
Exception::new('XMLException', 'message', 'cannot read line') called at local/lib/perl5/Throwable.pm line 75
Throwable::throw('XMLException', 'message', 'cannot read line') called at t/parse.pl line 8
main::read_line at t/parse.pl line 12
main::parse at t/parse.pl line 16
eval {...} at t/parse.pl line 16
I have changed the trace I want to print using a frame_filter
sub BUILD {
print STDERR Devel::StackTrace->new(
frame_filter => sub { return 0 if $_[ 0 ]{ caller }[ 0 ]->DOES( 'Throwable' ); return 1 } )->as_string;
}
This is the expected result
Trace begun at t/parse.pl line 8
main::read_line at t/parse.pl line 12
main::parse at t/parse.pl line 16
eval {...} at t/parse.pl line 16
For me the top frame of the filtered trace is
main::read_line at t/parse.pl line 12
but when I use
sub BUILD {
my $trace =
Devel::StackTrace->new( frame_filter => sub { return 0 if $_[ 0 ]{ caller }[ 0 ]->DOES( 'Throwable' ); return 1 } );
print STDERR $trace->next_frame->as_string, "\n";
}
I am getting
Throwable::throw('XMLException', 'message', 'cannot read line') called at t/parse.pl line 8
but why?
The filename in stack traces is normalized with File::Spec->canonpath. On unix systems, this will usually not change the reported file name. On Win32, it will usually change the directory separators. This makes the filename not match what perl thinks it is for the files, so it won't match things like __FILE__
, %INC
keys, internal error messages, or other uses of caller
, including Carp. The normalization doesn't seem particularly useful to begin with in this case, so I think it may be better to remove it. There could be some backwards compatibility issues with changing it though.
found while investigating a Moose/Throwable bug:
$ perl -MDevel::StackTrace -wle'sub foo { return Devel::StackTrace->new(message=>"something bad happened", indent=>1, skip_frames=>0, no_refs=>1);} my $trace= foo(); print $trace'
something bad happened at -e line 1
main::foo at -e line 1
$ perl -MDevel::StackTrace -wle'sub foo { return Devel::StackTrace->new(message=>"something bad happened", indent=>1, skip_frames=>1, no_refs=>1);} my $trace= foo(); print $trace'
something bad happened at -e line 1
$ perl -MDevel::StackTrace -wle'sub foo { return Devel::StackTrace->new(message=>"something bad happened", indent=>1, skip_frames=>2, no_refs=>1);} my $trace= foo(); print $trace'
No matter how high skip_frames
is, the message
part of the string should never be lost -- as that's still important.
I quite often find myself skipping frames at the top of the stack with
$t->frames( after_incl { $_->package !~ /^Foo::Bar\b|^Baz$/ } $t->frames );
my $where = first { $_->package !~ /^Foo::Bar\b|^Baz$/ } $t->frames;
i.e. not unlike what Carp::Clan does, and I can't help myself thinking that something like this (the first, filtering example) should be builtin; perhaps skip_package
and skip_class
params similar to the ignore_*
params.
Why doesn't Devel::StackTrace::Frame have overloaded stringification through as_string
?
Migrated from rt.cpan.org #50447 (status was 'open')
Requestors:
Attachments:
From [email protected] on 2009-10-13 14:12:36:
Simple (but awful) code, that raise error:
use Devel::StackTrace;
sub do_work {
my $s = Devel::StackTrace->new(
'no_refs' => 1,
);
}
sub call_with_args {
my ($arg_hash, $func) = @_;
$func->( @{$arg_hash->{'args'}} );
}
my $h = {};
my $arg_hash = { 'args' => [ undef ] };
call_with_args(
$arg_hash, sub {
$arg_hash->{'args'} = [];
do_work( sub { $h; } );
}
);
I propose this solution (in StackTrace.pm)
sub _record_caller_data
{
my $self = shift;
# We exclude this method by starting one frame back.
my $x = 1;
while ( my @c =
do { package DB; @DB::args = (); caller($x++) } )
{
my @args;
foreach ( @DB::args )
{
my $arg;
local $@;
eval
{
$arg = $self->{'no_refs'} && ref $_ ? $self->_ref_to_string( $_ ) : $_;
};
if ( $@ =~ /^Bizarre copy of \w+/ )
{
$arg = $&;
}
push @args, $arg;
}
push @{ $self->{raw} },
{ 'caller' => \@c,
'args' => \@args,
};
}
}
if ($trace && some_other_condition()) {
$trace->as_string;
}
this code looks as if $trace->as_string
doesn't get called if some_other_condition()
is false, or just once if the condition is true. But actually, the first if ($trace)
triggers as_string
due to the string overloading, and how perl's overload automatically uses the string value for boolean check. As a result, $trace->as_string
is called one extra time which could cause some slow down in the app when the stacktrace is huge.
Consider adding bool => sub { 1 }
to the overload list to avoid this. I've worked around in the caller code to change the if statement to if (ref $trace)
for now.
Migrated from rt.cpan.org #54611 (status was 'open')
Requestors:
Attachments:
From [email protected] on 2010-02-15 02:37:28:
(As outlined by mail privately the other day:)
Currently, the user has limited control over the way the stacktrace is
formatted for display. It would be nice to be able to have stacktraces
in ANSI colors, for example. They stand out better in the logfile.
The modifications required to accomodate this new feature are relatively
minor. See the attached patch (not the same as the one
Would you be opposed to adding the content of @DB::args
to this, so that at a given level of the stack trace the object would indicate what the passed arguments were? It seems useful โฆ
Looks handy to have something like this in application $Devel::StackTrace::ignore_package = [ 'Try::Tiny' ];
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.