A patch to fix one sort of mod_perl crash I've been experiencing.

"Kandarian, Richard M" <[email protected]>
Newsgroups gmane.comp.apache.mod-perl
Message-ID <275671956B4337459E14A61834A5C03E3B283835@ECS-EXG-P-MB01.win.lanl.gov>
Reading MP_TRACE messages I noticed that for every modperl_interp_select() call during a request there were two modperl_interp_unselect() calls, one bracketing the _select() call and one from the registered cleanup when the pool was destroyed. The attached patch stopped those crashes. I would call my fix VERY tentative  for various reasons including my noobiness and I've added comments near the active ingredient in modperl_interp.c. Inactive ingredients include diffs in the patch which are my adding trace info.

Now I'm chasing a bug which causes a much less frequent crash.

This patch is against the version of mod_perl I checked out some months ago: 1566538 which is in httpd24threading, but having checked the changes to that branch since then I didn't find an obvious conflict.

This is my httpd:

Server version: Apache/2.2.26 (Win32)
Server built:   Mar 17 2014 09:15:35
Server's Module Magic Number: 20051115:33
Server loaded:  APR 1.4.8, APR-Util 1.5.2
Compiled using: APR 1.4.8, APR-Util 1.5.2
Architecture:   32-bit
Server MPM:     WinNT
  threaded:     yes (fixed thread count)
    forked:     no
Server compiled with....
 -D APACHE_MPM_DIR="server/mpm/winnt"
 -D APR_HAS_SENDFILE
 -D APR_HAS_MMAP
 -D APR_HAS_OTHER_CHILD
 -D AP_HAVE_RELIABLE_PIPED_LOGS
 -D DYNAMIC_MODULE_LIMIT=128
 -D HTTPD_ROOT="/apache"
 -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
 -D DEFAULT_ERRORLOG="logs/error.log"
 -D AP_TYPES_CONFIG_FILE="conf/mime.types"
 -D SERVER_CONFIG_FILE="conf/httpd.conf"

And my Perl:

Summary of my perl5 (revision 5 version 18 subversion 2) configuration:

  Platform:
    osname=MSWin32, osvers=6.1, archname=MSWin32-x86-multi-thread
    uname=''
    config_args='undef'
    hint=recommended, useposix=true, d_sigaction=undef
    useithreads=define, usemultiplicity=define
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=undef, use64bitall=undef, uselongdouble=undef
    usemymalloc=y, bincompat5005=undef
  Compiler:
    cc='cl', ccflags ='-nologo -GF -W3 -O1 -MD -Zi -DNDEBUG -DWIN32 -D_CONSOLE -
DNO_STRICT -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE  -DPERL_TEXTMO
DE_SCRIPTS -DPERL_IMPLICIT_CONTEXT -DUSE_PERLIO',
    optimize='-O1 -MD -Zi -DNDEBUG',
    cppflags='-DWIN32'
    ccversion='15.00.30729.01', gccversion='', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=8
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='__int64', lseeksi
ze=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='link', ldflags ='-nologo -nodefaultlib -debug -opt:ref,icf  -libpath:"c:
\perl\5.18.2\lib\MSWin32-x86-multi-thread\CORE"  -machine:x86 "/manifestdependen
cy:type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' proce
ssorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"'
    libpth=\lib
    libs=oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib  comdlg32.l
ib advapi32.lib shell32.lib ole32.lib oleaut32.lib  netapi32.lib uuid.lib ws2_32
.lib mpr.lib winmm.lib  version.lib odbc32.lib odbccp32.lib comctl32.lib msvcrt.
lib
    perllibs=oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib  comdlg
32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib  netapi32.lib uuid.lib ws
2_32.lib mpr.lib winmm.lib  version.lib odbc32.lib odbccp32.lib comctl32.lib msv
crt.lib
    libc=msvcrt.lib, so=dll, useshrplib=true, libperl=perl518.lib
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
    cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -debug -opt:ref,icf  -
libpath:"c:\perl\5.18.2\lib\MSWin32-x86-multi-thread\CORE"  -machine:x86 "/manif
estdependency:type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0
.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"'



Characteristics of this binary (from libperl):
  Compile-time options: HAS_TIMES HAVE_INTERP_INTERN MULTIPLICITY MYMALLOC
                        PERLIO_LAYERS PERL_DONT_CREATE_GVSV
                        PERL_HASH_FUNC_ONE_AT_A_TIME_HARD
                        PERL_IMPLICIT_CONTEXT PERL_MALLOC_WRAP
                        PERL_PRESERVE_IVUV PERL_SAWAMPERSAND USE_ITHREADS
                        USE_LARGE_FILES USE_LOCALE USE_LOCALE_COLLATE
                        USE_LOCALE_CTYPE USE_LOCALE_NUMERIC USE_PERLIO
                        USE_PERL_ATOF
  Built under MSWin32
  Compiled at Mar 12 2014 12:48:53
  %ENV:
    PERL5LIB="c:/cygwin/home/085598/lib;c:/cygwin/home/085598/Perl"
    PERLDOC_PAGER="less -ir"
  @INC:
    c:/cygwin/home/085598/lib
    c:/cygwin/home/085598/Perl
    C:/perl/site/5.18.2/lib/MSWin32-x86-multi-thread
    C:/perl/site/5.18.2/lib
    C:/perl/5.18.2/lib/MSWin32-x86-multi-thread
    C:/perl/5.18.2/lib
    .

