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

sub END not called after some compile errors #1879

Closed
p5pRT opened this issue Apr 24, 2000 · 7 comments
Closed

sub END not called after some compile errors #1879

p5pRT opened this issue Apr 24, 2000 · 7 comments

Comments

@p5pRT
Copy link

p5pRT commented Apr 24, 2000

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

Searchable as RT3147$

@p5pRT
Copy link
Author

p5pRT commented Apr 24, 2000

From @aigan

Created by jonas@astral.paranormal.o.se

There is a incinsistent change of behaviour between v5.005_03 and v5.6.0

Only v5.005_03 calls END for this​:

#!/usr/local/bin/perl
END {print "After\n"}
priint "error";
__END__

But both calls END for this compile error​:

#!/usr/local/bin/perl
END {print "After\n"}
compile error now;
__END__

I would prefere the END to be called so that it could clean up all
things done in BEGIN.

Perl Info

Flags:
    category=core
    severity=medium

Site configuration information for perl v5.6.0:

Configured by jonas at Sat Apr  1 02:14:50 CEST 2000.

Summary of my perl5 (revision 5.0 version 6 subversion 0) configuration:
  Platform:
    osname=linux, osvers=2.2.12, archname=i586-linux-thread-multi
    uname='linux astral.paranormal.o.se 2.2.12 #1 thu oct 14 09:29:24 est 1999 i586 unknown '
    config_args='-Uinstallusrbinperl -Dusethreads -des'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=define use5005threads=undef useithreads=define usemultiplicity=define
    useperlio=undef d_sfio=undef uselargefiles=define 
    use64bitint=undef use64bitall=undef uselongdouble=undef usesocks=undef
  Compiler:
    cc='cc', optimize='-O2', gccversion=2.95.2 20000220 (Debian GNU/Linux)
    cppflags='-D_REENTRANT -fno-strict-aliasing -I/usr/local/include'
    ccflags ='-D_REENTRANT -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'
    stdchar='char', d_stdstdio=define, usevfork=false
    intsize=4, longsize=4, ptrsize=4, doublesize=8
    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, usemymalloc=n, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lnsl -lndbm -lgdbm -ldb -ldl -lm -lpthread -lc -lposix -lcrypt
    libc=/lib/libc-2.1.3.so, so=so, useshrplib=false, libperl=libperl.a
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic'
    cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib'

Locally applied patches:
    


@INC for perl v5.6.0:
    /usr/local/lib/perl5/5.6.0/i586-linux-thread-multi
    /usr/local/lib/perl5/5.6.0
    /usr/local/lib/perl5/site_perl/5.6.0/i586-linux-thread-multi
    /usr/local/lib/perl5/site_perl/5.6.0
    /usr/local/lib/perl5/site_perl
    .


Environment for perl v5.6.0:
    HOME=/home/jonas
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/usr/local/games:/usr/X11R6/bin:/home/jonas/bin:.
    PERL_BADLANG (unset)
    SHELL=/bin/bash


@p5pRT
Copy link
Author

p5pRT commented Apr 24, 2000

From @tamias

On Mon, Apr 24, 2000 at 05​:36​:34PM +0200, Jonas Liljegren wrote​:

But both calls END for this compile error​:

#!/usr/local/bin/perl
END {print "After\n"}
compile error now;
__END__

That one's a runtime error, not a compile error. It's compiled as
'error'->compile('now');

Ronald

@p5pRT
Copy link
Author

p5pRT commented Apr 24, 2000

From [Unknown Contact. See original ticket]

jonas@​paranormal.o.se (Jonas Liljegren) wrote

There is a incinsistent change of behaviour between v5.005_03 and v5.6.0

Only v5.005_03 calls END for this​:

#!/usr/local/bin/perl
END {print "After\n"}
priint "error";
__END__

This is a deliberate change. From "perldoc perldelta"​:

  END blocks and the `-c' switch

  Prior versions used to run BEGIN and END blocks when Perl
  was run in compile-only mode. Since this is typically not
  the expected behavior, END blocks are not executed anymore
  when the `-c' switch is used.

Hmmm.. wait a moment - that doesn't actually cover the case you quote.
Seems like the attached doc patch is needed.

Mike Guy

Inline Patch
--- ./pod/perldelta.pod.orig	Mon Apr 24 17:28:32 2000
+++ ./pod/perldelta.pod	Mon Apr 24 17:04:39 2000
@@ -1811,7 +1811,7 @@
 Prior versions used to run BEGIN B<and> END blocks when Perl was
 run in compile-only mode.  Since this is typically not the expected
 behavior, END blocks are not executed anymore when the C<-c> switch
-is used.
+is used, or if compilation fails.
 
 See L<CHECK blocks> for how to run things when the compile phase ends.
 
