Mailing List Archive

Perl malloc bug with require >= 16376 bytes on irix5.
On our irix5.2 systems "require 'big.pl'" where 'big.pl' is of size 16376
bytes or greater corrupts memory when using perl's malloc. This manifests
itself in socket connections opened afterwards. Par (SGI's trace) revealed
either that the read syscall from the socket fd had a negative size, or that
the write syscall to the socket didnt happen (zero size?).

The problem only happened when 'big.pl' was on an SGI file system. It did not
happen on NFS sun systems. Stdio allocates different size buffers in these
two cases (16384 for the sgi fs, and 8192 for the sun fs). These sizes are
used to SvGROW in sv_gets, so it looked like SvGROW was the problem. When I
reconfigured and recompiled to use the SGI malloc library the problem went
away.

Below is a test program which shows the problem. Here is the myconfig from
the current installation which does *not* use perl's malloc, but all the other
information should be the same. Sorry I dont have the buggy one. I could
redo it if needed.

Summary of my perl5 (patchlevel 1) configuration:
Platform:
osname=irix, osver=5, archname=sgi-irix
uname='irix idefix 5.2 02282015 ip20 mips '
hint=recommended
Compiler:
cc='cc', optimize='-O', ld='ld'
cppflags='-D_POSIX_SOURCE -ansiposix -D_BSD_TYPES'
ccflags ='-D_POSIX_SOURCE -ansiposix -D_BSD_TYPES -Olimit 3000'
ldflags =''
stdchar='unsigned char', d_stdstdio=define, usevfork=false
voidflags=15, castflags=1, d_casti32=define, d_castneg=undef
intsize=4, alignbytes=8, usemymalloc=n, randbits=15
Libraries:
so=so
libpth=/usr/lib /lib
libs=-lmalloc -lsun -lm -lc -lcrypt -lbsd -lPW
libc=/usr/lib/libc.so
Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef
cccdlflags=' ', ccdlflags=' ', lddlflags='-shared'

Test case...

#!/local/std/bin/perl
#
# If big.pl has more than 16375 characters in it this hangs in the second
# socket read. The contents of big.pl are irrelevant. I used
#
# 1;
# __END__
# aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
# aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
#
# where the 'a's were used to pad the file out to the correct size.

require 'big.pl';

# This will stop the bug by tying up the corrupted buffer.
# open(GRAB,"big.pl") || die();
# <GRAB>;

use Socket;

sub openservice
{
my($FH,$thathost,$port) = @_;
my($sockaddr,$thishost,$name,$aliased,$proto,
$type,$len,$thisaddr,$this,$thataddr,$that,$sockaddr);

$sockaddr = 'S n a4 x8';
(($name, $aliases, $proto) = getprotobyname('tcp'))
|| die;
(($name, $aliases, $port) = getservbyname($port, 'tcp'))
|| die
unless $port =~ /^\d+$/;

chop($thishost = `hostname`);
(($name, $aliases, $type, $len, $thisaddr) = gethostbyname($thishost))
|| die;
$this = pack($sockaddr, AF_INET(), 0, $thisaddr);

(($name, $aliases, $type, $len, $thataddr) = gethostbyname($thathost))
|| die;
$that = pack($sockaddr, AF_INET(), $port, $thataddr);

socket($FH, &PF_INET(), SOCK_STREAM(), $proto)
|| die;
bind($FH, $this)
|| die;
connect($FH,$that)
|| die;

select((select($FH),$| = 1)[0]);
}

openservice(ECHO,'localhost','echo');
print ECHO "Message #1\n"; # OK
print scalar <ECHO>; # OK
print ECHO "Message #2\n"; # Looks like write(2) never gets called.
print scalar <ECHO>; # Hangs (nothing to read).