Both build with VC 2008

Richard Kandarian
http://www.lanl.gov/cgi-bin/fonelink.pl/085598
My node in the Web: http://www.kandarian.com
unselect.patch (application/octet-stream, 3.7 KB)
Index: src/modules/perl/mod_perl.c
===================================================================
--- src/modules/perl/mod_perl.c	(revision 1574926)
+++ src/modules/perl/mod_perl.c	(working copy)
@@ -56,7 +56,8 @@
 static apr_status_t modperl_shutdown(void *data)
 {
     modperl_cleanup_data_t *cdata = (modperl_cleanup_data_t *)data;
-    PerlInterpreter *perl = (PerlInterpreter *)cdata->data;
+    dTHXa(cdata->data)
+    tTHX perl = aTHX;
     void **handles;
 
     handles = modperl_xs_dl_handles_get(aTHX);
Index: src/modules/perl/modperl_config.c
===================================================================
--- src/modules/perl/modperl_config.c	(revision 1574926)
+++ src/modules/perl/modperl_config.c	(working copy)
@@ -143,7 +143,7 @@
     modperl_config_req_t *rcfg =
         (modperl_config_req_t *)apr_pcalloc(r->pool, sizeof(*rcfg));
 
-    MP_TRACE_d(MP_FUNC, "0x%lx", (unsigned long)rcfg);
+    MP_TRACE_d(MP_FUNC, "new request, rec: %pp rcfg: %pp", r, rcfg);
 
     return rcfg;
 }
Index: src/modules/perl/modperl_interp.c
===================================================================
--- src/modules/perl/modperl_interp.c	(revision 1574926)
+++ src/modules/perl/modperl_interp.c	(working copy)
@@ -274,17 +274,22 @@
     modperl_interp_pool_t *mip = interp->mip;
 
     MP_ASSERT(interp && MpInterpIN_USE(interp));
-    MP_TRACE_i(MP_FUNC, "unselect(interp=%pp): refcnt=%d",
-               interp, interp->refcnt);
+    MP_TRACE_i(MP_FUNC, "unselect(interp=%pp): refcnt=%d in use: %d",
+               interp, interp->refcnt, MpInterpIN_USE(interp));
 
-    if (interp->refcnt > 1) {
+    if (interp->refcnt > 1) { /* Why not abort if refcnt <= 0? */
         --interp->refcnt;
         MP_TRACE_i(MP_FUNC, "interp=0x%lx, refcnt=%d -- interp still in use",
                    (unsigned long)interp, interp->refcnt);
         return APR_SUCCESS;
     }
+    if(!MpInterpIN_USE(interp)){
+        MP_TRACE_i(MP_FUNC, "interp=0x%lx, refcnt=%d -- interp not in use, already unselected?",
+                   (unsigned long)interp, interp->refcnt);
+        return APR_SUCCESS;
+    }
 
-    MpInterpIN_USE_Off(interp);
+    MpInterpIN_USE_Off(interp); /* Why not zero refcnt? */
 
     modperl_thx_interp_set(interp->perl, NULL);
 #ifdef MP_DEBUG
@@ -438,8 +443,8 @@
         ccfg->interp->refcnt++;
 
         MP_TRACE_i(MP_FUNC,
-                   "found interp 0x%lx in con config, refcnt incremented to %d",
-                   (unsigned long)ccfg->interp, ccfg->interp->refcnt);
+	 "req: %pp, found interp 0x%lx in con config, refcnt incremented to %d",
+	   r, (unsigned long)ccfg->interp, ccfg->interp->refcnt);
         /* set context (THX) for this thread */
         PERL_SET_CONTEXT(ccfg->interp->perl);
         /* modperl_thx_interp_set() is not called here because the interp
@@ -449,9 +454,11 @@
     }
 
     MP_TRACE_i(MP_FUNC,
-               "fetching interp for %s:%d", s->server_hostname, s->port);
+               "req: %pp, fetching interp for %s:%d, ccfg: %pp",
+	       r, s->server_hostname, s->port, ccfg);
     interp = modperl_interp_get(s);
-    MP_TRACE_i(MP_FUNC, "  --> got %pp (perl=%pp)", interp, interp->perl);
+    MP_TRACE_i(MP_FUNC,
+      "req: %pp,   --> got %pp (perl=%pp)", r, interp, interp->perl);
     ++interp->num_requests; /* should only get here once per request */
     interp->refcnt = 0;
 
@@ -466,8 +473,8 @@
     interp->ccfg = ccfg;
 
     MP_TRACE_i(MP_FUNC,
-               "pulled interp %pp (perl=%pp) from mip, num_requests is %d",
-               interp, interp->perl, interp->num_requests);
+               "req: %pp, pulled interp %pp (perl=%pp) from mip, num_requests is %d, ccfg: %pp",
+               r, interp, interp->perl, interp->num_requests, ccfg);
 
     /*
      * if a per-dir PerlInterpScope is specified, use it.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.