Revision: 909 Author: tim.bunce Date: Mon Nov 16 02:48:55 2009 Log: Fixed tortuous "goto into own sub that's been deleted and replaced" use-case used by Carp::Heavy. Thanks to ALEXMV for the bug report (RT#51149) and original tests (which I've edited).
http://code.google.com/p/perl-devel-nytprof/source/detail?r=909 Added: /trunk/t/test18-goto2.p /trunk/t/test18-goto2.pm /trunk/t/test18-goto2.t Modified: /trunk/MANIFEST /trunk/NYTProf.xs ======================================= --- /dev/null +++ /trunk/t/test18-goto2.p Mon Nov 16 02:48:55 2009 @@ -0,0 +1,16 @@ +# Test Carp::Heavy's "swap subs out from under you with goto &sub" + +use lib 't'; + +package Test18; + +sub longmess { goto &longmess_jmp } + +sub longmess_jmp { + # the required file deletes this longmess_jmp sub, while it's executing, + # and replaces it with longmess_real, which we then goto into! + require 'test18-goto2.pm'; # has to be require, not eval '...' + goto &longmess_real; +} + +longmess("Oops"); ======================================= --- /dev/null +++ /trunk/t/test18-goto2.pm Mon Nov 16 02:48:55 2009 @@ -0,0 +1,8 @@ +package Test18; + +sub longmess_real { return "Heavy" } + +delete $Test18::{longmess_jmp}; +*longmess_jmp = *longmess_real; + +1; ======================================= --- /dev/null +++ /trunk/t/test18-goto2.t Mon Nov 16 02:48:55 2009 @@ -0,0 +1,6 @@ +use strict; +use Test::More; +use lib qw(t/lib); +use NYTProfTest; + +run_test_group; ======================================= --- /trunk/MANIFEST Sat Nov 14 15:33:22 2009 +++ /trunk/MANIFEST Mon Nov 16 02:48:55 2009 @@ -121,6 +121,9 @@ t/test17-goto.p t/test17-goto.rdt t/test17-goto.t +t/test18-goto2.t +t/test18-goto2.pm +t/test18-goto2.p t/test20-streval.p t/test20-streval.rdt t/test20-streval.t ======================================= --- /trunk/NYTProf.xs Sun Nov 15 13:42:01 2009 +++ /trunk/NYTProf.xs Mon Nov 16 02:48:55 2009 @@ -2190,13 +2190,13 @@ /* ignore the typical second (fallback) destroy */ && !(subr_entry->prev_subr_entry_ix == subr_entry_ix && subr_entry->already_counted==1) ) { - logwarn("%2d << %s::%s done (seix %d->%d, ac%u)\n", + logwarn("%2d << %s::%s done (seix %d<-%d, ac%u)\n", subr_entry->subr_prof_depth, subr_entry->called_subpkg_pv, (subr_entry->called_subnam_sv && SvOK(subr_entry->called_subnam_sv)) ? SvPV_nolen(subr_entry->called_subnam_sv) : "?", - (int)subr_entry_ix, (int)subr_entry->prev_subr_entry_ix, + (int)subr_entry->prev_subr_entry_ix, (int)subr_entry_ix, subr_entry->already_counted); } if (subr_entry->caller_subnam_sv) { @@ -2750,7 +2750,7 @@ else { /* goto &sub opcode acts like a return followed by a call all in one. - * When this op start executing, the 'current' subr_entry that was + * When this op starts executing, the 'current' subr_entry that was * pushed onto the savestack by pp_subcall_profiler will be 'already_counted' * so the profiling of that call will be handled naturally for us. * So far so good. @@ -2758,8 +2758,11 @@ * Then tell subr_entry_setup() to use our copy as a template so it'll * seem like the sub we goto'd was called by the same sub that called * the one that executed the goto. Except that we do use the fid:line - * of the goto statement. Got all that? + * of the goto statement. That way the call graph makes sense and the + * 'calling location' make sense. Got all that? */ + /* save a copy of prev_cop - see t/test18-goto2.p */ + COP prev_cop_copy = *prev_cop; /* save a copy of the subr_entry of the sub we're goto'ing out of */ /* so we can reuse the caller _* info after it's destroyed */ subr_entry_t goto_subr_entry; @@ -2786,7 +2789,7 @@ /* now we're in goto'd sub, mortalize the REFCNT_inc's done above */ sv_2mortal(goto_subr_entry.caller_subnam_sv); sv_2mortal(goto_subr_entry.called_subnam_sv); - this_subr_entry_ix = subr_entry_setup(aTHX_ prev_cop, &goto_subr_entry, op_type, sub_sv); + this_subr_entry_ix = subr_entry_setup(aTHX_ &prev_cop_copy, &goto_subr_entry, op_type, sub_sv); SvREFCNT_dec(sub_sv); } -- You've received this message because you are subscribed to the Devel::NYTProf Development User group. Group hosted at: http://groups.google.com/group/develnytprof-dev Project hosted at: http://perl-devel-nytprof.googlecode.com CPAN distribution: http://search.cpan.org/dist/Devel-NYTProf To post, email: [email protected] To unsubscribe, email: [email protected]
