develooper Front page | perl.perl5.porters | Postings from October 2005

Perl's handling of environ breaks on Solaris 10

Thread Previous | Thread Next
From:
Alan Burlison
Date:
October 6, 2005 16:25
Subject:
Perl's handling of environ breaks on Solaris 10
Message ID:
4345B24C.1010103@sun.com
I've been trying to get DBD::Oracle to build with Oracle's new "Instant 
Client" and have been getting bizzare "out of memory" errors in 
perl_destruct.  To cut a long story short, this is caused by perl's 
handling of environ.

During Solaris 10 development bugfix the algorithm by which the environ 
array of a process is managed changed so that the buffer allocated to 
hold the environ array is filled from high to low addresses rather than 
the old low to high mechanism.  This was done for MT performance 
reasons, so that lock-free environment handling could be used.  The new 
code can be seen at 
http://cvs.opensolaris.org/source/xref/usr/src/lib/libc/port/gen/getenv.c

Perl_my_setenv directly manipulates the environ pointer and addition it 
makes assumptions as to what environ actually points to - namely that 
environ points to the start of a malloc'd buffer, so when perl wishes to 
grow environ it does so by realloc'ing it.  Unfortunately, on S10 
environ does not necessarily point to the start of the buffer (in most 
cases it won't) so perl's attempt to realloc the buffer results in heap 
corruption with subsequent hard-to-diagnose failures happening some time 
later.

The specific scenario that triggered this is that the Oracle "Instant 
Client" libraries modify the environment with libc's putenv, causing the 
environment to be grown, then DBD::Oracle Oracle.pm module subsequently 
modifies %ENV which in turn results in perl trying to realloc environ 
(which now points into the middle of a malloc'd block), and things 
rapidly go downhill from that point.

The handling of the %ENV array in perl has had a long and torturous 
history, and I'm not entirely clear why the direct manipulation of 
environ was deemed necessary.  It looks like there may be a simple way 
to disable this when building perl and to switch to using getenv/putenv, 
or another alternative is to get perl to always check that environ is 
the same as it was when perl last touched it before doing anything.

I'd like to understand what the current direct manipulation of environ 
is intended to achieve - it seems pretty vile to me, can someone shed 
some light?

Thanks,

-- 
Alan Burlison
--

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About