develooper 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


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