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

Attempt to reload [...] aborted after failed "eval use...", followed by another use #13797

Open
p5pRT opened this issue May 2, 2014 · 10 comments

Comments

@p5pRT
Copy link

p5pRT commented May 2, 2014

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

Searchable as RT121787$

@p5pRT
Copy link
Author

p5pRT commented May 2, 2014

From @wolfsage

Created by wolfsage@gmail.com

When a module is require'd in an eval but dies, and then later require'd,
you get the unhelpful "Attempt to reload [module] aborted.", masking the
actual error message.

This seems like something we could perhaps fix.

Example​:

  mhorsfall@​tworivers​:~/example$ cat RO.pm
  package RO;

  eval "use RO2;";

  1;

  mhorsfall@​tworivers​:~/example$ cat RO2.pm
  package RO2;

  die "Hah\n";

  1;

  mhorsfall@​tworivers​:~/example$ cat t.pl
  use RO;
  use RO2;

  mhorsfall@​tworivers​:~/example$ perl t.pl
  Attempt to reload RO2.pm aborted.
  Compilation failed in require at t.pl line 2.
  BEGIN failed--compilation aborted at t.pl line 2.

Perl Info

Flags:
    category=core
    severity=low

Site configuration information for perl 5.14.2:

Configured by Debian Project at Tue Feb  4 23:09:53 UTC 2014.

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

  Platform:
    osname=linux, osvers=2.6.42-37-generic,
archname=x86_64-linux-gnu-thread-multi
    uname='linux panlong 2.6.42-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
-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
-fno-strict-aliasing -pipe -fstack-protector -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 -fstack-protector -I/usr/local/include'
    ccversion='', gccversion='4.6.3', 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.15'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -O2 -g -L/usr/local/lib
-fstack-protector'

Locally applied patches:



@INC for perl 5.14.2:
    /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/mhorsfall
    LANG=en_US.UTF-8
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/mhorsfall/bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
    PERLDOC=-oman
    PERL_BADLANG (unset)
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Dec 4, 2014

From @jkeenan

On Fri May 02 06​:09​:08 2014, alh wrote​:

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

-----------------------------------------------------------------
[Please describe your issue here]

When a module is require'd in an eval but dies, and then later
require'd,
you get the unhelpful "Attempt to reload [module] aborted.", masking
the
actual error message.

And the actual error message is ... ?

This seems like something we could perhaps fix.

Example​:

mhorsfall@​tworivers​:~/example$ cat RO.pm
package RO;

eval "use RO2;";

1;

mhorsfall@​tworivers​:~/example$ cat RO2.pm
package RO2;

die "Hah\n";

1;

mhorsfall@​tworivers​:~/example$ cat t.pl
use RO;
use RO2;

mhorsfall@​tworivers​:~/example$ perl t.pl
Attempt to reload RO2.pm aborted.
Compilation failed in require at t.pl line 2.
BEGIN failed--compilation aborted at t.pl line 2.

[Please do not change anything below this line]
-----------------------------------------------------------------
---
Flags​:
category=core
severity=low
---
Site configuration information for perl 5.14.2​:

Configured by Debian Project at Tue Feb 4 23​:09​:53 UTC 2014.

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

Platform​:
osname=linux, osvers=2.6.42-37-generic,
archname=x86_64-linux-gnu-thread-multi
uname='linux panlong 2.6.42-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
-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
-fno-strict-aliasing -pipe -fstack-protector -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 -fstack-protector -I/usr/local/include'
ccversion='', gccversion='4.6.3', 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.15'
Dynamic Linking​:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
cccdlflags='-fPIC', lddlflags='-shared -O2 -g -L/usr/local/lib
-fstack-protector'

Locally applied patches​:

---
@​INC for perl 5.14.2​:
/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/mhorsfall
LANG=en_US.UTF-8
LANGUAGE (unset)
LD_LIBRARY_PATH (unset)
LOGDIR (unset)
PATH=/home/mhorsfall/bin​:/usr/lib/lightdm/lightdm​:/usr/local/sbin​:/usr/local/bin​:/usr/sbin​:/usr/bin​:/sbin​:/bin​:/usr/games
PERLDOC=-oman
PERL_BADLANG (unset)
SHELL=/bin/bash

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Dec 4, 2014

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

@p5pRT
Copy link
Author

p5pRT commented Dec 4, 2014

From @wolfsage

On Wed, Dec 3, 2014 at 9​:17 PM, James E Keenan via RT
<perlbug-followup@​perl.org> wrote​:

On Fri May 02 06​:09​:08 2014, alh wrote​:

When a module is require'd in an eval but dies, and then later
require'd,
you get the unhelpful "Attempt to reload [module] aborted.", masking
the
actual error message.

And the actual error message is ... ?

In this case, "Hah\n"​:

  mhorsfall@​tworivers​:~/example$ cat t2.pl
  use RO2;
  mhorsfall@​tworivers​:~/example$ perl t2.pl
  Hah
  Compilation failed in require at t2.pl line 1.
  BEGIN failed--compilation aborted at t2.pl line 1.

