In perl.git, the branch blead has been updated <http://perl5.git.perl.org/perl.git/commitdiff/bf2614180a655fadfe4ad9de9bbcf01c42b29e7e?hp=76b97db53754383a11c0e30949c54e45282d3317>
- Log ----------------------------------------------------------------- commit bf2614180a655fadfe4ad9de9bbcf01c42b29e7e Author: Father Chrysostomos <[email protected]> Date: Sat Jul 13 11:41:44 2013 -0700 [perl #118839] Make ânâ debugger cmd respect lv subs The ânâ debugger command, which is supposed to step over subs, was not stepping over lvalue subs. This is a regression from 5.8, but 5.8 was worse. This bug did not occur in 5.8 because there was no mechanism back then for handling lvalue subs specially (via DB::lsub), so assignment to an lvalue sub was completely broken under the debugger. Perl 5.10 introduced DB::lsub. The implementation in perl5db.pl contains these lines at the end of the sub: # Pop the single-step value back off the stack. $single |= $stack[ $stack_depth-- ]; # call the original lvalue sub. &$sub; The regular DB::sub does this: { no strict 'refs'; @ret = &$sub; } # Pop the single-step value back off the stack. $single |= $stack[ $stack_depth-- ]; Notice how $single (i.e., $DB::single) is modified before and after the sub call, respectively. The order is different. There are two types of lvalue list context for lvalue subs. (foo)=3 will allow sub foo:lvalue{@a} to return the array itself. \(foo) and bar(foo) will flatten the array. So there is no way in pure Perl to capture the return value and have it returned to the caller unchanged. That is why DB::lsub has to call the sub last of all (and have the context propagated). The solution here is to use localisation to accomplish the assigment to $single after the lvalue sub exits. M MANIFEST M lib/perl5db.pl M lib/perl5db.t A lib/perl5db/t/lsub-n commit c4a26ef3f320212167cfd6d700bfcc92f04a6939 Author: Father Chrysostomos <[email protected]> Date: Sat Jul 13 01:12:20 2013 -0700 perl5db.pl: Remove obsolete comment The regexp engine is now fully reëntrant. M lib/perl5db.pl commit 82046965c60ae9cb54f5878dca9fd926f7798f9d Author: Father Chrysostomos <[email protected]> Date: Sat Jul 13 01:06:46 2013 -0700 todo.pod: Donât mention âmake test.taintwarnâ M Porting/todo.pod commit 094fef224b8ab1b38ac513ac133efd6d4527af14 Author: Father Chrysostomos <[email protected]> Date: Sat Jul 13 01:02:24 2013 -0700 todo.pod: Class set regexp operations are done but they are still experimental. M Porting/todo.pod ----------------------------------------------------------------------- Summary of changes: MANIFEST | 1 + Porting/todo.pod | 12 +++--------- lib/perl5db.pl | 10 +++------- lib/perl5db.t | 16 +++++++++++++++- lib/perl5db/t/lsub-n | 6 ++++++ 5 files changed, 28 insertions(+), 17 deletions(-) create mode 100644 lib/perl5db/t/lsub-n diff --git a/MANIFEST b/MANIFEST index a676881..de8c16f 100644 --- a/MANIFEST +++ b/MANIFEST @@ -4169,6 +4169,7 @@ lib/perl5db/t/eval-line-bug Tests for the Perl debugger lib/perl5db/t/fact Tests for the Perl debugger lib/perl5db/t/filename-line-breakpoint Tests for the Perl debugger lib/perl5db/t/load-modules Tests for the Perl debugger +lib/perl5db/t/lsub-n Test script used by perl5db.t lib/perl5db/t/lvalue-bug Tests for the Perl debugger lib/perl5db/t/MyModule.pm Tests for the Perl debugger lib/perl5db/t/proxy-constants Tests for the Perl debugger diff --git a/Porting/todo.pod b/Porting/todo.pod index f0846f0..f8b8f11 100644 --- a/Porting/todo.pod +++ b/Porting/todo.pod @@ -128,8 +128,9 @@ L<Benchmark::Perl::Formance> =head2 fix tainting bugs -Fix the bugs revealed by running the test suite with the C<-t> switch (via -C<make test.taintwarn>). +Fix the bugs revealed by running the test suite with the C<-t> switch. +Setting the TEST_ARGS environment variable to C<-taintwarn> will accomplish +this. =head2 Dual life everything @@ -1189,13 +1190,6 @@ without a C<fchdir> function (in sv.c:Perl_dirp_dup). Fix Perl_sv_dup, et al so that threads can return objects. -=head2 Add class set operations to regexp engine - -Apparently these are quite useful. Anyway, Jeffery Friedl wants them. - -demerphq has this on his todo list, but right at the bottom. - - =head1 Tasks for microperl diff --git a/lib/perl5db.pl b/lib/perl5db.pl index b37018e..48ec301 100644 --- a/lib/perl5db.pl +++ b/lib/perl5db.pl @@ -4094,9 +4094,6 @@ sub _print_frame_message { } sub DB::sub { - # Do not use a regex in this subroutine -> results in corrupted memory - # See: [perl #66110] - # lock ourselves under threads lock($DBGR); @@ -4269,7 +4266,9 @@ sub lsub : lvalue { $stack[-1] = $single; # Turn off all flags except single-stepping. - $single &= 1; + # Use local so the single-step value is popped back off the + # stack for us. + local $single = $single & 1; # If we've gotten really deeply recursed, turn on the flag that will # make us stop with the 'deep recursion' message. @@ -4278,9 +4277,6 @@ sub lsub : lvalue { # If frame messages are on ... _print_frame_message($al); - # Pop the single-step value back off the stack. - $single |= $stack[ $stack_depth-- ]; - # call the original lvalue sub. &$sub; } diff --git a/lib/perl5db.t b/lib/perl5db.t index 6ab4694..26b0581 100644 --- a/lib/perl5db.t +++ b/lib/perl5db.t @@ -29,7 +29,7 @@ BEGIN { $ENV{PERL_RL} = 'Perl'; # Suppress system Term::ReadLine::Gnu } -plan(116); +plan(117); my $rc_filename = '.perldb'; @@ -1044,6 +1044,20 @@ sub _calc_trace_wrapper ); } +# Test for n with lvalue subs +DebugWrap->new({ + cmds => + [ + 'n', 'print "<$x>"', + 'n', 'print "<$x>"', + 'q', + ], + prog => '../lib/perl5db/t/lsub-n', +})->output_like( + qr/<1><11>/, + 'n steps over lvalue subs', +); + # Test for 'M' (module list). { my $wrapper = DebugWrap->new( diff --git a/lib/perl5db/t/lsub-n b/lib/perl5db/t/lsub-n new file mode 100644 index 0000000..83257b4 --- /dev/null +++ b/lib/perl5db/t/lsub-n @@ -0,0 +1,6 @@ +sub foo : lvalue { + $x+=10; +} +$x++; +foo(); +$x+=100; -- Perl5 Master Repository
