develooper Front page | perl.perl5.porters | Postings from February 2003

[perl #20772] perl_eval_sv does not set PL_errgv for compile errors

From:
perlbug-followup
Date:
February 6, 2003 14:40
Subject:
[perl #20772] perl_eval_sv does not set PL_errgv for compile errors
Message ID:
rt-20772-50498.18.9807902786829@bugs6.perl.org
# 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::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/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




nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About