Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segmentation failed on calling method of undef with use warnings FATAL => 'all' #14319

Closed
p5pRT opened this issue Dec 9, 2014 · 17 comments
Closed

Comments

@p5pRT
Copy link
Collaborator

@p5pRT p5pRT commented Dec 9, 2014

Migrated from rt.perl.org#123398 (status was 'resolved')

Searchable as RT123398$

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Dec 9, 2014

From @hurricup

Created by @hurricup

Example below leads to segmentation fault. Works fine without warnings FATAL => 'all'​:

#!/usr/bin/perl
package Foo;
use strict; use utf8; use warnings FATAL => 'all';

sub new
{
  return bless{ 'field' => undef }, 'Foo';
}

sub DESTROY
{
  my $self = shift;
  $self->{'field'}->missing_method;
}

package main;

my $foo = new Foo;
undef($foo);

Perl Info

Flags:
    category=core
    severity=critical

Site configuration information for perl 5.20.1:

Configured by root at Sun Dec  7 13:23:13 MSK 2014.

Summary of my perl5 (revision 5 version 20 subversion 1) configuration:
   
  Platform:
    osname=freebsd, osvers=9.3-release-p4, archname=amd64-freebsd-thread-multi
    uname='freebsd storage.cobweb-software.com 9.3-release-p4 freebsd 9.3-release-p4 #0 r273928: sat nov 1 17:16:18 msk 2014 root@storage.cobweb-software.com:usrobjusrsrcsysgeneric amd64 '
    config_args='-sde -Dprefix=/usr/local -Dlibperl=libperl.so.5.20 -Darchlib=/usr/local/lib/perl5/5.20/mach -Dprivlib=/usr/local/lib/perl5/5.20 -Dman3dir=/usr/local/lib/perl5/5.20/perl/man/man3 -Dman1dir=/usr/local/man/man1 -Dsitearch=/usr/local/lib/perl5/site_perl/mach/5.20 -Dsitelib=/usr/local/lib/perl5/site_perl -Dscriptdir=/usr/local/bin -Dsiteman3dir=/usr/local/lib/perl5/site_perl/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Ui_malloc -Ui_iconv -Uinstallusrbinperl -Dcc=cc -Duseshrplib -Dinc_version_list=none -Dccflags=-DAPPLLIB_EXP="/usr/local/lib/perl5/5.20/BSDPAN" -Dotherlibdirs=/usr/local/lib/perl5/site_perl/5.20:/usr/local/lib/perl5/site_perl/5.20/mach -Doptimize=-g -DDEBUGGING -Ui_gdbm -Dusemultiplicity=y -Duse64bitint -Dusethreads=y -Dusemymalloc=n'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-DAPPLLIB_EXP="/usr/local/lib/perl5/5.20/BSDPAN" -DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include',
    optimize='-g',
    cppflags='-DAPPLLIB_EXP="/usr/local/lib/perl5/5.20/BSDPAN" -DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
    ccversion='', gccversion='4.2.1 20070831 patched [FreeBSD]', gccosandvers=''
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='cc', ldflags ='-pthread -Wl,-E  -fstack-protector -L/usr/local/lib'
    libpth=/usr/lib /usr/local/lib /usr/include/gcc/4.2 /usr/lib
    libs=-lgdbm -lm -lcrypt -lutil
    perllibs=-lm -lcrypt -lutil
    libc=, so=so, useshrplib=true, libperl=libperl.so.5.20
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='  -Wl,-R/usr/local/lib/perl5/5.20/mach/CORE'
    cccdlflags='-DPIC -fPIC', lddlflags='-shared  -L/usr/local/lib -fstack-protector'



@INC for perl 5.20.1:
    /raid/www/lib
    /usr/local/lib/perl5/5.20/BSDPAN
    /usr/local/lib/perl5/site_perl/mach/5.20
    /usr/local/lib/perl5/site_perl
    /usr/local/lib/perl5/5.20/mach
    /usr/local/lib/perl5/5.20
    /usr/local/lib/perl5/site_perl/5.20
    /usr/local/lib/perl5/site_perl/5.20/mach
    .


Environment for perl 5.20.1:
    HOME=/root
    LANG=ru_RU.UTF-8
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:/root/bin
    PERL5LIB=/raid/www/lib
    PERL_BADLANG (unset)
    SHELL=/bin/csh

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Dec 9, 2014

From @hurricup

Created by @hurricup

Example below leads to segmentation fault. Works fine without warnings
FATAL => 'all'​:

#!/usr/bin/perl
package Foo;
use strict; use utf8; use warnings FATAL => 'all';

sub new
{
  return bless{ 'field' => undef }, 'Foo';
}

sub DESTROY
{
  my $self = shift;
  $self->{'field'}->missing_method;
}

package main;

my $foo = new Foo;
undef($foo);

Perl Info

Flags:
    category=core
    severity=critical

Site configuration information for perl 5.20.1:

Configured by root at Sun Dec  7 13:23:13 MSK 2014.

Summary of my perl5 (revision 5 version 20 subversion 1) configuration:

  Platform:
    osname=freebsd, osvers=9.3-release-p4,
archname=amd64-freebsd-thread-multi
    uname='freebsd storage.cobweb-software.com 9.3-release-p4 freebsd
9.3-release-p4 #0 r273928: sat nov 1 17:16:18 msk 2014
root@storage.cobweb-software.com:usrobjusrsrcsysgeneric amd64 '
    config_args='-sde -Dprefix=/usr/local -Dlibperl=libperl.so.5.20
-Darchlib=/usr/local/lib/perl5/5.20/mach
-Dprivlib=/usr/local/lib/perl5/5.20
-Dman3dir=/usr/local/lib/perl5/5.20/perl/man/man3
-Dman1dir=/usr/local/man/man1
-Dsitearch=/usr/local/lib/perl5/site_perl/mach/5.20
-Dsitelib=/usr/local/lib/perl5/site_perl -Dscriptdir=/usr/local/bin
-Dsiteman3dir=/usr/local/lib/perl5/site_perl/man/man3
-Dsiteman1dir=/usr/local/man/man1 -Ui_malloc -Ui_iconv -Uinstallusrbinperl
-Dcc=cc -Duseshrplib -Dinc_version_list=none
-Dccflags=-DAPPLLIB_EXP="/usr/local/lib/perl5/5.20/BSDPAN"
-Dotherlibdirs=/usr/local/lib/perl5/site_perl/5.20:/usr/local/lib/perl5/site_perl/5.20/mach
-Doptimize=-g -DDEBUGGING -Ui_gdbm -Dusemultiplicity=y -Duse64bitint
-Dusethreads=y -Dusemymalloc=n'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-DAPPLLIB_EXP="/usr/local/lib/perl5/5.20/BSDPAN"
-DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -DDEBUGGING -fno-strict-aliasing
-pipe -fstack-protector -I/usr/local/include',
    optimize='-g',
    cppflags='-DAPPLLIB_EXP="/usr/local/lib/perl5/5.20/BSDPAN"
-DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -DDEBUGGING -fno-strict-aliasing
-pipe -fstack-protector -I/usr/local/include'
    ccversion='', gccversion='4.2.1 20070831 patched [FreeBSD]',
gccosandvers=''
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t',
lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='cc', ldflags ='-pthread -Wl,-E  -fstack-protector -L/usr/local/lib'
    libpth=/usr/lib /usr/local/lib /usr/include/gcc/4.2 /usr/lib
    libs=-lgdbm -lm -lcrypt -lutil
    perllibs=-lm -lcrypt -lutil
    libc=, so=so, useshrplib=true, libperl=libperl.so.5.20
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='
 -Wl,-R/usr/local/lib/perl5/5.20/mach/CORE'
    cccdlflags='-DPIC -fPIC', lddlflags='-shared  -L/usr/local/lib
-fstack-protector'



