develooper Front page | perl.perl5.porters | Postings from January 2012

[perl #108276] C stack overflow in Perl_scalarvoid

Thread Previous | Thread Next
James E Keenan via RT
January 15, 2012 12:58
[perl #108276] C stack overflow in Perl_scalarvoid
Message ID:
On Sun Jan 15 10:35:13 2012, bulk88 wrote:
> Perl lexer (???) has a deep recursion bug in Perl_scalarvoid when
>    given a very large Perl subroutine to run.� Perl_scalarvoid calls
>    itself over and over, for what I blindly guess is every opcode in
>    the sub.� If there are too many opcodes, C stack overflows.
> I could not replicate this with any stock ActivePerl (AP 5.10.0, AP
>    5.12.3).� While the test script is running, ActivePerls peak at 8
>    MB on the C stack.� I checked with VMMAP.� If I lower the stack
>    reserve from 16 MB to 256KB in the PE header on perl.exe from
>    ActivePerls, I will get the same exact Perl_scalarvoid stack
>    overflow.� There is no reason for the interpreter to peak at many
>    MBs of C stack, which is irreversibly expanded (there are OS
>    specific ways to shrink C stacks.... I know it can be done with
>    VirtualFree and VirtualAlloc on Windows, but that is the wrong way
>    to fix C stack recursion) and wasted, never to be used again after
>    BEGIN blocks run.� I have not tested doing the "require" at
>    runtime.� On other perl scripts and apps I run, all the interpreter
>    (APs and my compiled Perl) peak at 20-50KB of C stack which is
>    fine.� I assume that the reason that my self-compiled Perl will
>    stack overflow at 16MB and ActivePerls do not is because of high C
>    stack overhead of each recursive Perl_scalarvoid when Perl is
>    compiled with -Od (no registers) meanwhile ActivePerls are compiled
>    with -O1 (small code).
> I wrote this test script to test how efficient Perl is at returning
>    memory to the OS after a Perl Module is "use"d and if, and how
>    well, memory behind the BEGIN blocks (SVs, CVs, Opcodes, pads, raw
>    malloced blocks) is returned to the OS.� If I lower the 100000 to
>    50000 in the test script, the script will run without a stack
>    overflow.� On sucessful runs, malloced memory went down from ~60MB
>    inside the module BEGIN block (at "print "after branches\n";") to
>    ~3MB at runtime ("print "in main\n";" ) according to VMMAP
>    (private/yellow memory).� C Stack remained at many MBs (7 to 8MB at
>    50000 in test script).
> Perl_scalarvoid, whatever it does to opcodes, should run in a loop
>    down the optree, not recursively on every opcode and thus eating
>    away the C stack.� I request that the above-reported bug be fixed.

1. I modified the test program you wrote to take the number of
iterations from the command-line rather than having it hard-coded.  I
then ran the program on the two OSes to which I have access, Darwin and
Linux.  In both cases, the program failed.

$ perl 10
number: 10
before require
Can't exec "pause": No such file or directory at line 23.
10after branches
Can't exec "pause": No such file or directory at
line 14.
in main
Can't exec "pause": No such file or directory at line 27.

'pause' is not an installed executable on those platforms (though it has
a man page as a C library function).

Could you modify your program to avoid the use of 'pause'?  That would
enable more people to run it.

2. While the screenshots you posted via the RT GUI are displaying, I
suspect they won't show up on the perl5-porters mailing list or newsgroup.

Thank you for your report.
Jim Keenan

via perlbug:  queue: perl5 status: open

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About