Front page | perl.perl5.porters |
Postings from April 2019
[perl #134035] Out of memory when doing IO via pipe and receivesignal
Thread Previous
From:
Tony Cook via RT
Date:
April 17, 2019 05:54
Subject:
[perl #134035] Out of memory when doing IO via pipe and receivesignal
Message ID:
rt-4.0.24-16443-1555480453-111.134035-15-0@perl.org
On Mon, 15 Apr 2019 21:18:40 -0700, azrlew@gmail.com wrote:
> This is a bug report for perl from azrlew@gmail.com,
> generated with the help of perlbug 1.40 running under perl 5.26.1.
>
> Out of memory error (ENOMEN) can occur when Perl is doing IO via pipe
> and a signal handler is triggered.
>
> Test codes to reproduce the problem can be found here:
> https://github.com/azrle/perl-signal-io-bug
>
> Perl will fail to run at least one of 'perlio-signal-while-safe.pl'
> and 'perlio-signal-while.pl'.
>
> Serveral Perl versions are affected including 5.16.1, 5.18.2, 5.26.1.
> Note that not all versions failed on both.
>
>
> ---
> Some crash logs (perl 5.18.2, macos):
>
> # perl perlio-signal-while.pl
> parent 43396
> timeout
> perl(43396,0x1173c15c0) malloc: can't allocate region
> *** mach_vm_map(size=18446744073683324928) failed (error code=3)
> perl(43396,0x1173c15c0) malloc: *** set a breakpoint in
> malloc_error_break to debug
> Out of memory!
>
>
> ---
> Some gdb results (perl 5.16.1, linux):
>
> (gdb) run perlio-signal-while.pl
> Starting program: /usr/bin/perl perlio-signal-while.pl
>
> Breakpoint 1, Perl_sv_gets (sv=0x780ca0, fp=0x76ee90, append=0) at
> sv.c:7821
> 7821 sv.c: No such file or directory.
> (gdb) c 18
> Will ignore next 17 crossings of breakpoint 1. Continuing.
> parent 25688
> timeout
>
> Breakpoint 1, Perl_sv_gets (sv=0x780c28, fp=0x76ee70, append=0) at
> sv.c:7821
> 7821 in sv.c
> (gdb) bt
> #0 Perl_sv_gets (sv=0x780c28, fp=0x76ee70, append=0) at sv.c:7821
> #1 0x000000000049a8d1 in Perl_do_readline () at pp_hot.c:1675
> #2 0x0000000000496193 in Perl_runops_standard () at run.c:41
> #3 0x0000000000434878 in S_run_body (oldscope=<optimized out>) at
> perl.c:2402
> #4 perl_run (my_perl=<optimized out>) at perl.c:2320
> #5 0x000000000041e10c in main (argc=2, argv=0x7fffffffdff8,
> env=0x7fffffffe010) at perlmain.c:120
>
> (gdb) p ptr
> $5 = 0x8d5dd1 "2\n"
> (gdb) p ptr-1
> $6 = 0x8d5dd0 "42\n"
>
> (gdb) p bp
> $7 = 0x76e070 ""
>
> (gdb) p ((const char*)((sv)->sv_u.svu_pv))
> $8 = 0x77dfe0 ""
>
> # underflow
> (gdb) p bp-((const char*)((sv)->sv_u.svu_pv))
> $9 = -65392
> (gdb) n
> 7822 in sv.c
> (gdb) p bpx
> $10 = 18446744073709486224
Yeah, the code isn't expecting the SV, $_ in this case, to be modified from underneath it.
Adding:
local $_;
to the beginning of the signal handler also fixes the problem and is probably the sane thing to do in a signal handler anyway.
Having perl do the local would fix it for $_, but it would still be broken for any other SV.
The attached patch fixes it for me.
$ ../perl/perl -I../perl/lib perlio-signal-while-safe.pl
parent 24425
timeout
panic: realloc, size=18446744073709476200 at perlio-signal-while-safe.pl line 27.
At first I thought it might be a safe signals problem, but that isn't the case.
Tony
---
via perlbug: queue: perl5 status: new
https://rt.perl.org/Ticket/Display.html?id=134035
Thread Previous