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

perl_eval_sv does not set PL_errgv for compile errors #6286

Closed
p5pRT opened this issue Feb 6, 2003 · 5 comments
Closed

perl_eval_sv does not set PL_errgv for compile errors #6286

p5pRT opened this issue Feb 6, 2003 · 5 comments

Comments

@p5pRT
Copy link

p5pRT commented Feb 6, 2003

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

Searchable as RT20772$

@p5pRT
Copy link
Author

p5pRT commented Feb 6, 2003

From andrew@pimlott.net

Created by andrew@pimlott.net

I was disturbed to find that, in a simple embedded perl interpreter like the
ones in perlembed, parse-time errors are not caught by perl_eval_sv. That
is, PL_errgv is clean after such an error. For example, if I run the
program at the end of this mail with input

  sub foo() { 2 }
  foo(1);

it will produce no output. Adding G_KEEPERR causes the expected error ("Too
many arguments ..."), but this modifies run-time exceptions, and is clearly
(according to perlcall) not meant for this problem.

Here is what happens (as far as I can understand)​:

- Perl_eval_sv calls call_body.
- In case of a parse error, ERRSV is set by the parser, and call_body
  returns normally. A few lines later, ERRSV is cleared.
- In case of another exception (compile- or run- time), ERRSV is set by
  Perl_vcroak, then control jumps back through a longjump to the switch
  statement with a new value of ret, so ERRSV is not cleared.

I haven't wrapped my head around the reasoning behind all this, but I wonder
why ERRSV isn't just cleared prior to call_body?

I haven't tested perl 5.8, and I haven't found a workaround, though I
haven't really looked yet.

At any rate, if this problem will affect every program that follows the
example of perlembed, it really would be best to fix perl_eval_sv. I ran
into it when using the perl scripting support in vim. It made it rather
frustrating to debug my extensions.

Andrew

Simple embedded interpreter​:

  /*
  cc -o perltry perltry.c $(perl -MExtUtils​::Embed -e ccopts -e ldopts)
  */

  #include <EXTERN.h>
  #include <perl.h>

  static char *args[] = { "", "-e", "" };

  int main(int argc, char **argv)
  {
  PerlInterpreter *perl_interp = NULL;
  char script[4096];
  size_t len;
  SV *sv;
  char *err;
  STRLEN length;

  len = fread(script, 1, 4096, stdin);
  sv = newSVpv(script, len);

  perl_interp = perl_alloc();
  perl_construct(perl_interp);
  perl_parse(perl_interp, NULL, 3, args, 0);
  perl_eval_sv(sv, G_DISCARD | G_NOARGS);

  err = SvPV(GvSV(PL_errgv), length);
  if (length)
  fprintf(stderr, err);

  return 0;
  }

Perl Info

Flags:
    category=core
    severity=low

Site configuration information for perl v5.6.1:

Configured by buildd at Sat Nov 30 17:45:17 UTC 2002.

Summary of my perl5 (revision 5.0 version 6 subversion 1) configuration:
  Platform:
    osname=linux, osvers=2.4.19, archname=i386-linux
    uname='linux cyberhq 2.4.19 #1 smp sun aug 4 11:30:45 pdt 2002 i686 unknown '
    config_args='-Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=i386-linux -Dprefix=/usr -Dprivlib=/usr/share/perl/5.6.1 -Darchlib=/usr/lib/perl/5.6.1 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.6.1 -Dsitearch=/usr/local/lib/perl/5.6.1 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Uusesfio -Duseshrplib -Dlibperl=libperl.so.5.6.1 -Dd_dosuid -des'
    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='cc', ccflags ='-DDEBIAN -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2',
    cppflags='-DDEBIAN -fno-strict-aliasing -I/usr/local/include'
    ccversion='', gccversion='2.95.4 20011002 (Debian prerelease)', 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, usemymalloc=n, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lgdbm -ldb -ldl -lm -lc -lcrypt
    perllibs=-ldl -lm -lc -lcrypt
    libc=/lib/libc-2.2.5.so, so=so, useshrplib=true, libperl=libperl.so.5.6.1
  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.1:
    /home/pimlott/local/lib/perl5
    /usr/local/lib/perl/5.6.1
    /usr/local/share/perl/5.6.1
    /usr/lib/perl5
    /usr/share/perl5
    /usr/lib/perl/5.6.1
    /usr/share/perl/5.6.1
    /usr/local/lib/site_perl
    .


Environment for perl v5.6.1:
    HOME=/home/pimlott
    LANG=C
    LANGUAGE (unset)
    LC_CTYPE=en_US
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/pimlott/bin:/usr/local/atria/bin:/home/pimlott/local/j2sdk1.4.0/bin:/usr/sbin:/sbin:/home/pimlott/bin:/usr/local/atria/bin:/home/pimlott/local/j2sdk1.4.0/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games
    PERL5LIB=/home/pimlott/local/lib/perl5
    PERL_BADLANG (unset)
    SHELL=/bin/zsh

@p5pRT
Copy link
Author

p5pRT commented Feb 7, 2003

From rwilding@micron.com

Created by andrew@pimlott.net

I was disturbed to find that, in a simple embedded perl interpreter like the
ones in perlembed, parse-time errors are not caught by perl_eval_sv. That
is, PL_errgv is clean after such an error. For example, if I run the
program at the end of this mail with input

  sub foo() { 2 }
  foo(1);

it will produce no output. Adding G_KEEPERR causes the expected error ("Too
many arguments ..."), but this modifies run-time exceptions, and is clearly
(according to perlcall) not meant for this problem.

Here is what happens (as far as I can understand)​:

- Perl_eval_sv calls call_body.
- In case of a parse error, ERRSV is set by the parser, and call_body
  returns normally. A few lines later, ERRSV is cleared.
- In case of another exception (compile- or run- time), ERRSV is set by
  Perl_vcroak, then control jumps back through a longjump to the switch
  statement with a new value of ret, so ERRSV is not cleared.

I haven't wrapped my head around the reasoning behind all this, but I wonder
why ERRSV isn't just cleared prior to call_body?

I haven't tested perl 5.8, and I haven't found a workaround, though I
haven't really looked yet.

At any rate, if this problem will affect every program that follows the
example of perlembed, it really would be best to fix perl_eval_sv. I ran
into it when using the perl scripting support in vim. It made it rather
frustrating to debug my extensions.

Andrew

Simple embedded interpreter​:

  /*
  cc -o perltry perltry.c $(perl -MExtUtils​::Embed -e ccopts -e ldopts)
  */

  #include <EXTERN.h>
  #include <perl.h>

  static char *args[] = { "", "-e", "" };

  int main(int argc, char **argv)
  {
  PerlInterpreter *perl_interp = NULL;
  char script[4096];
  size_t len;
  SV *sv;
  char *err;
  STRLEN length;

  len = fread(script, 1, 4096, stdin);
  sv = newSVpv(script, len);

  perl_interp = perl_alloc();
  perl_construct(perl_interp);
  perl_parse(perl_interp, NULL, 3, args, 0);
  perl_eval_sv(sv, G_DISCARD | G_NOARGS);

  err = SvPV(GvSV(PL_errgv), length);
  if (length)
  fprintf(stderr, err);

  return 0;
  }

Perl Info

Flags:
    category=core
    severity=low

Site configuration information for perl v5.6.1:

Configured by buildd at Sat Nov 30 17:45:17 UTC 2002.

Summary of my perl5 (revision 5.0 version 6 subversion 1) configuration:
  Platform:
    osname=linux, osvers=2.4.19, archname=i386-linux
    uname='linux cyberhq 2.4.19 #1 smp sun aug 4 11:30:45 pdt 2002 i686
unknown '
    config_args='-Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=i386-linux
-Dprefix=/usr -Dprivlib=/usr/share/perl/5.6.1 -Darchlib=/usr/lib/perl/5.6.1
-Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5
-Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.6.1
-Dsitearch=/usr/local/lib/perl/5.6.1 -Dman1dir=/usr/share/man/man1
-Dman3dir=/usr/share/man/man3 -Dman1ext=1 -Dman3ext=3perl
-Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Uusesfio -Duseshrplib
-Dlibperl=libperl.so.5.6.1 -Dd_dosuid -des'
    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='cc', ccflags ='-DDEBIAN -fno-strict-aliasing -I/usr/local/include
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2',
    cppflags='-DDEBIAN -fno-strict-aliasing -I/usr/local/include'
    ccversion='', gccversion='2.95.4 20011002 (Debian prerelease)',
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, usemymalloc=n, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lgdbm -ldb -ldl -lm -lc -lcrypt
    perllibs=-ldl -lm -lc -lcrypt
    libc=/lib/libc-2.2.5.so, so=so, useshrplib=true,
libperl=libperl.so.5.6.1
  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.1:
    /home/pimlott/local/lib/perl5
    /usr/local/lib/perl/5.6.1
    /usr/local/share/perl/5.6.1
    /usr/lib/perl5
    /usr/share/perl5
    /usr/lib/perl/5.6.1
    /usr/share/perl/5.6.1
    /usr/local/lib/site_perl
    .


Environment for perl v5.6.1:
    HOME=/home/pimlott
    LANG=C
    LANGUAGE (unset)
    LC_CTYPE=en_US
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
 
PATH=/home/pimlott/bin:/usr/local/atria/bin:/home/pimlott/local/j2sdk1.4.0/b
in:/usr/sbin:/sbin:/home/pimlott/bin:/usr/local/atria/bin:/home/pimlott/loca
l/j2sdk1.4.0/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/
usr/games
    PERL5LIB=/home/pimlott/local/lib/perl5
    PERL_BADLANG (unset)
    SHELL=/bin/zsh


@p5pRT
Copy link
Author

p5pRT commented Apr 29, 2012

From @Hugmeir

On Fri Feb 07 07​:42​:33 2003, rwilding@​micron.com wrote​:

Hi Andrew,

I came into a similar problem when using perl_eval_pv which internally
calls
perl_eval_sv. Likewise I found I could retrieve compilation errors by
passing G_KEEPERR and G_EVAL flags and then inspecting ERRSV. If
there's a
compilation error I set my own internal flags and then sv_setpv(ERRSV,"")
myself to suppress any runtime exceptions.

Perhaps it's not an ideal solution but it is a workaround for the time
being

Rich

-----Original Message-----
From​: andrew@​pimlott.net (via RT) [mailto​:perlbug-followup@​perl.org]
Sent​: Thursday, February 06, 2003 10​:22 PM
To​: perl5-porters@​perl.org
Subject​: [perl #20772] perl_eval_sv does not set PL_errgv for compile
errors

# New Ticket Created by andrew@​pimlott.net
# Please include the string​: [perl #20772]
# in the subject line of all future correspondence about this issue.
# <URL​: http​://rt.perl.org/rt2/Ticket/Display.html?id=20772 >

This is a bug report for perl from andrew@​pimlott.net,
generated with the help of perlbug 1.33 running under perl v5.6.1.

-----------------------------------------------------------------
[Please enter your report here]

I was disturbed to find that, in a simple embedded perl interpreter
like the
ones in perlembed, parse-time errors are not caught by perl_eval_sv. That
is, PL_errgv is clean after such an error. For example, if I run the
program at the end of this mail with input

sub foo\(\) \{ 2 \}
foo\(1\);

it will produce no output. Adding G_KEEPERR causes the expected error
("Too
many arguments ..."), but this modifies run-time exceptions, and is
clearly
(according to perlcall) not meant for this problem.

Here is what happens (as far as I can understand)​:

- Perl_eval_sv calls call_body.
- In case of a parse error, ERRSV is set by the parser, and call_body
returns normally. A few lines later, ERRSV is cleared.
- In case of another exception (compile- or run- time), ERRSV is set by
Perl_vcroak, then control jumps back through a longjump to the switch
statement with a new value of ret, so ERRSV is not cleared.

I haven't wrapped my head around the reasoning behind all this, but I
wonder
why ERRSV isn't just cleared prior to call_body?

I haven't tested perl 5.8, and I haven't found a workaround, though I
haven't really looked yet.

At any rate, if this problem will affect every program that follows the
example of perlembed, it really would be best to fix perl_eval_sv. I ran
into it when using the perl scripting support in vim. It made it rather
frustrating to debug my extensions.

Andrew

Simple embedded interpreter​:

/\*
   cc \-o perltry perltry\.c $\(perl \-MExtUtils&#8203;::Embed \-e ccopts \-e

ldopts)

 \*/

\#include \<EXTERN\.h>
\#include \<perl\.h>

static char \*args\[\] = \{ ""\, "\-e"\, "" \};

int main\(int argc\, char \*\*argv\)
\{
    PerlInterpreter \*perl\_interp = NULL;
    char script\[4096\];
    size\_t len;
    SV \*sv;
    char \*err;
    STRLEN length;

    len = fread\(script\, 1\, 4096\, stdin\);
    sv = newSVpv\(script\, len\);

    perl\_interp = perl\_alloc\(\);
    perl\_construct\(perl\_interp\);
    perl\_parse\(perl\_interp\, NULL\, 3\, args\, 0\);
    perl\_eval\_sv\(sv\, G\_DISCARD | G\_NOARGS\);

    err = SvPV\(GvSV\(PL\_errgv\)\, length\);
    if \(length\)
        fprintf\(stderr\, err\);

    return 0;
\}

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

Configured by buildd at Sat Nov 30 17​:45​:17 UTC 2002.

Summary of my perl5 (revision 5.0 version 6 subversion 1) configuration​:
Platform​:
osname=linux, osvers=2.4.19, archname=i386-linux
uname='linux cyberhq 2.4.19 #1 smp sun aug 4 11​:30​:45 pdt 2002 i686
unknown '
config_args='-Dccflags=-DDEBIAN -Dcccdlflags=-fPIC
-Darchname=i386-linux
-Dprefix=/usr -Dprivlib=/usr/share/perl/5.6.1
-Darchlib=/usr/lib/perl/5.6.1
-Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5
-Dvendorarch=/usr/lib/perl5
-Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.6.1
-Dsitearch=/usr/local/lib/perl/5.6.1 -Dman1dir=/usr/share/man/man1
-Dman3dir=/usr/share/man/man3 -Dman1ext=1 -Dman3ext=3perl
-Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Uusesfio -Duseshrplib
-Dlibperl=libperl.so.5.6.1 -Dd_dosuid -des'
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='cc', ccflags ='-DDEBIAN -fno-strict-aliasing -I/usr/local/include
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
optimize='-O2',
cppflags='-DDEBIAN -fno-strict-aliasing -I/usr/local/include'
ccversion='', gccversion='2.95.4 20011002 (Debian prerelease)',
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, usemymalloc=n, prototype=define
Linker and Libraries​:
ld='cc', ldflags =' -L/usr/local/lib'
libpth=/usr/local/lib /lib /usr/lib
libs=-lgdbm -ldb -ldl -lm -lc -lcrypt
perllibs=-ldl -lm -lc -lcrypt
libc=/lib/libc-2.2.5.so, so=so, useshrplib=true,
libperl=libperl.so.5.6.1
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.1​:
/home/pimlott/local/lib/perl5
/usr/local/lib/perl/5.6.1
/usr/local/share/perl/5.6.1
/usr/lib/perl5
/usr/share/perl5
/usr/lib/perl/5.6.1
/usr/share/perl/5.6.1
/usr/local/lib/site_perl
.

---
Environment for perl v5.6.1​:
HOME=/home/pimlott
LANG=C
LANGUAGE (unset)
LC_CTYPE=en_US
LD_LIBRARY_PATH (unset)
LOGDIR (unset)

PATH=/home/pimlott/bin​:/usr/local/atria/bin​:/home/pimlott/local/j2sdk1.4.0/b

in​:/usr/sbin​:/sbin​:/home/pimlott/bin​:/usr/local/atria/bin​:/home/pimlott/loca

l/j2sdk1.4.0/bin​:/usr/sbin​:/sbin​:/usr/local/bin​:/usr/bin​:/bin​:/usr/bin/X11​:/

usr/games
PERL5LIB=/home/pimlott/local/lib/perl5
PERL_BADLANG (unset)
SHELL=/bin/zsh

I couldn't get the original script to run on 5.14.2 -- I guess the API
must've changed -- but running the attached, modified version, ERRSV and
GvSV(PL_errgv) are both properly set. So this appears to have been fixed
already. I vote to close.

@p5pRT
Copy link
Author

p5pRT commented Apr 29, 2012

From @Hugmeir

#include <EXTERN.h>
#include <perl.h>

/*
$ cc -o 20772 20772.c `perl -MExtUtils::Embed -e ccopts -e ldopts`
$ printf "sub foo() { 2 }\nfoo(1);"  | ./20772
*/

int main(int argc, char **argv, char **env) {
   PerlInterpreter *my_perl;
   char *args[] = { "", "-e", "" };
   char script[4096];
   size_t len;
   SV *sv;
   char *err;
   STRLEN length;
      
   my_perl = perl_alloc();
   perl_construct(my_perl);

   len = fread(script, 1, 4096, stdin);
   sv = newSVpv(script, len);

   perl_parse(my_perl, NULL, 3, args, 0);
   perl_eval_sv(sv, G_DISCARD | G_NOARGS);

   err = SvPV(GvSV(PL_errgv), length);
   if (length) {
      sv_dump(ERRSV);
      fprintf(stderr, err);
   }
      
   perl_destruct(my_perl);
   perl_free(my_perl);
   return 1;
}

@p5pRT
Copy link
Author

p5pRT commented Apr 29, 2012

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

No branches or pull requests

1 participant