The patch below fixes the problems with MP_LIBNAME (and cwd) not being set 
correctly when building Apache::Reload and Apache::SizeLimit.

The problem was that the file-level $b variable was created only once when 
ModPerl::MM was first loaded, but that happened before Apache2::BuildConfig.pm 
was written. The patch simply rewrites $b (instead of writing a lexical $build 
which was never used!) later on, by which time Apache2::BuildConfig.pm has been 
created.

If the patch looks ok then shall I apply it before RC2 is rolled?

(Needless to say, this doesn't fix the more serious problem of the test suite 
still failing when httpd.exe crashes with an out of memory error part-way 
through...)

Index: lib/ModPerl/MM.pm
===================================================================
--- lib/ModPerl/MM.pm   (revision 1240026)
+++ lib/ModPerl/MM.pm   (working copy)
@@ -128,7 +128,7 @@
         $eu_mm_mv_all_methods_overriden++;
     }

-    my $build = build_config();
+    $b = build_config();
     my_import(__PACKAGE__);

     # set top-level WriteMakefile's values if weren't set already


-----Original Message-----
From: Steve Hay [mailto:steve...@planit.com] 
Sent: 08 February 2012 09:34
To: Torsten Förtsch; dev@perl.apache.org
Cc: Fred Moyer
Subject: RE: [RELEASE CANDIDATE]: mod_perl-2.0.6 RC1

[...]

I also still have the warnings from Makefile.PL that I reported before too, 
which Fred guessed are due to MP_LIBNAME not getting set correctly. I haven't 
had a chance to look further into that yet, sorry :-(

As before, this is all with httpd 2.2.21, with everything built from source in 
default configurations using VC++ 2010.


-----Original Message-----
From: Torsten Förtsch [mailto:torsten.foert...@gmx.net]
Sent: 07 February 2012 17:02
To: dev@perl.apache.org
Cc: Fred Moyer; Steve Hay
Subject: Re: [RELEASE CANDIDATE]: mod_perl-2.0.6 RC1

On Tuesday, 31 January 2012 15:32:44 Torsten Förtsch wrote:
> worker: I see the same behavior as Steve. I can also confirm that
> r1145161 is  the first commit that shows this behavior. Blame on me!
> 
> $ svn diff -c1145161
> Index: t/response/TestDirective/cmdparms.pm
> ===================================================================
> --- t/response/TestDirective/cmdparms.pm        (revision 1145160)
> +++ t/response/TestDirective/cmdparms.pm        (revision 1145161)
> @@ -134,6 +134,8 @@
>  
>  TestCmdParms "Location"
>  
> -<LimitExcept GET>
> -    TestCmdParms "Limit"
> -</LimitExcept>
> +<Directory />
> +    <LimitExcept GET>
> +        TestCmdParms "Limit"
> +    </LimitExcept>
> +</Directory>
> 
> looks quite innocent.
> 
> Except without the change the limit is part of the server's base config.
> With  it it will be merged at request time.

I think perhaps I have found the culprit. modperl has 2 ways of assigning a 
perl interpreter to the request. One is modperl_interp_select() that can be 
used if we have either a request_rec* or a conn_rec* or a server_rec*. The 
other is modperl_interp_pool_select() which is in my opinion basically a hack 
to work around the situation when one of the above is hidden on the stack 
somewhere but currently not accessible. To do this modperl_interp_select() ties 
the interpreter to a pool by storing it in the pool userdata hash. This pool 
might be a conn_req or request_rec pool depending on PerlInterpScope.
Now, when modperl_interp_pool_select() is called it hopes that the pool it is 
passed already contains an interpreter. If so, all is fine. Otherwise,
modperl_interp_pool_select() hopes that the server_rec it is also passed (or 
rather the mip stored there) matches the current request. Unfortunately, this 
assumption is false for dir config merger functions. That's what the XXX 
comment below is about.

modperl_module.c has this piece of code:

/*
 * XXX: vhosts may have different parent interpreters.
 */
static void *modperl_module_config_merge(apr_pool_t *p,
                                         void *basev, void *addv,
                                         int type) { ...
#ifdef USE_ITHREADS
    interp = modperl_interp_pool_select(p, s);
    MP_PERL_CONTEXT_STORE_OVERRIDE(interp->perl);
#endif

The first request in t/directive/perlrequire.t is a good test to show the 
problem. With change 1145161 it fails reliably, without it succeeds.

Now, if I set a breakpoint on modperl_interp_pool_select() it is hit only with 
change 1145161. Without it modperl_interp_pool_select() is not reached.
So, without 1145161 the interpreter is assigned by modperl_interp_select() 
while with it modperl_interp_pool_select() tries to do it (and picks the wrong 
interpreter pool).

Breakpoint 1, modperl_interp_pool_select (p=0x7f65840028f8, s=0x686848) at 
modperl_interp.c:341
341         int is_startup = (p == s->process->pconf);
(gdb) bt
#0  modperl_interp_pool_select (p=0x7f65840028f8, s=0x686848) at 
modperl_interp.c:341
#1  0x00007f6596ab2241 in modperl_module_config_merge (p=0x7f65840028f8, 
basev=0x2d2a9d0, addv=0x2d2c210, type=1) at modperl_module.c:186
#2  0x00007f6596ab2b83 in modperl_module_config_dir_merge (p=0x7f65840028f8, 
basev=0x2d2a9d0, addv=0x2d2c210) at modperl_module.c:260
#3  0x000000000043d598 in ap_merge_per_dir_configs (p=0x7f65840028f8, 
base=0x2de09a0, new_conf=0x7f6584009470) at config.c:248
#4  0x00000000004387d2 in ap_directory_walk (r=0x7f6584002970) at request.c:1195
#5  0x0000000000433c59 in core_map_to_storage (r=0x7f6584002970) at core.c:3621
#6  0x0000000000437978 in ap_run_map_to_storage (r=0x7f6584002970) at 
request.c:69
#7  0x0000000000439b38 in ap_process_request_internal (r=0x7f6584002970) at 
request.c:150
#8  0x000000000044a490 in ap_process_request (r=0x7f6584002970) at 
http_request.c:280
#9  0x0000000000447478 in ap_process_http_connection (c=0x7f6588003748) at 
http_core.c:190
#10 0x0000000000443898 in ap_run_process_connection (c=0x7f6588003748) at 
connection.c:43
#11 0x00000000004505b1 in process_socket (bucket_alloc=<optimized out>, 
my_thread_num=0, my_child_num=0, sock=0x7f6588003530, p=<optimized out>) at 
worker.c:544
#12 worker_thread (thd=0x2daf638, dummy=<optimized out>) at worker.c:894
#13 0x00007f65a0c64f05 in start_thread () from /lib64/libpthread.so.0
#14 0x00007f65a07a363d in ?? () from /lib64/libc.so.6
#15 0x0000000000000000 in ?? ()

