diff options
author | Hans Mulder <hansmu@xs4all.nl> | 1997-06-15 23:26:35 +1200 |
---|---|---|
committer | Tim Bunce <Tim.Bunce@ig.co.uk> | 1997-08-07 00:00:00 +1200 |
commit | 57569e04d232667a3e52996dff0f1e57f7d36b43 (patch) | |
tree | f9fef4c94a68dafd8316e9f5e7665b2e8d8913b7 /malloc.c | |
parent | c9de509e331450a10058399280ce28f68f0faf39 (diff) | |
download | perl-57569e04d232667a3e52996dff0f1e57f7d36b43.tar.gz |
infinite recursion in malloc() with some compile flags
Apologies if you see this twice, but I'm afraid my first attempt
fell into a black hole. Neither Achim's archive nor the NNTP
gateway seem to have recieved it.
If one tries to compile perl with all of
-DPACK_MALLOC -DHIDEMYMALLOC -DUSE_PERL_SBRK -DPERL_SBRK_VIA_MALLOC
then it's almost certain that miniperl will overflow the C stack on
its first attempt to call malloc().
This happens because with -DPACK_MALLOC Perl_malloc() expects sbrk()
to return 2K-aligned blocks and Perl_sbrk() provides the same sort
of alignments as the system malloc(), i.e. 8 bytes or so.
When Perl_malloc() notices the block returned by sbrk() isn't properly
aligned, it tries to croak("panic: Off-page sbrk"). Croak() calls
mess(); mess() calls mess_alloc(); mess_alloc() calls Perl_malloc();
Perl_malloc() again calls croak() and so on until the C stack overflows.
I see two problems here;
1. With -DPACK_MALLOC, Perl_sbrk() should return 2K-aligned blocks.
2. croak() should not recurse infinitely.
The patch below deals with #1. I'll think some more about #2.
p5p-msgid: 199706240050.CAA10550@xs2.xs4all.nl
Diffstat (limited to 'malloc.c')
-rw-r--r-- | malloc.c | 6 |
1 files changed, 6 insertions, 0 deletions
@@ -781,6 +781,9 @@ int size; #ifdef PERL_CORE reqsize = size; /* just for the DEBUG_m statement */ #endif +#ifdef PACK_MALLOC + size = (size + 0x7ff) & ~0x7ff; +#endif if (size <= Perl_sbrk_oldsize) { got = Perl_sbrk_oldchunk; Perl_sbrk_oldchunk += size; @@ -796,6 +799,9 @@ int size; small = 1; } got = (IV)SYSTEM_ALLOC(size); +#ifdef PACK_MALLOC + got = (got + 0x7ff) & ~0x7ff; +#endif if (small) { /* Chunk is small, register the rest for future allocs. */ Perl_sbrk_oldchunk = got + reqsize; |