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

@DB::args inconsistently reflects changes to @_ #13517

Open
p5pRT opened this issue Jan 9, 2014 · 3 comments
Open

@DB::args inconsistently reflects changes to @_ #13517

p5pRT opened this issue Jan 9, 2014 · 3 comments

Comments

@p5pRT
Copy link

p5pRT commented Jan 9, 2014

Migrated from rt.perl.org#120959 (status was 'open')

Searchable as RT120959$

@p5pRT
Copy link
Author

p5pRT commented Jan 9, 2014

From @jimav

This is a bug report for perl from james_avera@​yahoo.com,
generated with the help of perlbug 1.39 running under perl 5.14.2.


When caller() is called from package DB, it sets @​DB​::args
"to be the arguments with which the subroutine was invoked...
@​DB​::args will contain modifications the subroutine makes to @​_ or
its contents, not the original values at call time" [perlfunc]

However this is not always the case.

If the calling sub (not in package DB) modifies @​_ before calling into
package DB, then @​DB​::args may or may not reflect the changes.
Specifically, "shift @​_" is effectively un-done and the removed arg
re-appears in @​DB​::args, BUT only if no other changes have been made
to @​_, such as 'unshift' or 'push'.

Is this a bug, a side-effect of the optimizer, or intentional behavior?

On the surface, it seems like @​DB​::args should either always get
the current state of @​_ (my preference), or always get the args
before any modifications.

[This matters to me because @​_ isn't displayed reliably in a
a debug tool -- http​://abhweb.org/jima/perl/lib/Vis.pm ]

#!/usr/bin/perl
use strict; use warnings;
sub f(@​) {
  shift @​_;
  my @​a = &DB​::test; print "After 'shift', DB​::test returned (@​a)\n";
}
sub g(@​) {
  pop @​_;
  my @​a = &DB​::test; print "After 'pop', DB​::test returned (@​a)\n";
}
sub h(@​) {
  shift @​_; unshift @​_,"subst";
  my @​a = &DB​::test; print "After 'shift' then 'unshift', DB​::test
returned (@​a)\n";
}
f(1,2,3); # result is (1,2,3), i.e. shift alone not visible
g(1,2,3); # result is (1,2) pop is visible
h(1,2,3); # result is ("subst",2,3) shift visible if followed by unshift

package DB;
sub test {
  (undef) = (caller(1));
  return @​DB​::args;
}



Flags​:
  category=core
  severity=low


Site configuration information for perl 5.14.2​:

Configured by Debian Project at Thu Jul 18 22​:04​:35 UTC 2013.

Summary of my perl5 (revision 5 version 14 subversion 2) configuration​:

  Platform​:
  osname=linux, osvers=3.2.0-37-generic,
archname=x86_64-linux-gnu-thread-multi
  uname='linux roseapple 3.2.0-37-generic #58-ubuntu smp thu jan 24
15​:28​:10 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.14 -Darchlib=/usr/lib/perl/5.14
-Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5
-Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local
-Dsitelib=/usr/local/share/perl/5.14.2
-Dsitearch=/usr/local/lib/perl/5.14.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 -DDEBUGGING=-g -Doptimize=-O2 -Duseshrplib
-Dlibperl=libperl.so.5.14.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.1', 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.14.2
  gnulibc_version='2.17'
  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​:


@​INC for perl 5.14.2​:
  /home/jima/lib/perl
  /home/jima/perl5/lib/perl5/x86_64-linux-gnu-thread-multi
  /home/jima/perl5/lib/perl5/x86_64-linux-gnu-thread-multi
  /home/jima/perl5/lib/perl5
  /etc/perl
  /usr/local/lib/perl/5.14.2
  /usr/local/share/perl/5.14.2
  /usr/lib/perl5
  /usr/share/perl5
  /usr/lib/perl/5.14
  /usr/share/perl/5.14
  /usr/local/lib/site_perl
  .


Environment for perl 5.14.2​:
  HOME=/home/jima
  LANG=en_US.UTF-8
  LANGUAGE=en_US
  LD_LIBRARY_PATH=/home/jima/local/lib
  LOGDIR (unset)

PATH=/home/jima/perl5/bin​:/home/jima/bin​:/home/jima/local/bin​:/home/jima/jima_tools/x86_64/bin​:/home/jima/jima_tools/bin​:/usr/bin​:/bin​:/usr/sbin​:/sbin​:/usr/bin/X11​:/usr/local/bin​:/usr/lib/lightdm/lightdm​:/usr/local/sbin​:/usr/games​:/usr/local/games​:/usr/lib/jvm/java-7-oracle/bin​:/usr/lib/jvm/java-7-oracle/db/bin​:/usr/lib/jvm/java-7-oracle/jre/bin​:.

PERL5LIB=/home/jima/lib/perl​:/home/jima/perl5/lib/perl5/x86_64-linux-gnu-thread-multi​:/home/jima/perl5/lib/perl5
  PERL_BADLANG (unset)
  PERL_LOCAL_LIB_ROOT=/home/jima/perl5
  PERL_MB_OPT=--install_base /home/jima/perl5
  PERL_MM_OPT=INSTALL_BASE=/home/jima/perl5
  SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Jan 10, 2014

From @iabyn

On Thu, Jan 09, 2014 at 03​:35​:24PM -0800, Jim Avera wrote​:

If the calling sub (not in package DB) modifies @​_ before calling into
package DB, then @​DB​::args may or may not reflect the changes.
Specifically, "shift @​_" is effectively un-done and the removed arg
re-appears in @​DB​::args, BUT only if no other changes have been made
to @​_, such as 'unshift' or 'push'.

Is this a bug, a side-effect of the optimizer, or intentional behavior?

I think it's intentional behaviour. The code in caller() specifically
handles the case of a shifted @​_, and has been there since at least 5.000.
Also, some code tests fail without it.

I think its designed around the common idiom of

  sub foo {
  my $a = shift;
  my $b = shift;
  ...

which allows debuggers etc to see the args that that foo() was called
with, rather than just arg 3 onwards.

In particular, arrays that are shifted retain their earlier elements; its
just that the pointer to the start of the array is incremented - this is
the internal implementation detail that allows caller() to recover
shifted elements.

But yes, its a bit messy and inconsistent (but no more inconsistent than
it needs to be, given the constraints).

--
But Pity stayed his hand. "It's a pity I've run out of bullets",
he thought. -- "Bored of the Rings"

@p5pRT
Copy link
Author

p5pRT commented Jan 10, 2014

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants