This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Re: embedded perl and top_env problem
authorGurusamy Sarathy <gsar@engin.umich.edu>
Fri, 28 Mar 1997 00:31:42 +0000 (19:31 -0500)
committerChip Salzenberg <chip@atlantic.net>
Tue, 25 Mar 1997 19:04:34 +0000 (07:04 +1200)
commitf289f7d2518e7a8a82114282e774adf50fa6ce85
tree4c38fc787d2975f7c76edf0c288a629d955c5f8c
parentd7d933a26349f945f93b2f0dbf85b773d8ca3219
Re: embedded perl and top_env problem

On Mon, 24 Mar 1997 17:29:29 EST, Ken Fox wrote:
>Gurusamy Sarathy wrote:
>> >> Ken Fox wrote:
>> >> > The trouble with die happens in the longjmp to top_env ...
>> Testcase?
>
>Here's a good example that demonstrates both of my longjmp related
>problems.  I'm using 5.003_94 on Solaris 2.5.1 (more info at
>bottom).  I think that the perl_call_* API is being used correctly.
>
>---------------------------------------- BEGIN crash.c
>#include <EXTERN.h>
>#include <perl.h>
>static PerlInterpreter *my_perl;
>
>int call_sub(SV *sub)
>{
>    int result = -1;
>    int count;
>    dSP;
>
>    ENTER;
>    SAVETMPS;
>
>    PUSHMARK(sp);
>    XPUSHs(sv_2mortal(newSViv(1)));
>    PUTBACK;
>    count = perl_call_sv(sub, G_SCALAR);
>    SPAGAIN;
>    if (count == 1) result = POPi;
>    PUTBACK;
>
>    FREETMPS;
>    LEAVE;
>    return result;
>}
>
>int main(int argc, char *argv[], char *envp[])
>{
>    char *perl_args[] = { 0, "-e",
>              "sub ok { $_[0] + 1; } sub crash { die 'crash\n'; }", 0 };
>    my_perl = perl_alloc();
>    perl_construct(my_perl);
>    perl_parse(my_perl, 0, 3, perl_args, 0);
>    perl_run(my_perl);
>
>    /* this call works fine -- no error */
>    printf("   sub ok: return = %d\n", call_sub((SV *)perl_get_cv("ok", FALSE)));
>    /* this call eventually inokes die() which mangles the C stack with long jump */
>    printf("sub crash: return = %d\n", call_sub((SV *)perl_get_cv("crash", FALSE)));
>    /* this call is bogus but perl mangles the C stack with long jump trying to
>       tell me about it. */
>    printf(" sv_undef: return = %d\n", call_sub(&sv_undef));
>    perl_destruct(my_perl);
>    perl_free(my_perl);
>    return 0;
>}
>---------------------------------------- END crash.c
>
>I don't expect either of these cases to trap the error and go on -- I'd
>have used G_EVAL to do that.  What I do expect is that the C stack isn't
>scrambled when the error occurs -- that makes it virtually impossible to
>catch in a debugger:

Here's a patch for the above problem, which is symptomatic of larger
problems with perl_call_*() calls that happen outside perl_run() or
perl_parse().  Perl invokes longjmp() without checking if an associated
setjmp() exists.  This is likely to cause coredumps galore for all the
perl embedfellows out there.

Note the size of this patch is mostly due to the conversion of the
DOCATCH() business to macros in order to give it a semblance of
order.  It also does away with redundant calls to setjmp() (the
:restart branch in perl_call_sv()), and uses the C stack instead of
Copy().

I finished this patch yesterday, and gave it a day with my production
embeded app, so I'm fairly sure it don't have no bugs. :-)

p5p-msgid: 199703280031.TAA05711@aatma.engin.umich.edu
gv.c
interp.sym
perl.c
perl.h
pp_ctl.c
pp_sys.c
scope.h
util.c