[ID 20010521.002] die() a NOP after require()

This is a bug report for perl from ilya@math.ohio-state.edu,
generated with the help of perlbug 1.33 running under perl v5.6.1.

Ouph, this one took many hours to diagnose...

Here is the scoop:

  In many situations doing die() after a require() is a kinda no-op.

  Currently I can reproduce only one such situation:

    perl_call_*() without G_EVAL called inside eval {},

  but I believe many other contexts behave similarly.

Details of the control flow with the bug present: perl_call_*() does not
return (!), but the Perl control is quietly (without longjmp()ing out of
perl_call_*() (!)) transfered to the opcode after eval {}.  When the script
terminates, the C control returns to perl_call_(), then to the code
which calls perl_call_*() and so on (with most data already DESTROYed!).

Example:   dummy::callit() is an XSUB:

====================================================
void
callit(void)
{
   dSP;

   PUSHMARK(SP);
   perl_call_pv("mysub", G_DISCARD|G_NOARGS);
   fprintf(stderr, "finished call.\n");
}

MODULE = dummy		PACKAGE = dummy		

void
callit()
====================================================

Perl code is:

====================================================
sub mysub {
  require less;
  die "ok 2\n"
}

eval {
  dummy::callit();
  warn "after!";
};

print "err: $@" if $@;
====================================================

This prints:

====================================================
err: ok 2
finished call.
after! at test11.pl line 10.
====================================================

Of course, only the first line should be printed.  [This is an
extraction of what XML::Encoding is doing.]

----------------------------------------------------
----------------------------------------------------

Here are the debugging details: The bug happens when CATCH_GET() is true
(this is why Perl_call_*() is doing), and in_eval is true too.  The first
condition ensures that pp_require() calls docatch().  Due to this
pp_require() does not return when the end of the module is reached.  Due to
this, the code after require() is still executed within the same docatch().

The second condition ensures that die_where() does not longjmp().
Then vdie() does longjmp(3), and docatch() essentially catches it, and
reenters again - and does not return from pp_require()/perl_call_*() -
which leads to the behaviour described above.

---
Flags:
    category=core
    severity=critical
---
This perlbug was built using Perl v5.6.1 - Fri May 11 16:30:32 PDT 2001
It is being executed now by  Perl v5.6.1 - Tue May  8 02:31:51 PDT 2001.

Site configuration information for perl v5.6.1:

Configured by vera at Tue May  8 02:31:51 PDT 2001.

Summary of my perl5 (revision 5.0 version 6 subversion 1) configuration:
  Platform:
    osname=os2, osvers=2.30, archname=os2
    uname='os2 ia-ia 2 2.30 i386 '
    config_args='-des -D prefix=j:/test/perllib'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef
    useperlio=undef d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=undef use64bitall=undef uselongdouble=undef
  Compiler:
    cc='gcc', ccflags ='-Zomf -Zmt -DDOSISH -DOS2=2 -DEMBED -I. -D_EMX_CRT_REV_=63',
    optimize='-O2 -fomit-frame-pointer -malign-loops=2 -malign-jumps=2 -malign-functions=2 -s',
    cppflags='-Zomf -Zmt -DDOSISH -DOS2=2 -DEMBED -I. -D_EMX_CRT_REV_=63'
    ccversion='', gccversion='2.8.1', 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=4
    alignbytes=4, usemymalloc=y, prototype=define
  Linker and Libraries:
    ld='gcc', ldflags ='-Zexe -Zomf -Zmt -Zcrtdll -Zstack 32000'
    libpth=i:/emx.add/lib i:/emx/lib D:/DEVTOOLS/OPENGL/LIB I:/JAVA11/LIB i:/emx/lib/mt
    libs=-lsocket -lm -lbsd
    perllibs=-lsocket -lm -lbsd
    libc=i:/emx/lib/mt/c_import.lib, so=dll, useshrplib=true, libperl=libperl.lib
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
    cccdlflags='-Zdll', lddlflags='-Zdll -Zomf -Zmt -Zcrtdll -s'

Locally applied patches:
    

---
@INC for perl v5.6.1:
    j:/test/perllib/lib/5.6.1/os2
    j:/test/perllib/lib/5.6.1
    j:/test/perllib/lib/site_perl/5.6.1/os2
    j:/test/perllib/lib/site_perl/5.6.1
    j:/test/perllib/lib/site_perl
    .

---
Environment for perl v5.6.1:
    HOME=j:/home
    LANG=EN_US
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=[censored]
    PERLLIB_PREFIX=f:/perllib;i:/perllib
    PERL_BADLANG (unset)
    PERL_SH_DIR=i:/bin
    SHELL (unset)

0
ilya
5/21/2001 11:02:13 AM
perl.perl5.porters 47902 articles. 1 followers. Follow

0 Replies
104 Views

Similar Articles

[PageSpeed] 45

Reply: