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

caller() filenames broken by "use" #9845

Closed
p5pRT opened this issue Aug 21, 2009 · 6 comments
Closed

caller() filenames broken by "use" #9845

p5pRT opened this issue Aug 21, 2009 · 6 comments

Comments

@p5pRT
Copy link

@p5pRT p5pRT commented Aug 21, 2009

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

Searchable as RT68712$

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Aug 21, 2009

From zefram@fysh.org

Created by zefram@fysh.org

I'm looking at the stack, with caller(), during compilation. (Not just
for kicks, I have real reasons to do this.) Here's an unexpected result​:

$ cat x0.pm
package x0;
no warnings;
sub import {
  for(my$i=0;;$i++) {
  my @​c = caller($i);
  last unless @​c;
  print join(",", @​c), "\n";
  }
}
1;
$ perl -e 'use x0'
main,-e,1,x0​::import,1,0,,,0,,
main,x0.pm,1,main​::BEGIN,1,0,,,0,,
main,x0.pm,1,(eval),0,0,,,0,,

Observe that the direct caller of x0​::import is correctly ascribed the
filename "-e", but *its* callers, also located in the -e string, are
shown as being in x0.pm, which has just been read. This effect only
occurs if the "use" that invokes x0​::import is also the one in which
x0.pm was actually read. Subsequent "use" statements work fine​:

$ perl -e 'use x0 (); use x0'
main,-e,1,x0​::import,1,0,,,256,,
main,-e,1,main​::BEGIN,1,0,,,256,,
main,-e,1,(eval),0,0,,,256,,

A bit of deconstruction reveals that it's actually just one (implicit)
BEGIN block that's tainted​:

$ perl -e 'BEGIN { require x0; x0->import }'
main,-e,1,x0​::import,1,0,,,0,,
main,x0.pm,1,main​::BEGIN,1,0,,,0,,
main,x0.pm,1,(eval),0,0,,,0,,
$ perl -e 'BEGIN { require x0 } BEGIN { x0->import }'
main,-e,1,x0​::import,1,0,,,0,,
main,-e,1,main​::BEGIN,1,0,,,0,,
main,-e,1,(eval),0,0,,,0,,

This is annoying because I wanted to use caller() to get at the lexical
state of the code being compiled, distinct from the lexical state inside
the BEGIN block that invoked my compile-time code. This bug means that
the right caller() frame for me to use may have the wrong filename.
I can work around it by merging the two frames.

Perl Info

Flags:
    category=core
    severity=low

Site configuration information for perl 5.10.0:

Configured by Debian Project at Thu Jan  1 12:43:38 UTC 2009.

Summary of my perl5 (revision 5 version 10 subversion 0) configuration:
  Platform:
    osname=linux, osvers=2.6.26-1-686, archname=i486-linux-gnu-thread-multi
    uname='linux rebekka 2.6.26-1-686 #1 smp mon dec 15 18:15:07 utc 2008 i686 gnulinux '
    config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=i486-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.10 -Darchlib=/usr/lib/perl/5.10 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.10.0 -Dsitearch=/usr/local/lib/perl/5.10.0 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Ud_ualarm -Uusesfio -Uusenm -DDEBUGGING=-g -Doptimize=-O2 -Duseshrplib -Dlibperl=libperl.so.5.10.0 -Dd_dosuid -des'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=undef, use64bitall=undef, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -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 -fno-strict-aliasing -pipe -I/usr/local/include'
    ccversion='', gccversion='4.3.2', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=4, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib /usr/lib64
    libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt
    perllibs=-ldl -lm -lpthread -lc -lcrypt
    libc=/lib/libc-2.7.so, so=so, useshrplib=true, libperl=libperl.so.5.10.0
    gnulibc_version='2.7'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -O2 -g -L/usr/local/lib'

Locally applied patches:
    


@INC for perl 5.10.0:
    /etc/perl
    /usr/local/lib/perl/5.10.0
    /usr/local/share/perl/5.10.0
    /usr/lib/perl5
    /usr/share/perl5
    /usr/lib/perl/5.10
    /usr/share/perl/5.10
    /usr/local/lib/site_perl
    .


Environment for perl 5.10.0:
    HOME=/home/zefram
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/zefram/pub/i686-pc-linux-gnu/bin:/home/zefram/pub/common/bin:/usr/bin:/usr/X11R6/bin:/bin:/usr/local/bin:/usr/games
    PERL_BADLANG (unset)
    SHELL=/usr/bin/zsh

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Aug 21, 2009