--- ./pod/perlmod.pod.orig	Mon Mar 13 21:25:37 2000
+++ ./pod/perlmod.pod	Mon Apr 24 17:29:42 2000
@@ -233,7 +233,7 @@
 (if you can).)  You may have multiple C<END> blocks within a file--they
 will execute in reverse order of definition; that is: last in, first
 out (LIFO).  C<END> blocks are not executed when you run perl with the
-C<-c> switch.
+C<-c> switch, or if compilation fails..
 
 Inside an C<END> subroutine, C<$?> contains the value that the program is
 going to pass to C<exit()>.  You can modify C<$?> to change the exit
@@ -252,7 +252,7 @@
 
 When you use the B<-n> and B<-p> switches to Perl, C<BEGIN> and
 C<END> work just as they do in B<awk>, as a degenerate case.  As currently
-implemented (and subject to change, since its inconvenient at best),
+implemented (and subject to change, since it's inconvenient at best),
 both C<BEGIN> and<END> blocks are run when you use the B<-c> switch
 for a compile-only syntax check, although your main code is not.
 

End of patch

@p5pRT
Copy link
Author

p5pRT commented Apr 24, 2000

From @aigan

"M.J.T. Guy" wrote​:

jonas@​paranormal.o.se (Jonas Liljegren) wrote

There is a incinsistent change of behaviour between v5.005_03 and v5.6.0

Only v5.005_03 calls END for this​:

#!/usr/local/bin/perl
END {print "After\n"}
priint "error";
__END__

This is a deliberate change.

Why should END not be called?

I am using that behaviour in a module that checks STDERR​: CGI​::Debug
It works like this​:

program.cgi​:

#!/usr/bin/perl -w
use CGI​::Debug;
print "Content-type​: text/html\n\n";
priint "<h1>Hi!</h1>\n";
__END__

CGI/Debug.pm (in theory)​:

package CGI​::Debug;
BEGIN
{
  open (STDERR,">/tmp/error-$$");
}
END
{
  close STDERR;
  print "Content-type​: text/plain\n\n";
  open ERR, "/tmp/error-$$";
  print while <ERR>;
}
__END__

(But the whole thing is about 1000 lines...)

Why shouldn't I be able to do this now?

The main idea of the module was that I could just put the
"use CGI​::Debug;" line and get my errors to the browser without having
to change anything else in the program. And it should catch all
errors. That worked fine until now...

/jonas

@p5pRT
Copy link
Author

p5pRT commented Apr 30, 2000

From [Unknown Contact. See original ticket]

"M.J.T. Guy" wrote​:

jonas@​paranormal.o.se (Jonas Liljegren) wrote

There is a incinsistent change of behaviour between v5.005_03 and v5.6.0

Only v5.005_03 calls END for this​:

#!/usr/local/bin/perl
END {print "After\n"}
priint "error";
__END__

This is a deliberate change.

Why should END not be called?

Because in 5.6.0, then end-of-compilation phase is CHECK{}, not END{},
and the beginning of the runtime phase is INIT{}. Therefore you should
use CHECK{} to clean up non-ephemeral changes done by BEGIN{}, and use
INIT{} to start things that will be cleaned up by END{}.

package CGI​::Debug;
BEGIN
{
open (STDERR,">/tmp/error-$$");
}
END
{
close STDERR;
print "Content-type​: text/plain\n\n";
open ERR, "/tmp/error-$$";
print while <ERR>;
}

Here is the 5.6.0 way of doing that​:

BEGIN { # Start of compilation phase; put this at the top of the file.
  our $error_log = "/tmp/error-$$";
  open (STDERR,">$error_log");
}
CHECK { # End of compilation phase
  $_ = close STDERR ? "" : "close(STDERR)​: $!\n";
  if ($_ ne "" || -s $error_log) {
  local($\); # Read in entire file
  $_ .= open(ERR,$error_log) ? <ERR> : "Could not read error log​: $!";
  print "Content-type​: text/plain\n\n Compilation errors detected​:\n$_\n";
  unlink $error_log ? die("\n") : die("Clean-up failure​: $!\n");
  }
}

INIT { # Start of run time
  open (STDERR,">$error_log");
}
END { # End of run time
  $_ = close STDERR ? "" : "close(STDERR)​: $!\n";
  if ($_ ne "" || -s $error_log) {
  local($\);
  $_ .= open(ERR,$error_log) ? <ERR> : "Could not read error log​: $!";
  print "Content-type​: text/plain\n\n Runtime errors detected​:\n$_\n";
  unlink $error_log ? die("\n") : die("Clean-up failure​: $!\n");
  }
  unlink $error_log or print "&lt;BR&gt;Clean-up failure​: $!\n";
}
# Rest of module goes here.

@p5pRT
Copy link
Author

p5pRT commented May 2, 2003

From @iabyn

Doesn't appear to be a bug.

@p5pRT
Copy link
Author

p5pRT commented May 2, 2003

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

No branches or pull requests

1 participant