|
Packit |
985e12 |
use strict;
|
|
Packit |
985e12 |
use warnings;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
use Test::More 0.88;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
use Devel::StackTrace;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
sub get_file_name { File::Spec->canonpath( ( caller(0) )[1] ) }
|
|
Packit |
985e12 |
my $test_file_name = get_file_name();
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
# Test all accessors
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
my $trace = foo();
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my @f = ();
|
|
Packit |
985e12 |
while ( my $f = $trace->prev_frame ) { push @f, $f; }
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my $cnt = scalar @f;
|
|
Packit |
985e12 |
is(
|
|
Packit |
985e12 |
$cnt, 4,
|
|
Packit |
985e12 |
'Trace should have 4 frames'
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
@f = ();
|
|
Packit |
985e12 |
while ( my $f = $trace->next_frame ) { push @f, $f; }
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
$cnt = scalar @f;
|
|
Packit |
985e12 |
is(
|
|
Packit |
985e12 |
$cnt, 4,
|
|
Packit |
985e12 |
'Trace should have 4 frames'
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
is(
|
|
Packit |
985e12 |
$f[0]->package, 'main',
|
|
Packit |
985e12 |
'First frame package should be main'
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
is(
|
|
Packit |
985e12 |
$f[0]->filename, $test_file_name,
|
|
Packit |
985e12 |
"First frame filename should be $test_file_name"
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
is( $f[0]->line, 1009, 'First frame line should be 1009' );
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
is(
|
|
Packit |
985e12 |
$f[0]->subroutine, 'Devel::StackTrace::new',
|
|
Packit |
985e12 |
'First frame subroutine should be Devel::StackTrace::new'
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
is( $f[0]->hasargs, 1, 'First frame hasargs should be true' );
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
ok(
|
|
Packit |
985e12 |
!$f[0]->wantarray,
|
|
Packit |
985e12 |
'First frame wantarray should be false'
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my $trace_text = <<"EOF";
|
|
Packit |
985e12 |
Trace begun at $test_file_name line 1009
|
|
Packit |
985e12 |
main::baz(1, 2) called at $test_file_name line 1005
|
|
Packit |
985e12 |
main::bar(1) called at $test_file_name line 1001
|
|
Packit |
985e12 |
main::foo at $test_file_name line 13
|
|
Packit |
985e12 |
EOF
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
is( $trace->as_string, $trace_text, 'trace text' );
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
# Test constructor params
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
my $trace = SubTest::foo( ignore_class => 'Test' );
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my @f = ();
|
|
Packit |
985e12 |
while ( my $f = $trace->prev_frame ) { push @f, $f; }
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my $cnt = scalar @f;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
is( $cnt, 1, 'Trace should have 1 frame' );
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
is(
|
|
Packit |
985e12 |
$f[0]->package, 'main',
|
|
Packit |
985e12 |
'The package for this frame should be main'
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
$trace = Test::foo( ignore_class => 'Test' );
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
@f = ();
|
|
Packit |
985e12 |
while ( my $f = $trace->prev_frame ) { push @f, $f; }
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
$cnt = scalar @f;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
is( $cnt, 1, 'Trace should have 1 frame' );
|
|
Packit |
985e12 |
is(
|
|
Packit |
985e12 |
$f[0]->package, 'main',
|
|
Packit |
985e12 |
'The package for this frame should be main'
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
# 15 - stringification overloading
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
my $trace = baz();
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my $trace_text = <<"EOF";
|
|
Packit |
985e12 |
Trace begun at $test_file_name line 1009
|
|
Packit |
985e12 |
main::baz at $test_file_name line 99
|
|
Packit |
985e12 |
EOF
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my $t = "$trace";
|
|
Packit |
985e12 |
is( $t, $trace_text, 'trace text' );
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
# 16-18 - frame_count, frame, reset_pointer, frames methods
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
my $trace = foo();
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
is(
|
|
Packit |
985e12 |
$trace->frame_count, 4,
|
|
Packit |
985e12 |
'Trace should have 4 frames'
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my $f = $trace->frame(2);
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
is(
|
|
Packit |
985e12 |
$f->subroutine, 'main::bar',
|
|
Packit |
985e12 |
q{Frame 2's subroutine should be 'main::bar'}
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
$trace->next_frame;
|
|
Packit |
985e12 |
$trace->next_frame;
|
|
Packit |
985e12 |
$trace->reset_pointer;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
$f = $trace->next_frame;
|
|
Packit |
985e12 |
is(
|
|
Packit |
985e12 |
$f->subroutine, 'Devel::StackTrace::new',
|
|
Packit |
985e12 |
'next_frame should return first frame after call to reset_pointer'
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my @f = $trace->frames;
|
|
Packit |
985e12 |
is(
|
|
Packit |
985e12 |
scalar @f, 4,
|
|
Packit |
985e12 |
'frames method should return four frames'
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
is(
|
|
Packit |
985e12 |
$f[0]->subroutine, 'Devel::StackTrace::new',
|
|
Packit |
985e12 |
q{first frame's subroutine should be Devel::StackTrace::new}
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
is(
|
|
Packit |
985e12 |
$f[3]->subroutine, 'main::foo',
|
|
Packit |
985e12 |
q{last frame's subroutine should be main::foo}
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
# Not storing references
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
my $obj = RefTest->new;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my $trace = $obj->{trace};
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my $call_to_trace = ( $trace->frames )[1];
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my @args = $call_to_trace->args;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
is(
|
|
Packit |
985e12 |
scalar @args, 1,
|
|
Packit |
985e12 |
'Only one argument should have been passed in the call to trace()'
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
like(
|
|
Packit |
985e12 |
$args[0], qr/RefTest=HASH/,
|
|
Packit |
985e12 |
q{Actual object should be replaced by string 'RefTest=HASH'}
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
# Storing references
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
my $obj = RefTest2->new;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my $trace = $obj->{trace};
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my $call_to_trace = ( $trace->frames )[1];
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my @args = $call_to_trace->args;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
is(
|
|
Packit |
985e12 |
scalar @args, 1,
|
|
Packit |
985e12 |
'Only one argument should have been passed in the call to trace()'
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
isa_ok( $args[0], 'RefTest2' );
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
# Storing references (deprecated interface 1)
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
my $obj = RefTestDep1->new;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my $trace = $obj->{trace};
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my $call_to_trace = ( $trace->frames )[1];
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my @args = $call_to_trace->args;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
is(
|
|
Packit |
985e12 |
scalar @args, 1,
|
|
Packit |
985e12 |
'Only one argument should have been passed in the call to trace()'
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
isa_ok( $args[0], 'RefTestDep1' );
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
# No ref to Exception::Class::Base object without refs
|
|
Packit |
985e12 |
if ( $Exception::Class::VERSION && $Exception::Class::VERSION >= 1.09 )
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
## no critic (ErrorHandling::RequireCheckingReturnValueOfEval)
|
|
Packit |
985e12 |
eval {
|
|
Packit |
985e12 |
Exception::Class::Base->throw(
|
|
Packit |
985e12 |
error => 'error',
|
|
Packit |
985e12 |
show_trace => 1,
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
};
|
|
Packit |
985e12 |
my $exc = $@;
|
|
Packit |
985e12 |
eval { quux($exc) };
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
ok( !$@, 'create stacktrace with no refs and exception object on stack' );
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
sub FooBar::some_sub { return Devel::StackTrace->new }
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my $trace = eval { FooBar::some_sub('args') };
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my $f = ( $trace->frames )[2];
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
is( $f->subroutine, '(eval)', 'subroutine is (eval)' );
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my @args = $f->args;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
is( scalar @args, 0, 'no args given to eval block' );
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
package #hide
|
|
Packit |
985e12 |
FooBarBaz;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
sub func2 {
|
|
Packit |
985e12 |
return Devel::StackTrace->new( ignore_package => qr/^FooBar/ );
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
sub func1 { FooBarBaz::func2() }
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my $trace = FooBarBaz::func1('args');
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my @f = $trace->frames;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
is( scalar @f, 1, 'check regex as ignore_package arg' );
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
## no critic (Modules::ProhibitMultiplePackages)
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
package #hide
|
|
Packit |
985e12 |
StringOverloaded;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
use overload q{""} => sub {'overloaded'};
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
my $o = bless {}, 'StringOverloaded';
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my $trace = baz($o);
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
unlike(
|
|
Packit |
985e12 |
$trace->as_string, qr/\boverloaded\b/,
|
|
Packit |
985e12 |
'overloading is ignored by default'
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
my $o = bless {}, 'StringOverloaded';
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my $trace = respect_overloading($o);
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
like(
|
|
Packit |
985e12 |
$trace->as_string, qr/\boverloaded\b/,
|
|
Packit |
985e12 |
'overloading is ignored by default'
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
package #hide
|
|
Packit |
985e12 |
BlowOnCan;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
sub can { die 'foo' }
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
my $o = bless {}, 'BlowOnCan';
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my $trace = baz($o);
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
like(
|
|
Packit |
985e12 |
$trace->as_string, qr/BlowOnCan/,
|
|
Packit |
985e12 |
'death in overload::Overloaded is ignored'
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
my $trace = max_arg_length('abcdefghijklmnop');
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my $trace_text = <<"EOF";
|
|
Packit |
985e12 |
Trace begun at $test_file_name line 1021
|
|
Packit |
985e12 |
main::max_arg_length('abcdefghij...') called at $test_file_name line 307
|
|
Packit |
985e12 |
EOF
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
is( $trace->as_string, $trace_text, 'trace text' );
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my $trace_text_1 = <<"EOF";
|
|
Packit |
985e12 |
Trace begun at $test_file_name line 1021
|
|
Packit |
985e12 |
main::max_arg_length('abc...') called at $test_file_name line 307
|
|
Packit |
985e12 |
EOF
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
is(
|
|
Packit |
985e12 |
$trace->as_string( { max_arg_length => 3 } ),
|
|
Packit |
985e12 |
$trace_text_1,
|
|
Packit |
985e12 |
'trace text, max_arg_length = 3',
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
SKIP:
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
skip 'Test only runs on Linux', 1
|
|
Packit |
985e12 |
unless $^O eq 'linux';
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my $frame = Devel::StackTrace::Frame->new(
|
|
Packit |
985e12 |
[ 'Foo', 'foo/bar///baz.pm', 10, 'bar', 1, 1, q{}, 0 ],
|
|
Packit |
985e12 |
[]
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
is( $frame->filename, 'foo/bar/baz.pm', 'filename is canonicalized' );
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
my $obj = RefTest4->new();
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my $trace = $obj->{trace};
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
ok(
|
|
Packit |
985e12 |
( !grep { ref $_ } map { @{ $_->{args} } } @{ $trace->{raw} } ),
|
|
Packit |
985e12 |
'raw data does not contain any references when unsafe_ref_capture not set'
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
is(
|
|
Packit |
985e12 |
$trace->{raw}[1]{args}[1], 'not a ref',
|
|
Packit |
985e12 |
'non-refs are preserved properly in raw data as well'
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
my $trace = overload_no_stringify( CodeOverload->new() );
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
## no critic (ErrorHandling::RequireCheckingReturnValueOfEval)
|
|
Packit |
985e12 |
eval { $trace->as_string() };
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
is(
|
|
Packit |
985e12 |
$@, q{},
|
|
Packit |
985e12 |
'no error when respect_overload is true and object overloads but does not stringify'
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
my $trace = Filter::foo();
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my @frames = $trace->frames();
|
|
Packit |
985e12 |
is( scalar @frames, 2, 'frame_filtered trace has just 2 frames' );
|
|
Packit |
985e12 |
is(
|
|
Packit |
985e12 |
$frames[0]->subroutine(), 'Devel::StackTrace::new',
|
|
Packit |
985e12 |
'first subroutine'
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
is(
|
|
Packit |
985e12 |
$frames[1]->subroutine(), 'Filter::bar',
|
|
Packit |
985e12 |
'second subroutine (skipped Filter::foo)'
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
my $trace = FilterAllFrames::a_foo();
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
my @frames = $trace->frames();
|
|
Packit |
985e12 |
is(
|
|
Packit |
985e12 |
scalar @frames, 2,
|
|
Packit |
985e12 |
'after filtering whole list of frames, got just 2 frames'
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
is(
|
|
Packit |
985e12 |
$frames[0]->subroutine(), 'FilterAllFrames::a_bar',
|
|
Packit |
985e12 |
'first subroutine'
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
is(
|
|
Packit |
985e12 |
$frames[1]->subroutine(), 'FilterAllFrames::a_foo',
|
|
Packit |
985e12 |
'second subroutine'
|
|
Packit |
985e12 |
);
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
done_testing();
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
# This means I can move these lines down without constantly fiddling
|
|
Packit |
985e12 |
# with the checks for line numbers in the tests.
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
#line 1000
|
|
Packit |
985e12 |
sub foo {
|
|
Packit |
985e12 |
bar( @_, 1 );
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
sub bar {
|
|
Packit |
985e12 |
baz( @_, 2 );
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
sub baz {
|
|
Packit |
985e12 |
Devel::StackTrace->new( @_ ? @_[ 0, 1 ] : () );
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
sub quux {
|
|
Packit |
985e12 |
Devel::StackTrace->new();
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
sub respect_overloading {
|
|
Packit |
985e12 |
Devel::StackTrace->new( respect_overload => 1 );
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
sub max_arg_length {
|
|
Packit |
985e12 |
Devel::StackTrace->new( max_arg_length => 10 );
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
sub overload_no_stringify {
|
|
Packit |
985e12 |
return Devel::StackTrace->new( respect_overload => 1 );
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
package #hide
|
|
Packit |
985e12 |
Test;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
sub foo {
|
|
Packit |
985e12 |
trace(@_);
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
sub trace {
|
|
Packit |
985e12 |
Devel::StackTrace->new(@_);
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
package #hide
|
|
Packit |
985e12 |
SubTest;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
use base qw(Test);
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
sub foo {
|
|
Packit |
985e12 |
trace(@_);
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
sub trace {
|
|
Packit |
985e12 |
Devel::StackTrace->new(@_);
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
package #hide
|
|
Packit |
985e12 |
RefTest;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
sub new {
|
|
Packit |
985e12 |
my $self = bless {}, shift;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
$self->{trace} = trace($self);
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
return $self;
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
sub trace {
|
|
Packit |
985e12 |
Devel::StackTrace->new();
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
package #hide
|
|
Packit |
985e12 |
RefTest2;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
sub new {
|
|
Packit |
985e12 |
my $self = bless {}, shift;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
$self->{trace} = trace($self);
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
return $self;
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
sub trace {
|
|
Packit |
985e12 |
Devel::StackTrace->new( unsafe_ref_capture => 1 );
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
package #hide
|
|
Packit |
985e12 |
RefTestDep1;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
sub new {
|
|
Packit |
985e12 |
my $self = bless {}, shift;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
$self->{trace} = trace($self);
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
return $self;
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
sub trace {
|
|
Packit |
985e12 |
Devel::StackTrace->new( no_refs => 0 );
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
package #hide
|
|
Packit |
985e12 |
RefTest4;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
sub new {
|
|
Packit |
985e12 |
my $self = bless {}, shift;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
$self->{trace} = trace( $self, 'not a ref' );
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
return $self;
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
sub trace {
|
|
Packit |
985e12 |
Devel::StackTrace->new();
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
package #hide
|
|
Packit |
985e12 |
CodeOverload;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
use overload '&{}' => sub {'foo'};
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
sub new {
|
|
Packit |
985e12 |
my $class = shift;
|
|
Packit |
985e12 |
return bless {}, $class;
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
package #hide
|
|
Packit |
985e12 |
Filter;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
sub foo {
|
|
Packit |
985e12 |
bar();
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
sub bar {
|
|
Packit |
985e12 |
return Devel::StackTrace->new(
|
|
Packit |
985e12 |
frame_filter => sub { $_[0]{caller}[3] ne 'Filter::foo' } );
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
{
|
|
Packit |
985e12 |
package #hide
|
|
Packit |
985e12 |
FilterAllFrames;
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
sub a_foo { b_foo() }
|
|
Packit |
985e12 |
sub b_foo { a_bar() }
|
|
Packit |
985e12 |
sub a_bar { b_bar() }
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
sub b_bar {
|
|
Packit |
985e12 |
my $stacktrace = Devel::StackTrace->new();
|
|
Packit |
985e12 |
$stacktrace->frames( only_a_frames( $stacktrace->frames() ) );
|
|
Packit |
985e12 |
return $stacktrace;
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
|
|
Packit |
985e12 |
sub only_a_frames {
|
|
Packit |
985e12 |
my @frames = @_;
|
|
Packit |
985e12 |
return grep { $_->subroutine() =~ /^FilterAllFrames::a/ } @frames;
|
|
Packit |
985e12 |
}
|
|
Packit |
985e12 |
}
|