Now, if we look at the server_rec passed to modperl_interp_pool_select() it 
turns out to be the default server listening on localhost:8529.

(gdb) dump_server_rec s
name=localhost:8529
process_rec=0x67d218:
   pool=0x67d128, pconf=0x67f138

While r->server is the vhost listening on localhost:8560.

(gdb) up 5
#5  0x0000000000433c59 in core_map_to_storage (r=0x7f6584002970) at core.c:3621
3621        if ((access_status = ap_directory_walk(r))) {
(gdb) dump_server_rec r->server
name=localhost:8560
process_rec=0x67d218:
   pool=0x67d128, pconf=0x67f138
(gdb)

What to do now? I'd suggest to revert change 1145161 and get 2.0.6 out (perhaps 
with Steve's latest patch). Steve, do you use perl 5.14? If yes, can you try if 
you see the "panic: free from wrong pool" also with 5.12?

After that, we should merge the threading branch. There at the very beginning 
of a request the request_rec is stored as pool userdata in the request pool. 
Thus, modperl_interp_pool_select() can fetch it from there and then use 
r->server to get an interpreter from the right pool.

The other way would be to make sure there is an interpreter in the request pool 
before core_map_to_storage(). I think this would make the current mess even 
worse.

Thoughts?

Torsten Förtsch

--
Need professional modperl support? Hire me! (http://foertsch.name)

Like fantasy? http://kabatinte.net


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@perl.apache.org For additional 
commands, e-mail: dev-h...@perl.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@perl.apache.org
For additional commands, e-mail: dev-h...@perl.apache.org

Reply via email to