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

die() a NOP after require() #4010

Open
p5pRT opened this issue May 21, 2001 · 2 comments
Open

die() a NOP after require() #4010

p5pRT opened this issue May 21, 2001 · 2 comments

Comments

@p5pRT
Copy link

p5pRT commented May 21, 2001

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

Searchable as RT7020$

@p5pRT
Copy link
Author

p5pRT commented May 21, 2001

From ilya@math.ohio-state.edu

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)

@p5pRT
Copy link
Author

p5pRT commented May 24, 2001

From [Unknown Contact. See original ticket]

Since doing croak() will call a die() after require Carp​::Heavy, the
failing sequence may be as easy as

  From eval {}
  call an XSUB
  which calls (without G_EVAL) a Perl subroutine
  which croak()s

[Un]fortunately, all XSUBs from Perl distribution which call Perl
subroutines without G_EVAL do it from a "tie()ed method" context,
which replaces Perl stack, and the above bug is not triggered when a
stack is replaced.

There is only one exception - DProf. However, (due to some DProf
obfuscations?) I cannot see the effects of the bug with just calling
croak(). However, 'require less and die' shows the problem (segfault
on my system, I think it could print 12 nn some of other systems, with
other malloc()s).

perl -d​:Dprof -wle "
  sub f {require less; die 'OO'} eval {f; print 12} or warn; print 13"

Hope this helps,
Ilya

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