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

Not expected arguments for $SIG{__WARN__} handler #14917

Closed
p5pRT opened this issue Sep 17, 2015 · 13 comments
Closed

Not expected arguments for $SIG{__WARN__} handler #14917

p5pRT opened this issue Sep 17, 2015 · 13 comments

Comments

@p5pRT
Copy link

@p5pRT p5pRT commented Sep 17, 2015

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

Searchable as RT126085$

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Sep 17, 2015

From @KES777

Created by @KES777

The [doc](http​://perldoc.perl.org/functions/warn.html) says​:
 
  It is the handler's responsibility to deal with the message as it sees fit

Bug when I call warn​:

  warn 'arg1', 'arg2';

I expect to see two arguments in __WARN__ handler, but there is only one

perl -E '
$SIG{ __WARN__ } = sub {
  print ">>@​_<<";
  die "EXPECT two arguments" if scalar @​_ != 2;

  warn @​_;
};

warn "arg1", "arg2";
'
EXPECT two arguments at -e line 3.

If we need ( we do!) the line where 'warn' occour then
perl may just add to the last parameter of handler
" at -e line 9.\n"

So calling 'warn @​_' again will not break anything

Perl Info

Flags:
    category=core
    severity=medium

Site configuration information for perl 5.18.2:

Configured by Debian Project at Thu Mar 27 18:28:21 UTC 2014.

Summary of my perl5 (revision 5 version 18 subversion 2) configuration:
   
  Platform:
    osname=linux, osvers=3.2.0-58-generic, archname=x86_64-linux-gnu-thread-multi
    uname='linux brownie 3.2.0-58-generic #88-ubuntu smp tue dec 3 17:37:58 utc 2013 x86_64 x86_64 x86_64 gnulinux '
    config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -D_FORTIFY_SOURCE=2 -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Dldflags= -Wl,-Bsymbolic-functions -Wl,-z,relro -Dlddlflags=-shared -Wl,-Bsymbolic-functions -Wl,-z,relro -Dcccdlflags=-fPIC -Darchname=x86_64-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.18 -Darchlib=/usr/lib/perl/5.18 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.18.2 -Dsitearch=/usr/local/lib/perl/5.18.2 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Duse64bitint -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Ud_ualarm -Uusesfio -Uusenm -Ui_libutil -Uversiononly -DDEBUGGING=-g -Doptimize=-O2 -Duseshrplib -Dlibperl=libperl.so.5.18.2 -des'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fstack-protector -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2 -g',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fstack-protector -fno-strict-aliasing -pipe -I/usr/local/include'
    ccversion='', gccversion='4.8.2', 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 =' -fstack-protector -L/usr/local/lib'
    libpth=/usr/local/lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib /usr/lib
    libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt
    perllibs=-ldl -lm -lpthread -lc -lcrypt
    libc=, so=so, useshrplib=true, libperl=libperl.so.5.18.2
    gnulibc_version='2.19'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib -fstack-protector'

Locally applied patches:
    DEBPKG:debian/cpan_definstalldirs - Provide a sensible INSTALLDIRS default for modules installed from CPAN.
    DEBPKG:debian/db_file_ver - http://bugs.debian.org/340047 Remove overly restrictive DB_File version check.
    DEBPKG:debian/doc_info - Replace generic man(1) instructions with Debian-specific information.
    DEBPKG:debian/enc2xs_inc - http://bugs.debian.org/290336 Tweak enc2xs to follow symlinks and ignore missing @INC directories.
    DEBPKG:debian/errno_ver - http://bugs.debian.org/343351 Remove Errno version check due to upgrade problems with long-running processes.
    DEBPKG:debian/libperl_embed_doc - http://bugs.debian.org/186778 Note that libperl-dev package is required for embedded linking
    DEBPKG:fixes/respect_umask - Respect umask during installation
    DEBPKG:debian/writable_site_dirs - Set umask approproately for site install directories
    DEBPKG:debian/extutils_set_libperl_path - EU:MM: Set location of libperl.a to /usr/lib
    DEBPKG:debian/no_packlist_perllocal - Don't install .packlist or perllocal.pod for perl or vendor
    DEBPKG:debian/prefix_changes - Fiddle with *PREFIX and variables written to the makefile
    DEBPKG:debian/fakeroot - Postpone LD_LIBRARY_PATH evaluation to the binary targets.
    DEBPKG:debian/instmodsh_doc - Debian policy doesn't install .packlist files for core or vendor.
    DEBPKG:debian/ld_run_path - Remove standard libs from LD_RUN_PATH as per Debian policy.
    DEBPKG:debian/libnet_config_path - Set location of libnet.cfg to /etc/perl/Net as /usr may not be writable.
    DEBPKG:debian/mod_paths - Tweak @INC ordering for Debian
    DEBPKG:debian/module_build_man_extensions - http://bugs.debian.org/479460 Adjust Module::Build manual page extensions for the Debian Perl policy
    DEBPKG:debian/prune_libs - http://bugs.debian.org/128355 Prune the list of libraries wanted to what we actually need.
    DEBPKG:fixes/net_smtp_docs - [rt.cpan.org #36038] http://bugs.debian.org/100195 Document the Net::SMTP 'Port' option
    DEBPKG:debian/perlivp - http://bugs.debian.org/510895 Make perlivp skip include directories in /usr/local
    DEBPKG:debian/cpanplus_definstalldirs - http://bugs.debian.org/533707 Configure CPANPLUS to use the site directories by default.
    DEBPKG:debian/cpanplus_config_path - Save local versions of CPANPLUS::Config::System into /etc/perl.
    DEBPKG:debian/deprecate-with-apt - http://bugs.debian.org/702096 Point users to Debian packages of deprecated core modules
    DEBPKG:debian/squelch-locale-warnings - http://bugs.debian.org/508764 Squelch locale warnings in Debian package maintainer scripts
    DEBPKG:debian/skip-upstream-git-tests - Skip tests specific to the upstream Git repository
    DEBPKG:debian/patchlevel - http://bugs.debian.org/567489 List packaged patches for 5.18.2-2ubuntu1 in patchlevel.h
    DEBPKG:debian/skip-kfreebsd-crash - http://bugs.debian.org/628493 [perl #96272] Skip a crashing test case in t/op/threads.t on GNU/kFreeBSD
    DEBPKG:fixes/document_makemaker_ccflags - http://bugs.debian.org/628522 [rt.cpan.org #68613] Document that CCFLAGS should include $Config{ccflags}
    DEBPKG:debian/find_html2text - http://bugs.debian.org/640479 Configure CPAN::Distribution with correct name of html2text
    DEBPKG:debian/hurd_test_skip_stack - http://bugs.debian.org/650175 Disable failing GNU/Hurd tests dist/threads/t/stack.t
    DEBPKG:fixes/manpage_name_Test-Harness - http://bugs.debian.org/650451 [rt.cpan.org #73399] cpan/Test-Harness: add NAME headings in modules with POD
    DEBPKG:debian/makemaker-pasthru - http://bugs.debian.org/660195 [rt.cpan.org #28632] Make EU::MM pass LD through to recursive Makefile.PL invocations
    DEBPKG:debian/perl5db-x-terminal-emulator.patch - http://bugs.debian.org/668490 Invoke x-terminal-emulator rather than xterm in perl5db.pl
    DEBPKG:debian/cpan-missing-site-dirs - http://bugs.debian.org/688842 Fix CPAN::FirstTime defaults with nonexisting site dirs if a parent is writable
    DEBPKG:fixes/memoize_storable_nstore - [rt.cpan.org #77790] http://bugs.debian.org/587650 Memoize::Storable: respect 'nstore' option not respected
    DEBPKG:fixes/net_ftp_failed_command - [rt.cpan.org #37700] http://bugs.debian.org/491062 Net::FTP: cope gracefully with a failed command
    DEBPKG:fixes/perlbug-patchlist - [3541c11] http://bugs.debian.org/710842 [perl #118433] Make perlbug look up the list of local patches at run time
    DEBPKG:fixes/module_metadata_security_doc - [68cdd4b] CVE-2013-1437 documentation fix
    DEBPKG:fixes/module_metadata_taint_fix - [bff978f] http://bugs.debian.org/722210 [rt.cpan.org #88576] untaint version, if needed, in Module::Metadata
    DEBPKG:fixes/IPC-SysV-spelling - http://bugs.debian.org/730558 [rt.cpan.org #86736] Fix spelling of IPC_CREAT in IPC-SysV documentation
    DEBPKG:fixes/fix-undef-source -


@INC for perl 5.18.2:
    /home/kes/perl5/lib/perl5/x86_64-linux-gnu-thread-multi
    /home/kes/perl5/lib/perl5
    /etc/perl
    /usr/local/lib/perl/5.18.2
    /usr/local/share/perl/5.18.2
    /usr/lib/perl5
    /usr/share/perl5
    /usr/lib/perl/5.18
    /usr/share/perl/5.18
    /usr/local/lib/site_perl
    .


Environment for perl 5.18.2:
    HOME=/home/kes
    LANG=ru_UA.UTF-8
    LANGUAGE=en
    LC_MESSAGES=en_US.UTF-8
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/kes/perl5/bin:/home/kes/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
    PERL5LIB=/home/kes/perl5/lib/perl5
    PERL_BADLANG (unset)
    PERL_MB_OPT=--install_base "/home/kes/perl5"
    PERL_MM_OPT=INSTALL_BASE=/home/kes/perl5
    SHELL=/bin/bash

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Sep 17, 2015

From zefram@fysh.org

KES wrote​:

I expect to see two arguments in __WARN__ handler, but there is only one

The message is a single object, not a list. The list concatenation is
merely a superficial feature of the warn() function. (Likewise for
die().) This is not a bug, but may deserve a clarification in the
documentation.

But there is a related definite documentation bug. You raised the
issue of appending the location information. You suggest appending
it specifically to the last list element, but the way it's implemented
internally has the list concatenated first, and the location appended to
the concatenated result. But the documentation *does* imply a connection
specifically to the last list element​:

# If the last element of LIST
# does not end in a newline, it appends the same file/line number
# text as "die" does.

$ perl -lwe 'warn "foo\n", ""'
foo

The ending newline is actually looked for in the concatenated message,
not the last list element. The die() documentation has the same mistake.

-zefram

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Sep 17, 2015

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

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Sep 19, 2015

From @KES777

ZvR> The ending newline is actually looked for in the concatenated message,
ZvR> not the last list element. The die() documentation has the same mistake.

Seems same to me. The concatenated message actually is the list with one element.

The question is why arguments are changed?

This call 'warn' -> trigger this sub '$SUB{ __WARN__ }'
I have not see any places in perl where arguments are chaned for target sub
while calling.

What is the reason to merge arguments? ( I agree they must be merged when it is ready to send the message to destination (to STDOUT), but it is traveling yet to destination. And we must have a good reason to change args)

--
Eugen

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Sep 19, 2015

From @ap

* Eugen Konkov <kes-kes@​yandex.ru> [2015-09-19 07​:25]​:

This call 'warn' -> trigger this sub '$SUB{ __WARN__ }'
I have not see any places in perl where arguments are chaned for
target sub while calling.

What is the reason to merge arguments? ( I agree they must be merged
when it is ready to send the message to destination (to STDOUT), but
it is traveling yet to destination. And we must have a good reason to
change args)

You misunderstand what is going on.

$SIG{__WARN__} is called any time the warnings system is about to output
a message to its destination. (Which is STDERR of course, not STDOUT.)

These warnings do not have to come from `warn`. They can be any warnings
that Perl generates. $SIG{__WARN__} will see them all.

The job of `warn` is to take its arguments and turn them into a message
for the warning system. Once it has done that, the warning system sees
your $SIG{__WARN__} and passes it the message it received from `warn`.

If you want to intercept the arguments to `warn`, then that is what you
need to do � not intercept the messages given to the warnings system.

Chapter �Overriding Built-in Functions� in `perldoc perlsub` explains
your options. (And youâ��re in luck​: `warn` is easy to override. This is
absolutely not true for some other built-ins.)

Regards,
--
Aristotle Pagaltzis // <http​://plasmasturm.org/>

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Dec 16, 2017

From zefram@fysh.org

The documentation regarding looking for newline was fixed in commit
52e58e7. Since the request here was
otherwise mistaken, this ticket should be closed.

-zefram

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Dec 16, 2017

From @KES777

Zefram, in your commit you have a small typo​: You miss "s"
---without detroying it
+++without destroing it

16.12.2017, 08​:25, "Zefram via RT" <perlbug-followup@​perl.org>​:

The documentation regarding looking for newline was fixed in commit
52e58e7. Since the request here was
otherwise mistaken, this ticket should be closed.

-zefram

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Dec 16, 2017

From zefram@fysh.org

KES wrote​:

Zefram, in your commit you have a small typo​: You miss "s"

Thanks. Fixed in commit 6f0a679.

-zefram

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Dec 16, 2017

From @KES777

Zefram, thank you for clarifying the DOC. But one question​:

+By default, the exception derived from the operand LIST is stringified
+and printed to C<STDERR>. This behaviour can be altered by installing
+a L<C<$SIG{__WARN__}>|perlvar/%SIG> handler. If there is such a
+handler then no message is automatically printed; it is the handler's
+responsibility to deal with the exception

Are you speaking about warnings or exceptions here? if you are speaking about exceptions then "a L<C<$SIG{__DIE__}> handler" should be installed instead of $SIG{__WARN__}.
But I will be happy if warnings and exceptions are treated the same and handled the same way with only one difference​: warnings are not fatal

Aristotle Pagaltzis

The job of `warn` is to take its arguments and turn them into a message for the warning system
As I see from documentation it is "stuffed into $@​"

If you want to intercept the arguments to `warn`, then that is what you need to do � not intercept the messages given to the warnings system

The message given to the warnings systems is $@​, is not?
The handler is called up to "rewrite" a pending warning in $@​" and this messages is rewritten as more accurate as more context information it has.

So I will advocate to that that handler should be called with original LIST

Chapter â��Overriding Built-in Functionsâ�� in `perldoc perlsub` explains your options. (And youâ��re in luck​: `warn` is easy to override. This is absolutely not true for some other built-ins.)

Never thought about overloading because "this behaviour can be altered by installing a L<C<$SIG{__WARN__}>|perlvar/%SIG> handler." so maybe there will be a good point to describe the difference between installing the handler and overloading the CORE​::warn

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Dec 16, 2017

From zefram@fysh.org

KES via RT wrote​:

Are you speaking about warnings or exceptions here?

Both. The subject of warn() is an exception, in the sense of being a
notable program state that is being reported non-locally. The difference
between warn() and die() is not in whether their subject is an exception,
but in whether the code reporting the exception is prepared to continue.
We have plenty of code that shuffles exceptions between the warning and
dying mechanisms.

The message given to the warnings systems is $@​, is not?

warn() can take an exception from $@​, but within the warning system the
exception being warned about is generally not in $@​. The $SIG{__WARN__}
handler gets the exception as an argument. For that matter, the
$SIG{__DIE__} handler also gets the exception as an argument. The primary
purpose of $@​ is quite a limited one​: to communicate a caught exception
or lack thereof from "eval" to the code that runs immediately after.

-zefram

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Dec 18, 2017

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

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Jun 23, 2018

From @khwilliamson

Thank you for filing this report. You have helped make Perl better.

With the release yesterday of Perl 5.28.0, this and 185 other issues have been
resolved.

Perl 5.28.0 may be downloaded via​:
https://metacpan.org/release/XSAWYERX/perl-5.28.0

If you find that the problem persists, feel free to reopen this ticket.

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Jun 23, 2018

@khwilliamson - 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
Development

No branches or pull requests

1 participant