Re: [BUG] Bad refcounting in Apache->push_handlers()

[prev] [thread] [next] [Date index for 2005/03/10]

From: Stas Bekman
Subject: Re: [BUG] Bad refcounting in Apache->push_handlers()
Date: 02:35 on 10 Mar 2005
Dominique Quatravaux wrote:
> 
> -------------8<---------- Start Bug Report ------------8<----------
> 1. Problem Description:
> 
> I'm trying to make a PerlFixupHandler that reads:
> 
> sub ssl_is_mandatory {
>  my $r = shift;
>  require Apache::RequestRec;
>  return 403 unless defined($r->subprocess_env("SSL_SERVER_S_DN"));
>  return 0
> }
> Apache->push_handlers("PerlFixupHandler", \&ssl_is_mandatory);
> 
> So far so good, but when I try to do this instead:
> 
> Apache->push_handlers("PerlFixupHandler", sub { ... });

where do you call the above, Dominique? At the server startup?

> with the exact same Perl code inside the sub as above, I get extremely 
> weird error messages, namely a warning ("Use of uninitialized value in 
> null operation") and an error ("Undefined subroutine &main:: called"), 
> neither of which having any useful backtrace information according to 
> Apache::DB and some crocky breakpoints in $SIG{__WARN__} and 
> $SIG{__DIE__} that I put together: for example,
> 
>  DB<1> T
> $ = IDX::Debug::_die_with_stack_trace('Undefined subroutine &main:: 
> called.^J') called from -e line 0
> $ = eval {...} called from -e line 0
[...]
> So this looks a lot like modperl_callback is calling a CV that has been 
> free()d before at modperl_callback line 100. Being a nearly complete 
> ignorant in XS, I cannot investigate much further on my own, but I can 
> certainly run experiments on your behalf, apply patches, etc.
> 
> This problem isn't blocking me anymore as I found an adequate 
> workaround, namely to not use an anonymous sub (albeit after 2 days of 
> debugging). So please, Stas and all, don't rush to rescue me, it's very 
> nice of you but a bit embarassing at times :-)

Here is some explanation of what's happening inside:

/* How anon-subs are handled:
  * We have two ways anon-subs can be registered
  * A) at startup from httpd.conf:
  *    PerlTransHandler 'sub { ... }'
  * B) run-time perl code
  *    $r->push_handlers(PerlTransHandler => sub { .... });
  *
  * In the case of non-threaded perl, we just compile A or grab B and
  * store it in the mod_perl struct and call it when it's used. No
  * problems here
  *
  * In the case of threads, things get more complicated. we no longer
  * can store the CV value of the compiled anon-sub, since when
  * perl_clone is called each interpreter will have a different CV
  * value. since we need to be able to have 1 entry for each anon-sub
  * across all interpreters a different solution is needed. to remind
  * in the case of named subs, we just store the name of the sub and
  * look its corresponding CV when we need it.
  *
  * The used solution: each process has a global counter, which always
  * grows. Every time a new anon-sub is encountered, a new ID is
  * allocated from that process-global counter and that ID is stored in
  * the mod_perl struct. The compiled CV is stored as
  *     $PL_modglobal{ANONSUB}{$id} = CV;
  * when perl_clone is called, each clone will clone that CV value, but
  * we will still be able to find it, since we stored it in the
  * hash. so we retrieve the CV value, whatever it is and we run it.
  *
  * that explanation can be written and run in perl:
  *
  * use threads;
  * our %h;
  * $h{x} = eval 'sub { print qq[this is sub @_\n] }';
  * $h{x}->("main");
  * threads->new(sub { $h{x}->(threads->self->tid)});
  *
  * XXX: more nuances will follow
  */

but I'm confused as you are using 5.6.1 w/o threads. it should have worked 
there just fine.

Any chance you could add a test to the modperl2 test suite that I can 
reproduce the problem with? If you don't manage to I'll try to write one. 
You can take a look at one of:

t/hooks/TestHooks/inlined_handlers.pm
t/hooks/TestHooks/push_handlers_same_phase.pm
t/hooks/TestHooks/stacked_handlers2.pm
t/hooks/TestHooks/stacked_handlers.pm
t/hooks/TestHooks/push_handlers_blessed.pm
t/hooks/TestHooks/set_handlers.pm
t/hooks/TestHooks/push_handlers.pm

Thanks.

        -- 
        __________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@xxxxxx.xxx http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com

[BUG] Bad refcounting in Apache->push_handlers()
Dominique Quatravaux 12:28 on 09 Mar 2005

Re: [BUG] Bad refcounting in Apache->push_handlers()
Stas Bekman 02:35 on 10 Mar 2005

[PATCH] Re: [BUG] Bad refcounting in Apache->push_handlers()
Dominique Quatravaux 14:26 on 31 Mar 2005

Generated at 14:43 on 11 Apr 2005 by mariachi v0.52