@INC for perl 5.20.1:
    /raid/www/lib
    /usr/local/lib/perl5/5.20/BSDPAN
    /usr/local/lib/perl5/site_perl/mach/5.20
    /usr/local/lib/perl5/site_perl
    /usr/local/lib/perl5/5.20/mach
    /usr/local/lib/perl5/5.20
    /usr/local/lib/perl5/site_perl/5.20
    /usr/local/lib/perl5/site_perl/5.20/mach
    .


Environment for perl 5.20.1:
    HOME=/root
    LANG=ru_RU.UTF-8
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:/root/bin
    PERL5LIB=/raid/www/lib
    PERL_BADLANG (unset)
    SHELL=/bin/csh

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Dec 9, 2014

From @tonycoz

On Tue Dec 09 12​:27​:08 2014, hurricup@​gmail.com wrote​:

Example below leads to segmentation fault. Works fine without warnings
FATAL => 'all'​:

#!/usr/bin/perl
package Foo;
use strict; use utf8; use warnings FATAL => 'all';

sub new
{
return bless{ 'field' => undef }, 'Foo';
}

sub DESTROY
{
my $self = shift;
$self->{'field'}->missing_method;
}

package main;

my $foo = new Foo;
undef($foo);

This is recursing deeply​:

#0 0x000000000051d269 in Perl_sv_grow (sv=sv@​entry=0x1576988, newlen=16)
  at sv.c​:1620
#1 0x0000000000532b6a in Perl_sv_catpvn_flags (dsv=dsv@​entry=0x1576988,
  sstr=sstr@​entry=0x690396 "\t(in cleanup) %-p", slen=14,
  flags=flags@​entry=0) at sv.c​:5464
#2 0x0000000000510798 in Perl_sv_vcatpvfn_flags (sv=sv@​entry=0x1576988,
  pat=pat@​entry=0x690396 "\t(in cleanup) %-p", patlen=patlen@​entry=17,
  args=args@​entry=0x7ffffff7f348, svargs=0x0, svmax=0,
  maybe_tainted=maybe_tainted@​entry=0x0, flags=flags@​entry=0) at sv.c​:11354
#3 0x0000000000514b7b in Perl_sv_vsetpvfn (sv=sv@​entry=0x1576988,
  pat=pat@​entry=0x690396 "\t(in cleanup) %-p", patlen=17,
  args=args@​entry=0x7ffffff7f348, svargs=svargs@​entry=0x0,
  svmax=svmax@​entry=0, maybe_tainted=maybe_tainted@​entry=0x0) at sv.c​:10683
#4 0x00000000004d5118 in Perl_vmess (pat=0x690396 "\t(in cleanup) %-p",
  args=0x7ffffff7f348) at util.c​:1451
#5 0x00000000004d559a in Perl_vwarner (err=<optimized out>,
  pat=<optimized out>, args=<optimized out>) at util.c​:1926
#6 0x00000000004d57ce in Perl_ck_warner (err=err@​entry=12,
  pat=pat@​entry=0x690396 "\t(in cleanup) %-p") at util.c​:1905
#7 0x000000000056b19a in Perl_die_unwind (msv=msv@​entry=0x1576958)
  at pp_ctl.c​:1613
#8 0x00000000004d566e in Perl_vwarner (err=<optimized out>,
  pat=<optimized out>, args=<optimized out>) at util.c​:1933
#9 0x00000000004d57ce in Perl_ck_warner (err=err@​entry=12,
  pat=pat@​entry=0x690396 "\t(in cleanup) %-p") at util.c​:1905
#10 0x000000000056b19a in Perl_die_unwind (msv=msv@​entry=0x1576928)
  at pp_ctl.c​:1613
#11 0x00000000004d566e in Perl_vwarner (err=<optimized out>,
  pat=<optimized out>, args=<optimized out>) at util.c​:1933
#12 0x00000000004d57ce in Perl_ck_warner (err=err@​entry=12,
  pat=pat@​entry=0x690396 "\t(in cleanup) %-p") at util.c​:1905
#13 0x000000000056b19a in Perl_die_unwind (msv=msv@​entry=0x15768f8)
  at pp_ctl.c​:1613
