httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Steve Hay" <Steve...@planit.com>
Subject RE: VS2010 release builds of Apache/mod_perl crash on Vista/2008/Win7
Date Tue, 08 Feb 2011 14:29:13 GMT
Steve Hay wrote on 2011-02-07:
> Steve Hay wrote on 2011-02-07:
>> Steve Hay wrote on 2011-02-04:
>>> William A. Rowe Jr. wrote on 2011-02-04:
>>>> On 2/4/2011 3:49 PM, Steve Hay wrote:
>>>>> It looks like the original environ[] was allocated by msvcr100.dll
>>>> using something other than a function matching the HeapFree()
>>>> function where the crash finally happens. The CRT code is trying to
>>>> free the existing PATH in its environment before setting the new
>>>> value coming from _putenv(), and it is that free that crashes,
>>>> presumably because the APR re-processing of the environ entities
>>>> didn't fool MSVCRT well enough?
>>>> 
>>>  That makes sense, and it should be easy to make that conditional on
>>>  the vc version. Now the question is where were these allocated from
>>>  in MSVCR100? Only a trip through the crt sources will help out,
>>>  there. Indeed, but looking through the VS2010 CRT source code the
> environment
>>> seems to be initialized in stdenvp.c using _calloc_crt, which should
>>> match the _free_crt call in setenv.c line 211 where it all goes wrong,
>>> so I'm confused why it's crashing. The VS2008 CRT source code looks
>>> the same in this area too.
>> 
>> The attached modified version of my original test program no longer
>> crashes, but I'm not sure whether the environment re-processing still
>> achieves what it is meant to.
>> 
>> The only change is that it now does the UTF-8 conversion into env and
>> then copies that to _environ, rather than converting into _environ and
>> then copying that to env.
>> 
> Sadly, that change is no good: Apache/mod_perl now successfully runs
> with the -DONE_PROCESS option (which it didn't before), but is still
> unable to startup normally -- it fails to spawn the child process:
> 

After some more trial and error with this, I've now found that the following patch gets it
working (including a normal Apache/mod_perl setup this time).

I don't know what, if anything, is wrong with the original code (mallocing, then reallocing
memory, then assigning newarr to *retarr), but when the newarr is copied string-by-string
into _environ in the following manner (using the same method as the CRT source code's own
stdenvp.c initializes _environ in the first place) then it's all ok.

Does anybody have a view on whether there is anything wrong with the current APR code which
perhaps needs to be fixed in this kind of way, or whether this looks more like a bug in the
MS CRT which I could report to Microsoft? (Even in the latter case, I think the APR code still
needs a workaround for the current MSVCR100.dll behaviour otherwise Apache/mod_perl (and presumably
any other Apache HTTPd module that call putenv()) doesn't run on Vista/2008/Win7 when built
with VS2010.)


diff -ruN httpd-2.2.17.orig/srclib/apr/misc/win32/start.c httpd-2.2.17/srclib/apr/misc/win32/start.c
--- httpd-2.2.17.orig/srclib/apr/misc/win32/start.c	2007-08-26 17:19:56.000000000 +0100
+++ httpd-2.2.17/srclib/apr/misc/win32/start.c	2011-02-08 12:42:25.259024500 +0000
@@ -46,6 +46,7 @@
     apr_size_t newlen;
     apr_size_t wsize;
     char **newarr;
+    char **env;
     int arg;
 
     if (args < 0) {
@@ -85,7 +86,18 @@
 
     newarr[arg] = NULL;
 
-    *retarr = newarr;
+    /* *retarr = newarr; <--- Crashes in VS2010 release mode builds on Vista/2008/Win7
*/
+    *retarr = env = (char **)_malloc_dbg((args + 1) * sizeof(char*), _CRT_BLOCK, __FILE__,
__LINE__);
+    for (arg = 0; arg < args; ++arg) {
+        int len = (int)strlen(newarr[arg]) + 1;
+        *env = (char*)_malloc_dbg(len * sizeof(char), _CRT_BLOCK, __FILE__, __LINE__);
+        strcpy_s(*env, len, newarr[arg]);
+        env++;
+    }
+    *env = NULL;
+    _free_dbg(newarr[0], _CRT_BLOCK);
+    _free_dbg(newarr, _CRT_BLOCK);
+
     return args;
 }
 #endif
Mime
View raw message