From zefram@fysh.org

I wrote​:

Observe that the direct caller of x0​::import is correctly ascribed the
filename "-e", but *its* callers, also located in the -e string, are
shown as being in x0.pm, which has just been read.

Additional information​: this bug is present in every perl version at least
back to 5.004 (which is the earliest that I have available for testing).

-zefram

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Aug 21, 2009

From p5p@perl.wizbit.be

I'm looking at the stack, with caller(), during compilation. (Not just
for kicks, I have real reasons to do this.) Here's an unexpected result​:

$ cat x0.pm
package x0;
no warnings;
sub import {
for(my$i=0;;$i++) {
my @​c = caller($i);
last unless @​c;
print join(",", @​c), "\n";
}
}
1;
$ perl -e 'use x0'
main,-e,1,x0​::import,1,0,,,0,,
main,x0.pm,1,main​::BEGIN,1,0,,,0,,
main,x0.pm,1,(eval),0,0,,,0,,

Observe that the direct caller of x0​::import is correctly ascribed the
filename "-e", but *its* callers, also located in the -e string, are
shown as being in x0.pm, which has just been read. This effect only
occurs if the "use" that invokes x0​::import is also the one in which
x0.pm was actually read. Subsequent "use" statements work fine​:

$ perl -e 'use x0 (); use x0'
main,-e,1,x0​::import,1,0,,,256,,
main,-e,1,main​::BEGIN,1,0,,,256,,
main,-e,1,(eval),0,0,,,256,,

A bit of deconstruction reveals that it's actually just one (implicit)
BEGIN block that's tainted​:

[snip]

That does not seem to be the case​:

$ cat x1.pm
1;

$ cat rt-68712-1.pl
#!/usr/bin/perl -l

BEGIN {
  require x1;

  for(my$i=0;;$i++) {
  my @​c = caller($i);
  last unless @​c;
  print join(",", @​c);
  }
}

BEGIN {
  print "-" x 80;
  delete $INC{'x1.pm'};
  require x1;

  for(my$i=0;;$i++) {
  my @​c = caller($i);
  last unless @​c;
  print join(",", @​c);
  }
}
__END__
main,x1.pm,11,main​::BEGIN,1,0,,,0,
main,x1.pm,11,(eval),0,0,,,0,


main,x1.pm,23,main​::BEGIN,1,0,,,0,
main,x1.pm,23,(eval),0,0,,,0,

$ cat rt-68712-2.pl
#!/usr/bin/perl -l

BEGIN {
  do "x1.pm";

  for(my$i=0;;$i++) {
  my @​c = caller($i);
  last unless @​c;
  print join(",", @​c);
  }
}

BEGIN {
  print "-" x 80;
  do "x1.pm";

  for(my$i=0;;$i++) {
  my @​c = caller($i);
  last unless @​c;
  print join(",", @​c);
  }
}

__END__
main,x1.pm,11,main​::BEGIN,1,0,,,0,
main,x1.pm,11,(eval),0,0,,,0,


main,x1.pm,22,main​::BEGIN,1,0,,,0,
main,x1.pm,22,(eval),0,0,,,0,

Adding the require x1 or do "x1.pm" in a separate block also seems to work​:

#!/usr/bin/perl -l

BEGIN {
  {
  require x1;
  }

  for(my$i=0;;$i++) {
  my @​c = caller($i);
  last unless @​c;
  print join(",", @​c);
  }
}

BEGIN {
  print "-" x 80;
  {
  delete $INC{'x1.pm'};
  require x1;
  }

  for(my$i=0;;$i++) {
  my @​c = caller($i);
  last unless @​c;
  print join(",", @​c);
  }
}
__END__
main,rt-68712-3.pl,13,main​::BEGIN,1,0,,,0,
main,rt-68712-3.pl,13,(eval),0,0,,,0,


main,rt-68712-3.pl,27,main​::BEGIN,1,0,,,0,
main,rt-68712-3.pl,27,(eval),0,0,,,0,

(same output for { do "x0.pm" })

Best regards,

Bram

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Aug 21, 2009

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

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Dec 11, 2010

From @cpansprout

Fixed by b2ef6d4.

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Dec 11, 2010

@cpansprout - Status changed from 'open' to 'resolved'

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

Successfully merging a pull request may close this issue.

None yet
1 participant