#14 0x00000000004d566e in Perl_vwarner (err=<optimized out>,
  pat=<optimized out>, args=<optimized out>) at util.c​:1933
#15 0x00000000004d57ce in Perl_ck_warner (err=err@​entry=12,
  pat=pat@​entry=0x690396 "\t(in cleanup) %-p") at util.c​:1905
#16 0x000000000056b19a in Perl_die_unwind (msv=msv@​entry=0x15768c8)
  at pp_ctl.c​:1613
...
#4244 0x00000000004d3c98 in Perl_vcroak (pat=<optimized out>,
  args=args@​entry=0x7fffffffe278) at util.c​:1681
#4245 0x00000000004d3dbc in Perl_croak (
  pat=pat@​entry=0x65ced0 "Can't call method \"%-p\" on an undefined value")
  at util.c​:1726
#4246 0x00000000004f88ad in S_opmethod_stash (meth=0x8f7b48) at pp_hot.c​:3428
#4247 0x00000000005083f7 in Perl_pp_method_named () at pp_hot.c​:3539

#4248 0x00000000004d1f1a in Perl_runops_debug () at dump.c​:2230
#4249 0x000000000044afb6 in Perl_call_sv (sv=sv@​entry=0x8eac40,
  flags=flags@​entry=45) at perl.c​:2730
#4250 0x000000000050b2b9 in S_curse (sv=sv@​entry=0x8d6130,
  check_refcnt=check_refcnt@​entry=true) at sv.c​:6871
#4251 0x000000000050b846 in Perl_sv_clear (orig_sv=orig_sv@​entry=0x8d6130)
  at sv.c​:6499
#4252 0x000000000050c7e5 in Perl_sv_free2 (sv=0x8d6130, rc=<optimized out>)
  at sv.c​:6972
#4253 0x000000000053d73d in Perl_pp_undef () at pp.c​:984
#4254 0x00000000004d1f1a in Perl_runops_debug () at dump.c​:2230

#4255 0x0000000000453fff in S_run_body (oldscope=1) at perl.c​:2421
#4256 perl_run (my_perl=<optimized out>) at perl.c​:2344
#4257 0x0000000000424845 in main (argc=3, argv=0x7fffffffe8e8,
  env=0x7fffffffe908) at perlmain.c​:116

Tony

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Dec 9, 2014

The RT System itself - Status changed from 'new' to 'open'

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Dec 10, 2014

From @cpansprout

On Tue Dec 09 15​:19​:12 2014, tonyc wrote​:

On Tue Dec 09 12​:27​:08 2014, hurricup@​gmail.com wrote​:

Example below leads to segmentation fault. Works fine without
warnings
FATAL => 'all'​:

#!/usr/bin/perl
package Foo;
use strict; use utf8; use warnings FATAL => 'all';

sub new
{
return bless{ 'field' => undef }, 'Foo';
}

sub DESTROY
{
my $self = shift;
$self->{'field'}->missing_method;
}

package main;

my $foo = new Foo;
undef($foo);

This is recursing deeply​:

Oh, *that* bug. Last time this came up, no one could decide exactly how it should behave.

Errors in destructors are turned into warning. If those warnings are fatal, then they get turned into errors, but errors in destructors are caught and turned into warnings....

I don’t remember how the previous conversation ended, or which ticket it was in (it was a side issue in the ticket in question, so it’s hard to search for it).

Should we just ignore the fatality in this case and emit a warning?

--

Father Chrysostomos

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Dec 10, 2014

From @tonycoz

On Tue Dec 09 16​:11​:46 2014, sprout wrote​:

Errors in destructors are turned into warning. If those warnings are
fatal, then they get turned into errors, but errors in destructors are
caught and turned into warnings....

I don’t remember how the previous conversation ended, or which ticket
it was in (it was a side issue in the ticket in question, so it’s hard
to search for it).

Should we just ignore the fatality in this case and emit a warning?

I think so.

Tony

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Dec 10, 2014

From @mauke