This boils down to a module being required that may die/croak at
compile time (perhaps it tries to open a file and can't find it, or
doesn't have permissions) inside of an eval, and the error being
ignored, and then the file being loaded again later by another (or the
same) module. This may not really be a 'bug', since someone did
something silly (hid the initial error), but I think we could still
improve the situation if the internal effort/changes involved aren't
high.

If instead of just saying "Attempt to reload [module] aborted", we said​:

  "Attempt to reload [module] aborted, previous try was here"

...And/or

  "Attempt to reload [module] aborted, previous error was "...""

...I think it would go a long way.

-- Matthew Horsfall (alh)

@jkeenan
Copy link
Contributor

jkeenan commented Oct 29, 2023

From @wolfsage

On Wed, Dec 3, 2014 at 9​:17 PM, James E Keenan via RT <perlbug-followup@​perl.org> wrote​:

On Fri May 02 06​:09​:08 2014, alh wrote​:

When a module is require'd in an eval but dies, and then later
require'd,
you get the unhelpful "Attempt to reload [module] aborted.", masking
the
actual error message.

And the actual error message is ... ?

In this case, "Hah\n"​:

mhorsfall@​tworivers​:/example$ cat t2.pl use RO2; mhorsfall@​tworivers​:/example$ perl t2.pl Hah Compilation failed in require at t2.pl line 1. BEGIN failed--compilation aborted at t2.pl line 1.

This boils down to a module being required that may die/croak at compile time (perhaps it tries to open a file and can't find it, or doesn't have permissions) inside of an eval, and the error being ignored, and then the file being loaded again later by another (or the same) module. This may not really be a 'bug', since someone did something silly (hid the initial error), but I think we could still improve the situation if the internal effort/changes involved aren't high.

If instead of just saying "Attempt to reload [module] aborted", we said​:

"Attempt to reload [module] aborted, previous try was here"

...And/or

"Attempt to reload [module] aborted, previous error was "...""

...I think it would go a long way.

-- Matthew Horsfall (alh)

@wolfsage, discussion in this ticket petered out back in 2014. Have you had further thoughts about this problem?

Thank you very much.

@demerphq
Copy link
Collaborator

demerphq commented Oct 30, 2023

I agree with @wolfsage, we should track the previous error, and then show it. I have written code to do this myself, and I think it should be standard. We should have a parallel data structure to %INC (something like %INC_ERROR) which contains the error which resulted in %INC containing a false value. There are some tricks that have to be kept in mind, if someone does delete $INC{foo} then we should also trigger a delete $INC_ERROR{foo} (imo). Im happy to try to help with this one, although i dont have a lot of time these days. I think its a bit tricky as to what i think needs to be done we probably need to tie %INC (or add some magic to it at least), and think its currently possible to tie %INC anyway, so it is not immediately clear how the magic would work.

I dont think this should be closed.

BTW, I suspect that with Require hooks this is probably a /bit/ easier to do than it once was....

@haarg
Copy link
Contributor

haarg commented Oct 31, 2023

I was somewhat concerned about error lifetime for exception objects if we were storing them for later. But it doesn't seem like this should be a problem.

Normally, the error from require will be a string. If the module loading fails due to the module throwing an exception object, the error will be stringified with a Compilation failed in require message added to it before being rethrown by require. It is possible to get require to throw an exception object by throwing from an @INC hook, but in that case %INC won't be updated, so it would never result in an Attempt to reload error later.

Another potential thought is that it could increase memory usage. But modules failing to load due to compilation errors is a rather rare case. I doubt there would be enough of these in an otherwise working program for any extra memory used to be a problem.

So I don't see any real problem with a %INC_ERROR hash (or more likely %{^INC_ERROR}) to store these types of errors.

@demerphq
Copy link
Collaborator

Normally, the error from require will be a string.

Not if there are $SIG{DIE} hooks in place upgrading the string to an object.

but in that case %INC won't be updated

Huh? I didnt follow your reasoning there.

So I don't see any real problem with a %INC_ERROR hash

Yeah, I never saw any issue with it at Booking, and that code has been tracking these errors for years.

@haarg
Copy link
Contributor

haarg commented Oct 31, 2023

Normally, the error from require will be a string.

Not if there are $SIG{__DIE__} hooks in place upgrading the string to an object.

True, but internally require is still flattening the error from loading the module into a string. That would be the value set in %INC_ERROR, not the direct result of a __DIE__ handler.

but in that case %INC won't be updated

Huh? I didnt follow your reasoning there.

If a module throws an error while loading it, the %INC entry for that module is set to undef to record that failure. Trying to load the module a second time will give a Attempt to reload error.

If an @INC hook throws an error while loading a module, the %INC entry for the module will not be created at all. If you try to load the module a second time, it will try to find and compile it just like it did the first time. Since this case will already never cause an Attempt to reload error, there is no reason to store this type of error.

@firmwarecostum
Copy link

chmod 755 ../../lib/auto/Compress/Raw/Bzip2/Bzip2.so
make[4]: Leaving directory '/home/open/wrt/build_dir/target-aarch64_generic_musl/perl/perl-5.28.1/cpan/Compress-Raw-Bzip2'
LD_LIBRARY_PATH=/home/open/wrt/build_dir/target-aarch64_generic_musl/perl/perl-5.28.1 ./miniperl -Ilib -I. make_ext.pl lib/auto/Compress/Raw/Zlib/Zlib.so  MAKE="make" LIBPERL_A=libperl.so LINKTYPE=dynamic
Parsing config.in...
Building Zlib enabled
Auto Detect Gzip OS Code..
Setting Gzip OS Code to 3 [Unix/Default]
Looks Good.
Generating a Unix-style Makefile
Writing Makefile for Compress::Raw::Zlib
Attempt to reload B.pm aborted.
Compilation failed in require at ../../lib/CPAN/Meta/Requirements.pm line 90.
 at ../../lib/ExtUtils/MM_Any.pm line 1225.
Attempt to reload B.pm aborted.
Compilation failed in require at ../../lib/CPAN/Meta/Requirements.pm line 90.
Unsuccessful Makefile.PL(cpan/Compress-Raw-Zlib): code=65280 at make_ext.pl line 518.
make[3]: *** [makefile:579: lib/auto/Compress/Raw/Zlib/Zlib.so] Error 2
make[3]: Leaving directory '/home/open/wrt/build_dir/target-aarch64_generic_musl/perl/perl-5.28.1'

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

6 participants