Am 10.12.2014 um 03​:37 schrieb Tony Cook via RT​:

On Tue Dec 09 16​:11​:46 2014, sprout wrote​:

Errors in destructors are turned into warning. If those warnings are
fatal, then they get turned into errors, but errors in destructors are
caught and turned into warnings....

I don’t remember how the previous conversation ended, or which ticket
it was in (it was a side issue in the ticket in question, so it’s hard
to search for it).

Should we just ignore the fatality in this case and emit a warning?

I think so.

Seems reasonable to me.

--
Lukas Mai <plokinom@​gmail.com>

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Dec 10, 2014

From @iabyn

On Tue, Dec 09, 2014 at 12​:28​:24PM -0800, via RT wrote​:

Example below leads to segmentation fault. Works fine without warnings
FATAL => 'all'​:

#!/usr/bin/perl
package Foo;
use strict; use utf8; use warnings FATAL => 'all';

sub new
{
return bless{ 'field' => undef }, 'Foo';
}

sub DESTROY
{
my $self = shift;
$self->{'field'}->missing_method;
}

package main;

my $foo = new Foo;
undef($foo);

It's getting stuck in a recursive loop, emitting a warning which gets
upgraded to a croak (due to FATAL => 'all') which emits a warning,
and so on until either the stack blows or memory is exhausted.

The bit I don't understand is that die_unwind(), in addition to croaking
with this message​:

  Can't call method "missing_method" on an undefined value

is first attempting to emit this warning​:

  \t(in cleanup) Can't call method "missing_method" on an undefined value

The actual code in pp_ctl.c is​:

  if (in_eval & EVAL_KEEPERR) {
  Perl_ck_warner(aTHX_ packWARN(WARN_MISC), "\t(in cleanup) %"SVf,
  SVfARG(exceptsv));
  }

and EVAL_KEEPERR is true because S_curse() has done

  call_cv("DESTROY", G_DISCARD|G_EVAL|G_KEEPERR|G_VOID);

Because I don't understand the whole die / $@​ / stack unwind malarky,
I don't feel in a position to know how to fix this. Zefram? Anyone else?

--
You live and learn (although usually you just live).

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Dec 10, 2014

From @iabyn

On Wed, Dec 10, 2014 at 03​:47​:19PM +0000, Dave Mitchell wrote​:

On Tue, Dec 09, 2014 at 12​:28​:24PM -0800, via RT wrote​:

Example below leads to segmentation fault. Works fine without warnings
FATAL => 'all'​:

Ah I see now this is a duplicate of #123398. Any further discussion should
be on that ticket.

--
It's not that I'm afraid to die, I just don't want to be there when it
happens.
  -- Woody Allen

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Dec 10, 2014

From @cpansprout

On Wed Dec 10 07​:47​:44 2014, davem wrote​:

On Tue, Dec 09, 2014 at 12​:28​:24PM -0800, via RT wrote​:

Example below leads to segmentation fault. Works fine without warnings
FATAL => 'all'​:

#!/usr/bin/perl
package Foo;
use strict; use utf8; use warnings FATAL => 'all';

sub new
{
return bless{ 'field' => undef }, 'Foo';
}

sub DESTROY
{
my $self = shift;
$self->{'field'}->missing_method;
}

package main;

my $foo = new Foo;
undef($foo);

It's getting stuck in a recursive loop, emitting a warning which gets
upgraded to a croak (due to FATAL => 'all') which emits a warning,
and so on until either the stack blows or memory is exhausted.

The bit I don't understand is that die_unwind(), in addition to croaking
with this message​:

Can't call method "missing\_method" on an undefined value

is first attempting to emit this warning​:

\\t\(in cleanup\) Can't call method "missing\_method" on an undefined value

The actual code in pp_ctl.c is​:

if \(in\_eval & EVAL\_KEEPERR\) \{
    Perl\_ck\_warner\(aTHX\_ packWARN\(WARN\_MISC\)\, "\\t\(in cleanup\) %"SVf\,
           SVfARG\(exceptsv\)\);
\}

and EVAL_KEEPERR is true because S_curse() has done

call\_cv\("DESTROY"\, G\_DISCARD|G\_EVAL|G\_KEEPERR|G\_VOID\);

Because I don't understand the whole die / $@​ / stack unwind malarky,
I don't feel in a position to know how to fix this. Zefram? Anyone else?

Either we need to check for a fatal warning and disable it temporarily (in die_unwind), or when turning the warning into an error first make check that !(PL_in_eval & EVAL_KEEPERR) (in the warnings code itself).

--

Father Chrysostomos

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Feb 12, 2015

From @mauke

On Wed Dec 10 08​:47​:43 2014, sprout wrote​:

Either we need to check for a fatal warning and disable it temporarily
(in die_unwind), or when turning the warning into an error first make
check that !(PL_in_eval & EVAL_KEEPERR) (in the warnings code itself).

I've attached a patch to do the latter. Comments?

And how can I write a test for this that fails nicely? Some ulimit hackery?

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Feb 12, 2015

From @mauke

0001-don-t-fatalize-warnings-during-unwinding-123398.patch
From cc84a7c92a6f33ef6ac239d916132fa38ff1b689 Mon Sep 17 00:00:00 2001
From: Lukas Mai <l.mai@web.de>
Date: Thu, 12 Feb 2015 13:29:29 +0100
Subject: [PATCH] don't fatalize warnings during unwinding (#123398)

---
 util.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/util.c b/util.c
index 9ffdbde..0e4c2ce 100644
--- a/util.c
+++ b/util.c
@@ -1939,7 +1939,10 @@ Perl_vwarner(pTHX_ U32  err, const char* pat, va_list* args)
 {
     dVAR;
     PERL_ARGS_ASSERT_VWARNER;
-    if (PL_warnhook == PERL_WARNHOOK_FATAL || ckDEAD(err)) {
+    if (
+        (PL_warnhook == PERL_WARNHOOK_FATAL || ckDEAD(err)) &&
+        !(PL_in_eval & EVAL_KEEPERR)
+    ) {
 	SV * const msv = vmess(pat, args);
 
 	if (PL_parser && PL_parser->error_count) {
-- 
2.3.0

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Mar 17, 2015

From @wchristian

It seems to me that this behavior is not isolated to fatal warnings, but also runtime strict exceptions. I may be wrong, but here's the result i am seeing on my windows Perl​:

  C​:\>perl -e "use warnings FATAL => 'all'; sub DESTROY { my $x + 1;}; bless {}"
 
  C​:\>perl -e "use warnings FATAL => 'all'; my $x + 1;"
  Useless use of addition (+) in void context at -e line 1.
 
  C​:\>perl -e "use strict; my $r = 'f'; sub DESTROY { $$r; }; bless {}"
 
  C​:\>perl -e "use strict; my $r = 'f'; $$r;"
  Can't use string ("f") as a SCALAR ref while "strict refs" in use at -e line 1.

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Mar 17, 2015

From @wchristian

On Tue Mar 17 10​:49​:20 2015, Mithaldu wrote​:

I may be wrong

I was wrong, was seeing scoping oddities.

That said, while i'm poking this, Mauke's patch above has been sitting there for a while and deserves attention.

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Jun 9, 2015

From @tonycoz

On Thu Feb 12 04​:55​:24 2015, mauke- wrote​:

On Wed Dec 10 08​:47​:43 2014, sprout wrote​:

Either we need to check for a fatal warning and disable it temporarily
(in die_unwind), or when turning the warning into an error first make
check that !(PL_in_eval & EVAL_KEEPERR) (in the warnings code itself).

I've attached a patch to do the latter. Comments?

And how can I write a test for this that fails nicely? Some ulimit hackery?

Thanks, applied as 46b27d2.

Tony

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Jun 9, 2015

@tonycoz - Status changed from 'open' to 'pending release'

@p5pRT p5pRT closed this Jan 10, 2016
@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Jan 10, 2016

@mauke - Status changed from 'pending release' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant
You can’t perform that action at this time.